-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
611 lines (557 loc) · 42.2 KB
/
Copy pathindex.html
File metadata and controls
611 lines (557 loc) · 42.2 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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- ── SEO ─────────────────────────────────────────────────────────────── -->
<title>The Dojo Bay — public directory of Samourai & Ashigaru Dojo nodes over Tor</title>
<meta name="description" content="A live, community-run directory of Samourai and Ashigaru Dojo nodes, checked over Tor every ten minutes. The directory lives on an onion service — this page tells you what it is and how to reach it.">
<link rel="canonical" href="https://dojobay.org/">
<meta name="robots" content="index, follow, max-image-preview:large">
<meta name="theme-color" content="#0b0b0c">
<meta name="color-scheme" content="dark">
<!-- Open Graph / social. og-image.png is committed in the main repo; copy it here. -->
<meta property="og:type" content="website">
<meta property="og:site_name" content="The Dojo Bay">
<meta property="og:title" content="The Dojo Bay — public Dojo directory, reachable over Tor">
<meta property="og:description" content="A live directory of Samourai and Ashigaru Dojo nodes, checked over Tor every ten minutes. Install Tor Browser, open the onion address, pair a wallet to a node you didn't have to run yourself.">
<meta property="og:url" content="https://dojobay.org/">
<meta property="og:image" content="https://dojobay.org/og-image.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="The Dojo Bay — Public Dojo Directory">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="The Dojo Bay — public Dojo directory, reachable over Tor">
<meta name="twitter:description" content="A live directory of Samourai and Ashigaru Dojo nodes, checked over Tor every ten minutes.">
<meta name="twitter:image" content="https://dojobay.org/og-image.png">
<!-- favicon.svg ships in this repo (matches the header mark and hero emblem); PNG fallbacks for Safari/search. -->
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="icon" href="/favicon-32.png" sizes="32x32" type="image/png">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<!-- Structured data -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "The Dojo Bay",
"url": "https://dojobay.org/",
"description": "A public directory of Samourai and Ashigaru Dojo nodes, checked over Tor every ten minutes. The directory is served as a Tor onion service.",
"inLanguage": "en-GB"
}
</script>
<!--
Fonts: the site's exact families (Archivo, Hanken Grotesk, JetBrains Mono) are
self-hosted woff2 files in the main repo under assets/fonts/. To pixel-match the
onion site, copy that folder into this repo and uncomment the @font-face block
below. Left commented so the default deploy makes ZERO third-party requests and
logs no 404s; a clean system stack renders well in the meantime.
<style>
@font-face{font-family:'Archivo';src:url('/assets/fonts/Archivo-ExtraBold.woff2') format('woff2');font-weight:800;font-display:swap}
@font-face{font-family:'Archivo';src:url('/assets/fonts/Archivo-SemiBold.woff2') format('woff2');font-weight:600;font-display:swap}
@font-face{font-family:'Hanken Grotesk';src:url('/assets/fonts/HankenGrotesk-Regular.woff2') format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Hanken Grotesk';src:url('/assets/fonts/HankenGrotesk-Medium.woff2') format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:'JetBrains Mono';src:url('/assets/fonts/JetBrainsMono-Regular.woff2') format('woff2');font-weight:400;font-display:swap}
</style>
-->
<style>
:root{
--ink:#0b0b0c;
--panel:#131315;
--panel-2:#17171a;
--paper:#f4f4f3;
--muted:#a0a0a8;
--line:rgba(244,244,243,.09);
--line-strong:rgba(244,244,243,.16);
--red:#b5302a;
--red-light:#d6534a;
--font-display:'Archivo',ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
--font-body:'Hanken Grotesk',ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
--font-mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
--wrap:1060px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
margin:0;
background:var(--ink);
color:var(--paper);
font-family:var(--font-body);
font-size:17px;
line-height:1.6;
-webkit-font-smoothing:antialiased;
text-rendering:optimizeLegibility;
/* faint torii-red glow anchored top-centre, then flat ink */
background-image:radial-gradient(120% 90% at 50% -10%, rgba(181,48,42,.22), rgba(11,11,12,0) 60%);
background-repeat:no-repeat;
}
a{color:inherit}
h1,h2,h3{font-family:var(--font-display);font-weight:800;letter-spacing:-.02em;line-height:1.05;margin:0}
p{margin:0}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 24px}
.skip{position:absolute;left:-9999px;top:0;background:var(--paper);color:var(--ink);padding:10px 16px;border-radius:8px;z-index:10}
.skip:focus{left:16px;top:16px}
.eyebrow{
font-family:var(--font-mono);
font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;
color:var(--red-light);
}
/* ── header ─────────────────────────────────────────── */
header{position:sticky;top:0;z-index:5;backdrop-filter:blur(10px);
background:rgba(11,11,12,.66);border-bottom:1px solid var(--line)}
.bar{display:flex;align-items:center;justify-content:space-between;height:62px}
.brand{display:flex;align-items:center;gap:11px;text-decoration:none}
.brand .mark{width:30px;height:30px;flex:0 0 auto}
.brand .word{font-family:var(--font-display);font-weight:800;font-size:16px;letter-spacing:.02em}
.brand .word b{color:var(--red-light);font-weight:800}
.ghlink{display:inline-flex;align-items:center;gap:8px;text-decoration:none;color:var(--muted);
font-family:var(--font-mono);font-size:13px;padding:8px 12px;border:1px solid var(--line);border-radius:9px}
.ghlink:hover{color:var(--paper);border-color:var(--line-strong)}
.ghlink svg{width:16px;height:16px;flex:0 0 auto}
/* ── hero ───────────────────────────────────────────── */
.hero{padding:clamp(56px,10vw,104px) 0 clamp(44px,7vw,68px)}
.hero-grid{display:grid;grid-template-columns:1.12fr .88fr;gap:56px;align-items:center}
.hero-grid>*{min-width:0}
.hero h1{font-size:clamp(34px,6vw,58px);max-width:15ch}
.hero h1 .accent{color:var(--red-light)}
.lede{margin-top:22px;max-width:56ch;color:#d9d9dc;font-size:clamp(17px,2.1vw,19px)}
.lede .q{color:var(--muted)}
.hero-emblem{position:relative;display:flex;align-items:center;justify-content:center}
.hero-emblem::before{content:"";position:absolute;inset:-14%;z-index:0;
background:radial-gradient(closest-side,rgba(181,48,42,.30),rgba(11,11,12,0) 72%)}
.hero-emblem svg{position:relative;z-index:1;width:100%;max-width:430px;height:auto;
animation:floaty 6.5s ease-in-out infinite}
@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
@media (max-width:1000px){.hero-grid{grid-template-columns:1fr;gap:0}.hero-emblem{display:none}}
/* onion address plate */
.onion{margin-top:34px;border:1px solid var(--line-strong);border-radius:14px;background:
linear-gradient(180deg,var(--panel-2),var(--panel));overflow:hidden;width:fit-content;max-width:100%}
.onion .top{display:flex;align-items:center;gap:9px;padding:11px 16px;border-bottom:1px solid var(--line);
font-family:var(--font-mono);font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.onion .dot{width:9px;height:9px;border-radius:50%;background:var(--red-light);
box-shadow:0 0 0 4px rgba(214,83,74,.16)}
.onion .row{display:flex;align-items:stretch;gap:0}
.onion code{flex:0 1 auto;min-width:0;font-family:var(--font-mono);font-size:14px;color:var(--paper);
padding:16px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.onion .copy{flex:0 0 auto;border:0;border-left:1px solid var(--line);background:transparent;color:var(--muted);
font-family:var(--font-mono);font-size:13px;padding:0 18px;cursor:pointer;display:flex;align-items:center;gap:8px}
.onion .copy:hover{color:var(--paper);background:rgba(244,244,243,.04)}
.onion .copy svg{width:15px;height:15px}
.onion .note{padding:11px 16px;border-top:1px solid var(--line);color:var(--muted);font-size:13.5px;
box-sizing:border-box;width:0;min-width:100%}
.onion .note b{color:var(--red-light);font-weight:600}
.cta-row{display:flex;flex-wrap:wrap;gap:14px;margin-top:30px}
.btn{display:inline-flex;align-items:center;gap:10px;text-decoration:none;border-radius:11px;
padding:14px 22px;font-family:var(--font-display);font-weight:600;font-size:15.5px;letter-spacing:.01em;
border:1px solid transparent;transition:transform .08s ease,background .15s ease,border-color .15s ease}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--red);color:#fff;border-color:var(--red)}
.btn-primary:hover{background:var(--red-light);border-color:var(--red-light)}
.btn-ghost{color:var(--paper);border-color:var(--line-strong)}
.btn-ghost:hover{border-color:var(--paper);background:rgba(244,244,243,.04)}
.btn svg{width:17px;height:17px}
/* ── section frame ──────────────────────────────────── */
section{padding:clamp(48px,8vw,84px) 0;border-top:1px solid var(--line)}
.head{max-width:60ch;margin:0 auto 38px;text-align:center}
.head h2{font-size:clamp(26px,4vw,38px)}
.head p{margin-top:14px;color:var(--muted);font-size:17px}
/* how it works */
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.caution{margin-top:20px;color:var(--muted);font-size:14px;text-align:center;
border:1px solid rgba(214,83,74,.28);background:rgba(181,48,42,.07);border-radius:12px;padding:14px 18px}
.caution b{color:var(--red-light);font-weight:600}
.caution code{font-family:var(--font-mono);color:var(--paper);font-size:13px}
.card{border:1px solid var(--line);border-radius:14px;background:var(--panel);padding:26px 24px;text-align:center}
.card .ic{width:46px;height:46px;border-radius:12px;display:flex;align-items:center;justify-content:center;margin-left:auto;margin-right:auto;
background:rgba(181,48,42,.12);border:1px solid rgba(214,83,74,.24)}
.card .ic svg{width:26px;height:26px;color:var(--red-light)}
.card h3{font-size:19px;margin:14px 0 9px}
.card p{color:var(--muted);font-size:15.5px}
/* download cards */
.dl{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.dl .card{display:flex;flex-direction:column}
.dl .plat{display:flex;align-items:center;justify-content:center;gap:11px}
.dl .plat svg{width:24px;height:24px;color:var(--red-light)}
.dl .plat h3{font-size:18px}
.dl .os{font-family:var(--font-mono);font-size:12px;color:var(--muted);margin-top:3px;letter-spacing:.04em}
.dl .card p{margin-top:14px;flex:1}
.dl .card .btn{margin-top:20px;width:100%;justify-content:center;padding:12px 18px;font-size:14.5px}
.dl .card .btn-ghost{border-color:var(--line-strong)}
/* steps */
.steps{margin-top:34px;border:1px solid var(--line);border-radius:14px;background:var(--panel);
display:grid;grid-template-columns:repeat(3,1fr)}
.step{padding:24px 24px;border-left:1px solid var(--line);text-align:center}
.step:first-child{border-left:0}
.step .k{margin-right:8px}
.step .k svg{width:18px;height:18px;color:var(--red-light);vertical-align:-3px}
.step h3{font-size:16px;margin:0 0 6px}
.step p{color:var(--muted);font-size:14.5px}
.verify{margin-top:20px;color:var(--muted);font-size:14px}
.verify a{color:var(--red-light);text-decoration:underline;text-underline-offset:3px}
/* contribute */
.split{display:grid;grid-template-columns:1.3fr .7fr;gap:40px;align-items:center}
.split .body p{color:var(--muted);margin-top:14px}
.split .body p b{color:var(--paper);font-weight:600}
.split .aside{border:1px solid var(--line);border-radius:14px;background:var(--panel);padding:24px}
.split .aside ul{list-style:none;margin:0;padding:0}
.split .aside li{display:flex;gap:11px;padding:9px 0;color:var(--muted);font-size:15px;border-top:1px solid var(--line)}
.split .aside li:first-child{border-top:0}
.split .aside li svg{width:17px;height:17px;color:var(--red-light);flex:0 0 auto;margin-top:3px}
.split .aside .btn{margin-top:20px;width:100%;justify-content:center}
/* footer */
footer{border-top:1px solid var(--line);padding:34px 0 42px;color:var(--muted)}
.disclaimer{font-size:13.5px;line-height:1.7;width:100%}
.disclaimer b{color:var(--paper);font-weight:600}
/* floating back-to-top */
.to-top{position:fixed;right:22px;bottom:22px;z-index:40;width:46px;height:46px;border-radius:50%;
display:flex;align-items:center;justify-content:center;cursor:pointer;
background:var(--red);color:#fff;border:1px solid var(--red-light);
box-shadow:0 8px 22px rgba(0,0,0,.45);opacity:0;transform:translateY(10px);pointer-events:none;
transition:opacity .2s ease,transform .2s ease,background .15s ease}
.to-top.show{opacity:1;transform:translateY(0);pointer-events:auto}
.to-top:hover{background:var(--red-light)}
.to-top svg{width:20px;height:20px}
@media (max-width:480px){.to-top{right:14px;bottom:14px}}
/* responsive */
@media (max-width:860px){
.grid3,.dl{grid-template-columns:1fr;gap:14px}
.steps{grid-template-columns:1fr}
.step{border-left:0;border-top:1px solid var(--line)}
.step:first-child{border-top:0}
.split{grid-template-columns:1fr;gap:28px}
}
@media (max-width:480px){
.ghlink .txt{display:none}
.onion .copy .txt{display:none}
.onion .copy{padding:0 16px}
}
@media (max-width:1000px){
.hero-copy{text-align:center}
.hero-copy h1{margin-left:auto;margin-right:auto}
.hero-copy .lede{margin-left:auto;margin-right:auto}
.hero .onion{margin-left:auto;margin-right:auto;text-align:left;width:100%}
.hero .onion code{flex:1 1 auto}
.hero .cta-row{justify-content:center}
.hero .cta-row .btn{flex:1 1 220px;justify-content:center}
.head{text-align:center}
.head p{margin-left:auto;margin-right:auto}
.verify{text-align:center}
}
@media (prefers-reduced-motion:reduce){
html{scroll-behavior:auto}
*{transition:none!important}
.hero-emblem svg{animation:none}
}
:focus-visible{outline:2px solid var(--red-light);outline-offset:3px;border-radius:4px}
</style>
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<header>
<div class="wrap bar">
<a class="brand" href="/" aria-label="The Dojo Bay home">
<!-- torii-and-waves mark (same geometry as the hero emblem, OG card and favicon) -->
<svg class="mark" viewBox="28 84 268 268" aria-hidden="true" fill="none">
<g fill="#b5302a">
<path d="M40 96 Q160 112 280 96 L280 116 Q160 132 40 116 Z"/>
<path d="M154 116 H166 V124 H154 Z"/>
<path d="M74 124 H246 V144 H74 Z"/>
<path d="M104 126 H124 L118 250 H98 Z"/>
<path d="M196 126 H216 L222 250 H202 Z"/>
</g>
<g stroke="#d6534a" stroke-width="14" stroke-linecap="round" fill="none">
<path d="M50 272 q13.75 -13 27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0"/>
<path d="M50 300 q13.75 -13 27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0" opacity=".72"/>
<path d="M50 328 q13.75 -13 27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0" opacity=".48"/>
</g>
</svg>
<span class="word">THE DOJO <b>BAY</b></span>
</a>
<a class="ghlink" href="https://github.com/Dojobay/dojobay" rel="noopener">
<svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"/></svg>
<span class="txt">Source</span>
</a>
</div>
</header>
<main id="main">
<!-- ── HERO ─────────────────────────────────────────── -->
<div class="hero">
<div class="wrap hero-grid">
<div class="hero-copy">
<h1>A live directory of Dojo nodes,<br><span class="accent">reachable only over Tor.</span></h1>
<p class="lede">The Dojo Bay lists community-run Samourai and Ashigaru Dojo backends, connects to each one over Tor every ten minutes, and shows you which are answering right now, so you can pair a wallet to a full node you didn't have to run yourself. <span class="q">The directory is served as an onion service, so you will need Tor to open it.</span></p>
<div class="onion" aria-label="Onion address for the directory">
<div class="top"><span class="dot" aria-hidden="true"></span> The reference directory lives here</div>
<div class="row">
<code id="onion-addr" data-full="http://dojobayeryasshgghz537de5ckgd5hhi4z5sdeil3roeh65fwhdnu2yd.onion/">http://dojobayeryasshgghz537de5ckgd5hhi4z5sdeil3roeh65fwhdnu2yd.onion/</code>
<button class="copy" id="copy-btn" type="button" aria-label="Copy onion address">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
<span class="txt" id="copy-label">Copy</span>
</button>
</div>
<div class="note">Open this address in <b>Tor Browser</b>. It will not resolve in an ordinary browser.</div>
</div>
<div class="cta-row">
<a class="btn btn-primary" href="#tor">
Get Tor Browser
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M19 12l-7 7-7-7"/></svg>
</a>
<a class="btn btn-ghost" href="https://github.com/Dojobay/dojobay" rel="noopener">
Read the source
</a>
</div>
</div>
<div class="hero-emblem" aria-hidden="true">
<svg viewBox="0 0 320 350" xmlns="http://www.w3.org/2000/svg" fill="none">
<g fill="#b5302a">
<path d="M40 96 Q160 112 280 96 L280 116 Q160 132 40 116 Z"/>
<path d="M154 116 H166 V124 H154 Z"/>
<path d="M74 124 H246 V144 H74 Z"/>
<path d="M104 126 H124 L118 250 H98 Z"/>
<path d="M196 126 H216 L222 250 H202 Z"/>
</g>
<g stroke="#d6534a" stroke-width="8" stroke-linecap="round" fill="none">
<path d="M50 272 q13.75 -13 27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0"/>
<path d="M50 300 q13.75 -13 27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0" opacity=".6"/>
<path d="M50 328 q13.75 -13 27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0 t27.5 0" opacity=".32"/>
</g>
</svg>
</div>
</div>
</div>
<!-- ── HOW IT WORKS ─────────────────────────────────── -->
<section aria-labelledby="how">
<div class="wrap">
<div class="head">
<p class="eyebrow">What it is</p>
<h2 id="how" style="margin-top:12px">A directory, not a custodian.</h2>
<p>The Dojo Bay holds no keys and touches no funds. It publishes a list of independently operated Dojo nodes and keeps a live read on which ones are reachable.</p>
</div>
<div class="grid3">
<div class="card">
<!-- Tor onion mark © The Tor Project, Inc. (CC BY 3.0 US); recoloured for use here. "Tor" and the Onion Logo are trademarks of The Tor Project. -->
<div class="ic"><svg viewBox="0 0 69.9 107.3" fill="currentColor" aria-hidden="true" style="width:20px;height:31px"><path d="M59.9,54.5c-3.4-3.1-7.7-5.6-12.1-8.1c-2-1.1-8.1-5.9-6-12.7l-3.8-1.6c6-9.3,13.8-18.5,23.4-27.1 c-7.7,2.6-14.5,6.6-19.6,13.7c3-6.3,7.9-12.5,13.3-18.8c-7.4,5.3-13.8,11.3-17.8,19.3L40.1,8c-4,7.2-6.8,14.5-7.9,21.8l-5.9-2.4 l-1,0.8c5.2,9.3,2.5,14.2-0.1,15.9C20,47.6,12.5,52.1,8.7,56c-7.2,7.4-9.3,14.4-8.6,23.7c0.7,11.9,9.4,21.8,20.9,25.7 c5.1,1.7,9.8,1.9,15,1.9c8.4,0,17-2.2,23.3-7.5c6.7-5.5,10.6-13.9,10.6-22.5C69.9,68.6,66.3,60.3,59.9,54.5z M18.6,101.8 C9.3,97.3,3.1,87.6,2.7,79.7C1.9,63.6,9.6,58.9,16.8,53c4-3.3,9.6-4.9,12.8-10.8c0.6-1.3,1-4.1,0.2-7.1c-0.3-1-1.8-4.6-2.4-5.4 l8.9,3.9l0,0l0,0c-0.2,4.2-0.3,7.6,0.5,10.7c0.9,3.4,5.3,8.3,7.1,14c3.5,10.8,2.6,24.9,0.1,35.9c-0.4,1.8-1.7,4-3.3,6 c0.6-1.1,1.1-2.2,1.4-3.4c2.5-8.9,3.6-13,2.4-22.8c-0.2-1-0.6-4.2-2.1-7.7C40.3,61,37.1,56,36.7,54.9c-0.7-1.7-1.7-8.9-1.8-13.8 C35,45.3,35.3,53,36.4,56c0.3,1,3.2,5.5,5.3,11c1.4,3.8,1.7,7.3,2,8.3c1,4.5-0.2,12.1-1.8,19.3c-0.5,2.6-1.9,5.6-3.7,7.9 c1-1.4,1.8-3.2,2.4-5.3c1.2-4.2,1.7-9.6,1.6-13c-0.1-2-1-6.3-2.5-10.2c-0.9-2.1-2.2-4.3-3.1-5.8c-1-1.5-1-4.8-1.4-8.6 c0.1,4.1-0.3,6.2,0.7,9.1c0.6,1.7,2.8,4.1,3.4,6.4c0.9,3.1,1.8,6.5,1.7,8.6c0,2.4-0.1,6.8-1.2,11.6c-0.7,3.6-2.3,6.7-4.9,8.7 c1.1-1.4,1.7-2.8,2-4.2c0.4-2.1,0.5-4.1,0.7-6.6c0.2-2.1,0.1-4.8-0.5-7.7c-0.8-3.6-2.1-7.2-2.7-9.7c0.1,2.8,1.2,6.3,1.7,10 c0.4,2.7,0.2,5.4,0.1,7.8c-0.1,2.8-1,7.7-2.2,10.1c-1.2-0.5-1.6-1.2-2.4-2.2c-1-1.3-1.6-2.7-2.2-4.3c-0.5-1.2-1-2.6-1.3-4.1 c-0.3-2.4-0.2-6.1,2.5-9.9c2.1-3,2.5-3.2,3.2-6.7c-1,3.1-1.7,3.4-3.9,6c-2.5,2.9-2.9,7.1-2.9,10.5c0,1.4,0.6,3,1.1,4.5 c0.6,1.6,1.2,3.2,2,4.4c0.6,1,1.4,1.7,2.1,2.2c-2.6-0.7-5.3-1.7-7-3.1c-4.2-3.6-7.9-9.7-8.4-15.1c-0.4-4.4,3.6-10.8,9.3-14 c4.8-2.8,5.9-5.9,6.9-11c-1.4,4.4-2.8,8.2-7.4,10.5C19,75,15.6,80.8,15.9,86.4c0.5,7.1,3.3,12,9,15.9c1.3,0.9,3.1,1.8,5,2.5 c-7.1-1.7-8-2.7-10.4-5.5c0-0.2-0.6-0.6-0.6-0.7c-3.2-3.6-7.2-9.8-8.6-15.5c-0.5-2-1-4.1-0.4-6.1c2.6-9.4,8.3-13,14-16.9 c1.4-1,2.8-1.9,4.1-2.9c3.2-2.5,4-9,4.7-12.7c-1.3,4.5-2.7,10.1-5.2,11.9c-1.3,1-2.9,1.8-4.2,2.7c-5.9,4-11.8,7.8-14.5,17.5 c-0.6,2.5-0.2,4.3,0.4,6.7c1.5,5.9,5.5,12.3,8.9,16.1c0,0,0.6,0.6,0.6,0.6c1.5,1.7,3.4,3,5.7,3.9 C22.3,103.4,20.4,102.7,18.6,101.8z"/></svg></div>
<h3>Onion-only by design</h3>
<p>The directory has no clearnet endpoint. It is reached through Tor, the same network the Dojos themselves run on, so operators and users share one anonymity layer end to end.</p>
</div>
<div class="card">
<div class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg></div>
<h3>Checked every ten minutes</h3>
<p>An automated probe connects to each node through Tor and reads the chain tip. A node counts as active only when its whole stack answers: Tor, the web server, the Dojo API and bitcoind serving block data.</p>
</div>
<div class="card">
<!-- PayNym logo (BIP47 payment-code identity), recoloured to brand red -->
<div class="ic"><svg viewBox="0 0 114.65347 90.400553" fill="currentColor" aria-hidden="true" style="width:30px;height:auto"><g transform="translate(-126.27215,-120.56601)"><path d="m 183.89189,120.56601 c -20.04154,-2e-4 -36.28292,16.67697 -36.28306,37.11711 v 16.90492 h -18.14514 c -1.76805,0 -3.19154,1.42347 -3.19154,3.19153 0,1.76805 1.42349,3.19154 3.19154,3.19154 h 108.27039 c 1.76805,0 3.19154,-1.42349 3.19154,-3.19154 0,-1.76806 -1.42349,-3.19153 -3.19154,-3.19153 H 219.37241 V 159.8649 l -0.002,0.0977 c 0.86082,-20.81488 -14.96976,-38.50652 -35.37665,-39.39243 l -0.0512,-0.004 z m -0.0527,4.71702 c 0.48475,0.0218 0.96521,0.0591 1.44384,0.10232 l 8.1163,8.1163 -9.89139,9.89139 -9.89086,-9.89139 8.13697,-8.13748 c 0.68999,-0.0472 1.38373,-0.0799 2.08514,-0.0811 z m -5.34489,0.47956 -7.73907,7.73906 12.75168,12.75116 12.75116,-12.75116 -7.63726,-7.63777 c 15.40457,3.06473 26.7329,17.26788 26.04492,33.90335 l -0.002,0.0491 v 5.15834 h -18.62212 l 0.21807,-0.21808 -12.75271,-12.75271 -12.75168,12.75116 0.21963,0.21963 h -18.65519 v -7.29155 c 1.1e-4,-16.05881 11.31344,-29.30021 26.17463,-31.92053 z m 5.01261,1.50844 -6.23011,6.23011 6.23011,6.23062 6.23063,-6.23062 z m -15.87552,8.82426 -12.75167,12.75116 12.75322,12.75271 12.75116,-12.75116 z m 31.46578,0.28629 -1.82211,1.8216 1.71204,1.71204 1.8216,-1.8216 z m -31.46423,2.574 9.89087,9.89087 -9.89087,9.89139 -9.89138,-9.89139 z m 31.51229,1.05317 -1.82159,1.82159 1.71204,1.71205 1.82159,-1.82212 z m -3.69176,0.0165 -1.8216,1.82159 1.71204,1.71152 1.8216,-1.82159 z m 7.32358,0.0362 -1.82159,1.82211 1.71152,1.71153 1.8216,-1.8216 z m -35.14462,2.55488 -6.23063,6.23063 6.23063,6.23063 6.23011,-6.23063 z m 24.17785,1.05214 -1.82211,1.82159 1.71204,1.71204 1.82159,-1.82159 z m 3.67523,0 -1.8216,1.82159 1.71204,1.71152 1.8216,-1.82159 z m 7.34477,0.0248 -1.8216,1.82159 1.71153,1.71204 1.82159,-1.82159 z m -3.69693,0.0119 -1.8216,1.82159 1.71204,1.71204 1.8216,-1.82211 z m 7.32358,0.0367 -1.82159,1.82159 1.71204,1.71204 1.82159,-1.82211 z m -18.29036,3.5698 -1.82159,1.82212 1.71204,1.71152 1.82159,-1.8216 z m 3.65973,0.016 -1.82211,1.82211 1.71204,1.71153 1.82159,-1.8216 z m 3.66386,0.0207 -1.8216,1.8216 1.71153,1.71204 1.82211,-1.8216 z m 3.68039,0.005 -1.82159,1.82159 1.71152,1.71204 1.82211,-1.82159 z m 7.34426,0.0253 -1.8216,1.82159 1.71204,1.71204 1.8216,-1.82211 z m -3.70107,0.007 -1.82211,1.8216 1.71204,1.71204 1.8216,-1.8216 z m 7.32307,0.0367 -1.82159,1.8216 1.71204,1.71204 1.82159,-1.82159 z m -18.28984,3.57033 -1.82211,1.82159 1.71204,1.71204 1.82159,-1.82211 z m 3.66386,0.0207 -1.8216,1.82159 1.71205,1.71204 1.82159,-1.82159 z m 3.65921,0.016 -1.8216,1.82159 1.71204,1.71153 1.8216,-1.8216 z m 3.68504,0.009 -1.82159,1.8216 1.71204,1.71152 1.82159,-1.82159 z m 3.63854,0.0269 -1.82159,1.82211 1.71152,1.71153 1.82211,-1.8216 z m -10.96677,3.60702 -1.8216,1.82159 1.71153,1.71204 1.82159,-1.82159 z m 3.66903,0.0253 -1.82212,1.82211 1.71204,1.71152 1.8216,-1.82159 z m 3.65404,0.0114 -1.8216,1.82159 1.71204,1.71204 1.8216,-1.82211 z m -19.34301,0.15658 9.89087,9.89138 -0.21807,0.21808 h -3.66076 l 0.21859,-0.21859 -6.23063,-6.23011 -6.23011,6.23011 0.21859,0.21859 h -3.66179 l -0.21808,-0.21808 z m 15.69982,3.48661 -1.8216,1.82159 1.71204,1.71204 1.8216,-1.82159 z m -51.64336,27.11307 v 5.23482 0.48214 4.53668 a 14.874109,15.247428 0 0 0 14.87403,15.24765 h 3.14554 a 15.902565,16.301697 0 0 0 15.90239,-16.30185 v -3.48248 h 3.85093 v 3.48248 a 15.902565,16.301697 0 0 0 15.90238,16.30185 h 3.14503 a 14.874109,15.247428 0 0 0 14.87403,-15.24765 v -4.53668 -0.48214 -5.23482 z"/></g></svg></div>
<h3>Signed, not trusted</h3>
<p>Operators can sign their pairing code with their BIP47 payment code. Your wallet verifies that signature against their notification address, so a pairing payload is proven to come from the operator rather than from whoever runs the directory. A forged or tampered entry does not pass.</p>
</div>
</div>
</div>
</section>
<!-- ── THE WALLETS ──────────────────────────────────── -->
<section aria-labelledby="wallets-h">
<div class="wrap">
<div class="head">
<p class="eyebrow">The wallets</p>
<h2 id="wallets-h" style="margin-top:12px">What a Dojo is for.</h2>
<p>A Dojo is the backend a wallet talks to. These are the wallets that pair with the nodes listed in the directory.</p>
</div>
<div class="grid3">
<div class="card">
<h3>Ashigaru</h3>
<p>The actively maintained fork, released by the Ashigaru Open Source Project under GPLv3 after Samourai's development ended. A Dojo node is required rather than optional, which is what this directory exists to help with.</p>
<a class="btn btn-primary" href="https://ashigaru.rs/" rel="noopener" style="margin-top:20px;width:100%;justify-content:center;padding:12px 18px;font-size:14.5px">ashigaru.rs</a>
</div>
<div class="card">
<h3>Sentinel</h3>
<p>The watch-only companion: track balances and receive to a wallet whose keys stay offline, by importing an xpub rather than a seed.</p>
<a class="btn btn-ghost" href="https://github.com/wanderingking072/sentinel-android" rel="noopener" style="margin-top:20px;width:100%;justify-content:center;padding:12px 18px;font-size:14.5px">Source & releases</a>
</div>
<div class="card">
<h3>Samourai Wallet</h3>
<p>The original wallet, and the software Dojo was first written for. Development stopped in April 2024 when its founders were arrested, and it is no longer distributed or maintained. Kept here for reference only.</p>
<a class="btn btn-ghost" href="https://web.archive.org/web/20240424023506/https://samouraiwallet.com/" rel="noopener" style="margin-top:20px;width:100%;justify-content:center;padding:12px 18px;font-size:14.5px">Archived site (2024)</a>
</div>
</div>
<p class="caution"><b>Do not use the live Samourai domain.</b> The link above is a 2024 snapshot held by the Internet Archive. The domain itself, <code>samouraiwallet.com</code>, was seized in 2024 and has since passed to a third party serving a convincing fake of the original site; anything downloaded from it should be treated as malicious.</p>
</div>
</section>
<!-- ── GET TOR ──────────────────────────────────────── -->
<section id="tor" aria-labelledby="tor-h">
<div class="wrap">
<div class="head">
<p class="eyebrow">Getting connected</p>
<h2 id="tor-h" style="margin-top:12px">Get on Tor in a few minutes.</h2>
<p>You need a Tor-capable browser to open the directory. Install the right one for your device, then come back and paste the address above.</p>
</div>
<div class="dl">
<div class="card">
<div class="plat">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>
<h3>Desktop</h3>
</div>
<div class="os">Windows · macOS · Linux</div>
<p>The official Tor Browser from the Tor Project. This is the reference build, with the strongest fingerprinting and tracking protections.</p>
<a class="btn btn-primary" href="https://www.torproject.org/download/" rel="noopener">Download Tor Browser</a>
</div>
<div class="card">
<div class="plat">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M17.6 9.48l1.84-3.18a.4.4 0 1 0-.7-.4l-1.86 3.22a11.36 11.36 0 0 0-9.76 0L5.26 5.9a.4.4 0 1 0-.7.4L6.4 9.48A10.78 10.78 0 0 0 1 18h22a10.78 10.78 0 0 0-5.4-8.52ZM7 15.25a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Zm10 0a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Z"/></svg>
<h3>Android</h3>
</div>
<div class="os">Phone · tablet</div>
<p>Tor Browser for Android is an official Tor Project app, with the same multi-relay routing as desktop. Grab it from the same download page or F-Droid.</p>
<a class="btn btn-primary" href="https://www.torproject.org/download/#android" rel="noopener">Get it for Android</a>
</div>
<div class="card">
<div class="plat">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M16.36 12.78c.02 2.5 2.19 3.33 2.22 3.34-.02.06-.35 1.2-1.15 2.37-.69 1.02-1.41 2.03-2.55 2.05-1.11.02-1.47-.66-2.75-.66-1.27 0-1.68.64-2.73.68-1.09.04-1.92-1.1-2.62-2.11-1.42-2.06-2.51-5.83-1.05-8.37.72-1.27 2.02-2.07 3.42-2.09 1.08-.02 2.09.72 2.75.72.66 0 1.89-.9 3.19-.77.54.02 2.07.22 3.05 1.65-.08.05-1.82 1.06-1.8 3.17M14.6 5.3c.58-.71.98-1.69.87-2.67-.84.03-1.86.56-2.47 1.26-.54.62-1.02 1.62-.89 2.58.94.07 1.9-.48 2.49-1.17"/></svg>
<h3>iPhone & iPad</h3>
</div>
<div class="os">iOS · iPadOS</div>
<p>There is no Tor Browser for iOS: Apple requires every iOS browser to use its own WebKit engine, and Tor Browser is a Firefox build. The Tor Project recommends Onion Browser, open source and Tor-routed, as the closest option.</p>
<a class="btn btn-ghost" href="https://apps.apple.com/app/onion-browser/id519296448" rel="noopener">Get Onion Browser</a>
</div>
</div>
<div class="steps">
<div class="step">
<h3><span class="k"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v11"/><path d="m8 11 4 4 4-4"/><path d="M5 20h14"/></svg></span>Install and open it</h3>
<p>Only ever download Tor from torproject.org (or Onion Browser from the App Store). Let it connect to the network.</p>
</div>
<div class="step">
<h3><span class="k"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="3" width="8" height="4" rx="1"/><path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2"/></svg></span>Paste the address</h3>
<p>Copy the <code style="font-family:var(--font-mono);color:var(--paper)">.onion</code> address from the top of this page into the Tor address bar.</p>
</div>
<div class="step">
<h3><span class="k"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="m15.5 8.5-2 5-5 2 2-5 5-2z"/></svg></span>Browse the directory</h3>
<p>See which Dojos are live, open a node's pairing details, and connect your Samourai or Ashigaru wallet.</p>
</div>
</div>
<p class="verify">One habit worth keeping: only ever fetch Tor from the official site, and, if you can, verify the download signature. See the <a href="https://support.torproject.org/tbb/how-to-verify-signature/" rel="noopener">Tor Project's verification guide</a>.</p>
</div>
</section>
<!-- ── CONTRIBUTE ───────────────────────────────────── -->
<section aria-labelledby="run-h">
<div class="wrap split">
<div class="body">
<p class="eyebrow">Operators & builders</p>
<h2 id="run-h" style="margin-top:12px">Run a node, or read the code.</h2>
<p>The Dojo Bay is a static front end with no build step and no framework: <b>plain HTML, CSS and JavaScript</b>, released under the MIT licence. The reachability checker, the onion deployment and the operator submission flow are all in the repository.</p>
<p>If you run a Dojo, you can submit it to the directory; if you would rather host the whole thing yourself, a single command runs a text-based (TUI) installer that stands the stack up in one step, with the rest documented in the README.</p>
</div>
<div class="aside">
<ul>
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg> No build step, no framework, no CDN</li>
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg> Self-hostable as an onion service</li>
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg> One-command TUI installer</li>
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg> Auth47 operator submissions</li>
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg> MIT licensed</li>
</ul>
<a class="btn btn-primary" href="https://github.com/Dojobay/dojobay" rel="noopener">
<svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"/></svg>
Open the repository
</a>
</div>
</div>
</section>
</main>
<footer>
<div class="wrap">
<p class="disclaimer">
<b>No Dojo data is served on this domain.</b> This page exists only to introduce the project and help you reach it over Tor; the directory itself is available exclusively as an onion service. The Dojo Bay is open-source infrastructure for Bitcoin privacy tooling and is not affiliated with the wallets it lists. This page sets no cookies and makes no third-party requests, and the code is open for you to check. Use at your own discretion. © <span id="yr">2026</span> The Dojo Bay contributors · MIT licence.
</p>
</div>
</footer>
<button id="to-top" class="to-top" type="button" aria-label="Back to top" hidden>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
</button>
<script>
// Progressive enhancement only — all content above works with JavaScript off,
// which matters because Tor Browser's "Safest" level disables scripts.
(function () {
var y = document.getElementById('yr');
if (y) y.textContent = new Date().getFullYear();
var btn = document.getElementById('copy-btn');
var addr = document.getElementById('onion-addr');
var label = document.getElementById('copy-label');
var full = (addr && addr.dataset && addr.dataset.full) ? addr.dataset.full : (addr ? addr.textContent.trim() : '');
var host = full ? full.replace(/^https?:\/\//, '').replace(/\/+$/, '') : '';
// Middle-truncate to whatever fits the available width; the full URL stays
// in data-full for copying, so nothing is lost by shortening the display.
function fitAddress() {
if (!addr || !host) return;
var column = addr.parentNode.parentNode.parentNode; // .row -> .onion -> column
var avail = column ? column.clientWidth : 0;
if (!avail) return;
var cs = window.getComputedStyle(addr);
var probe = document.createElement('span');
probe.style.cssText = 'position:absolute;left:-9999px;top:0;white-space:pre;visibility:hidden';
probe.style.fontFamily = cs.fontFamily;
probe.style.fontSize = cs.fontSize;
probe.style.fontWeight = cs.fontWeight;
probe.style.letterSpacing = cs.letterSpacing;
probe.textContent = host;
document.body.appendChild(probe);
var fullW = probe.getBoundingClientRect().width;
probe.textContent = '0';
var charW = probe.getBoundingClientRect().width || 8;
document.body.removeChild(probe);
var padX = (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0);
var space = avail - (btn ? btn.offsetWidth : 0) - padX - 6; // 6px borders + safety
if (space <= 0) return;
if (fullW <= space) { addr.textContent = host; return; }
var maxChars = Math.floor(space / charW);
var lbl = host.replace(/\.onion$/, '');
var room = maxChars - 7; // ".onion" plus the ellipsis
if (room >= lbl.length) { addr.textContent = host; return; }
if (room < 10) room = 10;
var tail = Math.max(4, Math.min(12, Math.round(room * 0.35)));
var head = Math.max(4, room - tail);
addr.textContent = lbl.slice(0, head) + '…' + lbl.slice(-tail) + '.onion';
}
if (addr && full) {
addr.title = full;
fitAddress();
var refit;
window.addEventListener('resize', function () {
clearTimeout(refit); refit = setTimeout(fitAddress, 120);
});
if (document.fonts && document.fonts.ready && document.fonts.ready.then) {
document.fonts.ready.then(fitAddress).catch(function () {});
}
}
if (btn && addr) {
btn.addEventListener('click', function () {
var text = full;
var done = function () {
if (label) { var o = label.textContent; label.textContent = 'Copied'; setTimeout(function(){ label.textContent = o; }, 1600); }
};
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(done).catch(done);
} else {
var ta = document.createElement('textarea');
ta.value = text; ta.setAttribute('readonly', '');
ta.style.position = 'absolute'; ta.style.left = '-9999px';
document.body.appendChild(ta); ta.select();
try { document.execCommand('copy'); } catch (e) {}
document.body.removeChild(ta); done();
}
});
}
var top = document.getElementById('to-top');
if (top) {
top.hidden = false;
var onScroll = function () {
if (window.pageYOffset > 500) top.classList.add('show');
else top.classList.remove('show');
};
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
top.addEventListener('click', function () {
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
window.scrollTo({ top: 0, behavior: reduce ? 'auto' : 'smooth' });
});
}
})();
</script>
</body>
</html>