<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="dark">
<meta name="referrer" content="no-referrer">
<meta name="robots" content="noindex">
<meta name="description" content="A huddle relay — terminal-native, end-to-end encrypted chat over Tor. The relay only ever moves ciphertext.">
<title>huddle · onion relay</title>
<style>
:root{
--bg:#0a0c10;
--panel:rgba(255,255,255,.035);
--line:rgba(255,255,255,.09);
--text:#e7eaf0;
--dim:#8a93a4;
--accent:#5ad6c9;
--magenta:#c79bff;
--radius:14px;
--mono:ui-monospace,"SFMono-Regular",Menlo,Consolas,"DejaVu Sans Mono","Liberation Mono",monospace;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
min-height:100vh;
background:var(--bg);
color:var(--text);
font-family:var(--mono);
line-height:1.6;
-webkit-font-smoothing:antialiased;
display:flex;align-items:center;justify-content:center;
padding:clamp(20px,5vw,64px);
overflow-x:hidden;
}
.aurora{position:fixed;inset:0;z-index:-1;overflow:hidden;
background:radial-gradient(120% 120% at 50% 0%,#0d1118 0%,#070809 72%)}
.blob{position:absolute;border-radius:50%;filter:blur(90px);opacity:.45;will-change:transform}
.b1{width:46vmax;height:46vmax;left:-10vmax;top:-14vmax;background:#119c92;animation:drift1 26s ease-in-out infinite}
.b2{width:40vmax;height:40vmax;right:-12vmax;top:4vmax;background:#6d28d9;animation:drift2 32s ease-in-out infinite}
.b3{width:34vmax;height:34vmax;left:28vmax;bottom:-18vmax;background:#1d4ed8;opacity:.30;animation:drift3 38s ease-in-out infinite}
@keyframes drift1{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(8vmax,6vmax) scale(1.12)}}
@keyframes drift2{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(-7vmax,8vmax) scale(1.08)}}
@keyframes drift3{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(-5vmax,-7vmax) scale(1.15)}}
main{width:100%;max-width:680px}
.kicker{font-size:.72rem;letter-spacing:.32em;text-transform:uppercase;color:var(--accent);opacity:.85;margin:0 0 14px}
h1{font-size:clamp(2.6rem,9vw,4.2rem);line-height:1;margin:0;font-weight:700;letter-spacing:-.02em;display:flex;align-items:center}
.word{color:var(--text)}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
.word{background:linear-gradient(100deg,#7af2e6,var(--accent) 38%,var(--magenta));
-webkit-background-clip:text;background-clip:text;color:transparent}
}
.cursor{display:inline-block;width:.5ch;height:.92em;background:var(--accent);
margin-left:.14em;border-radius:1px;animation:blink 1.15s steps(1) infinite}
@keyframes blink{0%,50%{opacity:1}50.01%,100%{opacity:0}}
.tag{font-size:clamp(1rem,2.6vw,1.18rem);color:var(--text);margin:20px 0 0}
.lede{color:var(--dim);margin:14px 0 0;font-size:.95rem;max-width:60ch}
.term{margin:34px 0 0;border:1px solid var(--line);border-radius:var(--radius);
background:var(--panel);overflow:hidden;backdrop-filter:blur(6px)}
.term-bar{display:flex;align-items:center;gap:7px;padding:11px 14px;border-bottom:1px solid var(--line)}
.dot{width:11px;height:11px;border-radius:50%;background:#2a2f3a}
.term-bar .label{margin-left:8px;color:var(--dim);font-size:.76rem;letter-spacing:.04em}
.term-body{padding:18px 16px;font-size:.95rem;white-space:pre-wrap;word-break:break-word}
.row{display:block}
.prompt{color:var(--accent);user-select:none}
.cmd{color:var(--text)}
.comment{color:var(--dim)}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin:26px 0 0}
.chip{font-size:.76rem;color:var(--dim);border:1px solid var(--line);border-radius:999px;padding:6px 12px}
.chip b{color:var(--accent);font-weight:600}
.note{color:var(--dim);font-size:.82rem;margin:16px 0 0;max-width:60ch}
.note b{color:var(--magenta);font-weight:600}
.relay{margin:26px 0 0}
.relay .l{font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:var(--dim);margin:0 0 7px}
.addr{display:block;font-size:.82rem;color:var(--text);border:1px solid var(--line);
border-radius:10px;background:rgba(0,0,0,.25);padding:11px 13px;word-break:break-all;user-select:all}
footer{margin:34px 0 0;padding-top:18px;border-top:1px solid var(--line);
display:flex;flex-wrap:wrap;gap:14px;align-items:center;font-size:.82rem;color:var(--dim)}
footer a{color:var(--dim);text-decoration:none;border-bottom:1px solid transparent;transition:color .2s,border-color .2s}
footer a:hover{color:var(--accent);border-bottom-color:var(--accent)}
.sep{opacity:.4}
.rise{opacity:0;transform:translateY(16px);animation:rise .7s cubic-bezier(.2,.65,.3,1) forwards}
@keyframes rise{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
.blob,.cursor{animation:none}
.rise{animation:none;opacity:1;transform:none}
}
</style>
</head>
<body>
<div class="aurora" aria-hidden="true">
<div class="blob b1"></div><div class="blob b2"></div><div class="blob b3"></div>
</div>
<main>
<p class="kicker rise" style="animation-delay:.05s">Tor onion relay</p>
<h1 class="rise" style="animation-delay:.12s">
<span class="word">huddle</span><span class="cursor" aria-hidden="true"></span>
</h1>
<p class="tag rise" style="animation-delay:.20s">Terminal-native, end-to-end encrypted chat over Tor.</p>
<p class="lede rise" style="animation-delay:.28s">
You've reached a huddle relay. It moves ciphertext between people and mailboxes
messages for whoever's offline — it never holds your keys and never sees what you say.
</p>
<div class="term rise" style="animation-delay:.36s" aria-label="install and run">
<div class="term-bar">
<span class="dot"></span><span class="dot"></span><span class="dot"></span>
<span class="label">bash</span>
</div>
<div class="term-body"><span class="row"><span class="prompt">$ </span><span class="cmd">cargo install huddle</span></span><span class="row"><span class="prompt">$ </span><span class="cmd">huddle</span></span><span class="row"><span class="comment"># needs a local Tor daemon — SOCKS5 on 127.0.0.1:9050</span></span></div>
</div>
<div class="chips rise" style="animation-delay:.44s">
<span class="chip"><b>E2E</b> Megolm group sessions</span>
<span class="chip"><b>relay</b> sees only ciphertext</span>
<span class="chip"><b>Tor</b> reachable only as an onion</span>
</div>
<p class="note rise" style="animation-delay:.50s">
<b>heads up:</b> not yet independently audited — read the client source before trusting it with real secrets.
</p>
<div class="relay rise" style="animation-delay:.56s">
<p class="l">this relay</p>
<code class="addr">huddleg2647kbrmngflqai23f4rrc7l5dnszz5lij76uhqzmkebx2mid.onion</code>
</div>
<footer class="rise" style="animation-delay:.62s">
<a href="https://github.com/richer-richard/huddle">view source</a>
<span class="sep">·</span>
<span>v0.9.1</span>
<span class="sep">·</span>
<span>MIT / Apache-2.0</span>
</footer>
</main>
</body>
</html>