shell-mirror 1.5.132 → 1.5.138
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/public/.htaccess +7 -0
- package/public/app/dashboard.html +4 -3
- package/public/app/dashboard.js +4 -0
- package/public/app/terminal.html +1 -0
- package/public/contact.html +492 -0
- package/public/how-it-works.html +442 -0
- package/public/images/favicon.png +0 -0
- package/public/images/hero_mockup.png +0 -0
- package/public/images/private_by_design.png +0 -0
- package/public/images/real_terminal_view.png +0 -0
- package/public/images/same_session.png +0 -0
- package/public/images/shellmirror_clean_hero.png +0 -0
- package/public/images/shellmirror_macbook_hero.png +0 -0
- package/public/images/terminal-svgrepo-com.svg +7 -0
- package/public/index.html +909 -570
- package/public/privacy.html +362 -0
- package/server.js +9 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<link rel="icon" type="image/png" href="/images/favicon.png">
|
|
7
|
+
<title>How >shell-mirror Works</title>
|
|
8
|
+
<meta name="description" content=">shell-mirror lets you open the terminal session already running on your computer from your phone. Here is how to set it up.">
|
|
9
|
+
|
|
10
|
+
<meta property="og:type" content="website">
|
|
11
|
+
<meta property="og:title" content="How >shell-mirror Works">
|
|
12
|
+
<meta property="og:description" content=">shell-mirror lets you open the terminal session already running on your computer from your phone.">
|
|
13
|
+
<meta property="og:url" content="https://shellmirror.app/how-it-works">
|
|
14
|
+
|
|
15
|
+
<meta property="twitter:card" content="summary">
|
|
16
|
+
<meta property="twitter:title" content="How >shell-mirror Works">
|
|
17
|
+
<meta property="twitter:description" content=">shell-mirror lets you open the terminal session already running on your computer from your phone.">
|
|
18
|
+
|
|
19
|
+
<!-- Fonts -->
|
|
20
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
21
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
22
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;800&family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
|
|
23
|
+
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet">
|
|
24
|
+
|
|
25
|
+
<!-- Google Analytics 4 -->
|
|
26
|
+
<script>
|
|
27
|
+
window.dataLayer = window.dataLayer || [];
|
|
28
|
+
function gtag(){dataLayer.push(arguments);}
|
|
29
|
+
gtag('js', new Date());
|
|
30
|
+
gtag('config', 'G-LG7ZGLB8FK');
|
|
31
|
+
(function() {
|
|
32
|
+
var script = document.createElement('script');
|
|
33
|
+
script.async = true;
|
|
34
|
+
script.src = 'https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK';
|
|
35
|
+
script.onload = function() { window.gtagLoaded = true; };
|
|
36
|
+
script.onerror = function() { window.gtagLoaded = false; };
|
|
37
|
+
document.head.appendChild(script);
|
|
38
|
+
})();
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<!-- Microsoft Clarity -->
|
|
42
|
+
<script type="text/javascript">
|
|
43
|
+
(function(c,l,a,r,i,t,y){
|
|
44
|
+
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
|
|
45
|
+
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
|
|
46
|
+
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
|
|
47
|
+
})(window, document, "clarity", "script", "sy1w2d7il7");
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<style>
|
|
51
|
+
:root {
|
|
52
|
+
--bg-primary: #121315;
|
|
53
|
+
--bg-secondary: #1b1c1e;
|
|
54
|
+
--bg-tertiary: #1f2022;
|
|
55
|
+
--bg-hover: #292a2c;
|
|
56
|
+
--text-primary: #e3e2e5;
|
|
57
|
+
--text-secondary: #8a8f98;
|
|
58
|
+
--text-muted: #5a5f6a;
|
|
59
|
+
--accent: #7c4dff;
|
|
60
|
+
--accent-light: #cdbdff;
|
|
61
|
+
--accent-hover: #6833ea;
|
|
62
|
+
--success: #00c853;
|
|
63
|
+
--border: rgba(73, 68, 85, 0.15);
|
|
64
|
+
--border-visible: rgba(73, 68, 85, 0.3);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
68
|
+
|
|
69
|
+
body {
|
|
70
|
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
71
|
+
line-height: 1.6;
|
|
72
|
+
color: var(--text-primary);
|
|
73
|
+
background: var(--bg-primary);
|
|
74
|
+
min-height: 100vh;
|
|
75
|
+
-webkit-font-smoothing: antialiased;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.material-symbols-outlined {
|
|
79
|
+
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.container { max-width: 1200px; margin: 0 auto; padding: 0 32px; }
|
|
83
|
+
|
|
84
|
+
/* Header */
|
|
85
|
+
header {
|
|
86
|
+
position: fixed;
|
|
87
|
+
top: 0;
|
|
88
|
+
width: 100%;
|
|
89
|
+
z-index: 100;
|
|
90
|
+
background: rgba(18, 19, 21, 0.6);
|
|
91
|
+
backdrop-filter: blur(20px);
|
|
92
|
+
-webkit-backdrop-filter: blur(20px);
|
|
93
|
+
box-shadow: 0 8px 32px rgba(124, 77, 255, 0.04);
|
|
94
|
+
}
|
|
95
|
+
header .container {
|
|
96
|
+
display: flex;
|
|
97
|
+
justify-content: space-between;
|
|
98
|
+
align-items: center;
|
|
99
|
+
padding-top: 16px;
|
|
100
|
+
padding-bottom: 16px;
|
|
101
|
+
}
|
|
102
|
+
.logo { font-size: 1.3rem; font-weight: 800; color: #f0eff2; letter-spacing: -0.03em; text-decoration: none; }
|
|
103
|
+
.nav-links { display: flex; gap: 32px; align-items: center; }
|
|
104
|
+
.nav-links a { color: var(--text-muted); text-decoration: none; font-size: 0.9rem; font-weight: 500; transition: color 0.2s ease; }
|
|
105
|
+
.nav-links a:hover { color: var(--text-primary); }
|
|
106
|
+
.header-right { display: flex; align-items: center; gap: 16px; }
|
|
107
|
+
.cta-button {
|
|
108
|
+
background: var(--accent); color: white; padding: 10px 22px;
|
|
109
|
+
text-decoration: none; border-radius: 8px; font-weight: 600;
|
|
110
|
+
border: none; cursor: pointer; transition: all 0.2s ease; font-size: 0.9rem;
|
|
111
|
+
box-shadow: 0 4px 16px rgba(124, 77, 255, 0.2);
|
|
112
|
+
}
|
|
113
|
+
.cta-button:hover { background: var(--accent-hover); box-shadow: 0 4px 20px rgba(124, 77, 255, 0.35); }
|
|
114
|
+
|
|
115
|
+
/* Page content */
|
|
116
|
+
.page-header {
|
|
117
|
+
text-align: center;
|
|
118
|
+
padding: 140px 0 40px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.page-header h1 {
|
|
122
|
+
font-size: clamp(1.75rem, 4vw, 2.5rem);
|
|
123
|
+
font-weight: 800;
|
|
124
|
+
margin-bottom: 20px;
|
|
125
|
+
letter-spacing: -0.02em;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.page-header p {
|
|
129
|
+
color: var(--text-secondary);
|
|
130
|
+
font-size: 1.1rem;
|
|
131
|
+
max-width: 600px;
|
|
132
|
+
margin: 0 auto;
|
|
133
|
+
line-height: 1.7;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.content-section {
|
|
137
|
+
padding: 60px 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.content-section:nth-child(even) {
|
|
141
|
+
background: var(--bg-secondary);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.step-detail {
|
|
145
|
+
max-width: 640px;
|
|
146
|
+
margin: 0 auto;
|
|
147
|
+
padding: 40px 0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.step-detail h2 {
|
|
151
|
+
font-size: 1.35rem;
|
|
152
|
+
font-weight: 700;
|
|
153
|
+
margin-bottom: 16px;
|
|
154
|
+
color: var(--text-primary);
|
|
155
|
+
display: flex;
|
|
156
|
+
align-items: center;
|
|
157
|
+
gap: 14px;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.step-num {
|
|
161
|
+
width: 36px;
|
|
162
|
+
height: 36px;
|
|
163
|
+
background: var(--accent);
|
|
164
|
+
border-radius: 50%;
|
|
165
|
+
display: flex;
|
|
166
|
+
align-items: center;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
font-size: 0.85rem;
|
|
169
|
+
font-weight: 800;
|
|
170
|
+
color: white;
|
|
171
|
+
flex-shrink: 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.step-detail p {
|
|
175
|
+
color: var(--text-secondary);
|
|
176
|
+
font-size: 1rem;
|
|
177
|
+
line-height: 1.7;
|
|
178
|
+
margin-bottom: 16px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.install-code {
|
|
182
|
+
background: var(--bg-primary);
|
|
183
|
+
padding: 16px 20px;
|
|
184
|
+
border-radius: 8px;
|
|
185
|
+
border: 1px solid var(--border-visible);
|
|
186
|
+
position: relative;
|
|
187
|
+
display: flex;
|
|
188
|
+
align-items: center;
|
|
189
|
+
margin-top: 16px;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.install-code pre {
|
|
193
|
+
color: var(--accent-light);
|
|
194
|
+
font-family: 'JetBrains Mono', 'Monaco', 'Menlo', monospace;
|
|
195
|
+
font-size: 0.9rem;
|
|
196
|
+
margin: 0;
|
|
197
|
+
padding-right: 40px;
|
|
198
|
+
flex: 1;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.copy-btn {
|
|
202
|
+
position: absolute;
|
|
203
|
+
right: 12px;
|
|
204
|
+
top: 50%;
|
|
205
|
+
transform: translateY(-50%);
|
|
206
|
+
background: var(--bg-hover);
|
|
207
|
+
border: 1px solid var(--border-visible);
|
|
208
|
+
border-radius: 6px;
|
|
209
|
+
padding: 6px 10px;
|
|
210
|
+
color: var(--text-secondary);
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
transition: all 0.15s ease;
|
|
213
|
+
font-size: 0.75rem;
|
|
214
|
+
}
|
|
215
|
+
.copy-btn:hover { background: var(--accent); border-color: var(--accent); color: white; }
|
|
216
|
+
.copy-btn svg { display: block; }
|
|
217
|
+
|
|
218
|
+
/* Closing */
|
|
219
|
+
.closing {
|
|
220
|
+
text-align: center;
|
|
221
|
+
padding: 80px 0 100px;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.closing p {
|
|
225
|
+
color: var(--text-secondary);
|
|
226
|
+
font-size: 1.05rem;
|
|
227
|
+
max-width: 500px;
|
|
228
|
+
margin: 0 auto 32px;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.btn-primary {
|
|
232
|
+
background: linear-gradient(135deg, var(--accent-light), var(--accent));
|
|
233
|
+
color: #1a0050;
|
|
234
|
+
padding: 16px 36px;
|
|
235
|
+
text-decoration: none;
|
|
236
|
+
border-radius: 8px;
|
|
237
|
+
font-weight: 700;
|
|
238
|
+
font-size: 1rem;
|
|
239
|
+
border: none;
|
|
240
|
+
cursor: pointer;
|
|
241
|
+
transition: all 0.2s ease;
|
|
242
|
+
box-shadow: 0 0 40px rgba(124, 77, 255, 0.25);
|
|
243
|
+
}
|
|
244
|
+
.btn-primary:hover { box-shadow: 0 0 50px rgba(124, 77, 255, 0.4); transform: translateY(-1px); }
|
|
245
|
+
|
|
246
|
+
/* Footer */
|
|
247
|
+
footer {
|
|
248
|
+
background: rgba(13, 14, 16, 0.8);
|
|
249
|
+
border-top: 1px solid var(--border);
|
|
250
|
+
padding: 40px 0;
|
|
251
|
+
}
|
|
252
|
+
.footer-inner { display: flex; justify-content: space-between; align-items: center; }
|
|
253
|
+
.footer-brand {
|
|
254
|
+
font-family: 'Space Grotesk', sans-serif;
|
|
255
|
+
font-weight: 700; font-size: 0.85rem; color: var(--text-secondary);
|
|
256
|
+
letter-spacing: 0.15em; text-transform: uppercase;
|
|
257
|
+
}
|
|
258
|
+
.footer-links { display: flex; gap: 28px; }
|
|
259
|
+
.footer-links a {
|
|
260
|
+
color: var(--text-muted); text-decoration: none;
|
|
261
|
+
font-family: 'Space Grotesk', sans-serif; font-size: 0.8rem;
|
|
262
|
+
letter-spacing: 0.1em; text-transform: uppercase; transition: color 0.2s ease;
|
|
263
|
+
}
|
|
264
|
+
.footer-links a:hover { color: var(--accent-light); }
|
|
265
|
+
|
|
266
|
+
@media (max-width: 768px) {
|
|
267
|
+
.container { padding: 0 20px; }
|
|
268
|
+
.page-header { padding: 120px 0 30px; }
|
|
269
|
+
.page-header h1 { font-size: 1.5rem; }
|
|
270
|
+
.header-right .nav-links { display: none; }
|
|
271
|
+
.footer-inner { flex-direction: column; gap: 16px; text-align: center; }
|
|
272
|
+
.install-code pre { font-size: 0.8rem; }
|
|
273
|
+
}
|
|
274
|
+
</style>
|
|
275
|
+
</head>
|
|
276
|
+
<body>
|
|
277
|
+
<header>
|
|
278
|
+
<div class="container">
|
|
279
|
+
<a href="/" class="logo">>shell-mirror</a>
|
|
280
|
+
<div class="header-right">
|
|
281
|
+
<div class="nav-links">
|
|
282
|
+
<a href="/privacy">Privacy</a>
|
|
283
|
+
<a href="/contact">Contact</a>
|
|
284
|
+
</div>
|
|
285
|
+
<div id="header-cta">
|
|
286
|
+
<button class="cta-button" onclick="handleGoogleLogin()">Get Started</button>
|
|
287
|
+
</div>
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
</header>
|
|
291
|
+
|
|
292
|
+
<main>
|
|
293
|
+
<section class="page-header">
|
|
294
|
+
<div class="container">
|
|
295
|
+
<h1>How >shell-mirror works</h1>
|
|
296
|
+
<p>>shell-mirror lets you open the terminal session already running on your computer from your phone.</p>
|
|
297
|
+
</div>
|
|
298
|
+
</section>
|
|
299
|
+
|
|
300
|
+
<section class="content-section">
|
|
301
|
+
<div class="container">
|
|
302
|
+
<div class="step-detail">
|
|
303
|
+
<h2><span class="step-num">1</span> Start on your computer</h2>
|
|
304
|
+
<p>Install >shell-mirror and start it where your terminal session is already running.</p>
|
|
305
|
+
<div class="install-code">
|
|
306
|
+
<pre>npm install -g shell-mirror</pre>
|
|
307
|
+
<button class="copy-btn" onclick="copyToClipboard('npm install -g shell-mirror', this)" title="Copy">
|
|
308
|
+
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V2z"/><path d="M2 6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-2H4a2 2 0 0 1-2-2V6z"/></svg>
|
|
309
|
+
</button>
|
|
310
|
+
</div>
|
|
311
|
+
<div class="install-code" style="margin-top: 8px;">
|
|
312
|
+
<pre>shell-mirror</pre>
|
|
313
|
+
<button class="copy-btn" onclick="copyToClipboard('shell-mirror', this)" title="Copy">
|
|
314
|
+
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V2z"/><path d="M2 6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-2H4a2 2 0 0 1-2-2V6z"/></svg>
|
|
315
|
+
</button>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
</div>
|
|
319
|
+
</section>
|
|
320
|
+
|
|
321
|
+
<section class="content-section">
|
|
322
|
+
<div class="container">
|
|
323
|
+
<div class="step-detail">
|
|
324
|
+
<h2><span class="step-num">2</span> Sign in</h2>
|
|
325
|
+
<p>Sign in with your Google account to connect your phone and computer to the same session.</p>
|
|
326
|
+
</div>
|
|
327
|
+
</div>
|
|
328
|
+
</section>
|
|
329
|
+
|
|
330
|
+
<section class="content-section">
|
|
331
|
+
<div class="container">
|
|
332
|
+
<div class="step-detail">
|
|
333
|
+
<h2><span class="step-num">3</span> Open on your phone</h2>
|
|
334
|
+
<p>Open the session from your phone and continue from where you left off.</p>
|
|
335
|
+
</div>
|
|
336
|
+
</div>
|
|
337
|
+
</section>
|
|
338
|
+
|
|
339
|
+
<section class="closing">
|
|
340
|
+
<div class="container">
|
|
341
|
+
<p>>shell-mirror is meant to keep your place, not replace your setup.</p>
|
|
342
|
+
<button class="btn-primary" onclick="handleGoogleLogin()">Start mirroring</button>
|
|
343
|
+
</div>
|
|
344
|
+
</section>
|
|
345
|
+
|
|
346
|
+
<footer>
|
|
347
|
+
<div class="container footer-inner">
|
|
348
|
+
<div class="footer-brand" id="version-info">>shell-mirror</div>
|
|
349
|
+
<div class="footer-links">
|
|
350
|
+
<a href="/how-it-works">How it works</a>
|
|
351
|
+
<a href="/privacy">Privacy</a>
|
|
352
|
+
<a href="/contact">Contact</a>
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
</footer>
|
|
356
|
+
</main>
|
|
357
|
+
|
|
358
|
+
<script>
|
|
359
|
+
function copyToClipboard(text, button) {
|
|
360
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
361
|
+
const originalHTML = button.innerHTML;
|
|
362
|
+
button.innerHTML = '<span style="font-size: 0.9rem;">✓</span>';
|
|
363
|
+
button.style.background = 'rgba(0, 200, 83, 0.3)';
|
|
364
|
+
setTimeout(() => { button.innerHTML = originalHTML; button.style.background = ''; }, 2000);
|
|
365
|
+
}).catch(err => console.error('Copy failed:', err));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
async function checkAuthStatus() {
|
|
369
|
+
try {
|
|
370
|
+
const response = await fetch('/php-backend/api/auth-status.php');
|
|
371
|
+
const data = await response.json();
|
|
372
|
+
if (data.success && data.data && data.data.authenticated)
|
|
373
|
+
return { isAuthenticated: true, user: data.data.user };
|
|
374
|
+
} catch (error) {}
|
|
375
|
+
return { isAuthenticated: false, user: null };
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function sendGAEvent(n, p) { if (typeof gtag === 'function') gtag('event', n, p); }
|
|
379
|
+
|
|
380
|
+
async function handleGoogleLogin() {
|
|
381
|
+
sendGAEvent('cta_click', { cta_label: 'start_mirroring', cta_location: 'how_it_works_page' });
|
|
382
|
+
window.location.href = '/php-backend/api/auth-login.php?return=' + encodeURIComponent('/app/dashboard');
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
async function openDashboard() { window.location.href = '/app/dashboard.html'; }
|
|
386
|
+
|
|
387
|
+
async function loadVersionInfo() {
|
|
388
|
+
try {
|
|
389
|
+
const response = await fetch('/build-info.json');
|
|
390
|
+
const buildInfo = await response.json();
|
|
391
|
+
const el = document.getElementById('version-info');
|
|
392
|
+
if (el && buildInfo) el.textContent = `>shell-mirror v${buildInfo.version}`.toUpperCase();
|
|
393
|
+
} catch (e) {}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Scroll depth
|
|
397
|
+
const scrollFired = {};
|
|
398
|
+
window.addEventListener('scroll', () => {
|
|
399
|
+
const pct = Math.round((window.scrollY + window.innerHeight) / document.body.scrollHeight * 100);
|
|
400
|
+
[25, 50, 75, 100].forEach(t => {
|
|
401
|
+
if (pct >= t && !scrollFired[t]) { scrollFired[t] = true; sendGAEvent('scroll_depth', { scroll_percent: t, page_title: document.title }); }
|
|
402
|
+
});
|
|
403
|
+
}, { passive: true });
|
|
404
|
+
|
|
405
|
+
// Time on page
|
|
406
|
+
const pageLoadTime = Date.now();
|
|
407
|
+
window.addEventListener('beforeunload', () => {
|
|
408
|
+
sendGAEvent('time_on_page', {
|
|
409
|
+
seconds_on_page: Math.round((Date.now() - pageLoadTime) / 1000),
|
|
410
|
+
page_title: document.title,
|
|
411
|
+
max_scroll_percent: Math.max(...Object.keys(scrollFired).map(Number), 0)
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
async function updateHeaderAndCTA() {
|
|
416
|
+
const authStatus = await checkAuthStatus();
|
|
417
|
+
const headerCta = document.getElementById('header-cta');
|
|
418
|
+
if (authStatus.isAuthenticated) {
|
|
419
|
+
headerCta.innerHTML = `
|
|
420
|
+
<span style="color: var(--text-secondary); font-size: 0.85rem;">Welcome, ${authStatus.user.name || authStatus.user.email}</span>
|
|
421
|
+
<a href="/app/dashboard.html" class="cta-button">Dashboard</a>
|
|
422
|
+
`;
|
|
423
|
+
headerCta.style.display = 'flex';
|
|
424
|
+
headerCta.style.alignItems = 'center';
|
|
425
|
+
headerCta.style.gap = '15px';
|
|
426
|
+
document.querySelectorAll('.btn-primary').forEach(btn => {
|
|
427
|
+
btn.textContent = 'Open Dashboard';
|
|
428
|
+
btn.onclick = openDashboard;
|
|
429
|
+
});
|
|
430
|
+
} else {
|
|
431
|
+
headerCta.innerHTML = '<button class="cta-button" onclick="handleGoogleLogin()">Sign In</button>';
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
document.addEventListener('DOMContentLoaded', async () => {
|
|
436
|
+
sendGAEvent('page_view', { page_title: document.title, page_location: window.location.href });
|
|
437
|
+
await updateHeaderAndCTA();
|
|
438
|
+
loadVersionInfo();
|
|
439
|
+
});
|
|
440
|
+
</script>
|
|
441
|
+
</body>
|
|
442
|
+
</html>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
|
|
3
|
+
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
+
<g id="System / Terminal">
|
|
5
|
+
<path id="Vector" d="M17 15H12M7 10L10 12.5L7 15M3 15.8002V8.2002C3 7.08009 3 6.51962 3.21799 6.0918C3.40973 5.71547 3.71547 5.40973 4.0918 5.21799C4.51962 5 5.08009 5 6.2002 5H17.8002C18.9203 5 19.4796 5 19.9074 5.21799C20.2837 5.40973 20.5905 5.71547 20.7822 6.0918C21 6.5192 21 7.07899 21 8.19691V15.8031C21 16.921 21 17.48 20.7822 17.9074C20.5905 18.2837 20.2837 18.5905 19.9074 18.7822C19.48 19 18.921 19 17.8031 19H6.19691C5.07899 19 4.5192 19 4.0918 18.7822C3.71547 18.5905 3.40973 18.2837 3.21799 17.9074C3 17.4796 3 16.9203 3 15.8002Z" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
6
|
+
</g>
|
|
7
|
+
</svg>
|