Files
matrix/landing/index.html
T
jared fee26621bc
Lint / Shell (shellcheck) (push) Successful in 18s
Lint / JS (eslint) (push) Successful in 18s
Lint / Python (ruff) (push) Successful in 12s
Lint / Python deps (pip-audit) (push) Successful in 49s
Lint / Secret scan (gitleaks) (push) Successful in 15s
docs: add who-reacted row and expand also-available feature list
- New comparison table row: "Who reacted" with hover tooltip + avatar modal
- also-available paragraph now mentions emoji/sticker picker, pinned messages
  panel, and who-reacted viewer explicitly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 23:07:47 -04:00

1137 lines
58 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lotus Guild Matrix</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #0a0a0a;
color: #e0e0e0;
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px 16px 40px;
}
body::before {
content: '';
position: fixed;
top: 50%;
left: 50%;
width: 900px;
height: 900px;
transform: translate(-50%, -50%);
background: radial-gradient(circle, rgba(152, 0, 0, 0.07) 0%, transparent 65%);
pointer-events: none;
z-index: 0;
}
.container {
position: relative;
z-index: 1;
text-align: center;
width: 100%;
max-width: 900px;
}
.logo {
width: 140px;
height: 140px;
margin: 0 auto 28px;
border-radius: 50%;
filter: drop-shadow(0 0 24px rgba(152, 0, 0, 0.35));
animation: float 6s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
h1 {
font-size: 2rem;
font-weight: 300;
letter-spacing: 0.15em;
text-transform: uppercase;
color: #fff;
margin-bottom: 4px;
}
h1 span { color: #980000; font-weight: 600; }
.subtitle {
font-size: 0.85rem;
color: #555;
letter-spacing: 0.3em;
text-transform: uppercase;
margin-bottom: 36px;
}
/* ─── Cards / Panels ─── */
.card {
background: linear-gradient(145deg, rgba(22,22,22,0.95), rgba(14,14,14,0.98));
border: 1px solid rgba(152,0,0,0.2);
border-radius: 16px;
padding: 32px;
max-width: 560px;
margin: 0 auto;
}
.card h2 {
font-size: 0.9rem;
font-weight: 500;
color: #980000;
text-transform: uppercase;
letter-spacing: 0.15em;
margin-bottom: 20px;
}
/* ─── Steps ─── */
.steps { list-style: none; text-align: left; margin-bottom: 28px; }
.steps li {
display: flex;
align-items: flex-start;
gap: 14px;
padding: 12px 0;
border-bottom: 1px solid rgba(255,255,255,0.04);
}
.steps li:last-child { border-bottom: none; }
.step-num {
flex-shrink: 0;
width: 28px; height: 28px;
background: rgba(152,0,0,0.12);
border: 1px solid rgba(152,0,0,0.35);
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
font-size: 0.8rem; font-weight: 600; color: #c44;
}
.step-text { padding-top: 3px; font-size: 0.95rem; line-height: 1.5; color: #bbb; }
.step-text strong { color: #e0e0e0; }
.homeserver {
display: inline-block;
background: rgba(152,0,0,0.1);
border: 1px solid rgba(152,0,0,0.25);
color: #e88;
font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
font-size: 0.85rem;
padding: 3px 10px;
border-radius: 6px;
}
a { color: #c44; text-decoration: none; }
.step-text a, .option-block a {
border-bottom: 1px solid rgba(204,68,68,0.3);
transition: border-color 0.2s;
}
.step-text a:hover, .option-block a:hover { border-bottom-color: #c44; }
/* ─── Or divider ─── */
.or-divider {
display: flex; align-items: center; gap: 10px;
margin: 4px 0 10px 42px;
color: #444; font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase;
}
.or-divider::before, .or-divider::after {
content: ''; flex: 1; height: 1px; background: rgba(255,255,255,0.06);
}
.option-block {
margin-left: 42px;
padding: 12px 14px;
background: rgba(255,255,255,0.03);
border: 1px solid rgba(255,255,255,0.06);
border-radius: 8px;
text-align: left; font-size: 0.88rem; color: #888; line-height: 1.5;
}
.divider { height: 1px; background: rgba(152,0,0,0.15); margin: 24px 0; }
/* ─── Tags ─── */
.tag {
font-size: 0.65rem;
background: rgba(255,255,255,0.08);
border: 1px solid rgba(255,255,255,0.1);
padding: 2px 8px; border-radius: 4px;
text-transform: uppercase; letter-spacing: 0.05em; color: #bbb;
white-space: nowrap;
}
.tag.voice { background: rgba(0,180,120,0.2); border-color: rgba(0,180,120,0.4); color: #5effc4; }
.tag.beta { background: rgba(255,180,0,0.15); border-color: rgba(255,180,0,0.3); color: #ffcc55; }
.tag.dev { background: rgba(160,80,255,0.15); border-color: rgba(160,80,255,0.3); color: #cc88ff; }
.tag.rust { background: rgba(80,140,255,0.15); border-color: rgba(80,140,255,0.3); color: #88aaff; }
.tag.warn { background: rgba(255,140,0,0.15); border-color: rgba(255,140,0,0.3); color: #ffaa44; }
.tag.dim { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.08); color: #666; }
/* ─── Featured client ─── */
.client-featured { margin-bottom: 16px; }
.client-featured a {
display: flex; flex-direction: column; align-items: center; gap: 6px;
background: linear-gradient(135deg, rgba(152,0,0,0.25), rgba(120,0,0,0.15));
border: 1px solid rgba(152,0,0,0.55);
color: #fff; text-decoration: none;
padding: 18px 24px; border-radius: 12px;
transition: all 0.25s ease;
box-shadow: 0 0 20px rgba(152,0,0,0.1);
}
.client-featured a:hover {
background: linear-gradient(135deg, rgba(152,0,0,0.38), rgba(120,0,0,0.25));
border-color: rgba(152,0,0,0.8);
box-shadow: 0 0 32px rgba(152,0,0,0.25);
transform: translateY(-2px);
}
.client-name { font-size: 1.15rem; font-weight: 600; letter-spacing: 0.05em; }
.client-desc { font-size: 0.82rem; color: #ccc; }
.tag-row { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; margin-top: 2px; }
/* Also-available note */
.also-available {
font-size: 0.78rem; color: #555; margin-top: 8px; line-height: 1.6;
}
.also-available a { color: #666; border-bottom: 1px solid rgba(102,102,102,0.3); transition: color 0.2s; }
.also-available a:hover { color: #999; }
/* ─── Space join ─── */
.space-join {
margin-top: 20px; padding: 16px 20px;
background: rgba(152,0,0,0.06);
border: 1px solid rgba(152,0,0,0.2); border-radius: 10px;
}
.space-join p { font-size: 0.82rem; color: #666; margin-bottom: 10px; }
.space-join a {
display: inline-block;
background: rgba(152,0,0,0.15);
border: 1px solid rgba(152,0,0,0.35);
color: #c44; text-decoration: none;
padding: 8px 20px; border-radius: 8px; font-size: 0.88rem;
transition: all 0.25s ease;
}
.space-join a:hover { background: rgba(152,0,0,0.25); color: #fff; }
/* ─── Secondary client cards ─── */
.clients-section h3 {
font-size: 0.8rem; font-weight: 500; color: #666;
text-transform: uppercase; letter-spacing: 0.12em; margin-bottom: 14px;
}
.client-group { margin-bottom: 18px; }
.client-group-label {
font-size: 0.75rem; color: #555;
text-transform: uppercase; letter-spacing: 0.1em;
margin-bottom: 8px;
}
.client-cards { display: flex; flex-direction: column; gap: 8px; }
.client-card {
display: flex; flex-direction: column; gap: 6px;
background: rgba(255,255,255,0.025);
border: 1px solid rgba(255,255,255,0.06);
border-radius: 10px; padding: 12px 14px; text-align: left;
transition: border-color 0.2s;
}
.client-card:hover { border-color: rgba(152,0,0,0.3); }
.client-card-top {
display: flex; align-items: center;
justify-content: space-between; gap: 10px; flex-wrap: wrap;
}
.client-card-name {
font-size: 0.95rem; font-weight: 600; color: #e0e0e0;
text-decoration: none;
border-bottom: 1px solid rgba(204,68,68,0.2);
transition: color 0.2s, border-color 0.2s;
}
.client-card-name:hover { color: #c44; border-bottom-color: #c44; }
.client-card-tags { display: flex; gap: 5px; flex-wrap: wrap; }
.client-card-desc { font-size: 0.8rem; color: #666; line-height: 1.45; }
/* ─── Comparison table ─── */
.comparison-section {
margin-top: 32px;
background: linear-gradient(145deg, rgba(22,22,22,0.95), rgba(14,14,14,0.98));
border: 1px solid rgba(152,0,0,0.2);
border-radius: 16px;
overflow: hidden;
}
.comparison-title {
font-size: 0.78rem; font-weight: 500; color: #980000;
text-transform: uppercase; letter-spacing: 0.15em;
padding: 16px 20px 12px;
border-bottom: 1px solid rgba(152,0,0,0.1);
}
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table {
width: 100%; border-collapse: collapse;
font-size: 0.78rem; min-width: 760px;
}
thead tr { border-bottom: 1px solid rgba(152,0,0,0.15); }
th {
padding: 10px 8px; text-align: center;
font-size: 0.7rem; font-weight: 600;
color: #888; text-transform: uppercase; letter-spacing: 0.08em;
background: rgba(255,255,255,0.02);
}
th:first-child { text-align: left; padding-left: 16px; min-width: 140px; }
th.ours { color: #c66; }
th small { display: block; font-size: 0.6rem; font-weight: 400; color: #555; margin-top: 2px; text-transform: none; letter-spacing: 0; }
tr { border-bottom: 1px solid rgba(255,255,255,0.03); }
tr:last-child { border-bottom: none; }
tr.section-header td {
background: rgba(152,0,0,0.06);
color: #770000; font-weight: 600;
font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.12em;
padding: 6px 8px 5px 16px; text-align: left;
}
td {
padding: 8px 8px; text-align: center; vertical-align: middle;
color: #888; line-height: 1.3;
}
td:first-child {
text-align: left; padding-left: 16px;
color: #aaa; font-size: 0.78rem;
}
td small { display: block; font-size: 0.68rem; color: #555; margin-top: 1px; }
.yes { color: #5effc4; font-size: 1rem; }
.part { color: #ffcc55; font-size: 0.9rem; }
.no { color: #444; font-size: 1rem; }
/* highlight our hosted client column */
th.ours, td.ours { background: rgba(152,0,0,0.04); }
/* ─── Legend ─── */
.legend {
display: flex; gap: 18px; justify-content: center; flex-wrap: wrap;
padding: 10px 16px 14px;
border-top: 1px solid rgba(255,255,255,0.04);
font-size: 0.72rem; color: #555;
}
.legend span { display: flex; align-items: center; gap: 5px; }
/* ─── Security note ─── */
.security-note {
margin: 0 20px 16px;
padding: 10px 14px;
background: rgba(80,140,255,0.04);
border: 1px solid rgba(80,140,255,0.12);
border-radius: 8px;
font-size: 0.76rem; color: #556; line-height: 1.55; text-align: left;
}
.security-note strong { color: #88aaff; }
.all-clients { margin-top: 14px; }
.all-clients a {
font-size: 0.78rem; color: #555;
border-bottom: 1px solid rgba(85,85,85,0.3);
transition: color 0.2s, border-color 0.2s;
}
.all-clients a:hover { color: #888; border-bottom-color: #888; }
/* ─── Server info ─── */
.server-info {
margin-top: 24px;
background: linear-gradient(145deg, rgba(22,22,22,0.95), rgba(14,14,14,0.98));
border: 1px solid rgba(152,0,0,0.2);
border-radius: 12px; overflow: hidden;
}
.server-info-title {
font-size: 0.78rem; font-weight: 500; color: #980000;
text-transform: uppercase; letter-spacing: 0.15em;
padding: 14px 20px 10px;
border-bottom: 1px solid rgba(152,0,0,0.1);
}
.info-grid { display: grid; grid-template-columns: 1fr 1fr; }
.info-item {
padding: 12px 18px;
border-bottom: 1px solid rgba(255,255,255,0.03);
border-right: 1px solid rgba(255,255,255,0.03);
text-align: left;
}
.info-item:nth-child(even) { border-right: none; }
.info-item:nth-last-child(-n+2) { border-bottom: none; }
.info-label { font-size: 0.7rem; color: #555; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 3px; }
.info-value { font-size: 0.88rem; color: #ccc; }
.privacy-strip {
padding: 10px 18px;
border-top: 1px solid rgba(152,0,0,0.1);
display: flex; gap: 18px; justify-content: center; flex-wrap: wrap;
}
.privacy-badge { font-size: 0.75rem; color: #5effc4; display: flex; align-items: center; gap: 5px; }
.privacy-badge::before { content: '✓'; font-weight: 700; }
/* ─── Legal / contact / footer ─── */
.legal-note {
margin-top: 24px; padding: 12px 18px;
background: rgba(255,255,255,0.02);
border: 1px solid rgba(255,255,255,0.05);
border-radius: 8px; font-size: 0.75rem; color: #444;
line-height: 1.6; text-align: left;
}
.legal-note a { color: #555; border-bottom: 1px solid rgba(85,85,85,0.3); }
.legal-note a:hover { color: #888; }
.contact {
margin-top: 24px; padding: 16px;
background: linear-gradient(145deg, rgba(22,22,22,0.95), rgba(14,14,14,0.98));
border: 1px solid rgba(152,0,0,0.2);
border-radius: 12px; text-align: center;
}
.footer {
margin-top: 20px; font-size: 0.72rem; color: #383838;
letter-spacing: 0.04em;
display: flex; justify-content: center; gap: 14px; flex-wrap: wrap;
}
.footer a { color: #444; transition: color 0.2s; }
.footer a:hover { color: #777; }
/* ─── Sticky first table column (all screen sizes) ─── */
td:first-child {
position: sticky;
left: 0;
z-index: 1;
background: #0d0d0d;
}
th:first-child {
position: sticky;
left: 0;
z-index: 2;
background: #111;
}
tr.section-header td {
/* section headers span full width — override sticky bg */
position: static;
background: rgba(152,0,0,0.06);
}
/* Scroll hint — visible only on mobile via JS class */
.scroll-hint {
display: none;
font-size: 0.72rem;
color: #3a3a3a;
padding: 0 16px 10px;
letter-spacing: 0.05em;
}
/* ─── Tablet (≤ 700px) ─── */
@media (max-width: 700px) {
body { align-items: flex-start; }
}
/* ─── Mobile (≤ 540px) ─── */
@media (max-width: 540px) {
body { padding: 20px 12px 40px; }
.logo { width: 100px; height: 100px; margin-bottom: 20px; }
h1 { font-size: 1.5rem; letter-spacing: 0.1em; }
.subtitle { font-size: 0.78rem; letter-spacing: 0.18em; margin-bottom: 26px; }
.card { padding: 22px 16px; }
.step-text { font-size: 0.88rem; }
.homeserver { font-size: 0.75rem; word-break: break-all; }
.or-divider, .option-block { margin-left: 0; }
.client-card-top { flex-direction: column; align-items: flex-start; gap: 6px; }
.client-card-desc { font-size: 0.79rem; }
.client-card-tags { gap: 4px; }
.also-available { font-size: 0.75rem; }
/* Table */
.scroll-hint { display: block; }
table { font-size: 0.71rem; min-width: 620px; }
th { padding: 8px 5px; font-size: 0.6rem; }
th:first-child { min-width: 100px; padding-left: 10px; }
td { padding: 7px 5px; }
td:first-child { font-size: 0.71rem; padding-left: 10px; }
td small, th small { font-size: 0.58rem; }
.yes { font-size: 0.88rem; }
.part { font-size: 0.82rem; }
.no { font-size: 0.88rem; }
.comparison-title { font-size: 0.7rem; padding: 12px 14px 8px; letter-spacing: 0.1em; }
.security-note { margin: 10px 12px 4px; font-size: 0.71rem; }
.legend { padding: 8px 12px 12px; gap: 12px; font-size: 0.68rem; }
/* Server info */
.server-info-title { font-size: 0.7rem; padding: 12px 14px 8px; }
.info-item { padding: 10px 14px; }
.info-label { font-size: 0.65rem; }
.info-value { font-size: 0.82rem; }
.privacy-strip { flex-direction: column; align-items: center; gap: 8px; padding: 10px 14px; }
.privacy-badge { font-size: 0.71rem; }
/* Legal / footer */
.legal-note { font-size: 0.72rem; padding: 11px 14px; }
.contact { padding: 14px; }
.footer { gap: 8px; font-size: 0.68rem; }
}
/* ─── Very small (≤ 380px) ─── */
@media (max-width: 380px) {
h1 { font-size: 1.3rem; }
.logo { width: 84px; height: 84px; }
.card { padding: 18px 12px; }
table { font-size: 0.66rem; min-width: 580px; }
th { font-size: 0.55rem; padding: 7px 4px; }
td { padding: 6px 4px; }
td:first-child { font-size: 0.66rem; min-width: 90px; }
}
</style>
</head>
<body>
<div class="container">
<img class="logo" src="https://photos.lotusguild.org/api/assets/3c4eb2da-0d06-407f-bdb7-c9e4cf795f0a/thumbnail?key=4aoZxX5-FHE3m_Ywwz1uGo3iNW53kmFztxfUw91PdOgphPNxayLFicNuxPvit1OYTpY&size=preview&c=jUqDBQAWF9iId3J%2FyAeIcIAICEd4d3BzSA%3D%3D" alt="Lotus Guild">
<h1><span>Lotus</span> Guild</h1>
<p class="subtitle">Private Communications</p>
<!-- ── How to Join ── -->
<div class="card">
<h2>How to Join</h2>
<ol class="steps">
<li>
<span class="step-num">1</span>
<span class="step-text">Open <a href="https://chat.lotusguild.org" target="_blank" rel="noopener">chat.lotusguild.org</a> &mdash; your homeserver is pre-configured</span>
</li>
<li>
<span class="step-num">2</span>
<span class="step-text">Register with a <strong>token from Jared</strong> &mdash; <code class="homeserver">@jared:matrix.lotusguild.org</code></span>
</li>
<li>
<span class="step-num">3</span>
<span class="step-text">Join the <a href="https://matrix.to/#/!-1ZBnAH-JiCOV8MGSKN77zDGTuI3pgSdy8Unu_DrDyc?via=matrix.lotusguild.org&via=matrix.org" target="_blank" rel="noopener">Lotus Guild Space</a> to access all rooms</span>
</li>
</ol>
<div class="or-divider">or join from another server</div>
<div class="option-block">
Already have a Matrix account? Sign up free at <a href="https://app.element.io/#/register?hs_url=https://mozilla.modular.im" target="_blank" rel="noopener">mozilla.org</a> or <a href="https://app.element.io/#/register" target="_blank" rel="noopener">matrix.org</a>, then <a href="https://matrix.to/#/!-1ZBnAH-JiCOV8MGSKN77zDGTuI3pgSdy8Unu_DrDyc?via=matrix.lotusguild.org&via=matrix.org" target="_blank" rel="noopener">join our space</a>.
</div>
<div class="divider"></div>
<!-- ── Recommended client ── -->
<div class="clients-section">
<h3>Recommended Client</h3>
<div class="client-featured">
<a href="https://chat.lotusguild.org" target="_blank" rel="noopener">
<span class="client-name">Lotus Guild Chat</span>
<span class="client-desc">Hosted Cinny &mdash; homeserver pre-configured, no setup</span>
<span class="tag-row">
<span class="tag dim">Desktop &amp; Web</span>
<span class="tag dev">Lotus Fork</span>
<span class="tag voice">Voice &amp; Video Rooms</span>
<span class="tag">Discord-like UI</span>
</span>
</a>
</div>
<p class="also-available">
Our Lotus Guild fork of Cinny adds: voice message recording (MSC3245, works E2EE), device verification fix (cross-client SAS emoji + inline cards), per-member device session panel with per-device verify buttons, full Discord-style presence tracking (online on startup, idle/away after 10&nbsp;min inactivity, unavailable when tab hidden, offline on close &mdash; with a &ldquo;Hide Online Status&rdquo; privacy toggle), presence status indicators (online/busy/away dots) in member lists, incoming call ring + Answer/Decline (DMs &amp; group chats), GIF picker (Giphy), emoji &amp; sticker picker (custom packs, stickers send as <code style="font-size:0.8em;color:#e88;">m.sticker</code> events), pinned messages panel (pin icon in room header, pin/unpin from message menu), who-reacted viewer (hover any reaction for a name tooltip; right-click for a full avatar list), draggable+resizable picture-in-picture call window, poll display &amp; voting, message forwarding, image/video captions, location sharing (map view + send), deleted message placeholders, per-message read receipt avatars (click for full list with timestamps), screenshare fullscreen button, screenshare audio mute (mute a screenshare&rsquo;s audio without leaving the call), PTT (Push-to-Talk with configurable hold key), custom status messages with emoji picker + auto-clear timer (30&nbsp;min &ndash; 7&nbsp;days) shown below usernames, encrypted room search via local cache scan with per-room &ldquo;Load more&rdquo; history buttons, a dedicated Privacy settings section (hide typing, hide online status), and the Lotus Terminal design theme.
Prefer the unmodified upstream? <a href="https://cinny.in" target="_blank" rel="noopener">cinny.in</a> works with our homeserver &mdash; set it to <code style="font-size:0.8em;color:#e88;">matrix.lotusguild.org</code>.
</p>
<div class="space-join">
<p>Already signed in? Jump straight into the community:</p>
<a href="https://matrix.to/#/!-1ZBnAH-JiCOV8MGSKN77zDGTuI3pgSdy8Unu_DrDyc?via=matrix.lotusguild.org&via=matrix.org" target="_blank" rel="noopener">Join Lotus Guild Space &rarr;</a>
</div>
<div class="divider"></div>
<!-- ── Other clients ── -->
<div class="clients-section">
<h3>Other Clients</h3>
<div class="client-group">
<p class="client-group-label">Web &amp; Desktop &mdash; Official Cinny</p>
<div class="client-cards">
<div class="client-card">
<div class="client-card-top">
<a href="https://cinny.in" target="_blank" rel="noopener" class="client-card-name">Cinny</a>
<div class="client-card-tags">
<span class="tag dim">Web</span>
<span class="tag dim">Desktop</span>
</div>
</div>
<p class="client-card-desc">The upstream open-source Cinny client. Same Discord-like UI and best-in-class space navigation as Lotus Chat, but without our custom additions (no GIF picker, no call ring notification, no PiP window, no message forwarding). Set homeserver to <code style="font-size:0.85em;color:#e88;background:rgba(152,0,0,0.08);padding:1px 5px;border-radius:4px;">matrix.lotusguild.org</code>.</p>
</div>
</div>
</div>
<div class="client-group">
<p class="client-group-label">Mobile &mdash; iOS &amp; Android</p>
<div class="client-cards">
<div class="client-card">
<div class="client-card-top">
<a href="https://element.io/element-x" target="_blank" rel="noopener" class="client-card-name">Element X</a>
<div class="client-card-tags">
<span class="tag dim">iOS</span>
<span class="tag dim">Android</span>
<span class="tag rust">Rust SDK</span>
<span class="tag voice">Voice, Video &amp; Screenshare</span>
</div>
</div>
<p class="client-card-desc">Fastest Matrix client &mdash; instant load via Sliding Sync. Native MatrixRTC calls (voice-only + video), screenshare, DM voice calls, live location sharing, media captions. Full space create &amp; management. Rust encryption (Vodozemac).</p>
</div>
<div class="client-card">
<div class="client-card-top">
<a href="https://fluffychat.im/" target="_blank" rel="noopener" class="client-card-name">FluffyChat</a>
<div class="client-card-tags">
<span class="tag dim">iOS</span>
<span class="tag dim">Android</span>
<span class="tag dim">Desktop</span>
<span class="tag dim">Web</span>
<span class="tag dim">Dart SDK</span>
<span class="tag warn">Calls Experimental</span>
</div>
</div>
<p class="client-card-desc">Simple, beginner-friendly, fully cross-platform. Dart SDK with Vodozemac encryption. Unique: supports image captions (text + image as one event). Voice/video calls are experimental &mdash; reliability varies by homeserver and platform.</p>
</div>
</div>
</div>
<div class="client-group">
<p class="client-group-label">Discord-like &mdash; Android, Windows, macOS &amp; Linux</p>
<div class="client-cards">
<div class="client-card">
<div class="client-card-top">
<a href="https://commet.chat/" target="_blank" rel="noopener" class="client-card-name">Commet</a>
<div class="client-card-tags">
<span class="tag dim">Android</span>
<span class="tag dim">Windows</span>
<span class="tag dim">macOS</span>
<span class="tag dim">Linux</span>
<span class="tag beta">Beta</span>
<span class="tag voice">Voice &amp; Video</span>
</div>
</div>
<p class="client-card-desc">Most Discord-like client overall. Multi-account support, built-in GIF search (privacy proxy &mdash; uploads to homeserver), shared calendars &amp; photo albums, polls, screenshare on browsers &amp; Android. Available on Android, Windows, macOS, Linux, and Web. Active development &mdash; iOS planned.</p>
</div>
</div>
</div>
<div class="client-group">
<p class="client-group-label">Desktop &mdash; Windows, macOS &amp; Linux</p>
<div class="client-cards">
<div class="client-card">
<div class="client-card-top">
<a href="https://element.io/download" target="_blank" rel="noopener" class="client-card-name">Element</a>
<div class="client-card-tags">
<span class="tag dim">Windows</span>
<span class="tag dim">macOS</span>
<span class="tag dim">Linux</span>
<span class="tag dim">Web</span>
<span class="tag voice">Voice, Video &amp; Screenshare</span>
</div>
</div>
<p class="client-card-desc">Most feature-complete Matrix client &mdash; every spec feature including polls, widgets, threads, screenshare. Heavier on resources. Encrypted message search on desktop only (not web).</p>
</div>
<div class="client-card">
<div class="client-card-top">
<a href="https://nheko-reborn.github.io/" target="_blank" rel="noopener" class="client-card-name">Nheko</a>
<div class="client-card-tags">
<span class="tag dim">Windows</span>
<span class="tag dim">macOS</span>
<span class="tag dim">Linux</span>
<span class="tag voice">Voice &amp; Video</span>
</div>
</div>
<p class="client-card-desc">Native C++/Qt client &mdash; lightest desktop option, no Electron. Deep KDE/Plasma integration. No threads, no mobile or web. Best for Linux power users who want minimal resource usage.</p>
</div>
</div>
</div>
<p class="all-clients"><a href="https://matrix.org/ecosystem/clients/" target="_blank" rel="noopener">View all Matrix clients &rarr;</a></p>
</div>
</div>
</div><!-- end .card -->
<!-- ── Feature Comparison Table ── -->
<div class="comparison-section">
<p class="comparison-title">Client Feature Comparison &mdash; May 2026</p>
<p class="scroll-hint" id="scrollHint">← swipe to compare →</p>
<div class="table-wrap">
<table>
<thead>
<tr>
<th></th>
<th class="ours">Lotus Chat<small>chat.lotusguild.org<br>Our Cinny fork</small></th>
<th>Cinny<small>cinny.in<br>Official</small></th>
<th>Element X<small>iOS &amp; Android</small></th>
<th>FluffyChat<small>All platforms</small></th>
<th>Commet<small>Android / Win / macOS / Linux</small></th>
<th>Element<small>Web &amp; Desktop</small></th>
<th>Nheko<small>Desktop only</small></th>
</tr>
</thead>
<tbody>
<!-- Platform -->
<tr class="section-header"><td colspan="8">Platform</td></tr>
<tr>
<td>iOS</td>
<td class="ours"><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Android</td>
<td class="ours"><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Desktop app</td>
<td class="ours"><span class="yes"></span></td>
<td><span class="yes"></span><small>Cinny Desktop</small></td>
<td><span class="no"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span><small>Win, macOS &amp; Linux</small></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
</tr>
<tr>
<td>Web browser</td>
<td class="ours"><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Performance</td>
<td class="ours">Light</td>
<td>Light</td>
<td>Very fast<small>Sliding Sync</small></td>
<td>Moderate</td>
<td>Moderate</td>
<td>Heavy<small>Electron / JS</small></td>
<td>Light<small>Native C++</small></td>
</tr>
<!-- Security -->
<tr class="section-header"><td colspan="8">Security &amp; Encryption</td></tr>
<tr>
<td>E2EE</td>
<td class="ours"><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
</tr>
<tr>
<td>Vodozemac encryption<small>stronger crypto track record</small></td>
<td class="ours"><span class="no"></span><small>js-sdk</small></td>
<td><span class="no"></span><small>js-sdk</small></td>
<td><span class="yes"></span><small>Rust SDK</small></td>
<td><span class="yes"></span><small>dart-sdk</small></td>
<td><span class="yes"></span><small>dart-sdk</small></td>
<td><span class="no"></span><small>js-sdk, migrating</small></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Device verification</td>
<td class="ours"><span class="yes"></span><small>SAS emoji, cross-client requests show inline card</small></td>
<td><span class="part">~</span><small>cross-client requests<br>may show unsupported</small></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
</tr>
<!-- Calling -->
<tr class="section-header"><td colspan="8">Voice &amp; Video</td></tr>
<tr>
<td>Voice &amp; video calls</td>
<td class="ours"><span class="yes"></span><small>rooms &amp; DMs, group calls,<br>screenshare via Element Call</small></td>
<td><span class="part">~</span><small>Element Call embed;<br>no ring notification</small></td>
<td><span class="yes"></span><small>MatrixRTC</small></td>
<td><span class="part">~</span><small>experimental, varies<br>by homeserver</small></td>
<td><span class="part">~</span><small>1:1 + group,<br>no E2EE voice rooms</small></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
</tr>
<tr>
<td>Screenshare</td>
<td class="ours"><span class="yes"></span><small>via Element Call; fullscreen button,<br>independent audio mute</small></td>
<td><span class="yes"></span><small>via Element Call embed</small></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span><small>XDG portals &amp; native</small></td>
</tr>
<tr>
<td>Push-to-Talk<small>hold key to transmit</small></td>
<td class="ours"><span class="yes"></span><small>configurable hold key,<br>PTT badge in call bar</small></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Group calls</td>
<td class="ours"><span class="yes"></span><small>via Element Call embed</small></td>
<td><span class="yes"></span><small>via Element Call embed</small></td>
<td><span class="yes"></span><small>MatrixRTC</small></td>
<td><span class="no"></span></td>
<td><span class="part">~</span><small>no E2EE voice rooms</small></td>
<td><span class="yes"></span></td>
<td><span class="part">~</span><small>partial</small></td>
</tr>
<tr>
<td>Incoming call notification<small>ring + Answer/Decline</small></td>
<td class="ours"><span class="yes"></span><small>DMs &amp; group chats;<br>ring tone, auto-dismiss</small></td>
<td><span class="no"></span></td>
<td><span class="yes"></span><small>native push</small></td>
<td><span class="part">~</span><small>experimental</small></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span><small>desktop</small></td>
<td><span class="part">~</span><small>partial</small></td>
</tr>
<!-- Core features -->
<tr class="section-header"><td colspan="8">Core Features</td></tr>
<tr>
<td>Spaces</td>
<td class="ours"><span class="yes"></span><small>best-in-class sub-space nav</small></td>
<td><span class="yes"></span><small>best-in-class sub-space nav</small></td>
<td><span class="yes"></span><small>dedicated spaces tab,<br>full management</small></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span><small>Discord-like categories</small></td>
<td><span class="yes"></span><small>sub-spaces clunky</small></td>
<td><span class="part">~</span><small>limited</small></td>
</tr>
<tr>
<td>Threads</td>
<td class="ours"><span class="part">~</span><small>basic, no dedicated view</small></td>
<td><span class="part">~</span><small>basic, no dedicated view</small></td>
<td><span class="part">~</span><small>Labs flag</small></td>
<td><span class="no"></span><small>shows as regular messages</small></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Polls</td>
<td class="ours"><span class="yes"></span><small>display &amp; vote</small></td>
<td><span class="part">~</span><small>display only</small></td>
<td><span class="yes"></span><small>create, vote &amp; end</small></td>
<td><span class="yes"></span><small>added v2.3.0</small></td>
<td><span class="yes"></span><small>added v0.4.2</small></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Voice messages<small>record &amp; play</small></td>
<td class="ours"><span class="yes"></span><small>record &amp; play,<br>MSC3245, E2EE</small></td>
<td><span class="part">~</span><small>playback only</small></td>
<td><span class="yes"></span><small>record, play, variable speed,<br>reply with voice</small></td>
<td><span class="yes"></span><small>record &amp; play,<br>pause support</small></td>
<td><span class="part">~</span><small>playback confirmed;<br>recording unclear</small></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Pinned messages</td>
<td class="ours"><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span><small>dedicated pins view</small></td>
<td><span class="part">~</span><small>view only</small></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
</tr>
<tr>
<td>Custom emoji &amp; stickers</td>
<td class="ours"><span class="yes"></span><small>best-in-class</small></td>
<td><span class="yes"></span></td>
<td><span class="part">~</span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span><small>bulk upload, Signal packs</small></td>
<td><span class="part">~</span><small>sometimes shows mxc:// URLs</small></td>
<td><span class="yes"></span></td>
</tr>
<tr>
<td>GIF search / picker</td>
<td class="ours"><span class="yes"></span><small>Giphy, Terminal TDS themed,<br>click-outside to close</small></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="yes"></span><small>privacy proxy,<br>uploads to homeserver</small></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Message search (encrypted)</td>
<td class="ours"><span class="yes"></span><small>local cache scan; load-more<br>buttons extend history per room</small></td>
<td><span class="part">~</span><small>server search only;<br>no E2EE support</small></td>
<td><span class="no"></span></td>
<td><span class="part">~</span><small>cache scan only</small></td>
<td><span class="yes"></span><small>client-side; auto-fetches +<br>decrypts history during search</small></td>
<td><span class="part">~</span><small>desktop only, not web</small></td>
<td><span class="part">~</span><small>local DB scan</small></td>
</tr>
<tr>
<td>Widgets</td>
<td class="ours"><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
</tr>
<!-- UX / extras -->
<tr class="section-header"><td colspan="8">UX &amp; Extras</td></tr>
<tr>
<td>Multi-account</td>
<td class="ours"><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="part">~</span><small>supported but clunky</small></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span><small>CLI profiles only</small></td>
</tr>
<tr>
<td>Image captions<small>(text + image as one event)</small></td>
<td class="ours"><span class="yes"></span><small>caption field on<br>image &amp; video upload</small></td>
<td><span class="no"></span></td>
<td><span class="yes"></span><small>scrollable captions<br>on media (v26.04.2)</small></td>
<td><span class="yes"></span><small>unique feature</small></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="part">~</span></td>
</tr>
<tr>
<td>Discord-like UI</td>
<td class="ours"><span class="yes"></span><small>best-in-class for web</small></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span><small>WhatsApp/Telegram style</small></td>
<td><span class="yes"></span><small>most Discord-like overall</small></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Shared calendars &amp; albums</td>
<td class="ours"><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="yes"></span><small>unique to Commet</small></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Deleted message visibility<small>(redacted events)</small></td>
<td class="ours"><span class="yes"></span><small>"Message deleted" with reason<br>if provided</small></td>
<td><span class="no"></span><small>redacted messages hidden</small></td>
<td><span class="yes"></span><small>"Message deleted"<br>placeholder shown</small></td>
<td><span class="yes"></span><small>shows redaction notice</small></td>
<td><span class="yes"></span><small>shows redaction notice</small></td>
<td><span class="yes"></span><small>"Message deleted"<br>placeholder shown</small></td>
<td><span class="yes"></span><small>shows redaction notice</small></td>
</tr>
<tr>
<td>Location sharing</td>
<td class="ours"><span class="part">~</span><small>map embed view +<br>static share button</small></td>
<td><span class="no"></span></td>
<td><span class="yes"></span><small>live &amp; static,<br>map rendering</small></td>
<td><span class="part">~</span><small>basic static</small></td>
<td><span class="no"></span></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Message forwarding</td>
<td class="ours"><span class="yes"></span><small>forward to any room</small></td>
<td><span class="no"></span></td>
<td><span class="part">~</span><small>via share menu</small></td>
<td><span class="yes"></span></td>
<td><span class="part">~</span></td>
<td><span class="yes"></span></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Per-message read receipts<small>who read each message</small></td>
<td class="ours"><span class="yes"></span><small>avatar pill below message,<br>click for list + timestamps</small></td>
<td><span class="no"></span></td>
<td><span class="yes"></span><small>avatar thumbnails</small></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span><small>avatar row below message</small></td>
<td><span class="yes"></span></td>
</tr>
<tr>
<td>Who reacted<small>see who reacted with each emoji</small></td>
<td class="ours"><span class="yes"></span><small>hover tooltip with names;<br>right-click for full avatar modal</small></td>
<td><span class="no"></span></td>
<td><span class="part">~</span><small>tap reaction chip</small></td>
<td><span class="part">~</span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span><small>tooltip + click for list</small></td>
<td><span class="yes"></span></td>
</tr>
<tr>
<td>Custom status message<small>shown below username</small></td>
<td class="ours"><span class="yes"></span><small>emoji picker, auto-clear timer<br>(30 min 7 days), 64-char limit</small></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="no"></span></td>
<td><span class="yes"></span><small>via profile settings</small></td>
<td><span class="no"></span></td>
</tr>
<tr>
<td>Online presence tracking<small>idle/away auto-detection</small></td>
<td class="ours"><span class="yes"></span><small>online on start, idle after 10 min,<br>unavailable when tab hidden,<br>offline on close; hide-status toggle</small></td>
<td><span class="part">~</span><small>manual AFK only; auto idle<br>detection PR open, unmerged</small></td>
<td><span class="part">~</span><small>basic online/offline only</small></td>
<td><span class="part">~</span><small>basic online/offline only</small></td>
<td><span class="part">~</span><small>inactivity monitor shipped Oct 2025;<br>no tab/close detection confirmed</small></td>
<td><span class="part">~</span><small>3-min idle timer (shipped Nov 2023);<br>no tab detection, no offline on close,<br>no user-facing hide toggle</small></td>
<td><span class="part">~</span><small>basic online/offline only</small></td>
</tr>
<tr>
<td>Push notifications</td>
<td class="ours"><span class="part">~</span><small>web push only</small></td>
<td><span class="part">~</span><small>web push only</small></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span></td>
<td><span class="yes"></span><small>desktop</small></td>
<td><span class="yes"></span></td>
</tr>
</tbody>
</table>
</div><!-- table-wrap -->
<div class="security-note" style="margin:14px 16px 6px;">
<strong>Encryption architecture:</strong> Element X uses the native <strong>matrix-rust-sdk</strong> with Vodozemac. FluffyChat and Commet use <strong>matrix-dart-sdk</strong>, which also wraps Vodozemac for its crypto &mdash; all three benefit from Vodozemac's stronger security track record over the older JavaScript SDK. Cinny and Element Web/Desktop currently use <strong>matrix-js-sdk</strong>; Element is actively migrating to the Rust SDK. Clients using Vodozemac were not affected by historical js-sdk vulnerabilities.
</div>
<div class="legend">
<span><span class="yes"></span> Full support</span>
<span><span class="part">~</span> Partial / experimental</span>
<span><span class="no"></span> Not supported</span>
</div>
</div><!-- comparison-section -->
<!-- ── Server Details ── -->
<div class="server-info">
<p class="server-info-title">Server Details</p>
<div class="info-grid">
<div class="info-item">
<div class="info-label">Access</div>
<div class="info-value">Invite-only</div>
</div>
<div class="info-item">
<div class="info-label">Max Upload</div>
<div class="info-value">200 MB / file</div>
</div>
<div class="info-item">
<div class="info-label">Message History</div>
<div class="info-value">Kept indefinitely</div>
</div>
<div class="info-item">
<div class="info-label">Media Retention</div>
<div class="info-value">3 yr local &middot; 1 yr remote</div>
</div>
<div class="info-item">
<div class="info-label">Federation</div>
<div class="info-value">Fully federated</div>
</div>
<div class="info-item">
<div class="info-label">Minimum Age</div>
<div class="info-value">13+ (COPPA)</div>
</div>
</div>
<div class="privacy-strip">
<span class="privacy-badge">No ads or tracking</span>
<span class="privacy-badge">No data sold</span>
<span class="privacy-badge">E2EE &mdash; server cannot read encrypted rooms</span>
</div>
</div>
<div class="legal-note">
This service is provided "as-is" with no uptime guarantee. Not for emergency use &mdash; do not use to contact emergency services (e.g. 911). Use is governed by our <a href="https://wiki.lotusguild.org/en/Legal/terms-of-service" target="_blank" rel="noopener">Terms of Service</a> and <a href="https://wiki.lotusguild.org/en/Legal/privacy-policy" target="_blank" rel="noopener">Privacy Policy</a>. Governing law: State of Ohio, United States.
</div>
<div class="contact">
<p style="font-size:0.85rem;color:#777;margin-bottom:4px;">Questions or need a registration token?</p>
<p>Reach out to <code class="homeserver">@jared:matrix.lotusguild.org</code></p>
</div>
<p class="footer">
<a href="https://wiki.lotusguild.org/en/Services/service-matrix" target="_blank" rel="noopener">Wiki &amp; Setup Guide</a>
<span>&middot;</span>
<a href="https://wiki.lotusguild.org/en/Legal/privacy-policy" target="_blank" rel="noopener">Privacy Policy</a>
<span>&middot;</span>
<a href="https://wiki.lotusguild.org/en/Legal/terms-of-service" target="_blank" rel="noopener">Terms of Service</a>
<span>&middot;</span>
<span>Powered by Matrix &middot; E2E Encrypted</span>
</p>
</div><!-- container -->
<script>
// Show scroll hint only on touch devices; hide once table is scrolled
if ('ontouchstart' in window || navigator.maxTouchPoints > 0) {
var hint = document.getElementById('scrollHint');
if (hint) hint.style.display = 'block';
var wrap = hint && hint.nextElementSibling;
if (wrap) wrap.addEventListener('scroll', function hide() {
hint.style.display = 'none';
wrap.removeEventListener('scroll', hide);
}, { passive: true });
}
</script>
</body>
</html>