Files
Haven/docs/index.html
T
2026-09-05 17:57:27 -04:00

2529 lines
180 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Haven: Private Chat That Lives On Your Machine</title>
<meta name="description" content="Haven is a free, open-source private chat server you run on your own computer. Voice chat, screen sharing, Discord import and bridging, 26 themes, encrypted DMs, bots and more. Join from the desktop app, the Android app, or just a browser link.">
<meta name="keywords" content="private chat, self-hosted, discord alternative, open source, voice chat, screen sharing, encrypted, no cloud, mobile compatible">
<!-- Open Graph -->
<meta property="og:title" content="Haven: Private Chat That Lives On Your Machine">
<meta property="og:description" content="Free, open-source private chat with voice, screen sharing, Discord import and 26 themes. Join from the desktop app, the Android app, or a browser link.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://ancsemi.github.io/Haven/">
<meta property="og:image" content="https://github.com/user-attachments/assets/a3205eb4-7011-4b7b-825e-7aba76aa5c11">
<link rel="canonical" href="https://ancsemi.github.io/Haven/">
<meta name="theme-color" content="#191b28">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Haven: Private Chat That Lives On Your Machine">
<meta name="twitter:description" content="Free, open-source private chat. Voice, streaming, Discord bridging, 26 themes. Desktop app, Android app, or any browser.">
<meta name="twitter:image" content="https://github.com/user-attachments/assets/a3205eb4-7011-4b7b-825e-7aba76aa5c11">
<meta name="twitter:site" content="@ancsemi">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>⬡</text></svg>">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=AW-17950126697"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'AW-17950126697');
</script>
<style>
/* ============================================
RESET & BASE
============================================ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg-deep: #15172a;
--bg-card: #1c1e33;
--bg-card-hover: #252840;
--bg-surface: #191b28;
--bg-hover: #2c2f4a;
--bg-active: #333660;
--bg-input: #15172a;
--accent: #7c5cfc;
--accent-bright: #9478ff;
--accent-dim: #5a3fd4;
--accent-glow: rgba(124, 92, 252, 0.25);
--accent-glow-strong: rgba(124, 92, 252, 0.45);
--green: #43b581;
--green-glow: rgba(67, 181, 129, 0.35);
--danger: #f04747;
--warning: #faa61a;
--pink: #fd79a8;
--text: #e2e4f0;
--text-muted: #9498b3;
--text-dim: #5d6180;
--text-link: #82aaff;
--border: #2d3050;
--border-light: #383b5e;
--radius: 8px;
--radius-lg: 16px;
--font: 'Segoe UI', system-ui, -apple-system, sans-serif;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--font);
background: var(--bg-deep);
color: var(--text);
line-height: 1.6;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { line-height: 1.2; font-weight: 700; }
h1 { font-size: clamp(2.5rem, 6vw, 4.5rem); letter-spacing: -0.03em; }
h2 { font-size: clamp(1.8rem, 4vw, 3rem); letter-spacing: -0.02em; }
h3 { font-size: 1.25rem; }
p { color: var(--text-muted); font-size: 1.1rem; }
a { color: var(--text-link); text-decoration: none; transition: color 0.15s ease; }
a:hover { color: var(--accent-bright); }
.container { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
section { padding: 100px 0; }
/* ============================================
NAV
============================================ */
nav {
position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
background: rgba(21, 23, 42, 0.85);
backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
border-bottom: 1px solid var(--border);
padding: 0 24px; transition: background 0.3s;
}
.nav-inner {
max-width: 1200px; margin: 0 auto;
display: flex; align-items: center; justify-content: space-between; height: 64px;
}
.nav-brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 1.2rem; color: #fff; }
.nav-brand .hex { font-size: 1.6rem; color: var(--accent); filter: drop-shadow(0 0 10px var(--accent-glow)); text-shadow: 0 0 12px var(--accent-glow); }
.nav-links { display: flex; align-items: center; gap: 32px; list-style: none; }
.nav-links a { color: var(--text-muted); font-size: 0.9rem; font-weight: 500; transition: color 0.15s ease; }
.nav-links a:hover { color: var(--text); }
.nav-cta {
background: var(--accent); color: #fff !important; padding: 8px 20px;
border-radius: var(--radius); font-weight: 600; font-size: 0.9rem;
transition: all 0.15s ease; box-shadow: 0 0 16px var(--accent-glow);
}
.nav-cta:hover { background: var(--accent-bright); transform: translateY(-1px); box-shadow: 0 0 24px var(--accent-glow-strong); }
.nav-mobile-toggle { display: none; background: none; border: none; color: var(--text); font-size: 1.5rem; cursor: pointer; padding: 4px; }
/* ============================================
HERO
============================================ */
.hero {
min-height: 100vh; display: flex; align-items: center;
position: relative; overflow: hidden; padding-top: 64px;
}
.hero::before {
content: ''; position: absolute; top: -20%; left: -10%;
width: 600px; height: 600px;
background: radial-gradient(circle, rgba(124, 92, 252, 0.18) 0%, transparent 70%);
animation: floatOrb 15s ease-in-out infinite; pointer-events: none;
}
.hero::after {
content: ''; position: absolute; bottom: -10%; right: -10%;
width: 500px; height: 500px;
background: radial-gradient(circle, rgba(67, 181, 129, 0.12) 0%, transparent 70%);
animation: floatOrb 18s ease-in-out infinite reverse; pointer-events: none;
}
@keyframes floatOrb {
0%, 100% { transform: translate(0, 0); }
33% { transform: translate(30px, -40px); }
66% { transform: translate(-20px, 30px); }
}
.hero-content { position: relative; z-index: 2; text-align: center; max-width: 800px; margin: 0 auto; }
.hero-badge {
display: inline-flex; align-items: center; gap: 8px;
background: rgba(124, 92, 252, 0.12); border: 1px solid rgba(124, 92, 252, 0.3);
padding: 6px 16px; border-radius: 999px; font-size: 0.85rem;
color: var(--accent-bright); margin-bottom: 24px; font-weight: 500;
}
.hero-badge .dot { width: 8px; height: 8px; background: var(--green); border-radius: 50%; animation: pulse 2s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
.hero h1 { color: #fff; margin-bottom: 20px; }
.hero h1 .gradient-text {
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-bright) 40%, var(--text-link) 100%);
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
.hero-subtitle { font-size: clamp(1.1rem, 2.5vw, 1.35rem); color: var(--text-muted); max-width: 600px; margin: 0 auto 40px; line-height: 1.7; }
.hero-actions { display: flex; align-items: center; justify-content: center; gap: 16px; flex-wrap: wrap; margin-bottom: 48px; }
.btn {
display: inline-flex; align-items: center; gap: 10px;
padding: 14px 32px; border-radius: var(--radius); font-weight: 600;
font-size: 1.05rem; transition: all 0.15s ease; cursor: pointer; border: none; text-decoration: none;
}
.btn-primary { background: var(--accent); color: #fff; box-shadow: 0 4px 24px var(--accent-glow), 0 0 0 1px rgba(124, 92, 252, 0.3); }
.btn-primary:hover { background: var(--accent-bright); color: #fff; transform: translateY(-2px); box-shadow: 0 8px 36px var(--accent-glow-strong), 0 0 0 1px rgba(148, 120, 255, 0.5); }
.btn-secondary { background: rgba(255, 255, 255, 0.05); color: var(--text); border: 1px solid var(--border); }
.btn-secondary:hover { background: rgba(255, 255, 255, 0.1); color: #fff; transform: translateY(-2px); border-color: rgba(255, 255, 255, 0.15); }
.btn .icon { font-size: 1.2rem; }
.hero-note { font-size: 0.85rem; color: var(--text-dim); }
.hero-note strong { color: var(--text-muted); }
/* ============================================
DISCORD IMPORT BANNER
============================================ */
.discord-banner {
background: linear-gradient(135deg, #5865f2 0%, #7c5cfc 50%, #43b581 100%);
padding: 2px;
position: relative;
}
.discord-banner-inner {
background: var(--bg-deep);
padding: 64px 24px;
text-align: center;
}
.discord-banner h2 {
color: #fff;
font-size: clamp(1.8rem, 4vw, 2.8rem);
margin-bottom: 16px;
}
.discord-banner h2 .discord-blue { color: #5865f2; }
.discord-banner p {
color: var(--text-muted);
font-size: 1.15rem;
max-width: 700px;
margin: 0 auto 32px;
line-height: 1.7;
}
.discord-features {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 16px;
max-width: 800px;
margin: 0 auto;
}
.discord-feat {
display: inline-flex;
align-items: center;
gap: 8px;
background: rgba(88, 101, 242, 0.12);
border: 1px solid rgba(88, 101, 242, 0.3);
padding: 8px 18px;
border-radius: 999px;
font-size: 0.9rem;
color: var(--text);
font-weight: 500;
}
@media (max-width: 768px) {
.discord-banner-inner { padding: 40px 16px; }
.discord-feat { font-size: 0.8rem; padding: 6px 14px; }
}
/* ============================================
DESKTOP APP BANNER
============================================ */
.desktop-banner {
background: linear-gradient(135deg, #7c5cfc 0%, #43b581 50%, #82aaff 100%);
padding: 2px;
position: relative;
}
.desktop-banner-inner {
background: var(--bg-deep);
padding: 64px 24px;
text-align: center;
}
.desktop-banner h2 {
color: #fff;
font-size: clamp(1.8rem, 4vw, 2.8rem);
margin-bottom: 16px;
}
.desktop-banner .desktop-accent { color: var(--accent-bright); }
.desktop-banner p {
color: var(--text-muted);
font-size: 1.15rem;
max-width: 700px;
margin: 0 auto 32px;
line-height: 1.7;
}
.beta-badge-inline {
display: inline-block;
background: rgba(250, 166, 26, 0.2);
color: var(--warning);
font-size: 0.55em;
font-weight: 700;
padding: 4px 12px;
border-radius: 6px;
border: 1px solid rgba(250, 166, 26, 0.4);
vertical-align: middle;
letter-spacing: 0.08em;
}
.closed-beta-badge-inline {
display: inline-block;
background: rgba(61, 220, 132, 0.15);
color: #3ddc84;
font-size: 0.55em;
font-weight: 700;
padding: 4px 12px;
border-radius: 6px;
border: 1px solid rgba(61, 220, 132, 0.4);
vertical-align: middle;
letter-spacing: 0.08em;
}
/* Android banner */
.android-banner {
background: linear-gradient(135deg, #3ddc84 0%, #2bb55e 50%, #82aaff 100%);
padding: 2px;
position: relative;
}
.android-banner-inner {
background: var(--bg-deep);
padding: 64px 24px;
text-align: center;
}
.android-banner h2 {
color: #fff;
font-size: clamp(1.8rem, 4vw, 2.8rem);
margin-bottom: 16px;
}
.android-banner .android-accent { color: #3ddc84; }
.android-banner p {
color: var(--text-muted);
font-size: 1.15rem;
max-width: 700px;
margin: 0 auto 32px;
line-height: 1.7;
}
.android-beta-email-form {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
margin-top: 28px;
}
.android-beta-email-form input[type="email"] {
padding: 12px 18px;
font-size: 1rem;
border-radius: 8px;
border: 1px solid var(--border-light);
background: var(--bg-card);
color: var(--text);
width: 100%;
max-width: 360px;
outline: none;
transition: border-color 0.15s;
}
.android-beta-email-form input[type="email"]:focus {
border-color: #3ddc84;
box-shadow: 0 0 0 2px rgba(61, 220, 132, 0.2);
}
.android-beta-email-form .btn-android {
padding: 12px 24px;
font-size: 1rem;
font-weight: 600;
border-radius: 8px;
background: linear-gradient(135deg, #3ddc84, #2bb55e);
color: #fff;
border: none;
cursor: pointer;
transition: transform 0.1s, box-shadow 0.15s;
}
.android-beta-email-form .btn-android:hover {
transform: scale(1.03);
box-shadow: 0 4px 20px rgba(61, 220, 132, 0.35);
}
.android-credit {
margin-top: 20px;
font-size: 0.9rem;
color: var(--text-dim);
font-style: italic;
}
@media (max-width: 768px) {
.android-banner-inner { padding: 40px 16px; }
}
@media (max-width: 768px) {
.desktop-banner-inner { padding: 40px 16px; }
}
/* ============================================
COMMUNITY SERVER BANNER
============================================ */
.community-banner {
background: linear-gradient(135deg, #43b581 0%, #7c5cfc 50%, #82aaff 100%);
padding: 2px;
position: relative;
}
.community-banner-inner {
background: var(--bg-deep);
padding: 48px 24px;
text-align: center;
}
.community-banner h2 {
color: #fff;
font-size: clamp(1.5rem, 3vw, 2.2rem);
margin-bottom: 12px;
}
.community-banner .community-accent { color: var(--green); }
.community-banner p {
color: var(--text-muted);
font-size: 1.05rem;
max-width: 600px;
margin: 0 auto 24px;
line-height: 1.7;
}
@media (max-width: 768px) {
.community-banner-inner { padding: 32px 16px; }
}
.hero-screenshot {
position: relative; z-index: 2; max-width: 1000px; margin: 0 auto;
border-radius: var(--radius-lg); overflow: hidden;
box-shadow: 0 20px 80px rgba(0, 0, 0, 0.6), 0 0 0 1px var(--border), 0 0 60px var(--accent-glow);
aspect-ratio: 1920 / 948; /* fixed ratio prevents layout shift during carousel */
}
.hero-screenshot img {
width: 100%; height: 100%; object-fit: cover; display: block;
position: absolute; top: 0; left: 0;
opacity: 0; transition: opacity 1s ease-in-out;
pointer-events: none; /* only the visible frame should take a click */
}
.hero-screenshot img.active { opacity: 1; pointer-events: auto; }
/* ============================================
PLATFORM SHOWCASE (Desktop + Mobile)
============================================ */
.platform-showcase {
background: var(--bg-surface);
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
overflow: hidden;
}
.showcase-layout {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: center;
}
.showcase-text h2 { color: #fff; margin-bottom: 16px; }
.showcase-text p { margin-bottom: 20px; }
.platform-tags {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 24px;
}
.platform-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--bg-card);
border: 1px solid var(--border);
padding: 8px 16px;
border-radius: 999px;
font-size: 0.85rem;
color: var(--text);
font-weight: 500;
}
.platform-tag .ptag-icon { font-size: 1rem; }
/* Phone Mockup Frames */
.phone-mockups {
display: flex;
gap: 24px;
justify-content: center;
align-items: flex-start;
}
.phone-frame {
position: relative;
width: 220px;
background: #000;
border-radius: 28px;
padding: 8px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.08), 0 0 40px var(--accent-glow);
}
.phone-frame::before {
content: '';
position: absolute;
top: 8px;
left: 50%;
transform: translateX(-50%);
width: 80px;
height: 20px;
background: #000;
border-radius: 0 0 12px 12px;
z-index: 5;
}
.phone-frame img {
width: 100%;
height: auto;
border-radius: 20px;
display: block;
}
.phone-frame .phone-label {
text-align: center;
font-size: 0.75rem;
color: var(--text-dim);
margin-top: 10px;
padding-bottom: 2px;
}
.phone-frame:nth-child(2) {
margin-top: 40px;
}
/* ============================================
SCREENSHOT GALLERY (Desktop views)
============================================ */
.screenshot-gallery {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-top: 48px;
}
.screenshot-item {
border-radius: var(--radius-lg);
overflow: hidden;
border: 1px solid var(--border);
transition: all 0.3s ease;
position: relative;
}
.screenshot-item:hover {
border-color: rgba(124, 92, 252, 0.3);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 20px var(--accent-glow);
transform: translateY(-4px);
}
.screenshot-item img {
width: 100%;
height: auto;
display: block;
}
.screenshot-item .ss-caption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 12px 16px;
background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));
font-size: 0.85rem;
color: #fff;
font-weight: 500;
}
/* Single wide screenshot */
.screenshot-wide {
grid-column: span 2;
}
/* ============================================
HOW IT WORKS
============================================ */
.how-it-works {
background: var(--bg-surface);
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
}
.section-header { text-align: center; margin-bottom: 64px; }
.section-header .overline {
display: inline-block; font-size: 0.8rem; font-weight: 600;
text-transform: uppercase; letter-spacing: 0.15em;
color: var(--accent); margin-bottom: 12px;
}
.section-header h2 { color: #fff; margin-bottom: 16px; }
.section-header p { max-width: 560px; margin: 0 auto; font-size: 1.1rem; }
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; position: relative; }
.steps::before {
content: ''; position: absolute; top: 48px;
left: calc(16.66% + 48px); right: calc(16.66% + 48px);
height: 2px;
background: linear-gradient(90deg, var(--accent) 0%, var(--accent-bright) 50%, var(--green) 100%);
opacity: 0.3;
}
.step { text-align: center; position: relative; }
.step-number {
width: 96px; height: 96px; border-radius: var(--radius-lg);
background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-card-hover) 100%);
border: 1px solid var(--border-light);
display: flex; align-items: center; justify-content: center;
margin: 0 auto 20px; font-size: 2.5rem; position: relative; z-index: 2;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}
.step h3 { color: #fff; margin-bottom: 8px; font-size: 1.15rem; }
.step p { font-size: 0.95rem; max-width: 280px; margin: 0 auto; }
/* ============================================
KEY SELLING POINTS
============================================ */
.selling-points { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; margin-top: 64px; }
.sell-card {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--radius-lg); padding: 36px;
transition: all 0.15s ease; position: relative; overflow: hidden;
}
.sell-card:hover {
border-color: rgba(124, 92, 252, 0.35); transform: translateY(-4px);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4), 0 0 20px var(--accent-glow);
}
.sell-card.highlight {
grid-column: span 2;
background: linear-gradient(135deg, rgba(124, 92, 252, 0.08) 0%, rgba(67, 181, 129, 0.04) 100%);
border-color: rgba(124, 92, 252, 0.2);
}
.sell-card .card-icon { font-size: 2rem; margin-bottom: 16px; display: block; }
.sell-card h3 { color: #fff; margin-bottom: 10px; font-size: 1.25rem; }
.sell-card p { font-size: 1rem; line-height: 1.7; }
.sell-card .highlight-tag {
display: inline-block; background: rgba(67, 181, 129, 0.15); color: var(--green);
padding: 4px 12px; border-radius: 4px; font-size: 0.8rem; font-weight: 600; margin-bottom: 16px;
}
/* ============================================
FEATURES GRID
============================================ */
.features-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.feature-card {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--radius); padding: 28px; transition: all 0.15s ease;
}
.feature-card:hover {
border-color: rgba(124, 92, 252, 0.3); background: var(--bg-card-hover);
transform: translateY(-2px); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}
.feature-card .f-icon { font-size: 1.6rem; margin-bottom: 14px; display: block; }
.feature-card h3 { color: #fff; font-size: 1rem; margin-bottom: 6px; }
.feature-card p { font-size: 0.9rem; line-height: 1.6; color: var(--text-muted); }
/* ============================================
THEMES SHOWCASE
============================================ */
.themes-showcase {
margin-top: 48px;
border-radius: var(--radius-lg);
overflow: hidden;
border: 1px solid var(--border);
box-shadow: 0 12px 48px rgba(0, 0, 0, 0.4), 0 0 40px var(--accent-glow);
}
.themes-showcase img { width: 100%; height: auto; display: block; }
/* ============================================
COMPARISON
============================================ */
.comparison-section {
background: var(--bg-surface);
border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.comparison-table {
width: 100%; border-collapse: collapse; background: var(--bg-card);
border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--border);
}
.comparison-table thead th {
background: var(--bg-active); padding: 18px 24px; text-align: left;
font-weight: 600; font-size: 0.95rem; color: #fff; border-bottom: 1px solid var(--border);
}
.comparison-table thead th:first-child { color: var(--text-muted); }
.comparison-table thead th.haven-col { color: var(--accent-bright); }
.comparison-table tbody td {
padding: 14px 24px; border-bottom: 1px solid var(--border);
font-size: 0.9rem; color: var(--text-muted);
}
.comparison-table tbody tr:last-child td { border-bottom: none; }
.comparison-table tbody td:first-child { font-weight: 500; color: var(--text); }
.check { color: var(--green); font-size: 1.2rem; font-weight: 700; }
.cross { color: var(--danger); font-size: 1.2rem; }
.meh { color: var(--warning); font-size: 0.85rem; }
/* ============================================
DOWNLOAD
============================================ */
.download-section { text-align: center; }
.download-card {
max-width: 640px; margin: 0 auto; background: var(--bg-card);
border: 1px solid var(--border); border-radius: var(--radius-lg);
padding: 48px; position: relative; overflow: hidden;
}
.download-card::before {
content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
background: linear-gradient(90deg, var(--accent-dim), var(--accent), var(--accent-bright), var(--green));
box-shadow: 0 0 12px var(--accent-glow);
}
.download-version { font-size: 0.85rem; color: var(--text-dim); margin-top: 4px; margin-bottom: 24px; }
.download-card h2 { color: #fff; margin-bottom: 4px; font-size: 1.6rem; }
.download-btn-group { display: flex; flex-direction: column; gap: 12px; align-items: center; margin-bottom: 32px; }
.download-main { width: 100%; max-width: 400px; justify-content: center; font-size: 1.1rem; padding: 16px 32px; }
.download-alt-links { display: flex; gap: 20px; justify-content: center; flex-wrap: wrap; }
.download-alt-links a { font-size: 0.85rem; color: var(--text-muted); display: inline-flex; align-items: center; gap: 6px; }
.download-alt-links a:hover { color: var(--accent-bright); }
/* Version History */
.version-history { margin-top: 40px; text-align: left; }
.version-toggle {
background: none; border: 1px solid var(--border); color: var(--text-muted);
padding: 10px 20px; border-radius: 8px; cursor: pointer; font-size: 0.9rem;
width: 100%; display: flex; align-items: center; justify-content: space-between;
transition: all 0.2s; font-family: var(--font);
}
.version-toggle:hover { border-color: var(--accent); color: var(--text); }
.version-toggle .arrow { transition: transform 0.3s; }
.version-toggle.open .arrow { transform: rotate(180deg); }
.version-list { max-height: 0; overflow: hidden; transition: max-height 0.4s ease; }
.version-list.open { max-height: 600px; }
.version-list-inner { padding-top: 12px; }
.version-item {
display: flex; align-items: baseline; justify-content: space-between;
padding: 10px 16px; border-radius: 8px; transition: background 0.15s;
}
.version-item:hover { background: rgba(255, 255, 255, 0.03); }
.version-item .v-name { font-weight: 600; color: var(--text); font-size: 0.9rem; }
.version-item .v-date { font-size: 0.8rem; color: var(--text-dim); }
.version-item .v-tag {
display: inline-block; font-size: 0.7rem; padding: 2px 8px; border-radius: 4px;
background: rgba(124, 92, 252, 0.15); color: var(--accent-bright); margin-left: 8px;
}
.version-item .v-tag.latest { background: rgba(67, 181, 129, 0.15); color: var(--green); }
.version-item a { font-size: 0.8rem; }
/* ============================================
SETUP STEPS
============================================ */
.setup-steps { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 48px; }
.setup-step {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--radius); padding: 28px; display: flex; gap: 16px; align-items: flex-start;
}
.setup-step .s-num {
flex-shrink: 0; width: 36px; height: 36px; background: var(--accent);
color: #fff; border-radius: 10px; display: flex; align-items: center;
justify-content: center; font-weight: 700; font-size: 0.95rem;
}
.setup-step h4 { color: #fff; font-size: 1rem; margin-bottom: 4px; }
.setup-step p { font-size: 0.9rem; color: var(--text-muted); }
/* ============================================
SUPPORT / DONATE
============================================ */
.support-section { text-align: center; }
.support-card {
max-width: 560px; margin: 0 auto;
background: linear-gradient(135deg, rgba(124, 92, 252, 0.08) 0%, rgba(67, 181, 129, 0.06) 100%);
border: 1px solid rgba(124, 92, 252, 0.25);
border-radius: var(--radius-lg); padding: 48px;
}
.support-card .heart { font-size: 3rem; margin-bottom: 16px; display: block; }
.support-card h2 { color: #fff; font-size: 1.6rem; margin-bottom: 12px; }
.support-card p { margin-bottom: 24px; max-width: 420px; margin-left: auto; margin-right: auto; }
.btn-donate {
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-bright) 100%);
color: #fff; box-shadow: 0 4px 20px var(--accent-glow);
}
.btn-donate:hover { color: #fff; transform: translateY(-2px); box-shadow: 0 8px 30px var(--accent-glow-strong); }
.support-note { margin-top: 16px; font-size: 0.8rem !important; color: var(--text-dim) !important; }
/* ============================================
FOOTER
============================================ */
footer { border-top: 1px solid var(--border); padding: 48px 0; text-align: center; }
.footer-brand { display: flex; align-items: center; justify-content: center; gap: 10px; font-weight: 700; font-size: 1.1rem; color: #fff; margin-bottom: 12px; }
.footer-brand .hex { font-size: 1.4rem; color: var(--accent); text-shadow: 0 0 10px var(--accent-glow); }
footer p { font-size: 0.85rem; color: var(--text-dim); margin-bottom: 16px; }
.footer-links { display: flex; justify-content: center; gap: 24px; list-style: none; }
.footer-links a { color: var(--text-muted); font-size: 0.85rem; }
.footer-links a:hover { color: #fff; }
/* ============================================
RESPONSIVE
============================================ */
@media (max-width: 1024px) {
.features-grid { grid-template-columns: repeat(2, 1fr); }
.selling-points { grid-template-columns: 1fr; }
.sell-card.highlight { grid-column: span 1; }
.showcase-layout { grid-template-columns: 1fr; gap: 48px; }
.phone-mockups { justify-content: center; }
.screenshot-gallery { grid-template-columns: 1fr; }
.screenshot-wide { grid-column: span 1; }
}
@media (max-width: 768px) {
section { padding: 64px 0; }
.nav-links { display: none; }
.nav-links.open {
display: flex; flex-direction: column; position: absolute;
top: 64px; left: 0; right: 0;
background: rgba(21, 23, 42, 0.97); backdrop-filter: blur(20px);
padding: 24px; gap: 20px; border-bottom: 1px solid var(--border);
}
.nav-mobile-toggle { display: block; }
.steps { grid-template-columns: 1fr; gap: 40px; }
.steps::before { display: none; }
.features-grid { grid-template-columns: 1fr; }
.setup-steps { grid-template-columns: 1fr; }
.comparison-table { font-size: 0.85rem; }
.comparison-table thead th, .comparison-table tbody td { padding: 10px 12px; }
.hero-actions { flex-direction: column; }
.btn { width: 100%; max-width: 320px; justify-content: center; }
.download-card { padding: 32px 24px; }
.phone-frame { width: 160px; border-radius: 22px; padding: 6px; }
.phone-frame img { border-radius: 16px; }
.phone-frame::before { width: 60px; height: 16px; top: 6px; }
}
@media (max-width: 480px) {
.container { padding: 0 16px; }
h1 { font-size: 2rem; }
.hero-subtitle { font-size: 1rem; }
.phone-mockups { gap: 12px; }
.phone-frame { width: 140px; border-radius: 18px; }
}
/* ============================================
ANIMATIONS
============================================ */
.fade-in {
opacity: 0; transform: translateY(24px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.fade-in.visible { opacity: 1; transform: translateY(0); }
.stagger > * { opacity: 0; transform: translateY(16px); transition: opacity 0.5s ease, transform 0.5s ease; }
.stagger.visible > *:nth-child(1) { transition-delay: 0s; }
.stagger.visible > *:nth-child(2) { transition-delay: 0.1s; }
.stagger.visible > *:nth-child(3) { transition-delay: 0.2s; }
.stagger.visible > *:nth-child(4) { transition-delay: 0.25s; }
.stagger.visible > *:nth-child(5) { transition-delay: 0.3s; }
.stagger.visible > *:nth-child(6) { transition-delay: 0.35s; }
.stagger.visible > *:nth-child(7) { transition-delay: 0.4s; }
.stagger.visible > *:nth-child(8) { transition-delay: 0.45s; }
.stagger.visible > *:nth-child(9) { transition-delay: 0.5s; }
.stagger.visible > * { opacity: 1; transform: translateY(0); }
/* ============================================
SCREENSHOT LIGHTBOX
The hero and the gallery crop their images to
fit their frames, so clicking one opens the
whole picture at full size.
============================================ */
.zoomable { cursor: zoom-in; }
.lightbox {
position: fixed; inset: 0; z-index: 3000;
display: none; align-items: center; justify-content: center;
padding: 40px;
background: rgba(8, 9, 18, 0.94);
backdrop-filter: blur(6px);
}
.lightbox.open { display: flex; }
.lightbox img {
max-width: 100%; max-height: 100%; width: auto; height: auto;
object-fit: contain;
border-radius: var(--radius-lg);
box-shadow: 0 20px 80px rgba(0, 0, 0, 0.7), 0 0 0 1px var(--border);
}
.lightbox-close {
position: absolute; top: 22px; right: 26px;
width: 44px; height: 44px; border-radius: 50%;
display: flex; align-items: center; justify-content: center;
border: 1px solid var(--border);
background: rgba(21, 23, 42, 0.92);
color: var(--text); font-size: 1.6rem; line-height: 1;
cursor: pointer; transition: background 0.15s, color 0.15s;
}
.lightbox-close:hover { background: var(--accent); color: #fff; }
.lightbox-caption {
position: absolute; left: 0; right: 0; bottom: 18px;
padding: 0 40px; text-align: center;
color: var(--text-dim); font-size: 0.88rem;
}
@media (max-width: 600px) {
.lightbox { padding: 14px; }
.lightbox-close { top: 10px; right: 12px; }
.lightbox-caption { bottom: 8px; padding: 0 14px; font-size: 0.8rem; }
}
</style>
</head>
<body>
<!-- ===== NAV ===== -->
<nav>
<div class="nav-inner">
<div class="nav-brand"><span class="hex">⬡</span> HAVEN</div>
<button class="nav-mobile-toggle" onclick="document.querySelector('.nav-links').classList.toggle('open')" aria-label="Toggle menu">☰</button>
<ul class="nav-links">
<li><a href="#features">Features</a></li>
<li><a href="#how-it-works">How It Works</a></li>
<li><a href="#screenshots">Screenshots</a></li>
<li><a href="#compare">Compare</a></li>
<li><a href="#download">Download</a></li>
<li><a href="#desktop">Desktop App</a></li>
<li><a href="#android">Android App</a></li>
<li><a href="#community">Try Haven</a></li>
<li><a href="#support">Support</a></li>
<li><a href="https://github.com/ancsemi/Haven" target="_blank" class="nav-cta">GitHub</a></li>
</ul>
</div>
</nav>
<!-- ===== HERO ===== -->
<section class="hero">
<div class="container">
<div class="hero-content">
<div class="hero-badge">
<span class="dot"></span>
Open Source &amp; Free Forever
</div>
<h1>Free private chat that lives on <span class="gradient-text">your machine</span></h1>
<p class="hero-subtitle">
Haven is a full-featured chat server you host yourself. Voice chat, screen sharing, Discord import and two-way bridging, 26 themes, E2E encrypted direct messages, bots, file sharing, and more. No cloud, no Big Tech accounts, no one reading your messages.
</p>
<div class="hero-actions">
<a href="#download" class="btn btn-primary">
<span class="icon">⬇</span> Download Haven
</a>
<a href="#community" class="btn btn-secondary" style="border-color: var(--green); color: var(--green);">
<span class="icon">▶</span> Try it Live
</a>
<a href="https://github.com/ancsemi/Haven" target="_blank" class="btn btn-secondary">
<span class="icon">&#9965;</span> View Source
</a>
</div>
<p class="hero-note">
<strong>Join however you like.</strong> Desktop app, Android app, or just a browser link with nothing to install.
</p>
</div>
<!-- Hero image carousel -->
<div class="hero-screenshot fade-in" style="margin-top: 48px;">
<img src="https://github.com/user-attachments/assets/a3205eb4-7011-4b7b-825e-7aba76aa5c11"
alt="Haven login screen with theme selection" class="active" loading="eager">
<img src="https://github.com/user-attachments/assets/4103f3b8-547a-4508-b4d7-07fb321118e4"
alt="Haven chat interface with voice chat" loading="lazy">
<img src="https://github.com/user-attachments/assets/ac18c642-0410-4900-ba88-52f925cde982"
alt="Haven themed chat view" loading="lazy">
<img src="https://github.com/user-attachments/assets/47bfe39d-4fb2-4923-bf75-cc781e8d57a7"
alt="Haven desktop with channels and sidebar" loading="lazy">
<img src="https://github.com/user-attachments/assets/f745a6b8-ed7a-4f2f-a073-61c001cfda61"
alt="Haven screen sharing and streaming" loading="lazy">
<img src="https://github.com/user-attachments/assets/a6da197e-66df-4df6-a2a8-c215bf02ac10"
alt="Haven theme gallery showcase" loading="lazy">
</div>
</div>
</section>
<!-- ===== COMMUNITY SERVER BANNER ===== -->
<section class="community-banner fade-in" id="community">
<div class="community-banner-inner">
<div class="container">
<h2>🌐 Try Haven: <span class="community-accent">No Download Required</span></h2>
<p>
Want to see what Haven feels like before hosting your own? Jump into the community server
and explore, chat, voice, themes, the works.
</p>
<div style="margin-top: 20px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;">
<a href="https://haven.moviethingy.xyz/?invite=da0b9be7" target="_blank" class="btn btn-primary" style="padding: 14px 32px; font-size: 1.05rem; background: var(--green); box-shadow: 0 4px 24px var(--green-glow);">
<span class="icon">🌐</span> Join Community Server
</a>
</div>
<div style="margin-top: 24px; background: rgba(67, 181, 129, 0.08); border: 1px solid rgba(67, 181, 129, 0.25); border-radius: 12px; padding: 20px 28px; max-width: 480px; margin-left: auto; margin-right: auto;">
<p style="font-size: 0.95rem; color: var(--text); margin-bottom: 0; font-weight: 600;">✅ Just sign up, you'll be dropped straight into the community, no code needed.</p>
<p style="font-size: 0.8rem; color: var(--text-dim); margin: 8px 0 0;">Need to enter it manually? Channel code: <code style="background: rgba(67, 181, 129, 0.18); padding: 2px 8px; border-radius: 4px; color: var(--green); font-weight: 700;">da0b9be7</code></p>
</div>
<p style="margin-top: 16px; font-size: 0.8rem; color: var(--text-dim); font-style: italic;">
Volunteer-hosted community server, thanks MutantRabbit!
</p>
</div>
</div>
</section>
<!-- ===== DISCORD IMPORT BANNER ===== -->
<section class="discord-banner fade-in" id="discord-import">
<div class="discord-banner-inner">
<div class="container">
<h2>📥 Bring your <span class="discord-blue">Discord</span> with you, or keep both</h2>
<p>
Haven imports your whole Discord server: every channel, thread, forum post, reaction, pin and attachment. Paste your token, pick a server, go.
</p>
<p style="margin-top: 14px;">
<strong>Not everyone ready to leave?</strong> Haven passes messages straight to and from your Discord server, both directions, so the friends who stay can still talk to the ones who moved.
</p>
<div class="discord-features">
<span class="discord-feat">💬 Text channels</span>
<span class="discord-feat">📢 Announcements</span>
<span class="discord-feat">🗂️ Forums &amp; tags</span>
<span class="discord-feat">🧵 Threads</span>
<span class="discord-feat">😊 Reactions</span>
<span class="discord-feat">📌 Pins</span>
<span class="discord-feat">📎 Attachments</span>
<span class="discord-feat">🖼️ Avatars</span>
<span class="discord-feat">↩️ Replies</span>
<span class="discord-feat">🛶 Live two-way bridge</span>
</div>
</div>
</div>
</section>
<!-- ===== DESKTOP APP BANNER ===== -->
<section class="desktop-banner fade-in" id="desktop">
<div class="desktop-banner-inner">
<div class="container">
<h2>🖥️ <span class="desktop-accent">Haven Desktop</span></h2>
<p>
A native app with the things a browser cannot do: per-app audio sharing, device switching mid-call,
native notifications, and a system tray. It can also run the Haven server itself.
</p>
<div class="discord-features">
<span class="discord-feat">🎧 Per-App Audio</span>
<span class="discord-feat">🔀 Device Switching</span>
<span class="discord-feat">🔔 Native Notifications</span>
<span class="discord-feat">📍 System Tray</span>
<span class="discord-feat">⚡ One-Click Install</span>
<span class="discord-feat">🏠 Can Host The Server</span>
<span class="discord-feat">🖥️ Windows &amp; Linux</span>
</div>
<div style="margin-top: 28px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;">
<a href="https://github.com/ancsemi/Haven-Desktop/releases/download/v1.4.30/Haven-Setup-1.4.30.exe" class="btn btn-primary" style="padding: 12px 24px; font-size: 1rem;">
<span class="icon">🪟</span> Windows Installer
</a>
<a href="https://github.com/ancsemi/Haven-Desktop/releases/download/v1.4.30/Haven-1.4.30.AppImage" class="btn btn-primary" style="padding: 12px 24px; font-size: 1rem;">
<span class="icon">🐧</span> Linux AppImage
</a>
<a href="https://github.com/ancsemi/Haven-Desktop/releases/download/v1.4.30/haven-desktop_1.4.30_amd64.deb" class="btn btn-primary" style="padding: 12px 24px; font-size: 1rem;">
<span class="icon">📦</span> Linux .deb
</a>
</div>
<div style="margin-top: 12px;">
<a href="https://github.com/ancsemi/Haven-Desktop" target="_blank" class="btn btn-secondary" style="padding: 10px 24px; font-size: 0.95rem;">
<span class="icon">&#9965;</span> View on GitHub
</a>
</div>
<p style="margin-top: 16px; font-size: 0.85rem; color: var(--text-dim);">
Connects to any <strong><a href="https://github.com/ancsemi/Haven" style="color: var(--accent-bright);">Haven server</a></strong>, or hosts one for you.
</p>
</div>
</div>
</section>
<!-- ===== ANDROID APP BANNER ===== -->
<section class="android-banner fade-in" id="android">
<div class="android-banner-inner">
<div class="container">
<h2>📱 <span class="android-accent">Haven</span> Now on Google Play</h2>
<p>
A real Android app, not a web wrapper. Full chat, voice and push notifications,
available now on Google Play.
</p>
<div class="discord-features">
<span class="discord-feat">🤖 Native Android</span>
<span class="discord-feat">🔔 Push Notifications</span>
<span class="discord-feat">💬 Full Chat Support</span>
<span class="discord-feat">🎙️ Voice Chat</span>
<span class="discord-feat">⬡ Built for Haven</span>
</div>
<div style="margin-top:20px;text-align:center">
<a href="https://play.google.com/store/apps/details?id=com.havenapp.mobile" target="_blank" rel="noopener" style="display:inline-block">
<img src="https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png" alt="Get it on Google Play" style="height:60px">
</a>
</div>
<p class="android-credit">Built from the ground up by <strong>Amnibro</strong>. Thank you.</p>
</div>
</div>
</section>
<!-- ===== WORKS EVERYWHERE ===== -->
<section class="platform-showcase" id="mobile">
<div class="container">
<div class="showcase-layout fade-in">
<div class="showcase-text">
<span class="section-header" style="margin-bottom: 0; text-align: left;">
<span class="overline">Works Everywhere</span>
</span>
<h2>Desktop, tablet, and phone</h2>
<p>Haven isn't just for desktop. Friends can join from their phone's browser, no app download required. The interface adapts automatically to any screen size.</p>
<p>Full chat, channels, direct messages, voice chat, and the sidebar, all fully functional on mobile. Just open the link and go.</p>
<div class="platform-tags">
<span class="platform-tag"><span class="ptag-icon">🪟</span> Windows</span>
<span class="platform-tag"><span class="ptag-icon">🍏</span> macOS</span>
<span class="platform-tag"><span class="ptag-icon">🐧</span> Linux</span>
<span class="platform-tag"><span class="ptag-icon">📱</span> iOS Safari</span>
<span class="platform-tag"><span class="ptag-icon">🤖</span> Android</span>
<span class="platform-tag"><span class="ptag-icon">🌐</span> Any Browser</span>
</div>
</div>
<div class="phone-mockups">
<!-- Phone 1: Welcome / Channel view -->
<div class="phone-frame">
<img src="https://github.com/user-attachments/assets/e03573f7-da20-4a8c-bfae-d6f88d2c5e73"
alt="Haven mobile view: Welcome screen with channel selection"
loading="lazy">
<div class="phone-label">Welcome view</div>
</div>
<!-- Phone 2: Sidebar with channels & DMs -->
<div class="phone-frame">
<img src="https://github.com/user-attachments/assets/74bcf6af-4313-42de-a83e-0e1955f1af2b"
alt="Haven mobile view: Sidebar showing channels, DMs, and user profile"
loading="lazy">
<div class="phone-label">Channels &amp; DMs</div>
</div>
</div>
</div>
</div>
</section>
<!-- ===== HOW IT WORKS ===== -->
<section class="how-it-works" id="how-it-works">
<div class="container">
<div class="section-header fade-in">
<span class="overline">Dead Simple</span>
<h2>Up and running in 3 steps</h2>
<p>No terminal commands, no config files. Just double-click. (Docker supported too!)</p>
</div>
<div class="steps stagger">
<div class="step">
<div class="step-number">1️⃣</div>
<h3>Download &amp; unzip</h3>
<p>Download the .zip from GitHub and unzip it anywhere. Desktop is fine.</p>
</div>
<div class="step">
<div class="step-number">2️⃣</div>
<h3>Double-click to start</h3>
<p>Run <strong>Start Haven.bat</strong> (Windows) or <strong>start.sh</strong> (Mac/Linux). It handles everything.</p>
</div>
<div class="step">
<div class="step-number">3️⃣</div>
<h3>Share the link</h3>
<p>Send your friends the link. They open it in a browser, or use the desktop or Android app. Their choice.</p>
</div>
</div>
<div class="setup-steps stagger">
<div class="setup-step">
<div class="s-num">?</div>
<div>
<h4>What's a "self-hosted" server?</h4>
<p>It means the chat runs on YOUR computer, not a company's server. Your messages never leave your machine. You're the cloud.</p>
</div>
</div>
<div class="setup-step">
<div class="s-num">!</div>
<div>
<h4>Do my friends need to download anything?</h4>
<p>Only if they want to. A link in any modern browser works with nothing installed, phones included. If they would rather have a real app, there is a desktop app for Windows and Linux and an Android app on Google Play. Same server either way.</p>
</div>
</div>
<div class="setup-step">
<div class="s-num">🔒</div>
<div>
<h4>Is it secure?</h4>
<p>HTTPS encryption, bcrypt passwords, JWT auth, rate limiting, CSP headers, and more. Check the <a href="https://github.com/ancsemi/Haven" target="_blank">source code</a> yourself.</p>
</div>
</div>
<div class="setup-step">
<div class="s-num">💻</div>
<div>
<h4>What do I need?</h4>
<p>Windows, Mac, or Linux. <a href="https://nodejs.org/" target="_blank">Node.js</a> (free, 2-click install). About 50 MB disk space. That's everything. Or use <strong>Docker</strong>: <code>docker compose up -d</code> and you're done.</p>
</div>
</div>
</div>
</div>
</section>
<!-- ===== KEY SELLING POINTS ===== -->
<section id="features">
<div class="container">
<div class="section-header fade-in">
<span class="overline">Why Haven</span>
<h2>What makes it worth the switch</h2>
<p>A Discord-like experience that's completely private, completely free, and yours to control.</p>
</div>
<div class="selling-points stagger">
<div class="sell-card highlight">
<span class="highlight-tag">Key Differentiator</span>
<span class="card-icon">🌍</span>
<h3>Friends join however they want, including with nothing installed</h3>
<p>One person runs Haven. Everyone else picks: the desktop app, the Android app, or a link in a browser with nothing to install and no account with any company.</p>
</div>
<div class="sell-card">
<span class="card-icon">🎙️</span>
<h3>Crystal-clear voice chat</h3>
<p>Peer-to-peer voice that goes directly between users, not through a middleman server. Per-user volume sliders, mute, deafen, talking indicators, join/leave sounds, and sound effects.</p>
</div>
<div class="sell-card">
<span class="card-icon">🖥️</span>
<h3>Screen sharing &amp; streaming</h3>
<p>Share your screen with anyone in the voice channel. Multiple people can stream at once in a tiled grid. Perfect for watch parties, co-working, or showing gameplay.</p>
</div>
<div class="sell-card">
<span class="card-icon">🔒</span>
<h3>Truly private, with E2E encrypted DMs</h3>
<p>No cloud, no telemetry, no analytics. Messages live on your machine. DMs are end-to-end encrypted, so not even the host can read them. Haven never phones home.</p>
</div>
<div class="sell-card">
<span class="card-icon">📱</span>
<h3>Mobile-ready out of the box</h3>
<p>Fully responsive design that works on any phone or tablet. Channels, DMs, voice chat, and file sharing, all from your mobile browser. No app store needed.</p>
</div>
</div>
</div>
</section>
<!-- ===== SCREENSHOTS ===== -->
<section id="screenshots" style="padding-top: 0;">
<div class="container">
<div class="section-header fade-in">
<span class="overline">See It In Action</span>
<h2>Screenshots</h2>
<p>Haven running with different themes. Every pixel is customizable.</p>
</div>
<div class="screenshot-gallery stagger">
<div class="screenshot-item">
<img src="https://github.com/user-attachments/assets/a2acb368-0cd2-46ab-818e-b2a0785fe2de"
alt="Haven desktop: default Haven theme with voice chat, channels, and DMs"
loading="lazy">
<div class="ss-caption">Haven Theme: Full desktop chat</div>
</div>
<div class="screenshot-item">
<img src="https://github.com/user-attachments/assets/b4d7fd0d-92a1-48f5-a961-574af969cc36"
alt="Haven desktop: activities, games, Flash emulation, and themes"
loading="lazy">
<div class="ss-caption">Activities: Games, Flash emulation &amp; more</div>
</div>
<div class="screenshot-item screenshot-wide">
<img src="https://github.com/user-attachments/assets/b39edb2e-753f-4e38-8522-496a1d5b9dde"
alt="Haven desktop: screen sharing with voice chat, multi-stream, and Win95 theme"
loading="lazy">
<div class="ss-caption">Screen Sharing: Voice chat with multi-stream</div>
</div>
</div>
</div>
</section>
<!-- ===== ALL FEATURES ===== -->
<section style="padding-top: 0;">
<div class="container">
<div class="section-header fade-in">
<span class="overline">Packed</span>
<h2>All the features</h2>
<p>Haven isn't a toy. It's a full-featured chat platform.</p>
</div>
<div class="features-grid stagger">
<div class="feature-card">
<span class="f-icon">📥</span>
<h3>Discord Import</h3>
<p>Import your entire Discord server's history directly from Haven, channels, threads, forums, reactions, pins, attachments, and avatars. Paste your token, pick a server, done.</p>
</div>
<div class="feature-card">
<span class="f-icon">🛶</span>
<h3>Ferry: Two-Way Discord Bridge</h3>
<p>Messages pass both ways between a Haven channel and a Discord channel, under each person&#39;s real name. Friends who stay on Discord can still talk to the ones who left.</p>
</div>
<div class="feature-card">
<span class="f-icon">🎮</span>
<h3>Rich Presence</h3>
<p>See what everyone is playing and listening to. Steam for games, Last.fm or Spotify for music. Optional, and never saved to the database.</p>
</div>
<div class="feature-card">
<span class="f-icon">🎵</span>
<h3>Music &amp; Video Streaming</h3>
<p>Spotify, YouTube, and SoundCloud Listen Together with synced playback and seek bar. Share audio files or screen-share a movie, everyone hears and sees it together in real time.</p>
</div>
<div class="feature-card">
<span class="f-icon">💬</span>
<h3>Rich Chat</h3>
<p>Real-time messaging, image uploads, typing indicators, message editing, replies, emoji reactions, @mentions, and editable channel names with collapsible sub-channels.</p>
</div>
<div class="feature-card">
<span class="f-icon">🎙️</span>
<h3>Voice Chat</h3>
<p>Peer-to-peer audio. Per-user volume sliders. Mute, deafen, noise suppression. Talking indicators.</p>
</div>
<div class="feature-card">
<span class="f-icon">🖥️</span>
<h3>Screen Sharing</h3>
<p>Multi-stream support. Tiled grid layout. Resizable viewer. Share screens simultaneously.</p>
</div>
<div class="feature-card">
<span class="f-icon">🔒</span>
<h3>Encrypted Direct Messages</h3>
<p>End-to-end encrypted DMs using ECDH + AES-256-GCM. Keys sync across devices via password wrapping. Not even the server host can read them.</p>
</div>
<div class="feature-card">
<span class="f-icon">🎨</span>
<h3>26 Themes, Plus Your Own</h3>
<p>Matrix, Tron, HALO, Cyberpunk, Dark Souls, Elden Ring, Minecraft, Win95 and more, plus a colour picker and a plugin system for your own.</p>
</div>
<div class="feature-card">
<span class="f-icon">🎞️</span>
<h3>GIF Search &amp; /gif Command</h3>
<p>Search and send GIFs inline, powered by Tenor. Free API key, one-click admin setup. Star the ones you reuse.</p>
</div>
<div class="feature-card">
<span class="f-icon">📁</span>
<h3>File Sharing</h3>
<p>PDFs, docs, audio, video and archives, with inline players. 25 MB per file by default, raise it as far as your disk allows.</p>
</div>
<div class="feature-card">
<span class="f-icon">🔗</span>
<h3>Link Previews</h3>
<p>Automatic OpenGraph previews for shared URLs with title, description, and thumbnail.</p>
</div>
<div class="feature-card">
<span class="f-icon">⚡</span>
<h3>Slash Commands</h3>
<p>/shrug, /tableflip, /roll, /flip, /me, /tts, with autocomplete and descriptions.</p>
</div>
<div class="feature-card">
<span class="f-icon">🔍</span>
<h3>Message Search</h3>
<p>Ctrl+F to search any channel. Results with highlighted matches and jump-to-message.</p>
</div>
<div class="feature-card">
<span class="f-icon">📌</span>
<h3>Pinned Messages</h3>
<p>Admins can pin important messages. Dedicated panel to browse all pins in a channel.</p>
</div>
<div class="feature-card">
<span class="f-icon">🛡️</span>
<h3>Moderation Tools</h3>
<p>Roles with per-channel permissions. Kick, mute, ban, IP bans, slow mode, automod link filtering, and an audit log.</p>
</div>
<div class="feature-card">
<span class="f-icon">🌐</span>
<h3>Multi-Server</h3>
<p>Add friends' Haven servers to your sidebar. Live online/offline status indicators.</p>
</div>
<div class="feature-card">
<span class="f-icon">🔔</span>
<h3>Notification Sounds</h3>
<p>5 distinct tones. Per-channel volume. Enable/disable per channel. Unread badges persist.</p>
</div>
<div class="feature-card">
<span class="f-icon">🎮</span>
<h3>Games &amp; Activities</h3>
<p>Shippy Container, Flight, Learn to Fly 3, Bubble Tanks 3, Tanks, Super Smash Flash 2, and .io games. Server-wide leaderboards. Flash games via Ruffle emulator.</p>
</div>
<div class="feature-card">
<span class="f-icon">🧵</span>
<h3>Threads</h3>
<p>Branch a conversation off any message. One button lists every thread in the channel, with search.</p>
</div>
<div class="feature-card">
<span class="f-icon">🔑</span>
<h3>Single Sign-On</h3>
<p>Sign in with your own identity provider: Authentik, Keycloak, Authelia, Auth0, anything speaking OpenID Connect.</p>
</div>
<div class="feature-card">
<span class="f-icon">🤖</span>
<h3>Bots &amp; Webhooks</h3>
<p>A REST API for bots: send messages, play soundboard sounds, register slash commands, join voice, get signed callbacks.</p>
</div>
<div class="feature-card">
<span class="f-icon">⬆️</span>
<h3>One-Click Updates &amp; Backups</h3>
<p>Update from inside the app. Haven backs itself up first, then restarts. Backups also run on a schedule, with restore.</p>
</div>
<div class="feature-card">
<span class="f-icon">📲</span>
<h3>Push Notifications</h3>
<p>Real-time notifications on mobile and desktop, with UnifiedPush if you would rather leave Google out.</p>
</div>
<div class="feature-card">
<span class="f-icon">🎭</span>
<h3>Stickers, Personas &amp; Polls</h3>
<p>Your own sticker packs and emoji, alternate characters with <code>::Name</code>, polls, and a soundboard.</p>
</div>
<div class="feature-card">
<span class="f-icon">🚪</span>
<h3>Guests &amp; Invites</h3>
<p>Temporary guest logins, invite links, and per-channel join codes that rotate on their own.</p>
</div>
<div class="feature-card">
<span class="f-icon">🌐</span>
<h3>8 Languages</h3>
<p>English, French, German, Spanish, Polish, Russian, Chinese and Brazilian Portuguese, community translated.</p>
</div>
<div class="feature-card">
<span class="f-icon">☁️</span>
<h3>Connect Without Port Forwarding</h3>
<p>Built-in Cloudflare and LocalTunnel support, plus guides for Tailscale and reverse proxies.</p>
</div>
</div>
</div>
</section>
<!-- ===== COMPARISON ===== -->
<section class="comparison-section" id="compare">
<div class="container">
<div class="section-header fade-in">
<span class="overline">Honest Comparison</span>
<h2>Haven vs. the incumbents</h2>
</div>
<div class="fade-in">
<table class="comparison-table">
<thead>
<tr>
<th></th>
<th class="haven-col">Haven</th>
<th>Fluxer</th>
<th>Discord</th>
<th>Slack</th>
<th>Signal</th>
</tr>
</thead>
<tbody>
<tr>
<td>Self-hosted (you own the data)</td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
</tr>
<tr>
<td>No account with a company</td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
</tr>
<tr>
<td>End-to-end encrypted DMs</td>
<td><span class="check">&#10003;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="check">&#10003;</span></td>
</tr>
<tr>
<td>Voice chat</td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="meh">Paid</span></td>
<td><span class="check">&#10003;</span></td>
</tr>
<tr>
<td>Screen sharing</td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="meh">Paid</span></td>
<td><span class="cross">&#10007;</span></td>
</tr>
<tr>
<td>Open source</td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="check">&#10003;</span></td>
</tr>
<tr>
<td>Themes / customization</td>
<td><span class="check">25+</span></td>
<td><span class="check">CSS</span></td>
<td><span class="meh">Limited</span></td>
<td><span class="meh">Limited</span></td>
<td><span class="cross">&#10007;</span></td>
</tr>
<tr>
<td>Group channels</td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
</tr>
<tr>
<td>No email/phone required</td>
<td><span class="check">&#10003;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
</tr>
<tr>
<td>Free forever (no paid tier)</td>
<td><span class="check">&#10003;</span></td>
<td><span class="meh">Freemium</span></td>
<td><span class="meh">Freemium</span></td>
<td><span class="meh">Freemium</span></td>
<td><span class="check">&#10003;</span></td>
</tr>
<tr>
<td>Friends join with zero install</td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
</tr>
<tr>
<td>Works on mobile browsers</td>
<td><span class="check">&#10003;</span></td>
<td><span class="check">&#10003;</span></td>
<td><span class="cross">App only</span></td>
<td><span class="cross">App only</span></td>
<td><span class="cross">App only</span></td>
</tr>
<tr>
<td>Import history from Discord</td>
<td><span class="check">&#10003;</span></td>
<td><span class="cross">&#10007;</span></td>
<td>n/a</td>
<td><span class="cross">&#10007;</span></td>
<td><span class="cross">&#10007;</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<!-- ===== DOWNLOAD ===== -->
<section class="download-section" id="download">
<div class="container">
<div class="section-header fade-in">
<span class="overline">Get Started</span>
<h2>Download Haven</h2>
<p>One zip file. Unzip, double-click, done.</p>
</div>
<div class="download-card fade-in">
<h2>&#x2B21; Haven Server v4.4.1</h2>
<p class="download-version">Latest stable release &middot; Windows, macOS &amp; Linux &middot; ~5 MB</p>
<div class="download-btn-group">
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v4.4.1.zip" class="btn btn-primary download-main">
<span class="icon">&#x2B07;</span> Download v4.4.1 (.zip)
</a>
<div class="download-alt-links">
<a href="https://github.com/ancsemi/Haven" target="_blank">&#9965; View on GitHub</a>
<a href="https://github.com/ancsemi/Haven/blob/main/GUIDE.md" target="_blank">📖 Setup Guide</a>
<a href="https://github.com/ancsemi/Haven/blob/main/CHANGELOG.md" target="_blank">📋 Full Changelog</a>
</div>
</div>
<div class="version-history">
<button class="version-toggle" onclick="this.classList.toggle('open'); this.nextElementSibling.classList.toggle('open');">
<span>Version History</span>
<span class="arrow">▼</span>
</button>
<div class="version-list">
<div class="version-list-inner">
<div class="version-item">
<div><span class="v-name">v4.4.1</span><span class="v-tag latest">Latest</span> <strong>Fixes a broken page for visitors when Haven runs without a certificate.</strong> With no certificate present Haven falls back to plain HTTP, but it still sent the header telling browsers to load every stylesheet and script over HTTPS, which nothing was answering. Visitors got an unstyled page whose buttons did nothing, while the person hosting saw a perfect page, because browsers exempt localhost from that upgrade. The headers that assume HTTPS are now sent only when Haven is actually serving it. Microphone and camera still need HTTPS on any address other than localhost, so voice needs a certificate or a tunnel.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v4.4.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v4.4.0</span> <strong>Native screen share groundwork, invite email cards, and markdown shortcuts.</strong> The server can now negotiate a native, hardware-encoded screen share with a Haven Desktop build that carries the helper, off by default until you opt in. Each invite link can be copied as a formatted email card in your theme and language. With text selected, Ctrl+I, Ctrl+B, Ctrl+Shift+C, Ctrl+Shift+X and Ctrl+Shift+P wrap it in markdown. Promo popups and the recovery-codes notice remember their dismissal on your account instead of in the browser, login no longer re-asks for the 18+ and Terms checkboxes, and admin settings visibility comes from one access table. Fixed: the Cloudflare tunnel on a fresh Windows install (cloudflared is downloaded for you now), a clearer message when Windows refuses the port, stream bots bridged through Ferry losing their link and thumbnail, reply banners showing [Deleted User] for bots, emoji vanishing from soundboard names, and the Messages sound preview staying silent while the Notifications toggle is off. No migration steps. Thanks to @bernardokcosta, @birdcrazy, @Bo0sted, @delenda-delenda and @Amnibro.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v4.4.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v4.3.0</span> <strong>Forum channels, and Groups you join yourself.</strong> Any channel can be a forum: every message is a topic, replies go in its thread, and a new reply bumps the topic back to the newest end so old topics resurface. A role at level 0 is a Group that members join and leave from their own profile. The whole interface is translatable now, there is a Compact theme and a Compact Layout plugin, a safe mode for when a theme breaks the page, listening presence on your profile card from your music player, the encryption groundwork for group DMs, a voice connectivity test in admin settings, one right-click menu for people, markdown links from pasting over selected text, and GIPHY is back as the GIF provider. Fixed: images that phones showed but desktops left blank, screen share cleanup on leaving voice, Braid sub-channel cards, and full image mode now uses the whole message width. No migration steps. Thanks to @birdcrazy, @bernardokcosta, @Bo0sted, @Amnibro and @ArtyDaSmarty.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v4.3.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v4.2.0</span> <strong>One wrong STUN server no longer takes out voice between browsers.</strong> If an admin sets their own STUN servers, Haven used to replace its built-in ones rather than add to them, so a single mistyped address left browsers unable to reach each other across networks while phone clients kept working, which read as Haven breaking web calls. Haven now tests the servers you configure, names any that do not answer, and falls back to its own if every one of them is unreachable and you have no TURN relay. Your setting is never changed. Themes get a written contract that says which parts will not move without a major version, with an authoring guide, so custom themes stop breaking on updates. Bots can clear up to 100 messages in one call instead of one at a time. Also cleared 12 dependency advisories, 7 of them high, two of which sat directly under the chat transport itself. No migration steps. Thanks to @Vinylwalk3r, @birdcrazy, @dronostyka and @bernardokcosta.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v4.2.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v4.1.0</span> <strong>Deleted attachments really are deleted now, and bots can play audio in voice.</strong> A file moved out of a channel by deleting its message could still be fetched by anyone who had seen it, which is fixed, and registration can no longer hand out admin on a server that already has one. Bots with voice permission can upload an MP3, WAV or OGG and have it played to the channel, with a queue and a skip. Screen shares that quietly stopped reaching other people now recover on their own, and there is a new opt-in setting for people whose screen share drifts out of sync over a TURN relay. Also fixed: attachment cleanup was failing silently everywhere it ran from the server, an admin who signs in through SSO could not hand over admin at all, two memory leaks in the client, several themes missing from the admin theme list, and the Discord bridge relaying image-bot posts as links instead of pictures. No migration steps. Thanks to @bernardokcosta, @birdcrazy, @RCCore and @Raidenphantom.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v4.1.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v4.0.0</span> <strong>Haven now bridges to Discord.</strong> Pair a Haven channel with a Discord channel and messages cross both ways, with each person appearing under their own name and picture rather than as one anonymous bot. Every pairing chooses its own direction and whether it mirrors the whole channel or only messages deliberately addressed to Discord. It runs inside Haven, so nothing new has to be exposed to the internet, and the setup walks you through making the Discord bot. Sending is behind a new permission that starts off for everyone, and pings are off by default. Search moves into a panel over the member list that survives channel switches. Bots get a voice gateway with scoped access, and there is a RepoCloud deploy button. Fixes: the welcome screen no longer hides behind the server banner, Steam and Spotify linking works for accounts that changed their password, channel code rotation leaves clients in a working state, the docked soundboard handle points the right way, and spent invite links stop reading as active. Admin settings are now grouped instead of one flat list of twenty. No migration steps, but take a backup first as with any large release. Thanks to @Raidenphantom, whose own Discord bridge surfaced two real gaps in this one.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v4.0.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.50.0</span> <strong>Steam and Spotify linking works again, images stop disappearing on a tab left open for days, and you can see what is signed in to your account.</strong> Account linking had been broken since 3.45.0 and failed with nothing but "Internal server error"; it needs no changes to your existing keys once you update. Remote images and GIFs quietly stopped loading on a browser tab left open over a weekend, leaving a blank space where the picture should be, which is fixed and no longer needs a reload. Settings now has a Sessions pane showing the devices with Haven open right now plus a password-protected button to sign the rest out, and signing out now really does invalidate the old sign-in everywhere rather than only disconnecting it. Also adds a search box for the member list, orders members by role so admins and moderators sit at the top, adds profile picture borders, and lets you stop GIFs in chat from looping. Fixes automatic language selection. Thanks to @birdcrazy, @Bo0sted, @bernardokcosta, @josolanes and TGS.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.50.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.49.0</span> <strong>Brazilian Portuguese, the Google connections you could not opt out of are gone, and admins can finally see who is using all the storage.</strong> Portuguese is the eighth language and the only one translated in full, every phrase in the interface, reviewed by a native speaker. The bundled fonts mean Haven no longer calls Google Fonts to draw text, the Google STUN servers are out of the voice pool, and Android push now has a switch of its own since Google is what wakes the phone. All Members shows the upload storage each person is using, broken down by channels, direct messages and avatars, with a filter that ranks everyone. Invite links can now stand in for the registration token, so a link works on its own. Admins get a warning in the header when the disk reserve runs out, instead of only a line in the log. Fixes: banned users no longer appear in @mention suggestions; the sidebar updates when a main channel is deleted; and Last.fm album art loads again. Security: webhook callbacks now resist address forms written to slip past the check, are validated against what a hostname really resolves to, and are pinned to that address so a second DNS answer cannot redirect them. Thanks to @bernardokcosta, @Bo0sted, @birdcrazy, @josolanes and @KentuckyFriedBlyat.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.49.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.48.0</span> <strong>Every thread in a channel in one searchable list, display names in any language, and Haven now keeps disk space in reserve so a full server stays fixable.</strong> Threads were only reachable from the message that started them; a new button in the channel header lists them all with who started each one, how many replies it has and when it was last active, and a search box filters by text or author. Display names accept letters from any script, so Chinese, Japanese, Korean, Cyrillic, Arabic and Hebrew names no longer have to be transliterated. A full disk used to wedge a server completely, because deleting the files that filled it is itself a write; Haven now refuses to hand out the last of the space, so there is always room to delete. Also adds a role permission for seeing every channel including ones created later, invite buttons on the member lists, and a cancel button for uploads in progress. Fixes: signing in through Authentik and other providers that keep the trailing slash on their address; role editor buttons that did nothing at all on a half-updated server; and Haven now refuses to start on an install where an old leftover file was quietly overriding current code. Thanks to @birdcrazy, @Amnibro, @RCCore, @KentuckyFriedBlyat and @Amatsutsumi.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.48.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.47.0</span> <strong>The emoji picker is rebuilt from Unicode&#39;s own list, role permissions apply straight away, and your phone stops notifying you about your own messages.</strong> The picker no longer relies on a hand-written list with gaps: the server builds the whole categorised set from Unicode&#39;s published data and your device draws them in its own font. A copy ships with Haven so it works offline, and the optional monthly check for a newer standard is off unless you turn it on. Fixes: ticking a permission on a role now reaches everyone holding it instead of waiting for them to sign out and back in; a device that had been used with a second account could push your own messages back to you; white button labels on the lighter themes are now dark and readable; the Voice &amp; Connectivity settings finally have a sidebar entry; and spoilers no longer leak custom emojis, code blocks or link previews. Thanks to @Bo0sted, @josolanes and @birdcrazy.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.47.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.46.0</span> <strong>A way to spot accounts parked online to watch the server, an invite-users permission, and a fix for files pasted into threads posting instantly.</strong> A new Settings &rarr; Moderation section lists accounts that have stayed connected and shown online for hours without posting, joining voice, or changing status, which is what a script logging the server looks like since a real client goes idle on its own. Threshold is yours to set, it is read-only, and moderators who can ban or kick see it too. Also adds an invite-users permission so you can let someone bring people in without handing over the whole server, shows which settings are coming from an environment variable instead of leaving the box looking empty, and puts a short &quot;Haven can&#39;t verify who anyone is&quot; note on new DMs. Fixes: pasting a file into a thread no longer posts it before you press send, channel management no longer reaches into channels it was not granted on, and deleting a channel or a DM image now cleans up the file instead of orphaning it. Thanks to @test1 and @birdcrazy.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.46.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.45.0</span> <strong>Sign in with your own identity provider.</strong> Members can now sign in with an account from Authentik, Keycloak, Authelia, Auth0 or anything else that speaks OpenID Connect, instead of a Haven password. Set it up under Settings &rarr; Security. Because those members never type a password into Haven, and encrypted DMs are unlocked by a key derived from what you type, they set a separate encryption passphrase the first time they sign in and enter it again on each new device. It never reaches the server, so nobody can reset it, including the admin. Also fixed: a channel setting the server refused would still look like it had changed, the blank bar under the debug footer in the desktop app is gone, and follow-up messages now line up with the message above them on every density and theme. Thanks to @Lordingard and @Amnibro.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.45.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.44.2</span> <strong>Handing over admin now puts the new admin in every public channel.</strong> Admins cannot leave channels on purpose, so whoever runs the server can see what happens everywhere. A transfer quietly broke that: the incoming admin only had the channels they had already joined, with no way to add themselves to the rest. They now get all of them automatically. Hiding a channel from your own sidebar is a personal setting and still works.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.44.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.44.1</span> <strong>YouTube embeds play again, and thread replies stopped skipping the message checks.</strong> Since 3.41.0 Haven has told browsers not to say which page a request came from when loading something on another site, which is what stopped X refusing to play its videos. YouTube wants the opposite and its player would not start, showing Error 153. Haven&#39;s two embeds now pass along just the server address, with no page path and no invite code, which suits both. Separately, replies posted in threads were ignoring the link policy, going through while the sender was muted, ignoring a read-only channel and having no length limit, because the thread handler never picked up the checks the normal one has. Popped-out DMs also were not showing link warnings, since the DM check was looking for a marker that is not in the page. Thanks to @BolVerK and @birdcrazy.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.44.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.44.0</span> <strong>The auto-mod setting for direct messages now actually does something, and screen sharing stops tripping over itself.</strong> DMs are end-to-end encrypted, so the server cannot read them and never could block a link inside one, but the setting was there implying otherwise. The check now runs in the recipient&#39;s app after it decrypts: disallowed links appear as plain text with a warning instead of something clickable, and images from those domains are not loaded. On the screen-sharing side, a watchdog that asked for a renegotiation when a stream dropped frames could loop forever, because each renegotiation reset the counter that was meant to stop it. That is now capped and backed off. Double-clicking the share button no longer starts two shares at once, audio is given priority over video during the bandwidth spike when a share ramps up to 1080p (the cause of the robotic warble), and screen audio that arrives before its video no longer gets stuck in the voice mixer. Thanks to @birdcrazy and @RCCore.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.44.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.43.0</span> <strong>Haven now loads images for your members instead of sending them to other sites, and the protections added in 3.42.0 are on by default.</strong> An image link in a message used to be fetched straight from wherever it was hosted, in every viewer&#39;s browser, which quietly handed that site the IP address of everyone who scrolled past. Haven fetches each image once, caches it, and serves it from your own server, so nobody&#39;s browser talks to anyone else. Old embeds also stop breaking when the original link expires. Auto-mod, the domain allowlist, the 24-hour hold on links from brand-new accounts, and the image cache all now default to on; the two settings that can actually break something, relay-only voice and automatic IP bans, stay off until you choose them. Also fixes two permission bugs: moderators holding the ban permission can now ban from the sidebar rather than only the admin members list, and the &quot;also ban IP&quot; permission can finally be granted to a role at all, having been missing from the role editor entirely. Thanks to @MutantRabbit767.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.43.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.42.0</span> <strong>Auto-Mod arrives, link previews stop leaking your members&#39; IP addresses, and IP bans actually hold.</strong> A new Settings &rarr; Auto-Mod section lets you approve the domains people may link to and reject everything else the moment it is sent, across messages, edits, DMs, profiles and channel topics, with warn/mute/ban escalation and an optional hold on links from brand-new accounts. Link previews now obey the same list, which closes a quiet problem: Haven loads preview images straight from the other site in every viewer&#39;s browser, so a hostile link used to collect the IP address of everyone who scrolled past it without a single click. IP bans had two real defects, both fixed: the web gate and the connection gate disagreed about what an address is, so a ban blocked someone&#39;s web requests while their live connection kept working, and behind a reverse proxy Haven recorded the proxy&#39;s address for every visitor, which meant &quot;also ban IP&quot; would have banned the proxy and locked out the whole server. Bans now accept CIDR ranges and disconnect anyone already connected. Also adds relay-only voice, which hides member IP addresses in calls (Haven voice is peer-to-peer, so by default everyone in a call can see everyone else&#39;s address), and fixes message rate limiting that was counted per browser tab instead of per person.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.42.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.41.0</span> <strong>Twitter/X videos play again, web users stop getting dropped from voice every minute, and the desktop app stops burning CPU in calls.</strong> X refuses to serve its videos to anyone whose browser says where the request came from, and Haven's old default said exactly that, so every X embed showed a still frame and a dead play button. That default changed, and how much your address is shared is now a proper setting under Settings &rarr; Security. Web clients were also kicking themselves out of voice once a minute: Chrome slows a background tab's timers down, Haven mistook that for the computer waking from sleep, and rebuilt the connection every 60 seconds, which everyone in the call heard as a leave sound and a join sound. Haven Desktop had two frame loops that started at launch and never stopped, keeping the renderer drawing on every screen refresh through an audio-only call. Also fixes file themes inheriting the previous theme's effects, adds an in-call control dock and a one-click layout switch to the optional Braid Layout, lets channel creators invite to their own private channels, and updates adm-zip for CVE-2026-39244. Thanks to @Amnibro, @Bo0sted, @anupamme and @AlexT2803 (#5444, #5456, #5463, #5466, #5468, #5473, #5475, #5476, #5477).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.41.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.40.0</span> <strong>GIF search works again on new servers, names get their own line in the member list, and a silent startup failure is fixed.</strong> GIPHY stopped handing out keys to new servers, so GIF search could never be switched on; Tenor is now the recommended provider and existing GIPHY keys keep working. In the member list a custom status and a game no longer crowd out the username, whatever you are doing moves to a smaller line underneath. Haven could also appear to crash on launch when its port was already taken: it now says which port and why instead of leaving an invisible copy running. The status bar shows an address other people can actually connect on rather than localhost, the profile card no longer opens behind the member list on narrow windows, and Haven runs on Node 24 and 26. Also adds the optional Braid theme and layout, both off by default. Thanks to @Amnibro and @birdcrazy (#5465, #5471, #5472).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.40.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.39.0</span> <strong>Zoom the whole interface, keyboard control for the emoji picker, and sliding switches.</strong> A new Zoom slider scales the entire app from 70% to 150% rather than just the text, so sidebars, avatars, icons and spacing all stay in proportion and the layout reflows instead of running off the screen. The emoji picker is now fully keyboard-driven: Ctrl+E opens it, arrow keys move the selection, and Enter inserts. Settings that turn something on or off are sliding switches now, with a Toggle Style option if you prefer the classic checkboxes. Your status dot became a proper button, and the status menu can flip music and game activity sharing without opening Settings. Also fixes AI noise suppression, which crackled constantly and stopped working after rejoining a call, a member-list menu that did nothing on narrow windows, and channel roles that could not delete what they were allowed to. Thanks to @Bo0sted, @Serionard and @birdcrazy (#5458, #5459, #5461, #5462, #5464).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.39.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.38.0</span> <strong>Bulk message deletion, ban appeals, a configurable channel-creator role, and working AI noise suppression.</strong> Moderators can now select several messages and delete them in one go, right from the same tool used to move them. Banned members who sign in with the right password now see why they were banned and can send the admins an appeal, which shows up next to their name in the Banned Users list. Admins can choose which role a channel&rsquo;s creator automatically gets, so trusted members can manage the channels they make. The &ldquo;Suppression (AI)&rdquo; noise mode actually works now. It had been silently passing your mic through untouched. Also includes optional Cloudflare Turnstile and a new-account rate limit to slow bot waves, an admin bulk-cleanup tool, and a batch of voice and screen-share stability fixes (maximizing the window no longer looks like it drops you from a call). Thanks to @Serionard and @birdcrazy (#5444, #5457, #5458, #5460, #5461).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.38.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.37.2</span> <strong>A round of fixes and polish: reliable link previews, a working emoji menu, a readable admin reset window, and UI that scales with your font size.</strong> Link previews now load consistently on a channel full of links, instead of some cards appearing and others silently dropping. The emoji suggestion menu (the popup when you type a colon and an emoji name) no longer stops working after you use it inside a message edit box. The admin password reset window was showing raw placeholder labels instead of real sentences, which made it look broken; it now reads normally and explains that the person being reset needs two-factor authentication turned on first, which is a security requirement rather than a bug. The channel ID tag, the header action icons, and the left-side voice channel user list now grow with the Font Size setting under Settings &rarr; Layout &amp; Density. The Matrix theme&rsquo;s message editor no longer renders as a solid green block. This release also refines the remote-access guide with a safer Tailscale option; the emoji-menu fix and that guide both came from Bo0sted (#5450, #5451, #5452, #5454).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.37.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.37.0</span> <strong>A big emoji picker upgrade, right-click message menus, and welcome messages that finally stick around.</strong> The emoji picker now scrolls through every category in one continuous list with sticky headers, puts your server&rsquo;s own custom emoji front and center, and adds skin tones, a hand button next to the search bar lets you pick a tone, and your choice is remembered and applied everywhere (the picker, reactions and quick reactions). Right-clicking a message now opens a context menu with the same actions as the hover toolbar (edit, reply, quote, pin, react, thread, copy link, protect, delete), and you can start typing anywhere to jump straight into the message box. Welcome messages are now permanent: instead of a one-time flash that only whoever was looking at that channel ever saw, a new member&rsquo;s welcome is saved to the channel and stays in history for everyone, with a per-channel toggle in Channel Functions that is on by default for your first channel. Also includes a Steam linking fix for servers behind a CDN or proxy from KevonLin (#5445, #5446, #5447, #5448, #5449).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.37.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.36.0</span> <strong>A tidier voice panel and steadier audio after a reconnect.</strong> The voice list only shows mic and speaker icons when someone is actually muted or deafened now, drops the redundant &ldquo;you&rdquo; tag next to your own name, and compacts the LIVE badge to a red dot plus viewer count, hover it for the full &ldquo;who is watching&rdquo; detail. On the connection side, voice recovers more reliably after a brief disconnect, and Haven no longer hands the browser five or more STUN/TURN servers, which was slowing reconnects. There is also a new opt-in Debug toggle for the case where you rejoin a call and still cannot hear one person until you leave and rejoin again (#5444).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.36.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.35.0</span> <strong>Better behaviour behind Docker, proxies and tunnels.</strong> If you run Haven behind Docker port mapping, a reverse proxy or a Cloudflare Tunnel, linking Steam or Spotify could send you back to the wrong address and fail. You can now set your public address once as PUBLIC_URL in .env and both link flows use exactly that. Admins can also change a Steam, Spotify or Last.fm key straight from Settings instead of hand-editing .env and restarting, and a replaced Steam key takes effect immediately rather than on the next poll. Both of these came from KevonLin.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.35.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.34.0</span> <strong>Keep the GIFs you actually use.</strong> The GIF picker has a Favorites tab now: hover any GIF, click the star in its corner, and it is saved for next time. The search box filters your favorites too, so a big pile stays usable. They live in your own browser, so nothing is uploaded anywhere and the tab works even if your server has no GIPHY key. This release also fixes the ping figure in the status bar, which was showing a more or less random number instead of your real latency, and two voice bugs: being filtered out of your own voice channel so that everyone could see you in the call except you, and voice rows sprouting a blank-looking second line once someone picked up a LIVE or camera badge.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.34.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.33.0</span> <strong>See what everyone is playing and listening to.</strong> Haven can now show a friend&rsquo;s current game or track in the member list and on their profile. Music works through Last.fm, which just needs your username and covers Spotify, Apple Music, YouTube Music, Navidrome and Plex in one go; games work through Steam. All of it is optional, can be hidden per-category, is never shared while you are Invisible, and is never saved to the database. Settings is also reorganised into clear groups and can finally be resized, .mov videos play inline instead of forcing a download, and a batch of fixes landed for @mentions, image copying, the status bar toggle, the emoji customiser and the language flags.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.33.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.32.0</span> <strong>Live progress bars when restoring a backup, plus a fix for Apple Silicon Docker images.</strong> Restoring a backup now shows a real upload percentage and then a server-side extraction bar, so a large restore no longer sits silent for many minutes (#5438). You can also throttle how often notification pop-ups appear from Settings, the status bar hides your server address by default each session until you click to reveal it, and the sidebar collapse arrows no longer leave a gap on narrow windows. The Docker image ships linux/arm64 again, so Apple Silicon Macs no longer fall back to slow emulation (#5439).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.32.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.31.2</span> <strong>The manual Download Backup button works on large servers again.</strong> Automatic backups were already fixed, but clicking Download Backup on a big server (tens of GB of files) built the whole archive before sending anything, so it sat silent long enough for a proxy in front of Haven to return a 502. The download now streams straight to your browser as it builds, so it starts right away (#5434).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.31.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.31.1</span> <strong>Restoring a large backup works again.</strong> Restoring a full backup that included files used to fail after about 30 seconds with a &ldquo;failed to fetch&rdquo; error, because the server cut off long uploads, capped the upload at 4GB, and read the whole archive into memory at once. Restores now allow long uploads, accept large files, and stream straight to disk, so a 15GB or larger backup restores without crashing (#5436). The backup screen also now notes that only full backups, ones that include both Messages and Uploaded files, can be restored in place (#5435).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.31.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.31.0</span> <strong>Rich link preview cards for Bluesky and X posts, plus a fix for backups that include files.</strong> Social links now embed as full cards with the author&#39;s avatar, the post text, sized media, and engagement counts, matching the mobile app, and embed size is a single Off / Small / Medium / Full preference shared by Settings and a per-embed toggle (#5429, contributed by Amnibro). Backups that include files no longer crash the server: they used to build the whole archive in memory and run out of RAM once the uploads folder got large (around 30GB), and now stream straight to disk instead (#5434).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.31.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.30.3</span> <strong>The sidebar &ldquo;Create Channel&rdquo; section no longer shows up as a dead control for users who can only create sub-channels.</strong> Users who held <code>create_channel</code> only inside one specific channel could still see the always-visible sidebar section for creating a brand-new top-level channel, but every attempt was correctly denied, since that permission only covered sub-channels of the one channel it was granted in. That section now only appears for admins and users with a genuine server-wide <code>create_channel</code> grant.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.30.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.30.2</span> <strong>Betsy Ross and Gadsden flags now match the proportions of the rest of the Flags category.</strong> They were noticeably flatter and wider than every other flag since their source artwork wasn&#39;t the same 4:3 shape as the bundled country flags. Both are now cropped to match, full canton on Betsy Ross, full snake and lettering on Gadsden, so the whole Flags category looks consistent.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.30.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.30.1</span> <strong>Flags emoji now render on Windows.</strong> Windows browsers don&#39;t draw Unicode flag emoji, they show the bare two-letter country code instead, so the new Flags category looked like a list of letters (&ldquo;US&rdquo;, &ldquo;GB&rdquo;, &ldquo;DE&rdquo;&hellip;) there. Every country flag is now a bundled image, so the whole category renders the same on every platform, in the picker, in messages, and in reactions.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.30.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.30.0</span> <strong>A new Flags emoji category, smarter emoji search, and fixes for the last-read divider and channel-scoped roles.</strong> The emoji picker now has a Flags category with a wide set of country flags, the US flag leads, followed by the classic Betsy Ross and Gadsden flags, which ship built in and drop into messages and reactions like any other emoji. Emoji search now understands punctuation, so typing <code>?</code> finds &#x2753; and <code>!</code> finds &#x2757;. The &ldquo;new messages&rdquo; divider and jump-to-unread scroll work again after a regression (#5432), and per-channel role permissions such as &ldquo;create channel&rdquo; or &ldquo;rename sub-channels&rdquo; no longer leak server-wide (#5433). Also adds a maximize toggle to the screen-share pop-out window (#5430).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.30.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.29.0</span> <strong>Spoiler &amp; hide-image controls, granular guest channel access (#5401), grouped messages in DMs and threads, plus invite-link management.</strong> You can now mark an image as a spoiler when sending it (it shows blurred until clicked), or right-click any image to hide it from your own view. Guest access is now picked channel by channel, sub-channels and voice rooms included, so guests reach exactly the rooms you grant, fixing nested and voice channels that were unreachable before (#5401). Back-to-back messages from the same person now group together in pop-out DMs and in threads, the way the main channel already does. And invite links got a full management menu: multiple codes with per-link channel grants, expiry, and use limits, plus one-click copy and a community auto-join link.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.29.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.28.0</span> <strong>Admin-only Hide Channel, a screen-share audio sync fix over relays, and live custom-asset updates.</strong> Admins can now right-click to hide a channel from their own sidebar without leaving it (#5409). Screen-share audio now defaults to native playout so it no longer drifts out of sync over TURN relays, with Web Audio mixing as an opt-in for the &gt;100&#37; volume boost (#5426); custom sounds, emojis, and stickers now update live for everyone instead of after a restart (#5426); and voice peers now self-heal after a brief disconnect so you&#39;re not left silent to some people (#5427). Also: blocked sub-channel access via crafted codes / deep links (#5408), guests now see the Join Voice button in allowed channels (#5401), the status-bar server address copies correctly in the desktop app, and a full Russian retranslation (#5421).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.28.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.27.0</span> <strong>Admin-configurable STUN/TURN voice servers, plus a screen-share close-button fix.</strong> Server admins can now point voice and screen share at their own STUN/TURN servers from Settings &rarr; Voice &amp; Connectivity, with no env vars or redeploy, and clients now show a clear warning when no STUN server is reachable instead of silently hanging on &ldquo;ICE: Connecting&hellip;&rdquo; (#5399). The stream viewer&#39;s header close (&#x2715;) button no longer stops your own broadcast or breaks streams when closing, it now hides them the same restorable way the per-tile &#x2715; button does.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.27.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.26.0</span> <strong>Per-channel soundboard toggle, plus a batch of moderation, upload, and screen-share fixes.</strong> Admins can now switch the soundboard on or off per channel from the Channel Functions menu, right next to Voice, Text, Streams, Music, and Media, when it&#39;s off, nobody can play sounds into that channel&#39;s voice chat. Also: auto-cleanup no longer deletes persona avatars or other non-post files (#5423); sub-channel Rename and Organize now follow the <code>rename_sub_channel</code> / <code>manage_sub_channels</code> permissions instead of ignoring them (#5424); non-image attachments queued on their own now actually send (#5425); late joiners and tile-less viewers can reopen an active screen share; and screen-share audio no longer plays twice (#5426).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.26.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.25.2</span> <strong>Hotfix: app loaded completely blank, no servers, channels, users, or DMs, and nothing clickable.</strong> Three front-end modules (<code>app-messages.js</code>, <code>app-media.js</code>, <code>app-ui.js</code>) had been silently truncated mid-file in an earlier commit. Because the app bundles these modules together at startup, a single unterminated file is a fatal parse error that halts the whole interface, so the page connected to the server but rendered nothing and ignored every click. All three files were restored to their complete form. If you were stuck on a blank Haven screen, update and hard-refresh (Ctrl+Shift+R) and it loads normally again.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.25.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.25.1</span> <strong>Hotfix: Haven Desktop stuck on &ldquo;Loading Haven&hellip;&rdquo; on strict CSP clients.</strong> <code>app.html</code> had a single inline <code>&lt;script&gt;i18n.init();&lt;/script&gt;</code> tag that the page Content Security Policy (no <code>&#39;unsafe-inline&#39;</code> in <code>script-src</code>) was refusing to execute on strict clients (notably the Haven Desktop preload), which left the locale layer uninitialized and the splash hanging. Moved the bootstrap call into <code>i18n.js</code> itself and removed the inline tag from <code>app.html</code>. <code>init()</code> is idempotent so existing <code>await window.i18n.init()</code> callers still resolve against the same shared promise.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.25.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.25.0</span> <strong>Soundboard sidebar mode, non-image file upload queue (#5417), and a sweep of fixes for the post-3.24.0 soundboard rework.</strong> The soundboard now pins as a non-blocking side panel with grouped categories, search, and per-sound visibility / hide controls. Non-image files (PDFs, audio, video) now queue as removable chips before sending instead of uploading on selection. The Sound Manager &ldquo;Assign to Events&rdquo; dropdown was rewritten to stay inside the modal (was overflowing the window on long sound lists). Three reported issues fixed: #5417 (instant non-image upload), #5418 (multiple menu button icons broken + dropdown overflow), #5419 (popout blocking Sound Manager access). About 15 mojibake&#39;d theme logos and UI icons that survived the v3.17.0-era cp1252 round-trip damage were also restored. Also: Bluesky link previews (#5412), a link preview size picker, and the Auto-heal-on-zero-membership safety net.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.25.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.24.0</span> <strong>Bulk sticker upload (#5406), a new Desktop mute/PTT cue toggle (Haven-Desktop #37), and two safety fixes from main.</strong> Sticker management can now batch-upload multiple files with filename-based names and an optional shared pack. Desktop users can now turn off mute / deafen / push-to-talk cue beeps without muting all Haven sounds. This release also includes the already-on-main fixes for DM deletion moving sticker library files into <code>deleted-attachments/</code> (#5411) and for private channel message links leaking a joinable channel code (#5408).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.24.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.23.0</span> <strong>Private webhook bot replies (#5404) plus the full 3.22.0 batch.</strong> Bots can now send recipient-scoped ephemeral messages via <code>POST /api/webhooks/:token</code> with <code>ephemeral: true</code> and <code>recipient_id</code>. The server validates channel membership, delivers only to the targeted user, skips history persistence, and clients show an &ldquo;Only visible to you&rdquo; pill so private bot output is clearly marked. This release also includes the previously pending v3.22.0 work from main.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.23.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.21.0</span> <strong>Server-side per-channel mute + #5399 followup fixes.</strong> Channel mute state now lives on the server (new <code>user_channel_prefs</code> table + three endpoints), so muted channels stop pushing to mobile via FCM and to other browsers via web-push. Existing clients converge automatically on first connect. Also patches two latent SyntaxErrors (duplicate <code>const loginForm</code> in <code>auth.js</code> + orphan <code>_setupServerBar()</code> half-merge in <code>app-ui.js</code>) that had been quietly sitting in main since the v3.19.0 Guest mode merge and caused a blank login / blank app for anyone updating directly from v3.18.0. Server-side <code>/api/ice-servers</code> defaults refreshed to match the v3.20.1 client pool. Right-click &rarr; Copy image now actually copies the image (was silently rejecting due to dropped user-gesture token; rebuilt around Electron IPC for Desktop and a promise-based <code>ClipboardItem</code> for the web). Image and member context menus raised above the lightbox and PiP DM. Password eye-icon no longer overlaps the typed characters.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.21.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.20.1</span> <strong>Emergency fix for voice / screen-share outside local network (#5399).</strong> Both hardcoded default STUN servers had gone offline (one was decommissioned upstream, the other stopped responding), leaving any Haven instance using the default ICE config unable to connect users across the public internet. Symptom was LAN-to-LAN voice still working while anyone outside the server&rsquo;s subnet got stuck on &ldquo;ICE: Connecting&hellip;&rdquo; and soundboard / screen-share failed to external users. Replaced the defaults with a non-Google preferred pool (Cloudflare, Metered, Twilio) plus a startup health probe that prunes any STUN server that doesn&rsquo;t respond with a server-reflexive candidate within ~2.5 seconds. If every preferred server fails the probe, a Google fallback pool engages automatically. Admin-configured TURN servers continue to take precedence so anyone running their own TURN is unaffected.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.20.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.20.0</span> <strong>IP-level bans for moderators.</strong> New <code>ban_ip</code> role permission gates an &ldquo;Also ban recent IP address(es)&rdquo; checkbox in the Ban User modal (up to 5 most-recent IPs per user) and a new <strong>Banned IPs</strong> manage modal under Settings &rarr; Admin &rarr; Members for direct IP ban / unban with a reason. Enforced at both the HTTP layer (30-second cache) and Socket.IO layer; live sockets from a freshly-banned IP are disconnected immediately. Exact-string match in v1 (no CIDR / IPv6 normalization).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.20.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.19.1</span> Desktop-only fixes paired with Haven Desktop 1.4.21: Settings checkboxes and keybind recorders are now responsive immediately on opening the modal (previously dead until you clicked the matching left-nav item). Adds two opt-in Debug toggles (&ldquo;Disable GPU vsync&rdquo; and &ldquo;Remove Chromium frame-rate cap&rdquo;) for users hitting Nvidia G-Sync / VRR FPS-drop issues. Both off by default and require restart.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.19.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.19.0</span> <strong>Join as Guest (#5381).</strong> Admins can enable a guest-login mode and whitelist specific channels guests are auto-joined to. Guests get a real (temporary) account with a 12-hour token, no DMs, no E2E key derivation, and a visible Guest badge in the member list and message header; the row is cleaned up a few seconds after their last socket disconnects. Plus a fix for per-bot slash-command routing (#5398): bots with the same command name in different channels now route to the right callback URL instead of whichever bot was saved last.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.19.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.18.3</span> Desktop shortcut-recorder now shows a specific, actionable toast when a bind fails (&ldquo;install libuiohook&rdquo; vs &ldquo;pick a different combo&rdquo;) instead of a one-size-fits-all message. Pairs with Haven Desktop 1.4.20.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.18.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.18.2</span> Thank You / donors modal restructured so the Ko-fi donate button stays pinned at the bottom instead of falling below the fold on shorter screens. The tier lists own the scroll now.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.18.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.18.1</span> Screen-share encoder defaults tuned for modern home internet (#5379): bitrate caps raised 2-3x per resolution, encoder hinted as &ldquo;motion&rdquo; content, and <code>degradationPreference: maintain-framerate</code> set so the encoder drops resolution before chopping frames under bandwidth pressure. Big quality bump for games / video on screen-share.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.18.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.18.0</span> <strong>Server-synced nicknames (#5394):</strong> nicknames now persist server-side so they follow you to new devices and browsers (still private, only you see them). <strong>Per-channel default role (#5389):</strong> Channel Functions &rarr; &ldquo;Default Role&rdquo; picks a server role auto-granted to every current and future member of that channel. <strong>Admin-adjustable max sticker size (#5392)</strong>, bump the 1 MB ceiling up to 10 MB if you want stickers to double as a GIF library. <strong>New <code>/break</code> slash command + persona-compacting hard-stop (#5393)</strong> so back-to-back persona messages stay visually distinct for everyone. <strong>Channel auto-clear messages timer (#5390)</strong>, wipe messages on a schedule without deleting the channel itself. Fixes for screen-share reshare ghost tiles, channel-list silence watchdog (#5391), and landing-page emoji encoding.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.18.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.17.4</span> <strong>iOS Web fix:</strong> voice-channel audio and screen-share audio now actually play on iOS Safari, iOS Chrome, and every other iOS browser. WebKit&rsquo;s <code>MediaStreamAudioSourceNode</code> is silent for remote WebRTC tracks, so Haven&rsquo;s Web Audio routing dropped all incoming voice into a black hole on iOS. Calls looked connected but you heard nothing. iOS now skips the Web Audio graph and plays incoming audio natively (trade-off: no &gt;100&#37; volume boost on iOS only). Also restored the <em>Apply voice processing to screen-share audio</em> opt-in toggle (Settings &rarr; Debug) for users sharing voice content like tutorials or podcasts.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.17.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.17.3</span> Mobile &ldquo;Join Voice&rdquo; button no longer stayed visible after joining the call (#5387), CSS <code>!important</code> was beating the JS inline-hide. Language picker now actually switches the whole UI on change (#5386), dynamically-rendered strings used to keep their previous language until next reload; <code>setLocale()</code> now reloads. New admin setting <strong>Default Language</strong> for new users&rsquo; first visit. Screen-share audio is now full-fidelity by default (#5379), voice processing (echo cancel / noise suppression) is no longer applied to system audio, so music and game audio sound the way they should. Mic is unchanged. Bundles Haven Desktop 1.4.17 (occluded-window screen-share encoder stall fix).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.17.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.17.2</span> Mobile fixes: right-side userlist no longer hides behind the message composer between 769-900px (#5384), and the "Voice / Stage active" indicator now dims the background like the Members button does (#5385). Also: the <code>pin_message</code> role permission now actually shows the Pin/Unpin context menu entry (frontend was checking moderator level instead of the permission). GUIDE.md gains a Reverse Proxy section covering Caddy, nginx, and tunnel + Caddy chains.</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.17.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.17.1</span> Critical hotfix for the 3.17.0 ERR_INVALID_PACKAGE_CONFIG crash (#5374) caused by a stray non-UTF-8 byte in package.json. Show/hide password toggle on every password field. Expired tokens redirect to login instead of leaving you on an empty channel list (#5375).</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.17.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.17.0</span> Pinned messages PiP floating panel (#5370): pop-out button opens a draggable, resizable overlay so you can browse and manage pins without leaving the message feed; fullscreen button added to pins PiP. Muted channels now block bot/webhook notifications and badge re-seeding on reconnect. DM status dot offline display fix (#5372). PiP z-index fix (#5373). Pinned panel button alignment fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.17.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.15</span> Voice chat: actual root cause of the recurring self-vanish glitch (#5347) fixed, channel code rotation desync caused voice clients to hold stale codes after server rotation, breaking reconnects until manual rejoin; null audioCtx crash on voice leave patched; version display regression from v3.16.14 corrected (servers reported v3.16.13 despite running v3.16.14) (#5369)</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.15.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.14</span> Voice chat: server-side 4 s grace period before evicting a disconnected user so transient blips never broadcast <code>voice-user-left</code> to peers; fast-path rejoin that skips RTCPeerConnection renegotiation when the socket reconnects within the window; client-side roster watchdog that auto-fires <code>voice-rejoin</code> if we&rsquo;ve silently dropped off the server list, fixes the recurring self-vanish glitch (#5347)</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.14.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.13</span> Channel and sub-channel composers are now drag-resizable up to 60% of the viewport (#5327). New sub-channels inherit their parent channel&rsquo;s role access on creation (#5328). Voice chat: deferred soft-leave on transient socket blips so quick reconnects no longer tear down the mic and peers, plus a self-heal that emits voice-rejoin automatically when the right panel notices we&rsquo;ve dropped off the server roster, no more manual leave+rejoin churn</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.13.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.12</span> Voice chat audit: fixed missing-self in the right panel after server restart / reconnect races, stale roster ghosts after a reboot, and the &ldquo;clicked Start Voice 15 times during an outage and got 15 toasts at once&rdquo; spam-click flood</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.12.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.11</span> Removed servers no longer reappear after a restart (Desktop bootstrap and sync paths now honor the local removed-set). Transient server restarts no longer log users out, the auth-error handler now requires three consecutive errors before bouncing to login</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.11.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.10</span> Fixed displayed server version being stuck at v3.16.5 regardless of which release was installed (#5364, package.json was bumped off-by-one in v3.16.6 and never corrected). Also ships the originally-intended v3.16.5 code changes: editing a message from a DM PiP now works correctly, and encrypted upload failure toasts show the specific error</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.10.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.9</span> Fixed not appearing in the voice panel or sidebar while in a voice channel after a socket reconnect caused the server snapshot to race ahead of the rejoin re-registration</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.9.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.8</span> Fixed phantom unread badge on the current channel after returning from background: incoming messages bumped the badge while the window was hidden even if the user was already at the bottom; badge now clears immediately on window focus when coupled to the bottom</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.8.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.7</span> Images attached alongside a persona message now send as the persona instead of the real account. Persona badge was showing &ldquo;??&rdquo; prepended to the label; now shows the correct icon</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.7.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.6</span> Added Unpin button to the pinned-message panel (visible to users with the <code>pin_message</code> permission or admin). Fixed webhook management being locked to admins despite a dedicated <code>manage_webhooks</code> permission; users with that permission can now create, list, delete, and toggle per-channel webhooks</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.6.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.5</span> Fixed editing messages in the DM PiP doing nothing (server resolved the wrong channel; client now sends the channel code). Encrypted image upload failure toast now shows the specific error instead of always saying &ldquo;Encrypted image upload failed&rdquo;</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.5.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.4</span> Unicode letters (umlauts, accented characters, non-Latin scripts) now allowed in channel names. Fixed video and audio files appearing in the Files tab of the media gallery instead of Videos/Audio</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.2</span> Fixed CMD window closing on startup for Windows users past v3.15.1 (cmd.exe exits instead of returning from a <code>call :subroutine</code> inside an else-if compound block; restructured to use goto labels). Fixed published file themes not surviving a page refresh or applying on the login page (socket was never exposed for preference saving; theme-init.js now injects the CSS link immediately for file themes)</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.16.1</span> Clicking Leave Voice now clears the voice panel and sidebar count immediately without waiting for the server broadcast; stale in-flight broadcasts can no longer re-add a user to the voice panel after they've left</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.16.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.15.8</span> The fix that was already shipped, but actually shipped this time. Every cache-bust <code>?v=</code> string in app.html and app.js was pinned at 3.15.2/3.14.14 respectively, so browsers served stale client JS even on updated servers. None of the v3.15.3-3.15.7 client fixes (voice rejoin, sidebar sync, screen-share recovery, persona autocomplete) actually ran in any browser. Bumped them all to 3.15.8 to force a refresh</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.15.8.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.15.7</span> Critical hotfix: <code>getUserAllRoles</code> was missing from the server's permission destructure, causing every voice user broadcast to throw a ReferenceError silently. Voice lists never updated after joins/leaves/mutes. Also fixed the saved server list being rejected with a 500 once it grew past ~50 servers</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.15.7.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.15.6</span> Persona <code>::</code> autocomplete no longer appears in fullscreen DM view, and nicknames no longer override persona display names on messages</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.15.6.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.15.5</span> Screen-share reliability overhaul: fixed silent <code>_renegotiate</code> throw when signaling state wasn't stable (caused audio-but-no-video), late-joiner screen tracks skipped if webcam was also on, <code>screen-share-started</code> was emitting after renegotiation instead of before, and added a recovery handshake so receivers automatically ask the sharer to re-offer if no video appears within ~3s</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.15.5.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.15.4</span> Voice presence drift fix: sidebar and right voice panel now always in sync, reconnect after socket drop now correctly uses the rejoin path instead of a delayed plain join that left peers with dead connections</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.15.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.15.3</span> Ghost voice entries pruned on connection snapshot and get-voice-counts so users who already left no longer show in the sidebar or voice panel</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.15.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.15.2</span> Thread panel z-index fix, persona autocomplete hidden in DMs and threads, persona tooltip showing raw i18n key, double close button in media gallery, gallery button hidden in DMs, OpenSSL not recognized on Windows bat startup</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.15.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.15.1</span> Polish pass on the Channel Media Gallery + Personas: persona prefix changed to <code>::Name your message</code> with autocomplete, <code>@PersonaName</code> mentions now resolve and ping the owner, fixed the bug where consecutive messages from different personas all stacked under the first persona's header, jump-to-message button on photo/video gallery tiles, video tiles open in an inline player instead of silently closing the gallery, image lightbox now sits above the gallery modal, top-bar header buttons follow the Colorful/Monochrome icon setting</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.15.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.15.0</span> Channel Media Gallery: new 🖼️ button opens a five-tab modal (Photos, Videos, Audio, Files, Links) showing every shared media item in the channel. Personas: create up to 25 named alter-egos in your profile and send messages as one by typing <code>&gt;&gt;Name your message</code>, with persona badges and full moderation</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.15.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.16</span> Message status icons (E2E lock, burn flame) reworked into a fixed right-anchored slot, no more right-gutter misalignment on compact or PiP messages. PiP parent message action controls anchored correctly. Cache-bust strings bumped to force browsers to fetch updated files</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.16.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.15</span> Tightened fixed status slot padding in DM PiP to remove excess whitespace when one or both icons are absent</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.15.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.14</span> Message status icons (lock/flame) pinned to a fixed right slot instead of flowing with text</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.14.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.13</span> Status icons moved inline from separate right-gutter column</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.13.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.12</span> E2E lock anchored at right:8px always; burn flame shifts left in JS when both icons are present</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.12.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.11</span> Cache-bust query strings bumped on all script and stylesheet tags to force browsers to fetch updated files</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.11.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.10</span> E2E recovery error messaging overhaul (no data-loss prompts on bad-password or network failures), recovery toast stays 8-10 s, composer z-index fix above theme particle effects, burn indicator cleanup, Manage Servers modal height fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.10.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.9</span> Topic bar hidden in DMs; E2E recovery now fetches the partner&rsquo;s key before reloading messages</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.9.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.8</span> Burn flame position consistent on compact messages; burn indicator wired in PiP</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.8.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.7</span> Burn icons placed correctly; E2E decryption self-heals on key-fetch miss</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.7.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.6</span> DM channel codes are no longer exposed on the client. Removed &ldquo;Copy DM Link&rdquo; from the DM right-click menu and the copy-link button from the message toolbar in DMs. Server strips the code fields from DM channel payloads entirely</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.6.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.5</span> Security: blocked third-party DM joins via channel code or message link (#5348). Added &ldquo;Recover Keys from Backup&rdquo; to the E2E dropdown, non-destructive recovery that preserves existing encrypted history</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.5.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.4</span> Threads fully removed from DMs (toolbar button, preview, click handlers, server handlers - all gated). New `Add to Channel` entry in the user gear menu mirroring the right-click context menu</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.3</span> Burn-after-read DMs actually burn now and the sender finally sees a flame indicator on their own message (#5325). Voice participant list refreshes properly when you're talking on one channel and viewing text in another (#5347 follow-up)</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.2</span> Role Assignment Center fixes: per-user permission edits now actually persist across reopens, assigning one role no longer wipes sibling roles at the same scope, channel pane only lists channels the target user is in (with an inline picker to add them to a new channel), Transfer Admin removed from the perms grid (it was a no-op), and `assign-role` now validates `customPerms` against the caller to close a privilege-escalation hole</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.1</span> Voice rejoin after random disconnects no longer leaves users invisible to each other with broken audio (#5347)</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.14.0</span> Registration token gate alongside whitelist (#5344), default channels picker for invite joiners + private-channel safety fix (#5345), burn-after-read DM toggle is now persistent (#5280)</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.14.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.13.0</span> Multi-role per user per channel (#5341), DM auto-cleanup banner (#5340), admin-configurable login session duration (#5294), webhook expansion (per-event subscriptions, HMAC signatures, retry, delivery health, new events, test-webhook, inbound reply_to &amp; avatar override), link preview cache &amp; rate-limit fixes (#5337), phantom taskbar badge fix, slow-mode media bundling fix (#5342), burn-on-read visual indicator (#5280), PiP input vertical resize</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.13.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.12.0</span> Starter sticker pack, `:stickername:` shortcode, dedicated manage_stickers permission, sticker tab no longer auto-closes the picker, burn-after-read DM toast feedback &amp; i18n fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.12.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.11.2</span> Quick links to Bans/Deleted Users from members list, Manage Roles modal opens with role list visible, role modal resizes both directions, #5307 follow-up delete confirm i18n key fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.11.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.11.1</span> #184 voice output device honored from first track-add via AudioContext sinkId</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.11.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.11.0</span> Stickers (admin uploads + picker tab), DM PiP no-op when DM is already current</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.11.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.10.13</span> Voice stability fixes: self-speaking indicator, temp-voice grace period, Desktop memory-reload safety, category collapse persistence, DM PiP fixes, Role Members button</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.10.13.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.10.12</span> PTT lone modifiers + mouse4/5 + hold/toggle mode, themed delete confirms, rate limiter scoped to credential routes only, slash autocomplete Enter key</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.10.12.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.10.6</span> Win95 theme dark-sections fix &amp; softer dividers, multi-tier markdown lists, YouTube live embeds, Docker Update Now copyable command, HAVEN_DATA_DIR systemd doc</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.10.6.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.10.4</span> Self-DM PiP open fix, DM PiP unread auto-clear</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.10.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.10.3</span> #channel autocomplete, DM PiP z-index fix, voice highlight regressions</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.10.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.10.2</span> Pinned-message indicator, manage_server category visibility fix, message ordering tiebreaker</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.10.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.10.1</span> @everyone/@here mentions, #channel autolinks, duplicate role, voice ICE fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.10.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.10.0</span> Drag-reorder remote servers, View Audit Log permission</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.10.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.9.0</span> Drag-reorder tag categories, audit log, modal layout fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.9.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.8.0</span> DM Picture-in-Picture, configurable purge-on-ban</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.8.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.7.0</span> Scheduled auto-backups, in-app update check, add-all-members</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.7.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.6.0</span> Channel/message links, admin backups, update check, CORS fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.6.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.5.0</span> Threaded replies, toolbar customization, SSO auth improvements</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.5.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.4.0</span> Quote/edit UX, bot API upgrades, SSO quality fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.4.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.3.0</span> Last read indicator, per-event volume sliders, server list sync improvements</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.3.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.2.0</span> Mark as Read, pinned message jump, iOS Safari fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.2.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.1.1</span> Status bar toggle, server URL display, mobile fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.1.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.1.0</span> Server banners, server icon sync</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.1.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v3.0.0</span> SSO registration, advanced search filters, reply notifications</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v3.0.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.9</span> Encrypted server list sync, jump-to-bottom, edit-mode emoji picker</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.9.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.8</span> Read-only channels, server-relayed mic illumination, role display picker</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.8.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.7</span> Open-source STUN servers, STUN_URLS env var</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.7.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.6</span> Custom Terms of Service, unpin fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.6.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.5</span> License changed to AGPL-3.0</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.5.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.4</span> Bot webhook callbacks, community server</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.3</span> Android popup refresh, Desktop naming fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.2</span> Per-app audio CSP fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.1</span> View All Members permission fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.9.0</span> Temp voice channels, voice permission fix, AFK idle fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.9.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.9</span> Voice presence fixes, channel organize, collapsed sub badges</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.9.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.8</span> Voice AFK presence fix, video thumbnails</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.8.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.7</span> Donor &amp; sponsor list update</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.7.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.6</span> Heart/donate button position fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.6.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.5</span> Noise gate, screen share rejoin, setup script fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.5.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.4</span> AFK voice channel rework, video embed fullscreen fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.3</span> Bulk emoji upload, TTS permission, Shippy popout fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.2</span> Camera device selector, TTS abuse fixes, E2E spoiler fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.1</span> Camera selector, TTS fixes, channel sort sync, spoiler in E2E DMs</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.8.0</span> Expanded permissions, deleted users list, configurable voice bitrate</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.8.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.9</span> Custom login title, reset roles, Desktop push notif fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.9.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.8</span> Upload progress bar, view all members, stream reopen, Docker fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.8.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.7</span> Temporary channels, members list privacy, URL @ fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.7.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.6</span> Per-feature channel toggles, popout menu</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.6.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.5</span> Keyboard nav, dynamic sort, scroll fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.5.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.4</span> Account recovery codes, admin panel fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.3</span> Video fullscreen, PiP seek bar, stream tile fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.2</span> Scroll-to-bottom fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.1</span> Media toggle, channel functions polish, voice fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.7.0</span> Performance overhaul, RGB freeze fix, app modularization</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.7.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.6.0</span> Android beta sign-up, auto-accept streams</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.6.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.5.8</span> Auto-accept streams setting</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.5.8.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.5.7</span> Submenu overflow fix; email @mention false-tag fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.5.7.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.5.6</span> Channel re-parenting, modal resize/expand, organize drill-down</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.5.6.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.5.5</span> Settings layout hotfix; TOTP 2FA fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.5.5.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.5.4</span> Link preview fixes: Reddit JSON API, fxtwitter image fallback, HTML entity decoding</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.5.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.5.3</span> Built-in AOL sounds bundled with every server</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.5.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.5.2</span> manage_soundboard permission; fxtwitter, Pixiv &amp; oEmbed autodiscovery fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.5.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.5.1</span> Bug fixes: image upload race, DM reply encryption, voice reconnect; manage_emojis permission</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.5.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.5.0</span> One-click installer, FCM push notifications, admin update banner</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.5.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.4.0</span> Emoji upload crop/zoom editor, jumbo emoji messages</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.4.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.3.9</span> Two-factor authentication (TOTP), native OS notifications</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.3.9.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.3.8</span> Private channel code visibility, Docker healthcheck fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.3.8.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.3.7</span> Private channel invite lockdown, creator auto-mod role</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.3.7.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.3.4</span> Right-click voice users, donor tier styling</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.3.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.3.3</span> Member list DM/nickname, sidebar members, admin recovery</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.3.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.3.2</span> Sound Manager, kick channel revoke, font scaling</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.3.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.3.1</span> Plugin CSP fix, health check 404 fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.3.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.3.0</span> Webcam video, plugins, font size, channel invites</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.3.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.2.5</span> Security fixes, desktop code removed</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.2.5.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.2.4</span> Security hardening, SSRF fix, JWT verification</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.2.4.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.2.3</span> Screen share fixes, role save UX</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.2.3.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.2.2</span> FORCE_HTTP, auto-assign roles, Docker ARM fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.2.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.2.1</span> Mobile UI fixes, TURN credential fix, file upload fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.2.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.2.0</span> CRT vignette, YouTube embeds, emoji flip</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.2.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.1.0</span> E2E multi-device sync, channel organizer fix</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.1.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.0.1</span> Security fix (installer removal)</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.0.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v2.0.0</span> Discord import, E2E key fix, ARM64 Docker</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v2.0.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v1.9.2</span> Image lightbox, emoji autocomplete, GIF avatars</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v1.9.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v1.9.1</span> Auto-cleanup fix, server branding, emoji modal</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v1.9.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v1.9.0</span> Custom emojis, emoji quickbar, JWT security</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v1.9.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v1.8.2</span> PiP revert, YouTube playlists, bot fixes</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v1.8.2.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v1.8.1</span> Upload limits, mobile refresh, E2E sync</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v1.8.1.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v1.8.0</span> E2E encryption, Flash games, seek bar</div>
<a href="https://github.com/ancsemi/Haven/archive/refs/tags/v1.8.0.zip">Download &rarr;</a>
</div>
<div class="version-item">
<div><span class="v-name">v1.7.0</span> Role inheritance, voice dot colors</div>
<span class="v-date">Feb 16, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.6.0</span> Roles, voice controls, admin transfer</div>
<span class="v-date">Feb 15, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.5.0</span> Push notifications, emoji search</div>
<span class="v-date">Feb 14, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.4.7</span></div>
<span class="v-date">Feb 13, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.4.6</span></div>
<span class="v-date">Feb 13, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.4.5</span></div>
<span class="v-date">Feb 12, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.4.2</span></div>
<span class="v-date">Feb 12, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.4.1</span></div>
<span class="v-date">Feb 12, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.4.0</span> Display names, mobile voice</div>
<span class="v-date">Feb 12, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.3.0</span> DMs, user status, file sharing</div>
<span class="v-date">Feb 12, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.2.0</span> Voice UX, pinning, link previews</div>
<span class="v-date">Feb 12, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.1.0</span> Data isolation</div>
<span class="v-date">Feb 11, 2026</span>
</div>
<div class="version-item">
<div><span class="v-name">v1.0.0</span><span class="v-tag">First Release</span></div>
<a href="https://github.com/ancsemi/Haven/releases/tag/v1.0.0" target="_blank">Release notes →</a>
</div>
</div>
</div>
</div>
</div>
<!-- Desktop App Download Card -->
<div class="download-card fade-in" style="margin-top: 32px; border-color: rgba(250, 166, 26, 0.25);">
<div style="position: absolute; top: 0; left: 0; right: 0; height: 2px; background: linear-gradient(90deg, var(--accent-dim), var(--warning), var(--green)); box-shadow: 0 0 12px rgba(250, 166, 26, 0.3);"></div>
<h2>🖥️ Haven Desktop v1.4.30</h2>
<p class="download-version">Latest stable release &middot; Windows &amp; Linux &middot; Standalone installer</p>
<div class="download-btn-group">
<a href="https://github.com/ancsemi/Haven-Desktop/releases/latest" class="btn btn-primary download-main" style="background: var(--warning); box-shadow: 0 4px 24px rgba(250, 166, 26, 0.25), 0 0 0 1px rgba(250, 166, 26, 0.3);">
<span class="icon">⬇</span> Download Desktop v1.4.30
</a>
<div class="download-alt-links">
<a href="https://github.com/ancsemi/Haven-Desktop" target="_blank">&#9965; View on GitHub</a>
<a href="https://github.com/ancsemi/Haven-Desktop/blob/main/README.md" target="_blank">📘 README</a>
<a href="https://github.com/ancsemi/Haven-Desktop/issues" target="_blank">🐛 Report a Bug</a>
</div>
</div>
<p style="font-size: 0.85rem; color: var(--text-dim); margin-top: 16px;">
Connects to any <a href="https://github.com/ancsemi/Haven" style="color: var(--accent-bright);">Haven server</a>, or hosts one for you.
Bug reports and feedback are always welcome.
</p>
</div>
<!-- Android App Card -->
<div class="download-card fade-in" style="margin-top: 32px; border-color: rgba(61, 220, 132, 0.25);">
<div style="position: absolute; top: 0; left: 0; right: 0; height: 2px; background: linear-gradient(90deg, #3ddc84, #2bb55e, #82aaff); box-shadow: 0 0 12px rgba(61, 220, 132, 0.3);"></div>
<h2>📱 Haven Android App <span class="closed-beta-badge-inline" style="background: #3ddc84; color: #1a1a2e;">RELEASED</span></h2>
<p class="download-version">Available now &middot; Android &middot; Google Play</p>
<div style="margin-top:20px;text-align:center">
<a href="https://play.google.com/store/apps/details?id=com.havenapp.mobile&gl=US" target="_blank" rel="noopener" style="display:inline-block">
<img src="https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png" alt="Get it on Google Play" style="height:60px">
</a>
</div>
<p style="font-size: 0.85rem; color: var(--text-dim); margin-top: 16px; font-style: italic;">
Built from the ground up by <strong>Amnibro</strong>. Thank you.
</p>
</div>
<div class="setup-steps stagger" style="margin-top: 48px;">
<div class="setup-step">
<div class="s-num">1</div>
<div>
<h4>Install Node.js</h4>
<p>Download from <a href="https://nodejs.org/" target="_blank">nodejs.org</a> (click the big green LTS button). Restart your PC after installing.</p>
</div>
</div>
<div class="setup-step">
<div class="s-num">2</div>
<div>
<h4>Unzip Haven</h4>
<p>Extract the zip anywhere. Desktop, Documents, wherever you like. It creates one folder.</p>
</div>
</div>
<div class="setup-step">
<div class="s-num">3</div>
<div>
<h4>Double-click Start Haven.bat</h4>
<p>A terminal opens, does its thing, and your browser opens automatically. First boot takes ~30 seconds.</p>
</div>
</div>
<div class="setup-step">
<div class="s-num">4</div>
<div>
<h4>Create an account &amp; invite friends</h4>
<p>Register as admin, create channels, and share your IP + channel code. Friends open the link in their browser.</p>
</div>
</div>
</div>
</div>
</section>
<!-- ===== SUPPORT ===== -->
<section class="support-section" id="support">
<div class="container">
<div class="support-card fade-in">
<span class="heart">❤️</span>
<h2>Support Haven</h2>
<p>Haven is built by one person in their spare time and will always be free. If it's useful to you, a small donation helps keep development going.</p>
<a href="https://ko-fi.com/ancsemi" target="_blank" class="btn btn-donate">
☕ Buy me a coffee on Ko-fi
</a>
<p class="support-note">Ko-fi takes zero fees, 100% goes to the developer. No account required to donate.</p>
</div>
</div>
</section>
<!-- ===== FOOTER ===== -->
<footer>
<div class="container">
<div class="footer-brand"><span class="hex">⬡</span> HAVEN</div>
<p>Your server. Your rules. No cloud. No one reading your messages.</p>
<ul class="footer-links">
<li><a href="https://github.com/ancsemi/Haven" target="_blank">GitHub (Server)</a></li>
<li><a href="https://github.com/ancsemi/Haven-Desktop" target="_blank">GitHub (Desktop)</a></li>
<li><a href="https://github.com/ancsemi/Haven/blob/main/GUIDE.md" target="_blank">Setup Guide</a></li>
<li><a href="https://github.com/ancsemi/Haven/blob/main/CHANGELOG.md" target="_blank">Changelog</a></li>
<li><a href="mailto:help.havenapp@gmail.com?subject=Haven%20Bug%20Report">Report a Bug</a></li>
<li><a href="https://ancsemi.github.io/Haven/support.html" target="_blank">Help &amp; Support</a></li>
<li><a href="https://github.com/ancsemi/Haven/blob/main/LICENSE" target="_blank">AGPL-3.0 License</a></li>
</ul>
</div>
</footer>
<script>
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => { if (entry.isIntersecting) entry.target.classList.add('visible'); });
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
document.querySelectorAll('.fade-in, .stagger').forEach(el => observer.observe(el));
document.querySelectorAll('.nav-links a').forEach(link => {
link.addEventListener('click', () => document.querySelector('.nav-links').classList.remove('open'));
});
window.addEventListener('scroll', () => {
document.querySelector('nav').style.background = window.scrollY > 100 ? 'rgba(21, 23, 42, 0.97)' : 'rgba(21, 23, 42, 0.85)';
});
// Hero image carousel
(() => {
const imgs = document.querySelectorAll('.hero-screenshot img');
if (imgs.length < 2) return;
let current = 0;
setInterval(() => {
if (document.querySelector('.lightbox.open')) return;
imgs[current].classList.remove('active');
current = (current + 1) % imgs.length;
imgs[current].classList.add('active');
}, 4000);
})();
// Screenshot lightbox. Every shot on this page is cropped to fit its frame,
// so there was no way to actually look at one. Click, tap or press Enter to
// open it whole; Escape, the button or the backdrop closes it.
(() => {
const shots = document.querySelectorAll('.hero-screenshot img, .screenshot-item img, .phone-frame img');
if (!shots.length) return;
const box = document.createElement('div');
box.className = 'lightbox';
box.setAttribute('role', 'dialog');
box.setAttribute('aria-modal', 'true');
box.setAttribute('aria-label', 'Screenshot viewer');
box.innerHTML = '<button class="lightbox-close" type="button" aria-label="Close">&times;</button>'
+ '<img alt=""><div class="lightbox-caption"></div>';
document.body.appendChild(box);
const full = box.querySelector('img');
const caption = box.querySelector('.lightbox-caption');
const closeBtn = box.querySelector('.lightbox-close');
let lastFocused = null;
function openShot(img) {
full.src = img.currentSrc || img.src;
full.alt = img.alt || '';
caption.textContent = img.alt || '';
box.classList.add('open');
document.body.style.overflow = 'hidden';
lastFocused = document.activeElement;
closeBtn.focus();
}
function closeShot() {
box.classList.remove('open');
document.body.style.overflow = '';
full.removeAttribute('src');
if (lastFocused && lastFocused.focus) lastFocused.focus();
}
shots.forEach(img => {
img.classList.add('zoomable');
img.setAttribute('role', 'button');
img.setAttribute('tabindex', '0');
if (!img.title) img.title = 'Click to enlarge';
img.addEventListener('click', () => openShot(img));
img.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openShot(img); }
});
});
closeBtn.addEventListener('click', closeShot);
box.addEventListener('click', e => { if (e.target === box) closeShot(); });
document.addEventListener('keydown', e => {
if (e.key === 'Escape' && box.classList.contains('open')) closeShot();
});
})();
</script>
</body>
</html>