8 Commits

10 changed files with 1124 additions and 43 deletions

View File

@@ -4,14 +4,14 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Rosetta - Secure & Private Messaging | End-to-End Encrypted Chat</title> <title>Rosetta - Secure & Private Messaging | End-to-End Encrypted Chat</title>
<meta name="description" content="Rosetta is a secure, fast, and private messaging app with military-grade end-to-end encryption. Download for macOS, Windows, and Linux. No phone number required." /> <meta name="description" content="Rosetta is a secure, fast, and private messaging app with military-grade end-to-end encryption. Download for Windows, Linux, and Android. No phone number required." />
<meta name="keywords" content="secure messaging, encrypted chat, private messenger, end-to-end encryption, secure communication" /> <meta name="keywords" content="secure messaging, encrypted chat, private messenger, end-to-end encryption, secure communication" />
<meta name="author" content="Rosetta Team" /> <meta name="author" content="Rosetta Team" />
<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" /> <meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:url" content="https://rosetta.im/" /> <meta property="og:url" content="https://rosetta.im/" />
<meta property="og:title" content="Rosetta - Secure Messaging for Everyone" /> <meta property="og:title" content="Rosetta - Secure Messaging for Everyone" />
<meta property="og:description" content="End-to-end encrypted messaging app with zero-knowledge architecture. Download for macOS, Windows, Linux." /> <meta property="og:description" content="End-to-end encrypted messaging app with zero-knowledge architecture. Download for Windows, Linux, and Android." />
<meta property="og:image" content="/og-image.png" /> <meta property="og:image" content="/og-image.png" />
<meta property="og:site_name" content="Rosetta" /> <meta property="og:site_name" content="Rosetta" />
<meta property="og:locale" content="en_US" /> <meta property="og:locale" content="en_US" />
@@ -34,7 +34,7 @@
"description": "Secure end-to-end encrypted messaging application", "description": "Secure end-to-end encrypted messaging application",
"url": "https://rosetta.im", "url": "https://rosetta.im",
"applicationCategory": "CommunicationApplication", "applicationCategory": "CommunicationApplication",
"operatingSystem": ["Windows", "macOS", "Linux", "Android"], "operatingSystem": ["Windows", "Linux", "Android"],
"offers": { "offers": {
"@type": "Offer", "@type": "Offer",
"price": "0", "price": "0",

237
public/legal.css Normal file
View File

@@ -0,0 +1,237 @@
:root {
color-scheme: dark;
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
color: #edf3ff;
background: #0c111a;
font-synthesis: none;
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
min-width: 320px;
margin: 0;
background: #0c111a;
}
a {
text-decoration: none;
}
.page {
width: min(100% - 48px, 1120px);
margin: 0 auto;
padding: 20px 0 64px;
}
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 24px;
min-height: 56px;
border-bottom: 1px solid #29354a;
}
.brand {
display: inline-flex;
align-items: center;
gap: 10px;
color: #f5f8ff;
font-size: 18px;
font-weight: 750;
text-decoration: none;
}
.brand-mark {
display: grid;
width: 32px;
height: 32px;
place-items: center;
overflow: hidden;
border-radius: 8px;
background: #17325f;
}
.brand-mark img {
display: block;
width: 100%;
height: 100%;
}
.topbar nav,
.legal-footer {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 18px;
}
.topbar nav a,
.legal-footer a {
color: #aebbd0;
font-size: 14px;
text-decoration: none;
}
.topbar nav a:hover,
.topbar nav a[aria-current="page"],
.legal-footer a:hover {
color: #ffffff;
}
.document {
width: min(100%, 790px);
margin: 72px auto 0;
}
.document-header {
padding-bottom: 34px;
border-bottom: 1px solid #29354a;
}
.eyebrow {
margin: 0 0 12px;
color: #72afff;
font-size: 13px;
font-weight: 750;
letter-spacing: 0;
text-transform: uppercase;
}
h1 {
max-width: 680px;
margin: 0;
color: #f4f7ff;
font-size: clamp(36px, 6vw, 56px);
letter-spacing: 0;
line-height: 1.04;
}
.updated {
margin: 16px 0 0;
color: #8f9db3;
font-size: 15px;
}
.document-content {
padding-top: 32px;
}
.document-content > :first-child {
margin-top: 0;
}
.lead {
max-width: 740px;
color: #d3dcec;
font-size: 19px;
line-height: 1.55;
}
h2 {
margin: 48px 0 16px;
padding-top: 30px;
border-top: 1px solid #29354a;
color: #f2f6ff;
font-size: clamp(21px, 3vw, 26px);
letter-spacing: 0;
line-height: 1.24;
}
p,
li {
color: #b7c3d6;
font-size: 16px;
line-height: 1.68;
}
p {
margin: 0 0 18px;
}
ul {
display: grid;
gap: 9px;
margin: 0 0 20px;
padding-left: 22px;
}
li::marker {
color: #72afff;
}
.document-content a {
color: #8fc0ff;
overflow-wrap: anywhere;
text-underline-offset: 3px;
}
.address {
padding: 18px 20px;
border-left: 2px solid #4c8fe8;
background: #121c2b;
color: #d6dfef;
white-space: pre-line;
}
.legal-footer {
justify-content: space-between;
margin-top: 80px;
padding-top: 24px;
border-top: 1px solid #29354a;
}
.legal-footer p {
margin: 0;
color: #77869d;
font-size: 13px;
}
@media (max-width: 640px) {
.page {
width: min(100% - 32px, 1120px);
padding-top: 12px;
}
.topbar {
align-items: flex-start;
flex-direction: column;
gap: 14px;
padding-bottom: 16px;
}
.topbar nav,
.legal-footer {
gap: 14px;
}
.document {
margin-top: 48px;
}
.document-header {
padding-bottom: 26px;
}
.lead {
font-size: 18px;
}
h2 {
margin-top: 40px;
padding-top: 26px;
}
.legal-footer {
align-items: flex-start;
flex-direction: column;
margin-top: 56px;
}
}

View File

@@ -79,14 +79,32 @@
} }
} }
</style> </style>
<link rel="stylesheet" href="/legal.css" />
</head> </head>
<body> <body>
<main> <main class="page">
<a class="back" href="/">Back to home</a> <header class="topbar">
<h1>Privacy Policy for Rosetta</h1> <a class="brand" href="/" aria-label="Rosetta home">
<p class="muted">Last updated: May 22, 2026</p> <span class="brand-mark"><img src="/rosetta-logo.png" alt="" /></span>
Rosetta
</a>
<nav aria-label="Legal pages">
<a href="/support/">Support</a>
<a href="/privacy/" aria-current="page">Privacy</a>
<a href="/terms/">Terms</a>
</nav>
</header>
<p> <article class="document">
<header class="document-header">
<p class="eyebrow">Rosetta legal</p>
<h1>Privacy Policy</h1>
<p class="updated">Last updated: May 22, 2026</p>
</header>
<div class="document-content">
<p class="lead">
Rosetta IM is operated by ROSETTA CLOUD SERVICES LIMITED ("Rosetta", Rosetta IM is operated by ROSETTA CLOUD SERVICES LIMITED ("Rosetta",
"we", "us", or "our"). This Privacy Policy explains how we handle "we", "us", or "our"). This Privacy Policy explains how we handle
information when you use Rosetta, our end-to-end encrypted messaging information when you use Rosetta, our end-to-end encrypted messaging
@@ -176,7 +194,8 @@
<p> <p>
Depending on where you live, you may have rights to access, correct, Depending on where you live, you may have rights to access, correct,
delete, or object to certain processing of your personal information. To delete, or object to certain processing of your personal information. To
make a request, contact us at admin@rosetta.im. make a request, contact us at
<a href="mailto:admin@rosetta.im">admin@rosetta.im</a>.
</p> </p>
<p> <p>
Because Rosetta minimizes account data and uses cryptographic Because Rosetta minimizes account data and uses cryptographic
@@ -220,8 +239,22 @@ UNIT 704C 7/F BLK 3 NAN FUNG IND CITY
18 TIN HAU RD 18 TIN HAU RD
TUEN MUN TUEN MUN
HONG KONG</p> HONG KONG</p>
<p>Email: <a href="mailto:admin@rosetta.im">admin@rosetta.im</a></p> <p>
Email: <a href="mailto:admin@rosetta.im">admin@rosetta.im</a><br />
Support: <a href="/support/">https://rosetta.im/support/</a>
</p>
<p>Phone: <a href="tel:+85228910030">+852 2891 0030</a></p> <p>Phone: <a href="tel:+85228910030">+852 2891 0030</a></p>
</div>
</article>
<footer class="legal-footer">
<p>&copy; 2026 ROSETTA CLOUD SERVICES LIMITED</p>
<nav aria-label="Footer links">
<a href="/">Rosetta home</a>
<a href="/support/">Support</a>
<a href="/terms/">Terms of Use</a>
</nav>
</footer>
</main> </main>
</body> </body>
</html> </html>

BIN
public/rosetta-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -8,8 +8,26 @@
xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"> xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url> <url>
<loc>https://rosetta.im/</loc> <loc>https://rosetta.im/</loc>
<lastmod>2026-02-16</lastmod> <lastmod>2026-07-11</lastmod>
<changefreq>weekly</changefreq> <changefreq>weekly</changefreq>
<priority>1.0</priority> <priority>1.0</priority>
</url> </url>
<url>
<loc>https://rosetta.im/support/</loc>
<lastmod>2026-07-11</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://rosetta.im/privacy/</loc>
<lastmod>2026-07-11</lastmod>
<changefreq>yearly</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://rosetta.im/terms/</loc>
<lastmod>2026-07-11</lastmod>
<changefreq>yearly</changefreq>
<priority>0.5</priority>
</url>
</urlset> </urlset>

778
public/support/index.html Normal file
View File

@@ -0,0 +1,778 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Rosetta Support</title>
<meta
name="description"
content="Contact Rosetta Support for help with account access, recovery phrases, messaging, media, privacy, and security."
/>
<link rel="canonical" href="https://rosetta.im/support/" />
<meta name="robots" content="index, follow" />
<meta name="theme-color" content="#0a67ff" />
<script>
document.documentElement.classList.add("js");
</script>
<style>
:root {
color-scheme: light dark;
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
color: #172033;
background: #f6f8fc;
line-height: 1.5;
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
background: #f6f8fc;
}
a {
text-decoration: none;
}
a {
color: #075ed3;
}
a:focus-visible {
outline: 3px solid #8dc0ff;
outline-offset: 3px;
}
.page {
width: min(1120px, calc(100% - 40px));
margin: 0 auto;
padding: 24px 0 64px;
}
.js .page > * {
opacity: 0;
transform: translateY(14px);
transition: opacity 420ms ease, transform 520ms cubic-bezier(0.22, 1, 0.36, 1);
}
.js .page.is-ready > * {
opacity: 1;
transform: translateY(0);
}
.js .page.is-ready > :nth-child(1) {
transition-delay: 0ms;
}
.js .page.is-ready > :nth-child(2) {
transition-delay: 45ms;
}
.js .page.is-ready > :nth-child(3) {
transition-delay: 90ms;
}
.js .page.is-ready > :nth-child(n + 4) {
transition-delay: 130ms;
}
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
}
.brand {
display: inline-flex;
align-items: center;
gap: 10px;
color: inherit;
font-size: 18px;
font-weight: 760;
letter-spacing: 0;
text-decoration: none;
}
.brand-mark {
width: 34px;
height: 34px;
border-radius: 8px;
overflow: hidden;
}
.brand-mark img {
display: block;
width: 100%;
height: 100%;
}
.home-link {
color: #334155;
font-size: 15px;
font-weight: 600;
text-decoration: none;
}
.hero {
max-width: 760px;
padding: 88px 0 58px;
}
.eyebrow {
margin: 0 0 12px;
color: #075ed3;
font-size: 14px;
font-weight: 750;
text-transform: uppercase;
}
h1,
h2,
h3,
p {
margin-top: 0;
}
h1 {
max-width: 650px;
margin-bottom: 20px;
font-size: clamp(38px, 7vw, 68px);
font-weight: 760;
letter-spacing: 0;
line-height: 1.04;
}
.intro {
max-width: 620px;
margin-bottom: 28px;
color: #4b5568;
font-size: clamp(18px, 2.2vw, 21px);
line-height: 1.5;
}
.contact-button {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 50px;
padding: 12px 18px;
border-radius: 8px;
background: #0a67ff;
color: #ffffff;
font-size: 16px;
font-weight: 720;
text-decoration: none;
}
.contact-button:hover {
background: #0055ca;
}
.quick-links {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 14px;
margin-bottom: 72px;
}
.quick-link {
display: block;
min-height: 138px;
padding: 22px;
border: 1px solid #dbe2ee;
border-radius: 8px;
background: #ffffff;
color: inherit;
text-decoration: none;
}
.quick-link:hover {
border-color: #a7c9ff;
box-shadow: 0 10px 24px rgba(26, 61, 110, 0.08);
}
.quick-link strong {
display: block;
margin-bottom: 8px;
font-size: 17px;
}
.quick-link span {
color: #64748b;
font-size: 15px;
line-height: 1.4;
}
.section {
padding: 52px 0;
border-top: 1px solid #dbe2ee;
}
.section-heading {
display: grid;
grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
gap: 32px;
align-items: start;
margin-bottom: 28px;
}
h2 {
margin-bottom: 0;
font-size: clamp(28px, 4vw, 38px);
letter-spacing: 0;
line-height: 1.12;
}
.section-copy {
margin-bottom: 0;
color: #526176;
font-size: 17px;
}
.faq {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 12px;
}
details {
display: block;
box-sizing: border-box;
padding: 19px 20px;
border: 1px solid #dbe2ee;
border-radius: 8px;
background: #ffffff;
overflow: hidden;
transition: border-color 180ms ease, background-color 180ms ease;
}
details[open] {
border-color: #b8cce8;
background: #f9fbff;
}
details.is-animating {
will-change: height;
}
summary {
display: grid;
grid-template-columns: minmax(0, 1fr) 36px;
align-items: center;
gap: 16px;
min-height: 28px;
cursor: pointer;
color: #1d293d;
font-size: 17px;
font-weight: 710;
list-style: none;
}
summary::-webkit-details-marker {
display: none;
}
summary::marker {
content: "";
}
.faq-toggle {
display: grid;
width: 36px;
height: 36px;
place-items: center;
justify-self: end;
border: 1px solid #c3d5ed;
border-radius: 50%;
background: #f3f8ff;
color: #075ed3;
transition: background-color 180ms ease, border-color 180ms ease;
}
.faq-toggle svg {
display: block;
width: 18px;
height: 18px;
stroke: currentColor;
stroke-width: 2.4;
stroke-linecap: round;
stroke-linejoin: round;
transform: translateZ(0) rotate(0deg);
will-change: transform;
transition: transform 240ms cubic-bezier(0.25, 0.1, 0.25, 1);
}
details[open] .faq-toggle {
border-color: #78a8df;
background: #deedff;
}
details[open] .faq-toggle svg {
transform: translateZ(0) rotate(180deg);
}
summary:focus-visible {
outline: none;
}
summary:focus-visible .faq-toggle {
box-shadow: 0 0 0 3px #8cbeff;
}
details > p {
display: block;
margin: 0 40px 0 0;
color: #526176;
font-size: 15px;
opacity: 0;
transform: translateY(-3px);
transition: opacity 160ms ease, transform 220ms cubic-bezier(0.25, 0.1, 0.25, 1);
}
details:not([open]) > p {
display: none;
}
details[open] > p {
margin: 14px 40px 0 0;
opacity: 1;
transform: translateY(0);
}
details.is-closing > p {
margin: 0 40px 0 0;
opacity: 0;
transform: translateY(-3px);
}
@media (prefers-reduced-motion: reduce) {
.js .page > * {
opacity: 1;
transform: none;
transition: none;
}
details,
.faq-toggle,
.faq-toggle svg,
details > p {
transition: none;
}
}
.contact-panel {
display: grid;
grid-template-columns: minmax(0, 1.1fr) minmax(240px, 0.9fr);
gap: 28px;
padding: 32px;
border-radius: 8px;
background: #0e1e39;
color: #ffffff;
}
.contact-panel h2 {
margin-bottom: 12px;
}
.contact-panel p {
max-width: 580px;
margin-bottom: 0;
color: #cbd7ed;
font-size: 17px;
}
.contact-details {
align-self: center;
padding: 20px;
border: 1px solid rgba(255, 255, 255, 0.18);
border-radius: 8px;
background: rgba(255, 255, 255, 0.07);
}
.contact-details strong,
.contact-details a {
display: block;
}
.contact-details strong {
margin-bottom: 6px;
font-size: 15px;
}
.contact-details a {
color: #ffffff;
font-size: 18px;
font-weight: 700;
overflow-wrap: anywhere;
text-decoration: none;
}
.legal-links {
display: flex;
flex-wrap: wrap;
gap: 18px;
padding-top: 32px;
}
.legal-links a {
color: #526176;
font-size: 15px;
text-decoration: none;
}
@media (max-width: 720px) {
.page {
width: min(100% - 32px, 1120px);
padding-top: 16px;
}
.hero {
padding: 64px 0 42px;
}
.quick-links,
.faq,
.section-heading,
.contact-panel {
grid-template-columns: 1fr;
}
.quick-links {
margin-bottom: 52px;
}
.section {
padding: 40px 0;
}
.contact-panel {
gap: 20px;
padding: 24px;
}
}
@media (prefers-color-scheme: dark) {
:root {
color: #eff4ff;
background: #0c111a;
}
body {
background: #0c111a;
}
a,
.eyebrow {
color: #72afff;
}
.home-link,
.quick-link,
summary {
color: #eef4ff;
}
.faq-toggle {
color: #ffffff;
border-color: #354c6d;
background: #1d2b3f;
}
details[open] .faq-toggle {
border-color: #5e92ca;
background: #29466c;
}
.intro,
.section-copy,
.quick-link span,
details p,
.legal-links a {
color: #aab8cf;
}
.quick-link,
details {
border-color: #29354a;
background: #141c29;
}
details[open] {
border-color: #3c608b;
background: #18263a;
}
.quick-link:hover {
border-color: #427fc7;
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.2);
}
.section {
border-color: #29354a;
}
.contact-button {
background: #3986ff;
}
.contact-button:hover {
background: #5b9bff;
}
}
</style>
</head>
<body>
<main class="page">
<header class="topbar">
<a class="brand" href="/" aria-label="Rosetta home">
<span class="brand-mark"><img src="/rosetta-logo.png" alt="" /></span>
Rosetta
</a>
<a class="home-link" href="/">Back to home</a>
</header>
<section class="hero" aria-labelledby="support-title">
<p class="eyebrow">Rosetta Support</p>
<h1 id="support-title">Help with your Rosetta account and messages.</h1>
<p class="intro">
Find answers about account access, recovery phrases, private messaging,
shared media, and privacy. For anything else, contact our support team.
</p>
<a class="contact-button" href="mailto:admin@rosetta.im?subject=Rosetta%20Support%20Request">
Email Rosetta Support
</a>
</section>
<nav class="quick-links" aria-label="Support topics">
<a class="quick-link" href="#account">
<strong>Account and access</strong>
<span>Recovery phrases, device access, and account security.</span>
</a>
<a class="quick-link" href="#messaging">
<strong>Messaging and media</strong>
<span>Messages, photos, videos, files, voice messages, and groups.</span>
</a>
<a class="quick-link" href="#privacy">
<strong>Privacy and safety</strong>
<span>Security questions, privacy information, and abuse reports.</span>
</a>
</nav>
<section class="section" id="account" aria-labelledby="account-heading">
<div class="section-heading">
<h2 id="account-heading">Account and access</h2>
<p class="section-copy">
Rosetta accounts are accessed with a recovery phrase instead of a phone number.
Keep your phrase private and stored somewhere safe.
</p>
</div>
<div class="faq">
<details>
<summary><span>How do I access my account on a new device?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
Install Rosetta and enter your recovery phrase in the exact order it was created.
Rosetta may ask you to confirm a new device to protect your account.
</p>
</details>
<details>
<summary><span>I lost my recovery phrase. Can it be restored?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
No. Your recovery phrase is the key to your account. Rosetta cannot recover it
for you, so keep it private and backed up before you need it.
</p>
</details>
<details>
<summary><span>Why am I asked to confirm a new device?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
New-device confirmation helps prevent someone who has obtained a recovery phrase
from silently accessing your account on another device.
</p>
</details>
<details>
<summary><span>How do I report an account-access problem?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
Email us with the device model, Rosetta version, and a short description of what
happened. Do not include your recovery phrase or private keys.
</p>
</details>
</div>
</section>
<section class="section" id="messaging" aria-labelledby="messaging-heading">
<div class="section-heading">
<h2 id="messaging-heading">Messaging and media</h2>
<p class="section-copy">
Rosetta supports private chats, groups, photos, videos, files, and voice messages.
Attachment choices can vary depending on your device permissions and the selected item.
</p>
</div>
<div class="faq">
<details>
<summary><span>How do I send a photo, video, or file?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
Open a chat, tap the attachment button next to the message field, choose the item
you want to share, then send it. Allow Photos or Files access when iOS asks for it.
</p>
</details>
<details>
<summary><span>Why is an attachment still sending?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
Media uploads depend on the file size and your connection. Keep Rosetta open and
connected until the send indicator completes. You can retry a message that failed.
</p>
</details>
<details>
<summary><span>How do I send a voice message?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
In a chat, press and hold the microphone control to record, then release it to send.
Microphone permission is required the first time you record.
</p>
</details>
<details>
<summary><span>How do I get help with a group?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
Contact us with the group name and a description of the issue. Do not send private
recovery phrases, message contents, or encryption keys.
</p>
</details>
</div>
</section>
<section class="section" id="privacy" aria-labelledby="privacy-heading">
<div class="section-heading">
<h2 id="privacy-heading">Privacy and safety</h2>
<p class="section-copy">
Rosetta is designed for private communication. If you have a security concern or a
question about data handling, contact us directly.
</p>
</div>
<div class="faq">
<details>
<summary><span>How is message content protected?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
Rosetta is designed to encrypt message content before it is sent. For details about
how we handle data, read the Rosetta Privacy Policy.
</p>
</details>
<details>
<summary><span>How do I report abuse or a security issue?</span><span class="faq-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="m6 9 6 6 6-6" /></svg></span></summary>
<p>
Email <a href="mailto:admin@rosetta.im?subject=Rosetta%20Security%20Report">admin@rosetta.im</a>
with a description of the concern. Do not include recovery phrases or private keys.
</p>
</details>
</div>
</section>
<section class="contact-panel" aria-labelledby="contact-heading">
<div>
<h2 id="contact-heading">Need more help?</h2>
<p>
Send us a message with your device model, app version, and a short explanation of the
issue. Never send a recovery phrase, private key, or private message content.
</p>
</div>
<div class="contact-details">
<strong>Rosetta Support</strong>
<a href="mailto:admin@rosetta.im?subject=Rosetta%20Support%20Request">admin@rosetta.im</a>
</div>
</section>
<footer class="legal-links">
<a href="/">Rosetta home</a>
<a href="/privacy/">Privacy Policy</a>
<a href="/terms/">Terms of Use</a>
</footer>
</main>
<script>
window.addEventListener("DOMContentLoaded", () => {
requestAnimationFrame(() => {
document.querySelector(".page")?.classList.add("is-ready");
});
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const animationOptions = {
duration: 240,
easing: "cubic-bezier(0.25, 0.1, 0.25, 1)",
fill: "forwards",
};
document.querySelectorAll(".faq details").forEach((details) => {
const summary = details.querySelector("summary");
if (!summary) return;
let animation = null;
const setExpanded = (expanded) => summary.setAttribute("aria-expanded", String(expanded));
setExpanded(details.open);
summary.addEventListener("click", (event) => {
event.preventDefault();
if (animation) return;
if (prefersReducedMotion) {
details.open = !details.open;
setExpanded(details.open);
return;
}
const isOpening = !details.open;
const startHeight = details.getBoundingClientRect().height;
if (isOpening) {
details.open = true;
setExpanded(true);
const endHeight = details.scrollHeight;
details.classList.add("is-animating");
details.style.height = `${startHeight}px`;
animation = details.animate(
[{ height: `${startHeight}px` }, { height: `${endHeight}px` }],
animationOptions,
);
} else {
details.open = false;
const endHeight = details.getBoundingClientRect().height;
details.open = true;
details.classList.add("is-animating", "is-closing");
details.style.height = `${startHeight}px`;
animation = details.animate(
[{ height: `${startHeight}px` }, { height: `${endHeight}px` }],
animationOptions,
);
}
animation.onfinish = () => {
const completedAnimation = animation;
if (!isOpening) {
details.open = false;
setExpanded(false);
}
details.style.height = "";
details.classList.remove("is-animating", "is-closing");
completedAnimation.oncancel = null;
completedAnimation.cancel();
animation = null;
};
animation.oncancel = () => {
details.style.height = "";
details.classList.remove("is-animating", "is-closing");
animation = null;
};
});
});
});
</script>
</body>
</html>

View File

@@ -79,14 +79,32 @@
} }
} }
</style> </style>
<link rel="stylesheet" href="/legal.css" />
</head> </head>
<body> <body>
<main> <main class="page">
<a class="back" href="/">Back to home</a> <header class="topbar">
<h1>Terms of Use for Rosetta</h1> <a class="brand" href="/" aria-label="Rosetta home">
<p class="muted">Last updated: May 22, 2026</p> <span class="brand-mark"><img src="/rosetta-logo.png" alt="" /></span>
Rosetta
</a>
<nav aria-label="Legal pages">
<a href="/support/">Support</a>
<a href="/privacy/">Privacy</a>
<a href="/terms/" aria-current="page">Terms</a>
</nav>
</header>
<p> <article class="document">
<header class="document-header">
<p class="eyebrow">Rosetta legal</p>
<h1>Terms of Use</h1>
<p class="updated">Last updated: May 22, 2026</p>
</header>
<div class="document-content">
<p class="lead">
These Terms of Use and End User License Agreement ("Terms") govern your These Terms of Use and End User License Agreement ("Terms") govern your
use of Rosetta, an end-to-end encrypted messaging application operated by use of Rosetta, an end-to-end encrypted messaging application operated by
ROSETTA CLOUD SERVICES LIMITED ("Rosetta", "we", "us", or "our"). ROSETTA CLOUD SERVICES LIMITED ("Rosetta", "we", "us", or "our").
@@ -180,7 +198,10 @@
maintenance and support for Rosetta. Apple has no obligation to provide maintenance and support for Rosetta. Apple has no obligation to provide
maintenance or support services for Rosetta. maintenance or support services for Rosetta.
</p> </p>
<p>Support contact: <a href="mailto:admin@rosetta.im">admin@rosetta.im</a></p> <p>
Support contact: <a href="mailto:admin@rosetta.im">admin@rosetta.im</a><br />
Support centre: <a href="/support/">https://rosetta.im/support/</a>
</p>
<h2>11. Warranty</h2> <h2>11. Warranty</h2>
<p> <p>
@@ -252,6 +273,17 @@ TUEN MUN
HONG KONG</p> HONG KONG</p>
<p>Email: <a href="mailto:admin@rosetta.im">admin@rosetta.im</a></p> <p>Email: <a href="mailto:admin@rosetta.im">admin@rosetta.im</a></p>
<p>Phone: <a href="tel:+85228910030">+852 2891 0030</a></p> <p>Phone: <a href="tel:+85228910030">+852 2891 0030</a></p>
</div>
</article>
<footer class="legal-footer">
<p>&copy; 2026 ROSETTA CLOUD SERVICES LIMITED</p>
<nav aria-label="Footer links">
<a href="/">Rosetta home</a>
<a href="/support/">Support</a>
<a href="/privacy/">Privacy Policy</a>
</nav>
</footer>
</main> </main>
</body> </body>
</html> </html>

View File

@@ -5,13 +5,12 @@ import {
Flex, Flex,
Text, Text,
Title, Title,
useComputedColorScheme,
useMantineTheme, useMantineTheme,
} from '@mantine/core'; } from '@mantine/core';
import classes from './DownloadCenter.module.css'; import classes from './DownloadCenter.module.css';
import { RosettaLogo } from '../RosettaLogo/RosettaLogo'; import { RosettaLogo } from '../RosettaLogo/RosettaLogo';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { FaApple, FaWindows } from 'react-icons/fa'; import { FaWindows } from 'react-icons/fa';
import { FcAndroidOs, FcLinux } from 'react-icons/fc'; import { FcAndroidOs, FcLinux } from 'react-icons/fc';
import { Switch } from '../Switch/Switch'; import { Switch } from '../Switch/Switch';
import { IconDownload } from '@tabler/icons-react'; import { IconDownload } from '@tabler/icons-react';
@@ -41,7 +40,7 @@ const fetchUpdates = async (): Promise<DownloadFeature[]> => {
version: item.version, version: item.version,
link: new URL(item.downloadUrl, 'https://sdu.rosetta.im').toString(), link: new URL(item.downloadUrl, 'https://sdu.rosetta.im').toString(),
})).sort((a, b) => { })).sort((a, b) => {
const platformOrder = ['darwin', 'linux', 'win32', 'android']; const platformOrder = ['linux', 'win32', 'android'];
const archOrder = ['arm64', 'x64', 'universal'] const archOrder = ['arm64', 'x64', 'universal']
const platformComparison = platformOrder.indexOf(a.platform) - platformOrder.indexOf(b.platform); const platformComparison = platformOrder.indexOf(a.platform) - platformOrder.indexOf(b.platform);
if (platformComparison !== 0) { if (platformComparison !== 0) {
@@ -57,9 +56,8 @@ const fetchUpdates = async (): Promise<DownloadFeature[]> => {
export function DownloadCenter() { export function DownloadCenter() {
const theme = useMantineTheme(); const theme = useMantineTheme();
const colorScheme = useComputedColorScheme();
const [kernels, setKernels] = useState<DownloadFeature[]>([]); const [kernels, setKernels] = useState<DownloadFeature[]>([]);
const [targetPlatforms, setTargetPlatforms] = useState<string[]>(['darwin', 'linux', 'win32', 'android']); const [targetPlatforms, setTargetPlatforms] = useState<string[]>(['linux', 'win32', 'android']);
useEffect(() => { useEffect(() => {
fetchUpdates().then(setKernels); fetchUpdates().then(setKernels);
@@ -69,14 +67,11 @@ export function DownloadCenter() {
let targetPlatforms: string[] = []; let targetPlatforms: string[] = [];
switch(value){ switch(value){
case 'All': case 'All':
targetPlatforms = ['darwin', 'linux', 'win32', 'android']; targetPlatforms = ['linux', 'win32', 'android'];
break; break;
case 'Windows': case 'Windows':
targetPlatforms = ['win32']; targetPlatforms = ['win32'];
break; break;
case 'macOS':
targetPlatforms = ['darwin'];
break;
case 'Android': case 'Android':
targetPlatforms = ['android']; targetPlatforms = ['android'];
break; break;
@@ -89,8 +84,6 @@ export function DownloadCenter() {
const translatePlatformToOsName = (platform: string) => { const translatePlatformToOsName = (platform: string) => {
switch(platform){ switch(platform){
case 'darwin':
return 'macOS';
case 'linux': case 'linux':
return 'Linux'; return 'Linux';
case 'win32': case 'win32':
@@ -104,8 +97,6 @@ export function DownloadCenter() {
const translatePlatformAndArchToCpuName = (platform : string, arch: string) => { const translatePlatformAndArchToCpuName = (platform : string, arch: string) => {
switch(platform){ switch(platform){
case 'darwin':
return arch === 'arm64' ? 'Apple Silicon' : 'Intel';
case 'linux': case 'linux':
return arch === 'arm64' ? 'ARM64' : 'x64'; return arch === 'arm64' ? 'ARM64' : 'x64';
case 'win32': case 'win32':
@@ -121,9 +112,6 @@ export function DownloadCenter() {
const features = kernels.filter((v) => targetPlatforms.includes(v.platform)).map((feature) => ( const features = kernels.filter((v) => targetPlatforms.includes(v.platform)).map((feature) => (
<Card key={feature.link} radius="md" className={classes.card} padding="xl"> <Card key={feature.link} radius="md" className={classes.card} padding="xl">
<Flex direction={'column'} align="center" justify={'center'}> <Flex direction={'column'} align="center" justify={'center'}>
{feature.platform === 'darwin' && <FaApple size={50} color={
colorScheme == 'dark' ? 'white' : 'black'
} />}
{feature.platform === 'linux' && <FcLinux size={50} />} {feature.platform === 'linux' && <FcLinux size={50} />}
{feature.platform === 'win32' && <FaWindows size={50} color={theme.colors.blue[6]} />} {feature.platform === 'win32' && <FaWindows size={50} color={theme.colors.blue[6]} />}
{feature.platform === 'android' && <FcAndroidOs size={50} />} {feature.platform === 'android' && <FcAndroidOs size={50} />}
@@ -131,14 +119,6 @@ export function DownloadCenter() {
{translatePlatformToOsName(feature.platform)} - {translatePlatformAndArchToCpuName(feature.platform, feature.arch)} {translatePlatformToOsName(feature.platform)} - {translatePlatformAndArchToCpuName(feature.platform, feature.arch)}
</Text> </Text>
<Text c="dimmed" fz="sm" ta={'center'} mt="xs"> <Text c="dimmed" fz="sm" ta={'center'} mt="xs">
{feature.platform == 'darwin' && <>
{feature.arch == 'arm64' && <>
Download this version if you have a Mac with Apple Silicon (M1, M2 chips).
</>}
{feature.arch == 'x64' && <>
Download this version if you have a Mac with an Intel processor, which was most likely manufactured before 2020.
</>}
</>}
{feature.platform == 'linux' && <>This version is for Linux and comes as an AppImage for the GUI versions.</>} {feature.platform == 'linux' && <>This version is for Linux and comes as an AppImage for the GUI versions.</>}
{feature.platform == 'win32' && <>Download this version of you have computer on Windows 10 or later.</>} {feature.platform == 'win32' && <>Download this version of you have computer on Windows 10 or later.</>}
{feature.platform == 'android' && <>This version is for Android devices and all architectures.</>} {feature.platform == 'android' && <>This version is for Android devices and all architectures.</>}
@@ -165,7 +145,7 @@ export function DownloadCenter() {
</Text> </Text>
<Flex justify={'center'} mt={'lg'}> <Flex justify={'center'} mt={'lg'}>
<Switch onChange={switchTarget} data={['All', 'Windows', 'macOS', 'Linux', 'Android']}></Switch> <Switch onChange={switchTarget} data={['All', 'Windows', 'Linux', 'Android']}></Switch>
</Flex> </Flex>
<Flex gap="xl" justify={'center'} wrap={'wrap'} align={'center'} mt={50}> <Flex gap="xl" justify={'center'} wrap={'wrap'} align={'center'} mt={50}>

View File

@@ -12,6 +12,9 @@ export function Footer() {
&copy; {currentYear} {LEGAL_NAME}. All rights reserved. &copy; {currentYear} {LEGAL_NAME}. All rights reserved.
</Text> </Text>
<nav className={classes.links} aria-label="Legal information"> <nav className={classes.links} aria-label="Legal information">
<Anchor href="/support/" size="sm" c="dimmed">
Support
</Anchor>
<Anchor href="/privacy/" size="sm" c="dimmed"> <Anchor href="/privacy/" size="sm" c="dimmed">
Privacy Policy Privacy Policy
</Anchor> </Anchor>

View File

@@ -9,7 +9,7 @@ interface SEOProps {
export function SEO({ export function SEO({
title = 'Rosetta - Secure Messaging for Everyone', title = 'Rosetta - Secure Messaging for Everyone',
description = 'End-to-end encrypted messaging app with military-grade security. Download for macOS, Windows, Linux.', description = 'End-to-end encrypted messaging app with military-grade security. Download for Windows, Linux, and Android.',
ogImage = '/og-image.png', ogImage = '/og-image.png',
keywords = 'secure messaging, encrypted chat, private messenger' keywords = 'secure messaging, encrypted chat, private messenger'
}: SEOProps) { }: SEOProps) {