-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathabout.html
More file actions
281 lines (260 loc) · 12.5 KB
/
about.html
File metadata and controls
281 lines (260 loc) · 12.5 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About — Sentinel Node Tester</title>
<meta name="description" content="What the Sentinel Node Tester does, how it measures nodes, and what the numbers mean.">
<link rel="stylesheet" href="/sentinel.css">
<script>document.documentElement.dataset.theme = localStorage.getItem('theme') || 'dark';</script>
<style>
:root {
--text-primary: var(--text);
--text-secondary: var(--text-dim);
--glass-border: var(--border);
}
body { min-height: 100vh; overflow-x: hidden; }
h1, h2, h3 { font-family: var(--font-display); }
.glass-panel {
background: var(--glass-bg);
border: 1px solid var(--glass-border);
border-radius: 12px;
}
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--border-hover); }
header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 32px;
height: 60px;
position: sticky;
top: 0;
z-index: 100;
background: var(--glass-bg);
border-bottom: 1px solid var(--border);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.brand-logo { width: 26px; height: 26px; flex-shrink: 0; color: var(--accent); }
.brand-text { display: flex; flex-direction: column; gap: 1px; }
.brand h1 {
font-size: 14px;
font-weight: 700;
letter-spacing: 2px;
color: var(--text);
text-transform: uppercase;
line-height: 1.2;
}
.brand-sub {
font-size: 10px;
font-weight: 500;
letter-spacing: 1px;
color: var(--text-dim);
text-transform: uppercase;
line-height: 1.2;
}
.top-nav { display: flex; gap: 4px; align-items: center; }
.nav-link {
padding: 8px 14px;
font-size: 12px;
font-weight: 600;
letter-spacing: 1px;
text-transform: uppercase;
color: var(--text-dim);
text-decoration: none;
border-radius: 6px;
transition: color .15s, background .15s;
}
.nav-link:hover { color: var(--text); background: var(--bg-input); }
.nav-link.active { color: var(--accent); background: var(--bg-input); }
.header-right { display: flex; align-items: center; gap: 10px; }
.theme-toggle-btn {
display: inline-flex; align-items: center; justify-content: center;
background: transparent; border: 1px solid var(--border); color: var(--text);
cursor: pointer; transition: background .15s, border-color .15s;
}
.theme-toggle-btn:hover { background: var(--bg-input); border-color: var(--border-hover); }
main {
max-width: 820px;
margin: 40px auto;
padding: 0 24px 80px;
}
.about-hero {
padding: 32px 36px;
margin-bottom: 24px;
}
.about-hero h2 {
font-size: 26px;
font-weight: 700;
letter-spacing: -0.3px;
color: var(--text);
margin: 0 0 8px;
}
.about-hero p {
color: var(--text-dim);
font-size: 14px;
line-height: 1.6;
margin: 0;
}
.section {
padding: 24px 28px;
margin-bottom: 16px;
}
.section h3 {
font-size: 12px;
font-weight: 700;
letter-spacing: 1.5px;
text-transform: uppercase;
color: var(--accent);
margin: 0 0 14px;
}
.section p {
color: var(--text);
font-size: 13px;
line-height: 1.7;
margin: 0 0 10px;
}
.section p:last-child { margin-bottom: 0; }
.section strong { color: var(--text); font-weight: 700; }
.section code {
font-family: var(--font-mono);
font-size: 12px;
background: var(--bg-input);
border: 1px solid var(--border);
border-radius: 4px;
padding: 1px 6px;
color: var(--accent);
}
.metric-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 12px;
margin-top: 14px;
}
.metric-item {
padding: 14px 16px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-input);
}
.metric-name {
font-size: 11px;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 4px;
}
.metric-desc {
font-size: 12px;
color: var(--text-dim);
line-height: 1.5;
}
footer {
text-align: center;
padding: 24px;
color: var(--text-muted);
font-size: 11px;
letter-spacing: 0.5px;
text-transform: uppercase;
}
footer a { color: var(--accent); text-decoration: none; }
footer a:hover { text-decoration: underline; }
</style>
</head>
<body>
<header>
<a class="brand" href="/">
<svg width="26" height="26" viewBox="0 0 30 31" fill="none" xmlns="http://www.w3.org/2000/svg" class="brand-logo" aria-hidden="true">
<path d="M27.3966 1.4387C27.7459 1.4387 28.0281 1.72093 28.0281 2.07017V12.1372V12.7626C28.0362 14.0032 28.0464 15.5525 27.8291 17.1951C27.5773 19.1099 27.0778 20.6672 26.3103 21.9566C23.8068 26.1535 19.3093 29.2297 15.0879 29.6399C15.0676 29.6419 15.0473 29.6439 15.027 29.6439C15.0067 29.6439 14.9864 29.6439 14.9661 29.6399C10.7407 29.2256 6.24323 26.1515 3.74372 21.9566C2.97214 20.6672 2.47671 19.1078 2.22493 17.1951C2.0097 15.5525 2.01986 14.0053 2.03001 12.7626V12.1372L2.03204 2.07017C2.03204 1.72093 2.31427 1.4387 2.66351 1.4387H27.3966ZM27.3966 0.17981H2.66148C1.61985 0.17981 0.771119 1.02854 0.771119 2.07017V12.7565C0.758936 13.9606 0.746754 15.6154 0.974166 17.3576C1.25031 19.4469 1.80057 21.1606 2.65945 22.6002C3.97926 24.8134 5.82292 26.7667 7.99349 28.253C10.1844 29.7515 12.5458 30.6632 14.826 30.8886C14.891 30.8967 14.958 30.9008 15.025 30.9008C15.092 30.9008 15.157 30.8967 15.224 30.8886C17.5022 30.6632 19.8636 29.7536 22.0545 28.2551C24.225 26.7688 26.0707 24.8134 27.3926 22.6002C28.2535 21.1586 28.8037 19.4449 29.0779 17.3596C29.3053 15.6337 29.2951 14.0418 29.287 12.7606V12.1332V2.0722C29.287 1.02854 28.4383 0.18184 27.3966 0.18184V0.17981Z" fill="currentColor"/>
<path d="M25.6792 14.1846C25.864 14.3247 26.1279 14.1927 26.1279 13.9612L26.1218 12.6881V3.61598C26.1239 3.45963 25.998 3.33374 25.8416 3.33374H4.21715C4.0608 3.33374 3.93491 3.45963 3.93491 3.61598V9.1957C3.93491 9.43529 3.98974 9.67083 4.09735 9.88402C4.20496 10.0972 4.35928 10.284 4.55217 10.4262L20.8182 22.5907C20.9604 22.6963 20.9705 22.9013 20.8406 23.0232C20.5401 23.3074 20.2233 23.5734 19.8944 23.8252C19.7929 23.9024 19.6548 23.9024 19.5553 23.8272L4.38365 12.4587C4.19887 12.3206 3.93491 12.4505 3.93491 12.684C3.93491 14.6333 3.76232 18.2699 5.40091 21.0557C7.23036 24.1684 10.3715 26.6252 13.604 27.4212C14.071 27.5349 14.538 27.6161 15.005 27.6587C15.0233 27.6608 15.0416 27.6608 15.0578 27.6587C17.1736 27.4679 19.3259 26.5014 21.1736 25.0415C21.6365 24.6739 22.0812 24.278 22.5035 23.8536C23.336 23.0151 24.0629 22.077 24.6619 21.0597C25.2041 20.1399 25.5472 19.1267 25.7645 18.1135C25.8132 17.8942 25.8538 17.6729 25.8904 17.4495C25.9858 16.8688 25.7502 16.282 25.2812 15.9308L11.5086 5.63223C11.2933 5.46979 11.405 5.12664 11.6791 5.12664H13.5025C13.5634 5.12664 13.6223 5.14695 13.673 5.1835L25.6812 14.1866L25.6792 14.1866L25.6792 14.1846Z" fill="currentColor"/>
</svg>
<div class="brand-text">
<h1>Sentinel</h1>
<p class="brand-sub">Public Node Health</p>
</div>
</a>
<nav class="top-nav" aria-label="Site navigation">
<a class="nav-link" href="/">Directory</a>
<a class="nav-link" href="/live">Live</a>
<a class="nav-link active" href="/about">About</a>
</nav>
<div class="header-right">
<button id="btnTheme" class="theme-toggle-btn" onclick="toggleTheme()" title="Toggle light/dark theme" aria-label="Toggle theme" style="width:36px;height:36px;border-radius:8px;">
<svg id="themeIconDark" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
<svg id="themeIconLight" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"></path></svg>
</button>
</div>
</header>
<main>
<section class="glass-panel about-hero">
<h2>About Sentinel Node Tester</h2>
<p>Sentinel is a decentralized privacy network made of independent nodes that carry encrypted traffic. This tool measures every node continuously so you know, at a glance, which nodes are healthy, fast, and reachable right now.</p>
</section>
<section class="glass-panel section">
<h3>What this tester does</h3>
<p>The tester scans the full active node list on the Sentinel chain, then connects to each node, sends real traffic through it, and records the result. This is not a chain-only lookup — it is an end-to-end test of the handshake, the tunnel, and the throughput.</p>
<p>A full scan of the network is called a <strong>batch</strong>. Batches run back-to-back during public testing so the numbers shown are always based on recent, live evidence.</p>
</section>
<section class="glass-panel section">
<h3>What the numbers mean</h3>
<div class="metric-grid">
<div class="metric-item">
<div class="metric-name">Protocol</div>
<div class="metric-desc">The VPN transport the node advertises — WireGuard or V2Ray.</div>
</div>
<div class="metric-item">
<div class="metric-name">Connection test</div>
<div class="metric-desc">Did the cryptographic handshake with the node complete successfully?</div>
</div>
<div class="metric-item">
<div class="metric-name">Speed</div>
<div class="metric-desc">Measured download throughput over the live tunnel, in Mbps.</div>
</div>
<div class="metric-item">
<div class="metric-name">Recent uptime</div>
<div class="metric-desc">How often recent tests have succeeded for this node.</div>
</div>
<div class="metric-item">
<div class="metric-name">Speed over time</div>
<div class="metric-desc">A sparkline showing how throughput has moved across recent batches.</div>
</div>
<div class="metric-item">
<div class="metric-name">Peers</div>
<div class="metric-desc">Active connected clients reported by the node at test time.</div>
</div>
</div>
</section>
<section class="glass-panel section">
<h3>Where the data comes from</h3>
<p>The node list is pulled from the Sentinel chain (v3 LCD <code>/sentinel/node/v3/nodes</code>, with RPC-first fallback across multiple public endpoints). Every result on this site is generated by a real session on that node — nothing is synthetic, and nothing is cached from third parties.</p>
</section>
<section class="glass-panel section">
<h3>What is never shown to the public</h3>
<p>The admin wallet, plan IDs, fee-grant internals, and any operator-side controls stay on the admin surface. This public site is a read-only view of network health. There is nothing to click, nothing to start, and nothing to pay — by design.</p>
</section>
</main>
<footer>
<a href="/live">Live</a>
</footer>
<script>
function toggleTheme() {
const cur = document.documentElement.dataset.theme || 'dark';
const next = cur === 'dark' ? 'light' : 'dark';
document.documentElement.dataset.theme = next;
localStorage.setItem('theme', next);
document.getElementById('themeIconDark').style.display = next === 'dark' ? '' : 'none';
document.getElementById('themeIconLight').style.display = next === 'dark' ? 'none' : '';
}
(function syncIcons() {
const cur = document.documentElement.dataset.theme || 'dark';
document.getElementById('themeIconDark').style.display = cur === 'dark' ? '' : 'none';
document.getElementById('themeIconLight').style.display = cur === 'dark' ? 'none' : '';
})();
</script>
</body>
</html>