mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-11 00:05:01 +00:00
site: trim legal to terms + privacy, unify layout, real entity, contact emails only
Removes pages we do not need: - dpa - acceptable-use - subprocessors - cookies Footer Legal column drops the four removed entries and keeps just Terms and Privacy. Shared Legal layout (src/layouts/Legal.astro) now drives both pages: - Hero uses HeroAtmosphere for consistency with the product pages. - Sticky sidebar lists the in-page sections passed as a sections prop. - Scroll-spy script highlights the active section as you scroll and slides an animated vertical pill indicator next to it, matching the learn handbook treatment. - Documents block under the section list cross-links Terms <-> Privacy. - Footer line points to hello@warmbly.com (the only inbound legal address advertised on /contact). Real legal entity sourced from ~/warmbly-web: - Mindroot Ltd, company number 16543299, registered in England and Wales - Registered office: 71-75 Shelton Street, London, England, WC2H 9JQ - Governing law: England and Wales; jurisdiction: courts of London Terms rewritten as 17 numbered sections using the shared layout, with a Who-we-are section that names Mindroot Ltd and the registered office, Stripe as the payment processor, an Acceptable use section that absorbs the relevant bits from the removed acceptable-use page, and a contact section that points to hello@warmbly.com. Privacy rewritten as 13 numbered sections, mirroring the real encryption model (AWS KMS root, per-user 32-byte DEK, AES-GCM at the app layer, DEK ciphertext in DynamoDB, plaintext DEK cached briefly in Redis, control-plane state in PostgreSQL, workers operating over Kafka/KMS/DynamoDB/S3/Redis only). UK ICO named as supervisory authority; UK IDTA and EU SCCs referenced for international transfers. Email cleanup across the site so only addresses that appear on the contact page are used (hello@ and sales@): - trust: security@warmbly.com -> hello@warmbly.com in the hero CTA, the responsible-disclosure body and email chip, and the final CTA; CTA secondary link swapped from /subprocessors/ to /privacy/. - trust: subprocessors-summary block keeps the table of infrastructure providers (real, sourced from CLAUDE.md) but drops the link out to the deleted /subprocessors/ page and the DPA-on-request note. - brand: press@warmbly.com -> hello@warmbly.com in the press contact. - faq: DPA answer email updated from security@ to hello@. Build: 36 pages (was 40); no remaining links to the removed pages.
This commit is contained in:
@@ -54,10 +54,6 @@ const groups: { title: string; links: { label: string; href: string }[] }[] = [
|
||||
links: [
|
||||
{ label: 'Terms', href: '/terms/' },
|
||||
{ label: 'Privacy', href: '/privacy/' },
|
||||
{ label: 'DPA', href: '/dpa/' },
|
||||
{ label: 'Acceptable use', href: '/acceptable-use/' },
|
||||
{ label: 'Subprocessors', href: '/subprocessors/' },
|
||||
{ label: 'Cookies', href: '/cookies/' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
+164
-31
@@ -1,66 +1,199 @@
|
||||
---
|
||||
import Layout from './Layout.astro';
|
||||
import Cloud from '../components/Cloud.astro';
|
||||
import HeroAtmosphere from '../components/HeroAtmosphere.astro';
|
||||
|
||||
interface Section {
|
||||
id: string;
|
||||
num: string;
|
||||
title: string;
|
||||
}
|
||||
interface Props {
|
||||
title: string;
|
||||
description?: string;
|
||||
effective?: string;
|
||||
updated?: string;
|
||||
sections: Section[];
|
||||
}
|
||||
const { title, description, effective = '2026-05-01' } = Astro.props;
|
||||
const {
|
||||
title,
|
||||
description,
|
||||
effective = '2026-05-27',
|
||||
updated = '2026-05-27',
|
||||
sections,
|
||||
} = Astro.props;
|
||||
|
||||
const docs = [
|
||||
{ label: 'Terms of Service', href: '/terms/' },
|
||||
{ label: 'Privacy Policy', href: '/privacy/' },
|
||||
{ label: 'Data Processing Addendum', href: '/dpa/' },
|
||||
{ label: 'Acceptable Use', href: '/acceptable-use/' },
|
||||
{ label: 'Subprocessors', href: '/subprocessors/' },
|
||||
{ label: 'Cookies', href: '/cookies/' },
|
||||
{ label: 'Terms of Service', href: '/terms/' },
|
||||
{ label: 'Privacy Policy', href: '/privacy/' },
|
||||
];
|
||||
|
||||
const path = Astro.url.pathname;
|
||||
---
|
||||
<Layout title={title} description={description ?? title}>
|
||||
<section class="relative isolate overflow-hidden text-white" style="background: radial-gradient(ellipse 130% 140% at 72% 28%, #0284c7 0%, #0369a1 25%, #075985 50%, #0c4a6e 80%, #0a3d5c 100%);">
|
||||
<div class="absolute top-0 right-0 w-[360px] opacity-25 pointer-events-none cloud-drift cloud-2" style="mix-blend-mode: screen;">
|
||||
<Cloud variant={3} opacity={1} />
|
||||
</div>
|
||||
<div class="container-page relative pt-14 pb-12">
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-white/55 font-mono mb-3">Legal</div>
|
||||
<h1 class="text-[32px] md:text-[44px] font-semibold tracking-[-0.025em] leading-[1.06] text-white max-w-3xl">{title}</h1>
|
||||
<div class="mt-3 text-[11.5px] font-mono text-white/55">Effective {effective}</div>
|
||||
|
||||
<!-- HERO -->
|
||||
<section class="relative isolate overflow-hidden" id="legal-hero">
|
||||
<HeroAtmosphere />
|
||||
<div class="container-page relative pt-14 md:pt-20 pb-14 md:pb-20">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.22em] font-mono text-white/75 mb-3">Legal</div>
|
||||
<h1 class="text-[36px] md:text-[48px] font-semibold tracking-[-0.025em] leading-[1.06] text-white max-w-3xl">
|
||||
{title}
|
||||
</h1>
|
||||
<div class="mt-4 flex flex-wrap items-center gap-x-5 gap-y-1.5 text-[11.5px] font-mono text-white/75">
|
||||
<span>Effective {effective}</span>
|
||||
<span class="w-1 h-1 rounded-full bg-white/40"></span>
|
||||
<span>Last updated {updated}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="container-page py-12 md:py-16 grid grid-cols-1 lg:grid-cols-[220px_minmax(0,1fr)] gap-10 lg:gap-16">
|
||||
<aside class="lg:sticky lg:top-20 self-start">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-3">Documents</div>
|
||||
<ul class="space-y-0.5">
|
||||
{docs.map((d) => (
|
||||
<!-- BODY -->
|
||||
<div class="container-page py-12 md:py-16 grid grid-cols-1 lg:grid-cols-[240px_minmax(0,1fr)] gap-10 lg:gap-16">
|
||||
|
||||
<!-- STICKY SIDEBAR -->
|
||||
<aside class="lg:sticky lg:top-24 self-start hidden lg:block">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.22em] font-mono text-muted-foreground mb-4">On this page</div>
|
||||
<ol class="space-y-px text-[13px] relative" data-legal-rail>
|
||||
<span
|
||||
data-legal-indicator
|
||||
aria-hidden="true"
|
||||
class="absolute left-0 w-[2px] rounded-full bg-[#0284c7] pointer-events-none opacity-0 transition-all duration-300 ease-out"
|
||||
style="top:0;height:0;"
|
||||
></span>
|
||||
{sections.map((s) => (
|
||||
<li>
|
||||
<a
|
||||
href={d.href}
|
||||
class={
|
||||
'block text-[13.5px] -mx-2 px-2 py-1.5 rounded-md transition-colors ' +
|
||||
(path === d.href
|
||||
? 'bg-[color:var(--surface-2)] text-foreground font-medium'
|
||||
: 'text-muted-foreground hover:text-foreground hover:bg-[color:var(--surface-2)]/60')
|
||||
}
|
||||
href={`#${s.id}`}
|
||||
data-target-id={s.id}
|
||||
class="legal-link group flex items-baseline gap-3 py-1.5 pl-3 pr-2 -ml-px rounded-md text-foreground/60 hover:text-[#0369a1] transition-colors duration-300 ease-out"
|
||||
>
|
||||
{d.label}
|
||||
<span class="legal-num font-mono text-[10.5px] text-muted-foreground/55 w-5 shrink-0 transition-colors duration-300">{s.num}</span>
|
||||
<span class="leading-snug">{s.title}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</ol>
|
||||
|
||||
<div class="mt-8 pt-6 border-t border-[color:var(--border)]">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.22em] font-mono text-muted-foreground mb-3">Documents</div>
|
||||
<ul class="space-y-0.5">
|
||||
{docs.map((d) => {
|
||||
const isCurrent = path === d.href;
|
||||
return (
|
||||
<li>
|
||||
<a
|
||||
href={d.href}
|
||||
aria-current={isCurrent ? 'page' : undefined}
|
||||
class={
|
||||
'block text-[13px] -mx-2 px-2 py-1.5 rounded-md transition-colors duration-200 ' +
|
||||
(isCurrent
|
||||
? 'text-[#0369a1] font-semibold'
|
||||
: 'text-muted-foreground hover:text-[#0369a1]')
|
||||
}
|
||||
>
|
||||
{d.label}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- MAIN -->
|
||||
<article class="max-w-3xl">
|
||||
<div class="space-y-6 [&_h2]:text-[22px] [&_h2]:md:text-[26px] [&_h2]:font-semibold [&_h2]:tracking-[-0.02em] [&_h2]:mt-12 [&_h2]:mb-3 [&_h2]:text-heading [&_h3]:text-[16px] [&_h3]:font-semibold [&_h3]:mt-8 [&_h3]:mb-2 [&_h3]:text-heading [&_p]:text-[15px] [&_p]:leading-relaxed [&_p]:text-foreground/85 [&_ul]:list-disc [&_ul]:pl-5 [&_ul]:space-y-1.5 [&_ul]:text-[14.5px] [&_ul]:text-foreground/85 [&_ol]:list-decimal [&_ol]:pl-5 [&_ol]:space-y-1.5 [&_ol]:text-[14.5px] [&_ol]:text-foreground/85 [&_a]:text-[color:var(--brand)] [&_a:hover]:text-[color:var(--brand-strong)] [&_code]:font-mono [&_code]:text-[0.92em] [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:bg-[color:var(--surface-2)] [&_code]:ring-1 [&_code]:ring-[color:var(--border)]">
|
||||
<slot />
|
||||
</div>
|
||||
<div class="mt-16 text-[12.5px] text-muted-foreground border-t border-[color:var(--border)] pt-6">
|
||||
Questions about this document? Email <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]" href="mailto:legal@warmbly.com">legal@warmbly.com</a>.
|
||||
Questions about this document? Email <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]" href="mailto:hello@warmbly.com">hello@warmbly.com</a>.
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<!-- Scrollspy + animated active indicator -->
|
||||
<script is:inline>
|
||||
(function () {
|
||||
var links = Array.prototype.slice.call(document.querySelectorAll('.legal-link'));
|
||||
if (!links.length) return;
|
||||
var sections = links
|
||||
.map(function (a) {
|
||||
return { link: a, el: document.getElementById(a.getAttribute('data-target-id')) };
|
||||
})
|
||||
.filter(function (s) { return s.el; });
|
||||
if (!sections.length) return;
|
||||
|
||||
var indicator = document.querySelector('[data-legal-indicator]');
|
||||
|
||||
var inactiveText = ['text-foreground/60', 'hover:text-[#0369a1]'];
|
||||
var activeText = ['text-[#0369a1]', 'font-semibold'];
|
||||
var inactiveNum = ['text-muted-foreground/55'];
|
||||
var activeNum = ['text-[#0284c7]'];
|
||||
|
||||
var currentId = null;
|
||||
function setActive(id) {
|
||||
if (id === currentId) return;
|
||||
currentId = id;
|
||||
var activeLink = null;
|
||||
sections.forEach(function (s) {
|
||||
var num = s.link.querySelector('.legal-num');
|
||||
if (s.el.id === id) {
|
||||
activeLink = s.link;
|
||||
s.link.classList.remove.apply(s.link.classList, inactiveText);
|
||||
s.link.classList.add.apply(s.link.classList, activeText);
|
||||
if (num) {
|
||||
num.classList.remove.apply(num.classList, inactiveNum);
|
||||
num.classList.add.apply(num.classList, activeNum);
|
||||
}
|
||||
} else {
|
||||
s.link.classList.remove.apply(s.link.classList, activeText);
|
||||
s.link.classList.add.apply(s.link.classList, inactiveText);
|
||||
if (num) {
|
||||
num.classList.remove.apply(num.classList, activeNum);
|
||||
num.classList.add.apply(num.classList, inactiveNum);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (indicator && activeLink) {
|
||||
var railParent = indicator.parentElement;
|
||||
var railRect = railParent.getBoundingClientRect();
|
||||
var linkRect = activeLink.getBoundingClientRect();
|
||||
indicator.style.opacity = '1';
|
||||
indicator.style.top = (linkRect.top - railRect.top) + 'px';
|
||||
indicator.style.height = linkRect.height + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
function onScroll() {
|
||||
var probe = window.innerHeight * 0.30;
|
||||
var active = sections[0].el.id;
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
var rect = sections[i].el.getBoundingClientRect();
|
||||
if (rect.top - probe <= 0) active = sections[i].el.id; else break;
|
||||
}
|
||||
setActive(active);
|
||||
}
|
||||
|
||||
onScroll();
|
||||
var raf = 0;
|
||||
window.addEventListener('scroll', function () {
|
||||
if (raf) return;
|
||||
raf = requestAnimationFrame(function () { raf = 0; onScroll(); });
|
||||
}, { passive: true });
|
||||
window.addEventListener('resize', function () {
|
||||
var id = currentId;
|
||||
currentId = null;
|
||||
if (id) setActive(id);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style is:global>
|
||||
@media print {
|
||||
header, footer, aside { display: none !important; }
|
||||
#legal-hero { height: auto !important; padding: 1.5rem 0 !important; background: none !important; color: #111 !important; }
|
||||
#legal-hero * { color: #111 !important; }
|
||||
article { max-width: 100% !important; }
|
||||
}
|
||||
</style>
|
||||
</Layout>
|
||||
|
||||
@@ -1,551 +0,0 @@
|
||||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import HeroAtmosphere from '../components/HeroAtmosphere.astro';
|
||||
import Icon from '../components/Icon.astro';
|
||||
import CTA from '../components/CTA.astro';
|
||||
|
||||
const lastUpdated = '2026-05-27';
|
||||
|
||||
// Sibling legal documents for cross-linking.
|
||||
const docs = [
|
||||
{ label: 'Terms of Service', href: '/terms/' },
|
||||
{ label: 'Privacy Policy', href: '/privacy/' },
|
||||
{ label: 'Data Processing Addendum', href: '/dpa/' },
|
||||
{ label: 'Acceptable Use', href: '/acceptable-use/' },
|
||||
{ label: 'Subprocessors', href: '/subprocessors/' },
|
||||
{ label: 'Cookies', href: '/cookies/' },
|
||||
];
|
||||
const path = Astro.url.pathname;
|
||||
|
||||
// Top-of-page rule strip. "Warmbly is for ..." lines.
|
||||
const ruleStrip = [
|
||||
'Legitimate B2B cold outreach.',
|
||||
'Warmup that protects shared reputation.',
|
||||
'Reply handling on mailboxes you own.',
|
||||
'Transactional follow-up to people you actually do business with.',
|
||||
];
|
||||
|
||||
// Sidebar table of contents.
|
||||
const toc = [
|
||||
{ id: 'scope', label: '1. Scope' },
|
||||
{ id: 'for', label: '2. What Warmbly is for' },
|
||||
{ id: 'allowed', label: '3. Allowed vs not allowed' },
|
||||
{ id: 'content', label: '4. Prohibited content' },
|
||||
{ id: 'targeting', label: '5. Prohibited senders and targeting' },
|
||||
{ id: 'law', label: '6. Compliance with email law' },
|
||||
{ id: 'auth', label: '7. Authentication and identification' },
|
||||
{ id: 'suppression', label: '8. Suppression and unsubscribe' },
|
||||
{ id: 'volume', label: '9. Volume and rate' },
|
||||
{ id: 'pool', label: '10. Warmup pool integrity' },
|
||||
{ id: 'security', label: '11. Security and integrity' },
|
||||
{ id: 'enforcement', label: '12. Enforcement' },
|
||||
{ id: 'reporting', label: '13. Reporting abuse' },
|
||||
{ id: 'changes', label: '14. Changes to this policy' },
|
||||
];
|
||||
|
||||
// Allowed / Not allowed two-column.
|
||||
const allowed = [
|
||||
'Cold outreach to business addresses with a documented, plausible reason for contact.',
|
||||
'Personalized one-to-one prospecting in low daily volumes per mailbox.',
|
||||
'Warmup traffic through pools you are entitled to use.',
|
||||
'Reply handling and follow-up on conversations you actually started.',
|
||||
'Transactional and operational mail to people you have a relationship with.',
|
||||
'Honoring opt-outs immediately and keeping a clean suppression list.',
|
||||
'Running multiple healthy mailboxes you own, each within its own budget.',
|
||||
];
|
||||
const notAllowed = [
|
||||
'Mass-marketing to consumer addresses sourced without consent.',
|
||||
'Sending to scraped or purchased lists you cannot justify recipient by recipient.',
|
||||
'Dating, romance scams, sextortion, MLM, crypto pump-and-dump, or other high-abuse verticals.',
|
||||
'Forging sender identity or pretending to be a person, company, or Warmbly.',
|
||||
'Circumventing per-mailbox budgets, warmup posture, or platform rate limits.',
|
||||
'Coordinating distributed bulk-sending across accounts or mailboxes you do not own.',
|
||||
'Probing, scraping, or stress-testing the platform without written consent.',
|
||||
];
|
||||
|
||||
// Enforcement ladder. Mirrors the mailbox health states in CLAUDE.md.
|
||||
const enforcement = [
|
||||
{
|
||||
state: 'healthy',
|
||||
chip: 'bg-emerald-50 text-emerald-700 ring-emerald-100',
|
||||
dot: 'bg-emerald-500',
|
||||
title: 'Healthy',
|
||||
body: 'Default state. Mailbox is participating in normal sending and warmup. No action required.',
|
||||
},
|
||||
{
|
||||
state: 'watch',
|
||||
chip: 'bg-sky-50 text-sky-700 ring-sky-100',
|
||||
dot: 'bg-sky-500',
|
||||
title: 'Watch',
|
||||
body: 'Early negative signals such as rising spam placement or borderline complaint rate. Volume guidance tightens and monitoring increases.',
|
||||
},
|
||||
{
|
||||
state: 'throttled',
|
||||
chip: 'bg-amber-50 text-amber-700 ring-amber-100',
|
||||
dot: 'bg-amber-500',
|
||||
title: 'Throttled',
|
||||
body: 'Per-mailbox send rate is reduced and pacing is forced. We notify the workspace owner with the reason and the criteria for recovery.',
|
||||
},
|
||||
{
|
||||
state: 'quarantined',
|
||||
chip: 'bg-orange-50 text-orange-700 ring-orange-100',
|
||||
dot: 'bg-orange-500',
|
||||
title: 'Quarantined',
|
||||
body: 'Mailbox is removed from shared warmup pools and held in a recovery state. Active sequences for that mailbox may be paused.',
|
||||
},
|
||||
{
|
||||
state: 'blocked',
|
||||
chip: 'bg-rose-50 text-rose-700 ring-rose-100',
|
||||
dot: 'bg-rose-500',
|
||||
title: 'Blocked',
|
||||
body: 'Mailbox or workspace is suspended from sending. Re-entry requires review. For workspace-level abuse, the account can be terminated.',
|
||||
},
|
||||
];
|
||||
---
|
||||
<Layout
|
||||
title="Acceptable Use Policy · Warmbly"
|
||||
description="The conduct Warmbly expects from customers. Strong, opinionated rules for legitimate B2B cold outreach, and a hard line against abuse."
|
||||
>
|
||||
<!-- ============================================================
|
||||
HERO · HeroAtmosphere, shorter than product pages
|
||||
============================================================ -->
|
||||
<section class="relative isolate overflow-hidden">
|
||||
<HeroAtmosphere />
|
||||
|
||||
<div class="container-page relative pt-16 md:pt-20 pb-16 md:pb-20">
|
||||
<div class="inline-flex items-center gap-2 h-7 pl-1 pr-3 rounded-full bg-white/15 backdrop-blur ring-1 ring-white/25 text-[12px] text-white/95 shadow-[0_4px_14px_-4px_rgba(0,0,0,0.25)]">
|
||||
<span class="inline-flex items-center h-5 px-1.5 rounded-full text-[10.5px] font-semibold uppercase tracking-[0.06em] bg-white" style="color:#0369a1;">
|
||||
Legal
|
||||
</span>
|
||||
Acceptable Use Policy
|
||||
</div>
|
||||
|
||||
<h1 class="mt-7 md:mt-9 text-[40px] sm:text-5xl md:text-[64px] lg:text-[72px] font-semibold tracking-[-0.035em] leading-[1.0] text-white max-w-4xl">
|
||||
Acceptable use.
|
||||
</h1>
|
||||
<p class="mt-5 text-[16.5px] md:text-[18px] text-white/80 max-w-2xl leading-relaxed">
|
||||
Warmbly is built for legitimate B2B cold outreach and the warmup that protects it. It is not built for spam, scams, scraped consumer lists, or anything that puts shared sender reputation at risk. These rules apply to every customer, every workspace, every mailbox.
|
||||
</p>
|
||||
|
||||
<div class="mt-7 flex flex-wrap items-center gap-3 text-[12px] font-mono">
|
||||
<span class="inline-flex items-center gap-2 h-7 px-3 rounded-full bg-white/10 ring-1 ring-white/25 text-white/90">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-300"></span>
|
||||
Last updated {lastUpdated}
|
||||
</span>
|
||||
<a href="#enforcement" class="inline-flex items-center gap-1.5 h-7 px-3 rounded-full bg-white/10 ring-1 ring-white/25 text-white/90 hover:bg-white/20 transition-colors">
|
||||
Enforcement ladder
|
||||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
||||
</a>
|
||||
<a href="mailto:abuse@warmbly.com" class="inline-flex items-center gap-1.5 h-7 px-3 rounded-full bg-white/10 ring-1 ring-white/25 text-white/90 hover:bg-white/20 transition-colors">
|
||||
abuse@warmbly.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================
|
||||
RULE STRIP · "Warmbly is for ..."
|
||||
============================================================ -->
|
||||
<section class="border-y border-[color:var(--border)] bg-white">
|
||||
<div class="container-page py-6 md:py-7">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-x-8 gap-y-3 items-center">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground lg:col-span-4 lg:mb-1">
|
||||
Warmbly is for
|
||||
</div>
|
||||
{ruleStrip.map((line) => (
|
||||
<div class="flex items-start gap-2.5">
|
||||
<span class="mt-2 inline-flex w-1.5 h-1.5 rounded-full bg-[color:var(--brand)] shrink-0"></span>
|
||||
<span class="text-[13.5px] text-foreground/85 leading-snug">{line}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================
|
||||
BODY · sticky sidebar TOC + main content column
|
||||
============================================================ -->
|
||||
<section class="bg-[color:var(--surface-1)]/30 py-14 md:py-20">
|
||||
<div class="container-page grid grid-cols-1 lg:grid-cols-[240px_minmax(0,1fr)] gap-10 lg:gap-16">
|
||||
|
||||
<!-- ===== Sidebar ===== -->
|
||||
<aside class="lg:sticky lg:top-20 self-start space-y-8">
|
||||
<div>
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-3">On this page</div>
|
||||
<ul class="space-y-0.5">
|
||||
{toc.map((t) => (
|
||||
<li>
|
||||
<a
|
||||
href={`#${t.id}`}
|
||||
class="block text-[13px] -mx-2 px-2 py-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-[color:var(--surface-2)]/70 transition-colors"
|
||||
>
|
||||
{t.label}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="pt-6 border-t border-[color:var(--border)]">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-3">Other documents</div>
|
||||
<ul class="space-y-0.5">
|
||||
{docs.map((d) => (
|
||||
<li>
|
||||
<a
|
||||
href={d.href}
|
||||
class={
|
||||
'block text-[13px] -mx-2 px-2 py-1.5 rounded-md transition-colors ' +
|
||||
(path === d.href
|
||||
? 'bg-[color:var(--surface-2)] text-foreground font-medium'
|
||||
: 'text-muted-foreground hover:text-foreground hover:bg-[color:var(--surface-2)]/60')
|
||||
}
|
||||
>
|
||||
{d.label}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="pt-6 border-t border-[color:var(--border)]">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-2">Report abuse</div>
|
||||
<a href="mailto:abuse@warmbly.com" class="text-[13px] text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] font-medium">
|
||||
abuse@warmbly.com
|
||||
</a>
|
||||
<p class="mt-2 text-[12px] text-muted-foreground leading-relaxed">
|
||||
Include headers if you can. Reviewed within one business day.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- ===== Main column ===== -->
|
||||
<article class="max-w-3xl space-y-14">
|
||||
|
||||
<!-- ===== 1. Scope ===== -->
|
||||
<section id="scope" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 1</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Scope</h2>
|
||||
<div class="mt-4 space-y-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
<p>
|
||||
This Acceptable Use Policy applies to everyone who uses Warmbly. That includes account owners, team members, integrators, and anyone sending mail through a mailbox connected to a Warmbly workspace. It applies to the API, the dashboard, and any future surface we ship.
|
||||
</p>
|
||||
<p>
|
||||
The rules in this document sit on top of the <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]" href="/terms/">Terms of Service</a>. If something here looks looser than the Terms, the Terms win. If something here looks stricter, the stricter rule applies.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===== 2. What Warmbly is for ===== -->
|
||||
<section id="for" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 2</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">What Warmbly is for</h2>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly is a control plane for serious B2B email programs. The intended use cases are narrow and named.
|
||||
</p>
|
||||
<div class="mt-5 grid sm:grid-cols-2 gap-3">
|
||||
<div class="rounded-[12px] bg-white ring-1 ring-[color:var(--border)] p-5">
|
||||
<div class="inline-flex items-center justify-center w-9 h-9 rounded-[9px] bg-sky-50 text-[color:var(--brand-strong)] ring-1 ring-sky-100">
|
||||
<Icon name="send" size={16} />
|
||||
</div>
|
||||
<div class="mt-3 text-[14.5px] font-semibold text-heading">Legitimate B2B cold outreach</div>
|
||||
<p class="mt-1 text-[13px] text-foreground/70 leading-relaxed">Personalized prospecting to business addresses with a real reason for contact.</p>
|
||||
</div>
|
||||
<div class="rounded-[12px] bg-white ring-1 ring-[color:var(--border)] p-5">
|
||||
<div class="inline-flex items-center justify-center w-9 h-9 rounded-[9px] bg-emerald-50 text-emerald-700 ring-1 ring-emerald-100">
|
||||
<Icon name="flame" size={16} />
|
||||
</div>
|
||||
<div class="mt-3 text-[14.5px] font-semibold text-heading">Warmup</div>
|
||||
<p class="mt-1 text-[13px] text-foreground/70 leading-relaxed">Gradual, paced warmup traffic on pools you are entitled to use.</p>
|
||||
</div>
|
||||
<div class="rounded-[12px] bg-white ring-1 ring-[color:var(--border)] p-5">
|
||||
<div class="inline-flex items-center justify-center w-9 h-9 rounded-[9px] bg-amber-50 text-amber-700 ring-1 ring-amber-100">
|
||||
<Icon name="reply" size={16} />
|
||||
</div>
|
||||
<div class="mt-3 text-[14.5px] font-semibold text-heading">Reply handling</div>
|
||||
<p class="mt-1 text-[13px] text-foreground/70 leading-relaxed">Threaded follow-up on conversations you actually started.</p>
|
||||
</div>
|
||||
<div class="rounded-[12px] bg-white ring-1 ring-[color:var(--border)] p-5">
|
||||
<div class="inline-flex items-center justify-center w-9 h-9 rounded-[9px] bg-foreground/5 text-foreground ring-1 ring-foreground/10">
|
||||
<Icon name="inbox" size={16} />
|
||||
</div>
|
||||
<div class="mt-3 text-[14.5px] font-semibold text-heading">Transactional follow-up</div>
|
||||
<p class="mt-1 text-[13px] text-foreground/70 leading-relaxed">Operational mail to people you actually do business with.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-5 text-[14px] leading-relaxed text-foreground/70">
|
||||
Anything outside that envelope is out of scope. Warmbly is not a newsletter platform, not a consumer marketing tool, and not a way to evade sending limits on platforms that already told you no.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ===== 3. Allowed vs Not allowed (two-column visual) ===== -->
|
||||
<section id="allowed" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 3</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Allowed vs not allowed</h2>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
A plain-English summary. The detailed rules in later sections govern in case of conflict.
|
||||
</p>
|
||||
|
||||
<div class="mt-6 grid md:grid-cols-2 gap-4">
|
||||
<!-- Allowed -->
|
||||
<div class="rounded-[14px] bg-white ring-1 ring-emerald-200/70 overflow-hidden">
|
||||
<div class="flex items-center gap-2.5 px-5 py-3 bg-emerald-50/70 border-b border-emerald-100">
|
||||
<span class="inline-flex items-center justify-center w-6 h-6 rounded-full bg-emerald-500 text-white">
|
||||
<Icon name="check" size={14} strokeWidth={2.5} />
|
||||
</span>
|
||||
<span class="text-[13px] font-semibold font-mono uppercase tracking-[0.12em] text-emerald-700">Allowed</span>
|
||||
</div>
|
||||
<ul class="px-5 py-4 space-y-3">
|
||||
{allowed.map((line) => (
|
||||
<li class="flex items-start gap-2.5">
|
||||
<span class="mt-2 w-1.5 h-1.5 rounded-full bg-emerald-500 shrink-0"></span>
|
||||
<span class="text-[13.5px] text-foreground/85 leading-relaxed">{line}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Not allowed -->
|
||||
<div class="rounded-[14px] bg-white ring-1 ring-rose-200/70 overflow-hidden">
|
||||
<div class="flex items-center gap-2.5 px-5 py-3 bg-rose-50/70 border-b border-rose-100">
|
||||
<span class="inline-flex items-center justify-center w-6 h-6 rounded-full bg-rose-500 text-white">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
|
||||
</span>
|
||||
<span class="text-[13px] font-semibold font-mono uppercase tracking-[0.12em] text-rose-700">Not allowed</span>
|
||||
</div>
|
||||
<ul class="px-5 py-4 space-y-3">
|
||||
{notAllowed.map((line) => (
|
||||
<li class="flex items-start gap-2.5">
|
||||
<span class="mt-2 w-1.5 h-1.5 rounded-full bg-rose-500 shrink-0"></span>
|
||||
<span class="text-[13.5px] text-foreground/85 leading-relaxed">{line}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===== 4. Prohibited content ===== -->
|
||||
<section id="content" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 4</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Prohibited content</h2>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
You may not use Warmbly to create, send, link to, or distribute any of the following. Lists like this are never exhaustive. Use judgment. If a category fits the spirit of what is listed here, treat it as prohibited.
|
||||
</p>
|
||||
<ul class="mt-5 space-y-2.5 text-[14.5px] text-foreground/85 list-disc pl-5 marker:text-rose-400">
|
||||
<li>Content that is illegal in the sender's jurisdiction or in the recipient's.</li>
|
||||
<li>Sexual content involving minors, in any form, no exceptions.</li>
|
||||
<li>Malware, exploit code, ransomware, credential harvesters, or links to any of the above.</li>
|
||||
<li>Phishing kits or content designed to deceive a recipient into giving up credentials, payment information, or access.</li>
|
||||
<li>Targeted harassment, threats, stalking, or doxxing of individuals.</li>
|
||||
<li>Content that incites violence or hatred against people based on race, ethnicity, religion, gender, sexual orientation, disability, or other protected characteristics.</li>
|
||||
<li>Content designed to defraud the recipient, including fake invoices, fake job offers, and impersonation of trusted brands.</li>
|
||||
<li>Content that violates intellectual property rights you do not hold.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- ===== 5. Prohibited senders and targeting ===== -->
|
||||
<section id="targeting" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 5</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Prohibited senders and targeting</h2>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Some sending behavior is harmful regardless of the message body. The following patterns are prohibited because they reliably generate complaints, damage shared reputation, or are used as cover for fraud.
|
||||
</p>
|
||||
<ul class="mt-5 space-y-2.5 text-[14.5px] text-foreground/85 list-disc pl-5 marker:text-rose-400">
|
||||
<li>Sending to scraped consumer lists, purchased lists, or any list where you cannot point to a per-recipient basis for contacting that specific person.</li>
|
||||
<li>Mass marketing to non-business addresses such as personal Gmail, Yahoo, Outlook, or ISP mailboxes.</li>
|
||||
<li>Dating, hookup, romance, or sextortion mail. This includes mail that pretends to be from a real or fake person seeking a relationship.</li>
|
||||
<li>MLM recruitment, crypto pump-and-dump, get-rich-quick offers, fake investment opportunities, and similar high-abuse verticals.</li>
|
||||
<li>Sending on behalf of clients in any of the above categories, even if your own brand looks legitimate.</li>
|
||||
<li>Reactivating recipients who have already opted out, asked to be removed, or marked your prior mail as spam.</li>
|
||||
<li>Splitting one campaign across many workspaces or many mailboxes to dodge per-mailbox limits.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- ===== 6. Compliance with email law ===== -->
|
||||
<section id="law" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 6</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Compliance with email law</h2>
|
||||
<div class="mt-4 space-y-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
<p>
|
||||
You are responsible for sending in compliance with the laws that apply to you and to your recipients. Warmbly does not relieve you of that responsibility, and we will not run mail that obviously breaks the law.
|
||||
</p>
|
||||
<p>
|
||||
Depending on jurisdiction and audience, that may include CAN-SPAM in the United States, GDPR in the European Union, CASL in Canada, and the ePrivacy regime in the European Union. The specific obligations vary by law, by recipient location, and by message type. If you are unsure, talk to a lawyer who understands the regime that applies to your sending.
|
||||
</p>
|
||||
<p>
|
||||
At minimum, every commercial message you send through Warmbly must accurately identify the sender, must not use deceptive subject lines or headers, and must give the recipient a clear way to stop receiving mail from you.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===== 7. Authentication and identification ===== -->
|
||||
<section id="auth" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 7</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Authentication and identification</h2>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
You must send as yourself, from infrastructure you are entitled to use, with the authentication that mailbox providers expect.
|
||||
</p>
|
||||
<ul class="mt-5 space-y-2.5 text-[14.5px] text-foreground/85 list-disc pl-5 marker:text-[color:var(--brand)]">
|
||||
<li>Real sender identity. The name, company, and address in your messages must match the person or business actually sending them.</li>
|
||||
<li>SPF, DKIM, and DMARC must be configured for every domain you send from. We will warn you if they are not, and we may refuse to send if they remain broken.</li>
|
||||
<li>No impersonation of other people, brands, or organizations. No pretending mail is from someone it is not from.</li>
|
||||
<li>No impersonation of Warmbly. Do not present yourself as a Warmbly employee, do not use the Warmbly name to vouch for your sending, and do not spoof internal Warmbly addresses.</li>
|
||||
<li>Use mailboxes you legitimately control. Connecting a mailbox you do not own, or whose owner has not authorized your use, is a hard violation.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- ===== 8. Suppression and unsubscribe ===== -->
|
||||
<section id="suppression" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 8</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Suppression and unsubscribe</h2>
|
||||
<div class="mt-4 space-y-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
<p>
|
||||
Opt-outs are not negotiable. If a recipient asks you to stop, you stop. The platform enforces suppression automatically, but the policy is independent of the enforcement.
|
||||
</p>
|
||||
<p>
|
||||
For marketing and bulk mail where the applicable law requires it, you must provide a working one-click unsubscribe, and you must honor it. For one-to-one cold outreach, a clear opt-out instruction in the body of the message is the minimum.
|
||||
</p>
|
||||
<p>
|
||||
You may not remove a contact from your suppression list to retry them later. You may not move a suppressed contact between workspaces to evade suppression. You may not buy enrichment data that re-introduces the same person under a different address and treat that as a fresh contact.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===== 9. Volume and rate ===== -->
|
||||
<section id="volume" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 9</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Volume and rate</h2>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly enforces per-mailbox volume budgets, minimum spacing between sends, and a gradual warmup ramp. Those defaults exist to protect deliverability for you and for everyone else on shared infrastructure.
|
||||
</p>
|
||||
<ul class="mt-5 space-y-2.5 text-[14.5px] text-foreground/85 list-disc pl-5 marker:text-[color:var(--brand)]">
|
||||
<li>You must respect the warmup posture of each mailbox. A fresh mailbox is not allowed to jump straight to high cold-outreach volume, no matter how confident you are in your list.</li>
|
||||
<li>You may not bypass or trick per-mailbox daily caps and per-send spacing rules.</li>
|
||||
<li>You may not coordinate distributed bulk-sending across mailboxes or accounts you do not own. Renting other people's mailboxes to spread volume is not allowed.</li>
|
||||
<li>You may not split a single underlying campaign across many separate workspaces to dodge our caps or our enforcement.</li>
|
||||
<li>Spinning up new mailboxes after quarantine to keep the same campaign running is treated as evasion.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- ===== 10. Warmup pool integrity ===== -->
|
||||
<section id="pool" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 10</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Warmup pool integrity</h2>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Shared warmup pools depend on every participant behaving like a real mailbox. Abuse here hurts every paying customer in the same pool, so the rules are strict.
|
||||
</p>
|
||||
<ul class="mt-5 space-y-2.5 text-[14.5px] text-foreground/85 list-disc pl-5 marker:text-[color:var(--brand)]">
|
||||
<li>No forging or tampering with warmup verification tokens.</li>
|
||||
<li>No synthetic engagement patterns designed to inflate scores or fake reputation.</li>
|
||||
<li>No using the shared paid pool from mailboxes that have been quarantined or are otherwise unhealthy.</li>
|
||||
<li>No mixing low-trust mailboxes into the paid pool to inflate volume.</li>
|
||||
<li>No scripted automation that imitates pool participation from outside the platform.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- ===== 11. Security and integrity ===== -->
|
||||
<section id="security" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 11</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Security and integrity</h2>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
You must not attack the platform, the people who work on it, or the customers who use it. Coordinated testing of our security is welcome through the contact in our trust center. Anything else is out of bounds.
|
||||
</p>
|
||||
<ul class="mt-5 space-y-2.5 text-[14.5px] text-foreground/85 list-disc pl-5 marker:text-[color:var(--brand)]">
|
||||
<li>No probing, scanning, or vulnerability testing of Warmbly infrastructure without prior written consent.</li>
|
||||
<li>No denial-of-service attempts against the API, the dashboard, the tracking edge, or any other component.</li>
|
||||
<li>No scraping of platform internals, other workspaces, other customers, or other customers' contacts.</li>
|
||||
<li>No credential stuffing, brute-forcing, or automated trial of credentials against imported mailboxes or third-party providers from Warmbly infrastructure.</li>
|
||||
<li>No interference with other customers' sending, warmup, or reply handling.</li>
|
||||
<li>No reverse-engineering of rate limits or abuse controls in order to defeat them.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- ===== 12. Enforcement ===== -->
|
||||
<section id="enforcement" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 12</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Enforcement</h2>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Enforcement runs on the same mailbox health states the platform uses internally. Most action happens at the mailbox level. Workspace-level action follows when the pattern is broader or the abuse is severe.
|
||||
</p>
|
||||
|
||||
<div class="mt-6 rounded-[14px] bg-white ring-1 ring-[color:var(--border)] overflow-hidden">
|
||||
{enforcement.map((s, i) => (
|
||||
<div class={`flex flex-col sm:flex-row sm:items-start gap-3 sm:gap-5 px-5 py-4 ${i === enforcement.length - 1 ? '' : 'border-b border-[color:var(--border)]'}`}>
|
||||
<div class="sm:w-36 shrink-0">
|
||||
<span class={`inline-flex items-center gap-1.5 h-6 px-2.5 rounded-full text-[10.5px] font-semibold font-mono uppercase tracking-[0.1em] ring-1 ${s.chip}`}>
|
||||
<span class={`w-1.5 h-1.5 rounded-full ${s.dot}`}></span>
|
||||
{s.state}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-[14.5px] font-semibold text-heading">{s.title}</div>
|
||||
<p class="mt-1 text-[13.5px] text-foreground/75 leading-relaxed">{s.body}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div class="mt-5 space-y-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
<p>
|
||||
Where reasonable, we give notice and time to fix the problem. Where the behavior is actively damaging shared infrastructure, threatens other customers, or is clearly fraudulent, we act first and explain after.
|
||||
</p>
|
||||
<p>
|
||||
Serious or repeated violations can result in immediate workspace suspension, account termination, refusal to do business in the future, and where appropriate, reporting to law enforcement or affected third parties.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===== 13. Reporting abuse ===== -->
|
||||
<section id="reporting" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 13</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Reporting abuse</h2>
|
||||
|
||||
<div class="mt-5 rounded-[14px] bg-white ring-1 ring-[color:var(--border)] p-5 md:p-6">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="inline-flex items-center justify-center w-10 h-10 rounded-[10px] bg-rose-50 text-rose-700 ring-1 ring-rose-100 shrink-0">
|
||||
<Icon name="warning" size={18} />
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-[15px] font-semibold text-heading">Saw something? Email us.</div>
|
||||
<p class="mt-1.5 text-[13.5px] text-foreground/75 leading-relaxed">
|
||||
To report a suspected violation by a Warmbly customer, send the message and full headers to <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] font-medium" href="mailto:abuse@warmbly.com">abuse@warmbly.com</a>. We acknowledge reports within one business day and act on them based on the evidence, not based on who reported.
|
||||
</p>
|
||||
<p class="mt-2 text-[13px] text-foreground/65 leading-relaxed">
|
||||
Security issues belong at <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]" href="mailto:security@warmbly.com">security@warmbly.com</a>. Privacy questions belong at <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]" href="mailto:privacy@warmbly.com">privacy@warmbly.com</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===== 14. Changes ===== -->
|
||||
<section id="changes" class="scroll-mt-20">
|
||||
<div class="text-[10.5px] font-mono uppercase tracking-[0.18em] text-muted-foreground mb-2">Section 14</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.02em] text-heading">Changes to this policy</h2>
|
||||
<div class="mt-4 space-y-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
<p>
|
||||
This policy evolves as the platform and the abuse landscape change. We will update it as needed. Material changes are announced by email to workspace owners and by in-app notice. Minor clarifications and typo fixes can land without notice.
|
||||
</p>
|
||||
<p>
|
||||
The current version is always at this URL, with a last-updated date at the top. Continued use of Warmbly after a change takes effect counts as acceptance of the change.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 pt-6 border-t border-[color:var(--border)] flex flex-wrap items-center justify-between gap-3 text-[12.5px] font-mono">
|
||||
<span class="text-muted-foreground">Last updated <span class="text-heading font-semibold">{lastUpdated}</span></span>
|
||||
<span class="text-muted-foreground">Questions? <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]" href="mailto:legal@warmbly.com">legal@warmbly.com</a></span>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CTA
|
||||
title="Send cold email that earns the inbox."
|
||||
description="Real outreach, real warmup, real rules. Connect a mailbox and start the right way."
|
||||
primaryLabel="Start free trial"
|
||||
primaryHref="https://app.warmbly.com/register"
|
||||
secondaryLabel="Read the terms"
|
||||
secondaryHref="/terms/"
|
||||
/>
|
||||
</Layout>
|
||||
@@ -692,9 +692,9 @@ scheduler.<span style="color:#a78bfa">scheduleSend</span>({
|
||||
Email is the fastest way to reach us. Include the publication or context and a deadline if you have one. We try to reply within one business day.
|
||||
</p>
|
||||
<div class="mt-6 flex flex-wrap items-center gap-3">
|
||||
<a href="mailto:press@warmbly.com" class="inline-flex h-10 px-4 items-center gap-2 rounded-[10px] text-[13.5px] font-semibold bg-white hover:bg-white/95" style="color:#075985;">
|
||||
<a href="mailto:hello@warmbly.com" class="inline-flex h-10 px-4 items-center gap-2 rounded-[10px] text-[13.5px] font-semibold bg-white hover:bg-white/95" style="color:#075985;">
|
||||
<Icon name="mail" size={13} />
|
||||
press@warmbly.com
|
||||
hello@warmbly.com
|
||||
</a>
|
||||
<a href="/brand.zip" class="inline-flex h-10 px-4 items-center gap-2 rounded-[10px] text-[13.5px] font-medium bg-white/10 backdrop-blur ring-1 ring-white/40 text-white hover:bg-white/20">
|
||||
<Icon name="arrowRight" size={13} class="rotate-90" />
|
||||
|
||||
@@ -1,673 +0,0 @@
|
||||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import HeroAtmosphere from '../components/HeroAtmosphere.astro';
|
||||
import Icon from '../components/Icon.astro';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
Cookies policy. Full redesign.
|
||||
|
||||
Source of truth:
|
||||
- CLAUDE.md, sections "Auth and signup protection", "Sharing"
|
||||
- internal/pkg/captcha/turnstile.go (Cloudflare Turnstile)
|
||||
- internal/api/middleware/ratelimit.go (session + CSRF surface)
|
||||
- /subprocessors page (Stripe, Cloudflare)
|
||||
|
||||
Honest posture: Warmbly does not run third-party advertising
|
||||
trackers and does not currently set marketing or analytics cookies
|
||||
on the marketing site. Product analytics is server-side and the
|
||||
workspace owner can disable it from the app. The page says so.
|
||||
|
||||
Tone: no em dashes. No fictional analytics vendors.
|
||||
|
||||
Astro parser quirk: any `<` or `<=` comparison inside `{}` blocks
|
||||
breaks the parser. Hoist them up here.
|
||||
----------------------------------------------------------------- */
|
||||
|
||||
const LAST_UPDATED = '2026-05-27';
|
||||
|
||||
// Sidebar TOC. Each entry maps to an in-page anchor on a section.
|
||||
const toc = [
|
||||
{ id: 'what-cookies-are', label: 'What cookies are' },
|
||||
{ id: 'how-we-use', label: 'How Warmbly uses cookies' },
|
||||
{ id: 'strictly-necessary', label: 'Strictly necessary' },
|
||||
{ id: 'functional', label: 'Functional' },
|
||||
{ id: 'analytics', label: 'Analytics' },
|
||||
{ id: 'marketing', label: 'Marketing' },
|
||||
{ id: 'third-party', label: 'Third-party cookies' },
|
||||
{ id: 'choices', label: 'Your choices and controls' },
|
||||
{ id: 'changes', label: 'Changes to this policy' },
|
||||
{ id: 'contact', label: 'Contact' },
|
||||
];
|
||||
|
||||
// Cookie type definition used by the table renderer. Centralised so
|
||||
// every category section uses the same row shape and visual.
|
||||
type Cookie = {
|
||||
name: string;
|
||||
provider: string;
|
||||
purpose: string;
|
||||
duration: string;
|
||||
party: '1st' | '3rd';
|
||||
essential?: boolean;
|
||||
};
|
||||
|
||||
// Strictly necessary cookies. These are what Warmbly actually sets to
|
||||
// keep an authenticated session safe. Disabling these breaks login.
|
||||
const strictlyNecessary: Cookie[] = [
|
||||
{
|
||||
name: 'wb_session',
|
||||
provider: 'warmbly.com',
|
||||
purpose: 'Authenticated session cookie. Keeps you signed in to the Warmbly application.',
|
||||
duration: '30 days, or until sign-out',
|
||||
party: '1st',
|
||||
essential: true,
|
||||
},
|
||||
{
|
||||
name: 'wb_csrf',
|
||||
provider: 'warmbly.com',
|
||||
purpose: 'Cross-site request forgery token. Protects state-changing form submissions.',
|
||||
duration: 'Session',
|
||||
party: '1st',
|
||||
essential: true,
|
||||
},
|
||||
{
|
||||
name: 'wb_workspace',
|
||||
provider: 'warmbly.com',
|
||||
purpose: 'Remembers the workspace you were last viewing so you land back in it after sign-in.',
|
||||
duration: '180 days',
|
||||
party: '1st',
|
||||
essential: true,
|
||||
},
|
||||
{
|
||||
name: 'cf_clearance',
|
||||
provider: 'cloudflare.com',
|
||||
purpose: 'Cloudflare bot challenge clearance. Marks your browser as having passed a Turnstile or managed challenge.',
|
||||
duration: '30 minutes',
|
||||
party: '3rd',
|
||||
essential: true,
|
||||
},
|
||||
{
|
||||
name: '__cf_bm',
|
||||
provider: 'cloudflare.com',
|
||||
purpose: 'Cloudflare Bot Management. Distinguishes humans from automated traffic on the edge.',
|
||||
duration: '30 minutes',
|
||||
party: '3rd',
|
||||
essential: true,
|
||||
},
|
||||
];
|
||||
|
||||
// Functional cookies. UI memory only. Optional but very low impact if
|
||||
// you turn them off.
|
||||
const functional: Cookie[] = [
|
||||
{
|
||||
name: 'wb_theme',
|
||||
provider: 'warmbly.com',
|
||||
purpose: 'Stores your light or dark theme preference.',
|
||||
duration: '1 year',
|
||||
party: '1st',
|
||||
},
|
||||
{
|
||||
name: 'wb_sidebar',
|
||||
provider: 'warmbly.com',
|
||||
purpose: 'Remembers whether the app sidebar is collapsed or expanded.',
|
||||
duration: '1 year',
|
||||
party: '1st',
|
||||
},
|
||||
{
|
||||
name: 'wb_dismissed_notice_*',
|
||||
provider: 'warmbly.com',
|
||||
purpose: 'Tracks which one-time in-app notices and onboarding tips you have dismissed.',
|
||||
duration: '1 year',
|
||||
party: '1st',
|
||||
},
|
||||
];
|
||||
|
||||
// Analytics cookies. Be honest: the marketing site does not run a
|
||||
// third-party analytics cookie today. Product analytics in the app is
|
||||
// server-side and workspace-owner-controlled.
|
||||
const analytics: Cookie[] = [];
|
||||
|
||||
// Marketing cookies. Warmbly does not run third-party ad trackers or
|
||||
// retargeting pixels on the marketing site.
|
||||
const marketing: Cookie[] = [];
|
||||
|
||||
// Third-party cookies. Only when you reach a page that loads the
|
||||
// vendor's script.
|
||||
const thirdParty: Cookie[] = [
|
||||
{
|
||||
name: '__stripe_mid',
|
||||
provider: 'stripe.com',
|
||||
purpose: 'Stripe fraud-prevention identifier. Set when you reach a billing or checkout page.',
|
||||
duration: '1 year',
|
||||
party: '3rd',
|
||||
},
|
||||
{
|
||||
name: '__stripe_sid',
|
||||
provider: 'stripe.com',
|
||||
purpose: 'Stripe session identifier used during checkout.',
|
||||
duration: '30 minutes',
|
||||
party: '3rd',
|
||||
},
|
||||
{
|
||||
name: 'cf_clearance',
|
||||
provider: 'cloudflare.com',
|
||||
purpose: 'Cloudflare challenge clearance. Same cookie as the essential row above, listed here for completeness.',
|
||||
duration: '30 minutes',
|
||||
party: '3rd',
|
||||
},
|
||||
];
|
||||
|
||||
// Overview card stats. Pulled from the actual category counts above so
|
||||
// the page stays honest when these tables change.
|
||||
const totalCookies =
|
||||
strictlyNecessary.length +
|
||||
functional.length +
|
||||
analytics.length +
|
||||
marketing.length +
|
||||
thirdParty.length;
|
||||
const essentialCount = strictlyNecessary.length;
|
||||
const optionalCount = functional.length + analytics.length + marketing.length;
|
||||
const thirdPartyCount = strictlyNecessary.filter((c) => c.party === '3rd').length + thirdParty.length;
|
||||
|
||||
const overview = [
|
||||
{
|
||||
k: 'Total cookies',
|
||||
v: String(totalCookies),
|
||||
note: 'Across every category Warmbly currently sets.',
|
||||
},
|
||||
{
|
||||
k: 'Strictly necessary',
|
||||
v: String(essentialCount),
|
||||
note: 'Needed to keep you signed in and protect form submissions.',
|
||||
},
|
||||
{
|
||||
k: 'Optional',
|
||||
v: String(optionalCount),
|
||||
note: 'Functional preferences only. No analytics or ad cookies today.',
|
||||
},
|
||||
{
|
||||
k: 'Third-party',
|
||||
v: String(thirdPartyCount),
|
||||
note: 'Only Stripe and Cloudflare. No advertising networks.',
|
||||
},
|
||||
];
|
||||
|
||||
// Category section definitions consumed by the main column.
|
||||
const categories: {
|
||||
id: string;
|
||||
eyebrow: string;
|
||||
title: string;
|
||||
intro: string;
|
||||
rows: Cookie[];
|
||||
emptyNote?: string;
|
||||
tone: 'essential' | 'functional' | 'analytics' | 'marketing';
|
||||
}[] = [
|
||||
{
|
||||
id: 'strictly-necessary',
|
||||
eyebrow: 'Required',
|
||||
title: 'Strictly necessary cookies',
|
||||
intro: 'These cookies are required for the Warmbly application to function. They keep you signed in, protect form submissions against forgery, and let Cloudflare distinguish humans from automated traffic. You cannot opt out of these and still use the app.',
|
||||
rows: strictlyNecessary,
|
||||
tone: 'essential',
|
||||
},
|
||||
{
|
||||
id: 'functional',
|
||||
eyebrow: 'Optional',
|
||||
title: 'Functional cookies',
|
||||
intro: 'These cookies remember small interface preferences so the app feels consistent between visits. They do not track you across sites and they do not feed any analytics or advertising system.',
|
||||
rows: functional,
|
||||
tone: 'functional',
|
||||
},
|
||||
{
|
||||
id: 'analytics',
|
||||
eyebrow: 'Optional',
|
||||
title: 'Analytics cookies',
|
||||
intro: 'We do not currently set analytics cookies on the marketing site. Product analytics inside the application is collected server-side, and the workspace owner can disable it from workspace settings. If this changes, this section will list every cookie before it ships.',
|
||||
rows: analytics,
|
||||
emptyNote: 'We do not currently set cookies in this category.',
|
||||
tone: 'analytics',
|
||||
},
|
||||
{
|
||||
id: 'marketing',
|
||||
eyebrow: 'Optional',
|
||||
title: 'Marketing cookies',
|
||||
intro: 'We do not run advertising trackers, retargeting pixels, or cross-site identifiers. We have no marketing cookies to disclose. This is a deliberate product decision and we intend to keep it that way.',
|
||||
rows: marketing,
|
||||
emptyNote: 'We do not currently set cookies in this category.',
|
||||
tone: 'marketing',
|
||||
},
|
||||
];
|
||||
|
||||
// Controls card. Each item is a way you can manage cookies for
|
||||
// Warmbly specifically.
|
||||
const controls = [
|
||||
{
|
||||
icon: 'shield',
|
||||
title: 'Browser controls',
|
||||
body: 'Every modern browser lets you view, block and delete cookies for a single site. Blocking strictly necessary cookies will sign you out of Warmbly.',
|
||||
},
|
||||
{
|
||||
icon: 'lock',
|
||||
title: 'Do Not Track',
|
||||
body: 'Warmbly serves the same product whether or not your browser sends a Do Not Track signal, because we do not run targeted advertising trackers either way.',
|
||||
},
|
||||
{
|
||||
icon: 'filter',
|
||||
title: 'Workspace analytics toggle',
|
||||
body: 'Workspace owners can disable product analytics for the entire workspace from workspace settings. This affects server-side telemetry, not cookies on this site.',
|
||||
},
|
||||
{
|
||||
icon: 'cpu',
|
||||
title: 'Third-party scripts',
|
||||
body: 'Stripe cookies only appear when you reach a billing page. Cloudflare cookies appear when the edge needs to challenge a request. Neither is used for advertising.',
|
||||
},
|
||||
];
|
||||
|
||||
// Per-category visual tone for the category eyebrow chip.
|
||||
const toneStyles: Record<string, string> = {
|
||||
essential: 'bg-rose-50 text-rose-700 ring-1 ring-rose-100',
|
||||
functional: 'bg-sky-50 text-sky-700 ring-1 ring-sky-100',
|
||||
analytics: 'bg-amber-50 text-amber-700 ring-1 ring-amber-100',
|
||||
marketing: 'bg-violet-50 text-violet-700 ring-1 ring-violet-100',
|
||||
};
|
||||
---
|
||||
<Layout
|
||||
title="Cookies · Warmbly"
|
||||
description="The cookies Warmbly sets, why we set them, and how you can control them. We do not run advertising trackers and we do not sell cookie data."
|
||||
>
|
||||
|
||||
<!-- =====================================================
|
||||
HERO. Shorter than product pages. Centered, with the
|
||||
last-updated date prominently displayed.
|
||||
===================================================== -->
|
||||
<section class="relative isolate overflow-hidden">
|
||||
<HeroAtmosphere />
|
||||
|
||||
<div class="container-page relative pt-16 md:pt-20 pb-28 md:pb-36 text-center">
|
||||
<div class="inline-flex items-center gap-2 h-7 pl-1 pr-3 rounded-full bg-white/15 backdrop-blur ring-1 ring-white/25 text-[12px] text-white/95 shadow-[0_4px_14px_-4px_rgba(0,0,0,0.25)]">
|
||||
<span class="inline-flex items-center h-5 px-1.5 rounded-full text-[10.5px] font-semibold uppercase tracking-[0.06em] bg-white" style="color:#0369a1;">
|
||||
Legal
|
||||
</span>
|
||||
Cookies policy
|
||||
</div>
|
||||
|
||||
<h1 class="mt-8 text-[44px] sm:text-5xl md:text-[64px] lg:text-[72px] font-semibold tracking-[-0.04em] leading-[0.98] text-white max-w-3xl mx-auto">
|
||||
Cookies.
|
||||
</h1>
|
||||
|
||||
<p class="mt-6 text-[16px] md:text-[18px] text-white/80 max-w-2xl mx-auto leading-relaxed">
|
||||
Warmbly only uses the cookies it needs to keep you signed in, protect your account, and remember a handful of interface preferences. No advertising trackers. No cross-site identifiers. You stay in control.
|
||||
</p>
|
||||
|
||||
<div class="mt-8 inline-flex items-center gap-2 h-9 px-4 rounded-full bg-white/10 backdrop-blur ring-1 ring-white/30 text-white/90">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4"/><path d="M8 2v4"/><path d="M3 10h18"/>
|
||||
</svg>
|
||||
<span class="text-[12.5px] font-mono tracking-[0.04em]">Last updated {LAST_UPDATED}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- =====================================================
|
||||
MAIN LAYOUT. Sticky TOC sidebar + content column.
|
||||
===================================================== -->
|
||||
<section class="relative -mt-20 md:-mt-24 pb-20 md:pb-28 z-10">
|
||||
<div class="container-page">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-[240px_minmax(0,1fr)] gap-10 lg:gap-14">
|
||||
|
||||
<!-- ============ SIDEBAR TOC ============ -->
|
||||
<aside class="lg:sticky lg:top-24 self-start">
|
||||
<div class="rounded-[14px] bg-white ring-1 ring-slate-200 p-5 shadow-[0_18px_40px_-22px_rgba(2,32,71,0.18),0_2px_6px_-2px_rgba(15,23,42,0.06)]">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-3">On this page</div>
|
||||
<ul class="space-y-0.5">
|
||||
{toc.map((t) => (
|
||||
<li>
|
||||
<a
|
||||
href={`#${t.id}`}
|
||||
class="block text-[13.5px] -mx-2 px-2 py-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-[color:var(--surface-2)]/60 transition-colors"
|
||||
>
|
||||
{t.label}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div class="mt-5 pt-5 border-t border-slate-200">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-2">Related</div>
|
||||
<ul class="space-y-1">
|
||||
<li><a class="text-[13px] text-muted-foreground hover:text-foreground" href="/privacy/">Privacy Policy</a></li>
|
||||
<li><a class="text-[13px] text-muted-foreground hover:text-foreground" href="/dpa/">Data Processing Addendum</a></li>
|
||||
<li><a class="text-[13px] text-muted-foreground hover:text-foreground" href="/subprocessors/">Subprocessors</a></li>
|
||||
<li><a class="text-[13px] text-muted-foreground hover:text-foreground" href="/terms/">Terms of Service</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="#cookie-settings"
|
||||
class="mt-3 group inline-flex w-full items-center justify-between gap-2 h-11 px-4 rounded-[10px] bg-[color:var(--brand)] hover:bg-[color:var(--brand-strong)] text-white text-[13.5px] font-semibold transition-colors"
|
||||
>
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
|
||||
</svg>
|
||||
Manage preferences
|
||||
</span>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="transition-transform group-hover:translate-x-0.5" aria-hidden="true">
|
||||
<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
</aside>
|
||||
|
||||
<!-- ============ MAIN CONTENT ============ -->
|
||||
<article class="min-w-0">
|
||||
|
||||
<!-- WHAT COOKIES ARE -->
|
||||
<section id="what-cookies-are" class="scroll-mt-24">
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">Background</div>
|
||||
<h2 class="text-[26px] md:text-[32px] font-semibold tracking-[-0.025em] leading-[1.1] text-heading">
|
||||
What cookies are.
|
||||
</h2>
|
||||
<p class="mt-4 text-[15px] text-foreground/85 leading-relaxed max-w-3xl">
|
||||
A cookie is a small piece of text that a website stores in your browser. The browser sends that text back to the same site on later requests. Cookies let the site recognise that two requests came from the same browser, which is how a site keeps you signed in, remembers a setting, or measures a session. Cookies are not executable, they cannot read other files on your computer, and a cookie set by one site cannot be read by an unrelated site.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- HOW WE USE -->
|
||||
<section id="how-we-use" class="scroll-mt-24 mt-14">
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">Overview</div>
|
||||
<h2 class="text-[26px] md:text-[32px] font-semibold tracking-[-0.025em] leading-[1.1] text-heading">
|
||||
How Warmbly uses cookies.
|
||||
</h2>
|
||||
<p class="mt-4 text-[15px] text-foreground/85 leading-relaxed max-w-3xl">
|
||||
Warmbly keeps its cookie surface deliberately small. The cookies you see below fall into four buckets: strictly necessary, functional, analytics, and marketing. We currently set cookies in two of those four buckets, and we say so plainly when a category is empty.
|
||||
</p>
|
||||
|
||||
<div class="mt-6 rounded-[16px] bg-white ring-1 ring-slate-200 overflow-hidden shadow-[0_18px_40px_-22px_rgba(2,32,71,0.18),0_2px_6px_-2px_rgba(15,23,42,0.06)]">
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-4">
|
||||
{overview.map((o, i) => {
|
||||
const borderRight = (i % 2) !== 1 ? 'sm:border-r' : '';
|
||||
const borderRightLg = (i % 4) !== 3 ? 'lg:border-r' : '';
|
||||
const borderBottom = i < (overview.length - 1) ? 'border-b sm:border-b-0' : '';
|
||||
const borderBottomSm = i < 2 ? 'sm:border-b lg:border-b-0' : '';
|
||||
return (
|
||||
<div class={`p-5 md:p-6 border-slate-200 ${borderRight} ${borderRightLg} ${borderBottom} ${borderBottomSm}`}>
|
||||
<div class="text-[10.5px] uppercase tracking-[0.16em] text-muted-foreground font-mono">{o.k}</div>
|
||||
<div class="mt-2 text-[34px] font-semibold tracking-[-0.03em] text-heading leading-none">{o.v}</div>
|
||||
<div class="mt-2 text-[12.5px] text-muted-foreground leading-relaxed">{o.note}</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CATEGORY SECTIONS WITH TABLES -->
|
||||
{categories.map((cat) => (
|
||||
<section id={cat.id} class="scroll-mt-24 mt-16">
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<span class={`inline-flex items-center h-5 px-2 rounded text-[10.5px] font-semibold uppercase tracking-[0.08em] ${toneStyles[cat.tone]}`}>
|
||||
{cat.eyebrow}
|
||||
</span>
|
||||
<span class="text-[11px] font-mono text-muted-foreground">{cat.rows.length} {cat.rows.length === 1 ? 'cookie' : 'cookies'}</span>
|
||||
</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.025em] leading-[1.1] text-heading">
|
||||
{cat.title}
|
||||
</h2>
|
||||
<p class="mt-3 text-[14.5px] text-foreground/80 leading-relaxed max-w-3xl">{cat.intro}</p>
|
||||
|
||||
{cat.rows.length === 0 ? (
|
||||
<div class="mt-5 rounded-[14px] border border-dashed border-slate-300 bg-[color:var(--surface-2)]/60 px-5 py-6 flex items-start gap-3">
|
||||
<div class="mt-0.5 w-7 h-7 rounded-full bg-white ring-1 ring-slate-200 flex items-center justify-center text-slate-400">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="10"/><path d="M8 12h8"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-[14px] font-medium text-heading">{cat.emptyNote}</div>
|
||||
<div class="mt-1 text-[12.5px] text-muted-foreground">If this changes, the table will be populated here before any new cookie is shipped, and the last-updated date at the top of this page will move.</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<!-- Desktop table -->
|
||||
<div class="mt-5 hidden md:block rounded-[14px] bg-white ring-1 ring-slate-200 overflow-hidden shadow-[0_18px_40px_-22px_rgba(2,32,71,0.16),0_2px_6px_-2px_rgba(15,23,42,0.05)]">
|
||||
<table class="w-full text-[13.5px]">
|
||||
<thead class="bg-[color:var(--surface-2)]/70 text-[11px] uppercase tracking-[0.12em] text-muted-foreground">
|
||||
<tr>
|
||||
<th class="text-left font-semibold px-5 py-3">Name</th>
|
||||
<th class="text-left font-semibold px-5 py-3">Provider</th>
|
||||
<th class="text-left font-semibold px-5 py-3">Purpose</th>
|
||||
<th class="text-left font-semibold px-5 py-3 whitespace-nowrap">Duration</th>
|
||||
<th class="text-left font-semibold px-5 py-3 whitespace-nowrap">Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-200">
|
||||
{cat.rows.map((c) => (
|
||||
<tr class="align-top hover:bg-[color:var(--surface-2)]/40 transition-colors">
|
||||
<td class="px-5 py-3.5">
|
||||
<code class="font-mono text-[12.5px] px-1.5 py-0.5 rounded bg-[color:var(--surface-2)] ring-1 ring-[color:var(--border)] text-foreground">{c.name}</code>
|
||||
{c.essential && (
|
||||
<div class="mt-1.5 inline-flex items-center gap-1 text-[10.5px] font-medium text-rose-700">
|
||||
<span class="w-1 h-1 rounded-full bg-rose-500"></span>
|
||||
Essential
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
<td class="px-5 py-3.5 text-foreground/85 whitespace-nowrap">{c.provider}</td>
|
||||
<td class="px-5 py-3.5 text-foreground/75 leading-relaxed">{c.purpose}</td>
|
||||
<td class="px-5 py-3.5 text-muted-foreground whitespace-nowrap">{c.duration}</td>
|
||||
<td class="px-5 py-3.5 whitespace-nowrap">
|
||||
<span class={`inline-flex items-center h-5 px-1.5 rounded text-[10.5px] font-medium ${c.party === '1st' ? 'bg-sky-50 text-sky-700' : 'bg-slate-100 text-slate-700'}`}>
|
||||
{c.party === '1st' ? '1st party' : '3rd party'}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Mobile stacked cards -->
|
||||
<div class="mt-5 md:hidden space-y-3">
|
||||
{cat.rows.map((c) => (
|
||||
<div class="rounded-[12px] bg-white ring-1 ring-slate-200 p-4 shadow-[0_8px_22px_-16px_rgba(2,32,71,0.18),0_1px_3px_-1px_rgba(15,23,42,0.05)]">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<code class="font-mono text-[12.5px] px-1.5 py-0.5 rounded bg-[color:var(--surface-2)] ring-1 ring-[color:var(--border)] text-foreground break-all">{c.name}</code>
|
||||
<span class={`shrink-0 inline-flex items-center h-5 px-1.5 rounded text-[10.5px] font-medium ${c.party === '1st' ? 'bg-sky-50 text-sky-700' : 'bg-slate-100 text-slate-700'}`}>
|
||||
{c.party === '1st' ? '1st party' : '3rd party'}
|
||||
</span>
|
||||
</div>
|
||||
{c.essential && (
|
||||
<div class="mt-2 inline-flex items-center gap-1 text-[10.5px] font-medium text-rose-700">
|
||||
<span class="w-1 h-1 rounded-full bg-rose-500"></span>
|
||||
Essential
|
||||
</div>
|
||||
)}
|
||||
<p class="mt-2 text-[13px] text-foreground/80 leading-relaxed">{c.purpose}</p>
|
||||
<dl class="mt-3 grid grid-cols-2 gap-2 text-[11.5px]">
|
||||
<div>
|
||||
<dt class="uppercase tracking-[0.12em] text-muted-foreground font-mono text-[10px]">Provider</dt>
|
||||
<dd class="mt-0.5 text-foreground/85">{c.provider}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="uppercase tracking-[0.12em] text-muted-foreground font-mono text-[10px]">Duration</dt>
|
||||
<dd class="mt-0.5 text-foreground/85">{c.duration}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
))}
|
||||
|
||||
<!-- THIRD-PARTY COOKIES SECTION -->
|
||||
<section id="third-party" class="scroll-mt-24 mt-16">
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<span class="inline-flex items-center h-5 px-2 rounded text-[10.5px] font-semibold uppercase tracking-[0.08em] bg-slate-100 text-slate-700 ring-1 ring-slate-200">
|
||||
Vendors
|
||||
</span>
|
||||
<span class="text-[11px] font-mono text-muted-foreground">{thirdParty.length} cookies</span>
|
||||
</div>
|
||||
<h2 class="text-[24px] md:text-[28px] font-semibold tracking-[-0.025em] leading-[1.1] text-heading">
|
||||
Third-party cookies.
|
||||
</h2>
|
||||
<p class="mt-3 text-[14.5px] text-foreground/80 leading-relaxed max-w-3xl">
|
||||
The Warmbly application uses two third-party vendors that may set cookies in your browser: Stripe for billing and Cloudflare for edge protection. Neither is used for advertising. Each vendor publishes its own cookie policy.
|
||||
</p>
|
||||
|
||||
<div class="mt-5 grid sm:grid-cols-2 gap-3">
|
||||
<a href="https://stripe.com/legal/cookies-policy" target="_blank" rel="noopener noreferrer" class="group rounded-[14px] bg-white ring-1 ring-slate-200 p-5 hover:ring-[color:var(--brand)] hover:-translate-y-0.5 transition-all duration-200 shadow-[0_18px_40px_-22px_rgba(2,32,71,0.18),0_2px_6px_-2px_rgba(15,23,42,0.06)]">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-[14px] font-semibold text-heading">Stripe</div>
|
||||
<Icon name="arrowUpRight" size={14} class="text-muted-foreground group-hover:text-[color:var(--brand)] transition-colors" />
|
||||
</div>
|
||||
<p class="mt-2 text-[12.5px] text-muted-foreground leading-relaxed">Sets cookies only when you reach a billing or checkout page. Used for fraud prevention and to keep checkout state.</p>
|
||||
<div class="mt-3 text-[10.5px] uppercase tracking-[0.12em] text-muted-foreground font-mono">stripe.com/legal/cookies-policy</div>
|
||||
</a>
|
||||
<a href="https://www.cloudflare.com/cookie-policy/" target="_blank" rel="noopener noreferrer" class="group rounded-[14px] bg-white ring-1 ring-slate-200 p-5 hover:ring-[color:var(--brand)] hover:-translate-y-0.5 transition-all duration-200 shadow-[0_18px_40px_-22px_rgba(2,32,71,0.18),0_2px_6px_-2px_rgba(15,23,42,0.06)]">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-[14px] font-semibold text-heading">Cloudflare</div>
|
||||
<Icon name="arrowUpRight" size={14} class="text-muted-foreground group-hover:text-[color:var(--brand)] transition-colors" />
|
||||
</div>
|
||||
<p class="mt-2 text-[12.5px] text-muted-foreground leading-relaxed">Provides DDoS protection, bot management, and Turnstile CAPTCHA on auth surfaces. Necessary for the app to load safely.</p>
|
||||
<div class="mt-3 text-[10.5px] uppercase tracking-[0.12em] text-muted-foreground font-mono">cloudflare.com/cookie-policy</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 hidden md:block rounded-[14px] bg-white ring-1 ring-slate-200 overflow-hidden shadow-[0_18px_40px_-22px_rgba(2,32,71,0.16),0_2px_6px_-2px_rgba(15,23,42,0.05)]">
|
||||
<table class="w-full text-[13.5px]">
|
||||
<thead class="bg-[color:var(--surface-2)]/70 text-[11px] uppercase tracking-[0.12em] text-muted-foreground">
|
||||
<tr>
|
||||
<th class="text-left font-semibold px-5 py-3">Name</th>
|
||||
<th class="text-left font-semibold px-5 py-3">Provider</th>
|
||||
<th class="text-left font-semibold px-5 py-3">Purpose</th>
|
||||
<th class="text-left font-semibold px-5 py-3 whitespace-nowrap">Duration</th>
|
||||
<th class="text-left font-semibold px-5 py-3 whitespace-nowrap">Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-200">
|
||||
{thirdParty.map((c) => (
|
||||
<tr class="align-top hover:bg-[color:var(--surface-2)]/40 transition-colors">
|
||||
<td class="px-5 py-3.5">
|
||||
<code class="font-mono text-[12.5px] px-1.5 py-0.5 rounded bg-[color:var(--surface-2)] ring-1 ring-[color:var(--border)] text-foreground">{c.name}</code>
|
||||
</td>
|
||||
<td class="px-5 py-3.5 text-foreground/85 whitespace-nowrap">{c.provider}</td>
|
||||
<td class="px-5 py-3.5 text-foreground/75 leading-relaxed">{c.purpose}</td>
|
||||
<td class="px-5 py-3.5 text-muted-foreground whitespace-nowrap">{c.duration}</td>
|
||||
<td class="px-5 py-3.5 whitespace-nowrap">
|
||||
<span class="inline-flex items-center h-5 px-1.5 rounded text-[10.5px] font-medium bg-slate-100 text-slate-700">3rd party</span>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 md:hidden space-y-3">
|
||||
{thirdParty.map((c) => (
|
||||
<div class="rounded-[12px] bg-white ring-1 ring-slate-200 p-4 shadow-[0_8px_22px_-16px_rgba(2,32,71,0.18),0_1px_3px_-1px_rgba(15,23,42,0.05)]">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<code class="font-mono text-[12.5px] px-1.5 py-0.5 rounded bg-[color:var(--surface-2)] ring-1 ring-[color:var(--border)] text-foreground break-all">{c.name}</code>
|
||||
<span class="shrink-0 inline-flex items-center h-5 px-1.5 rounded text-[10.5px] font-medium bg-slate-100 text-slate-700">3rd party</span>
|
||||
</div>
|
||||
<p class="mt-2 text-[13px] text-foreground/80 leading-relaxed">{c.purpose}</p>
|
||||
<dl class="mt-3 grid grid-cols-2 gap-2 text-[11.5px]">
|
||||
<div>
|
||||
<dt class="uppercase tracking-[0.12em] text-muted-foreground font-mono text-[10px]">Provider</dt>
|
||||
<dd class="mt-0.5 text-foreground/85">{c.provider}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="uppercase tracking-[0.12em] text-muted-foreground font-mono text-[10px]">Duration</dt>
|
||||
<dd class="mt-0.5 text-foreground/85">{c.duration}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- YOUR CHOICES -->
|
||||
<section id="choices" class="scroll-mt-24 mt-16">
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">Controls</div>
|
||||
<h2 class="text-[26px] md:text-[32px] font-semibold tracking-[-0.025em] leading-[1.1] text-heading">
|
||||
Your choices and controls.
|
||||
</h2>
|
||||
<p class="mt-3 text-[14.5px] text-foreground/80 leading-relaxed max-w-3xl">
|
||||
You can manage cookies at the browser level, at the workspace level for product analytics, or by avoiding the pages that load third-party scripts. Each option below applies to Warmbly specifically.
|
||||
</p>
|
||||
|
||||
<div class="mt-6 grid sm:grid-cols-2 gap-3">
|
||||
{controls.map((c) => (
|
||||
<div class="rounded-[14px] bg-white ring-1 ring-slate-200 p-5 shadow-[0_18px_40px_-22px_rgba(2,32,71,0.16),0_2px_6px_-2px_rgba(15,23,42,0.05)]">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div class="w-8 h-8 rounded-[8px] bg-[color:var(--brand-soft)] ring-1 ring-sky-100 flex items-center justify-center text-[color:var(--brand-strong)]">
|
||||
<Icon name={c.icon} size={15} />
|
||||
</div>
|
||||
<div class="text-[14px] font-semibold text-heading tracking-[-0.01em]">{c.title}</div>
|
||||
</div>
|
||||
<p class="mt-3 text-[13px] text-foreground/75 leading-relaxed">{c.body}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<!-- Manage preferences card -->
|
||||
<div id="cookie-settings" class="scroll-mt-24 mt-8 rounded-[16px] overflow-hidden ring-1 ring-slate-200 bg-gradient-to-br from-sky-50 via-white to-white shadow-[0_30px_60px_-30px_rgba(2,32,71,0.25)]">
|
||||
<div class="p-6 md:p-8 grid md:grid-cols-[1fr_auto] items-center gap-5">
|
||||
<div>
|
||||
<div class="text-[10.5px] uppercase tracking-[0.16em] text-[color:var(--brand-strong)] font-mono">Manage your preferences</div>
|
||||
<h3 class="mt-2 text-[20px] md:text-[22px] font-semibold tracking-[-0.02em] text-heading">Open the cookie settings panel.</h3>
|
||||
<p class="mt-2 text-[13.5px] text-foreground/75 leading-relaxed max-w-xl">
|
||||
Adjust optional cookies, view what is currently stored in your browser, and reset preferences. Strictly necessary cookies cannot be disabled without signing you out.
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
href="#cookie-settings"
|
||||
class="inline-flex items-center justify-center gap-2 h-11 px-5 rounded-[10px] bg-[color:var(--brand)] hover:bg-[color:var(--brand-strong)] text-white text-[13.5px] font-semibold transition-colors"
|
||||
>
|
||||
Open settings
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CHANGES -->
|
||||
<section id="changes" class="scroll-mt-24 mt-16">
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">Maintenance</div>
|
||||
<h2 class="text-[26px] md:text-[32px] font-semibold tracking-[-0.025em] leading-[1.1] text-heading">
|
||||
Changes to this policy.
|
||||
</h2>
|
||||
<p class="mt-4 text-[15px] text-foreground/85 leading-relaxed max-w-3xl">
|
||||
We may update this page when we add, remove, or change a cookie. The last-updated date at the top of the page always reflects the most recent revision. Material changes that affect optional cookies will be announced via email or in-app notice at least 30 days before they take effect.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- CONTACT -->
|
||||
<section id="contact" class="scroll-mt-24 mt-16">
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">Contact</div>
|
||||
<h2 class="text-[26px] md:text-[32px] font-semibold tracking-[-0.025em] leading-[1.1] text-heading">
|
||||
Contact.
|
||||
</h2>
|
||||
<p class="mt-4 text-[15px] text-foreground/85 leading-relaxed max-w-3xl">
|
||||
Questions about this policy or a specific cookie set by Warmbly? Email
|
||||
<a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] font-medium" href="mailto:privacy@warmbly.com">privacy@warmbly.com</a>
|
||||
and we will respond within 30 days. For a copy of our Data Processing Addendum, see
|
||||
<a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] font-medium" href="/dpa/">/dpa</a>.
|
||||
</p>
|
||||
|
||||
<div class="mt-8 pt-6 border-t border-slate-200 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 text-[12.5px] text-muted-foreground">
|
||||
<div>Warmbly Labs, Inc. 1209 N. Orange Street, Wilmington, DE 19801, USA.</div>
|
||||
<div class="font-mono">Last updated {LAST_UPDATED}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
@@ -1,590 +0,0 @@
|
||||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import HeroAtmosphere from '../components/HeroAtmosphere.astro';
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Last-updated date is the single source of truth for this DPA.
|
||||
// -----------------------------------------------------------------
|
||||
const LAST_UPDATED = '2026-05-27';
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Sidebar TOC. The id values must match the section ids in the body.
|
||||
// -----------------------------------------------------------------
|
||||
const toc = [
|
||||
{ num: '01', id: 'definitions', label: 'Definitions' },
|
||||
{ num: '02', id: 'scope-roles', label: 'Scope and roles' },
|
||||
{ num: '03', id: 'processing', label: 'Subject matter and duration' },
|
||||
{ num: '04', id: 'data-subjects', label: 'Categories of data subjects' },
|
||||
{ num: '05', id: 'data-categories', label: 'Categories of personal data' },
|
||||
{ num: '06', id: 'instructions', label: 'Customer instructions' },
|
||||
{ num: '07', id: 'confidentiality', label: 'Confidentiality and personnel' },
|
||||
{ num: '08', id: 'security', label: 'Security measures' },
|
||||
{ num: '09', id: 'subprocessors', label: 'Sub-processors' },
|
||||
{ num: '10', id: 'transfers', label: 'International transfers' },
|
||||
{ num: '11', id: 'rights', label: 'Data subject rights' },
|
||||
{ num: '12', id: 'breach', label: 'Breach notification' },
|
||||
{ num: '13', id: 'audits', label: 'Audits and inspections' },
|
||||
{ num: '14', id: 'return-deletion', label: 'Return or deletion' },
|
||||
{ num: '15', id: 'liability', label: 'Liability and limitations' },
|
||||
{ num: '16', id: 'precedence', label: 'Order of precedence' },
|
||||
{ num: '17', id: 'governing-law', label: 'Governing law' },
|
||||
{ num: '18', id: 'annex-1', label: 'Annex 1: Processing details' },
|
||||
{ num: '19', id: 'annex-2', label: 'Annex 2: Security measures' },
|
||||
{ num: '20', id: 'annex-3', label: 'Annex 3: Sub-processors' },
|
||||
];
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Definitions table. Plain English where the law allows, with the
|
||||
// formal term kept first so legal teams can map back to GDPR.
|
||||
// -----------------------------------------------------------------
|
||||
const definitions: Array<[string, string]> = [
|
||||
['Controller', 'The party that decides why and how personal data is processed. Under this DPA, Customer is the Controller for the personal data Customer uploads, imports, or sends through the Warmbly platform.'],
|
||||
['Processor', 'The party that processes personal data on behalf of the Controller. Warmbly is the Processor for the personal data Customer entrusts to the platform.'],
|
||||
['Sub-processor', 'A third party engaged by Warmbly to process personal data on behalf of Customer, such as a hosting provider, an email-tracking processor, or a payments processor.'],
|
||||
['Personal Data', 'Any information relating to an identified or identifiable natural person that is processed under the Agreement.'],
|
||||
['Processing', 'Any operation performed on personal data, including collection, storage, transmission, analysis, deletion, and similar actions.'],
|
||||
['Data Subject', 'The natural person whose personal data is being processed.'],
|
||||
['Personal Data Breach', 'A confirmed security incident that leads to the accidental or unlawful destruction, loss, alteration, unauthorised disclosure of, or access to personal data processed under this DPA.'],
|
||||
['Data Protection Laws', 'All laws and regulations that apply to the parties’ processing of personal data under this DPA, including the EU GDPR, UK GDPR, the UK Data Protection Act 2018, the Swiss FADP, the California Consumer Privacy Act as amended, and any successor or equivalent statute.'],
|
||||
['Standard Contractual Clauses (SCCs)', 'The European Commission’s Standard Contractual Clauses for the transfer of personal data to third countries, in their then-current form approved by the European Commission.'],
|
||||
['UK IDTA', 'The United Kingdom International Data Transfer Agreement, together with the UK Addendum to the SCCs, as published by the Information Commissioner’s Office.'],
|
||||
];
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Annex 1: Processing details. Mirrors the structure mandated by the
|
||||
// SCCs Annex I but kept readable.
|
||||
// -----------------------------------------------------------------
|
||||
const annex1: Array<[string, string]> = [
|
||||
['Subject matter', 'Processing of personal data in connection with the email warmup, cold outreach, deliverability monitoring, and related services that Warmbly makes available under the Agreement.'],
|
||||
['Duration', 'For the term of the Agreement and any wind-down period set out in the Privacy Policy or the Terms.'],
|
||||
['Nature', 'Hosting, storage, transmission, indexing, analytics, deliverability scoring, and routine maintenance of Customer Data through the Warmbly platform.'],
|
||||
['Purpose', 'Providing the platform to Customer, including sending and receiving email, syncing mailbox state, tracking opens and clicks, generating warmup activity, and surfacing analytics back to Customer.'],
|
||||
['Frequency', 'Continuous for the duration of the Agreement.'],
|
||||
['Data subjects', 'Customer’s authorised users, Customer’s contacts and recipients, and any other natural persons whose personal data Customer chooses to upload or process through the platform.'],
|
||||
['Categories', 'Identifiers (name, email address, IP address), professional contact information (company, role, phone), message content (subject lines, bodies, attachments), and behavioural signals (opens, clicks, replies, bounces, suppression status).'],
|
||||
['Special categories', 'None requested by Warmbly. Customer must not upload special category data, government identifiers, payment card data, or children’s data through the platform.'],
|
||||
['Recipients', 'Warmbly personnel acting under confidentiality obligations and the approved sub-processors listed at /subprocessors/.'],
|
||||
['Retention', 'For the term of the Agreement plus the retention windows set out in the Privacy Policy. Customer can delete records earlier from within the product.'],
|
||||
];
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Annex 2: Security measures. Short, factual, mapped to what is
|
||||
// actually implemented in this repo.
|
||||
// -----------------------------------------------------------------
|
||||
const annex2 = [
|
||||
{
|
||||
cat: 'Encryption',
|
||||
items: [
|
||||
'Envelope encryption rooted in AWS KMS. A unique 32-byte Data Encryption Key (DEK) is generated per customer and never stored in plaintext at rest.',
|
||||
'Sensitive payloads (mailbox credentials, message bodies, OAuth tokens) are sealed with AES-256-GCM using the customer’s DEK.',
|
||||
'Decrypted DEKs are cached in Redis with a strict TTL so the plaintext key is not held in memory longer than required.',
|
||||
'TLS 1.2 or higher in transit for all customer-facing endpoints and inter-service traffic.',
|
||||
],
|
||||
},
|
||||
{
|
||||
cat: 'Access control',
|
||||
items: [
|
||||
'Role-based access control across the application surface, with workspace, organisation, and admin scopes.',
|
||||
'Single sign-on and short-lived credentials for production access. No shared accounts.',
|
||||
'Least-privilege IAM for backend, consumer, worker, tracking, and realtime services.',
|
||||
'Audit logs of administrative actions, ban events, rate-limit overrides, and key rotations.',
|
||||
],
|
||||
},
|
||||
{
|
||||
cat: 'Isolation and integrity',
|
||||
items: [
|
||||
'Workers run as stateless executors. They do not hold direct SQL access to the control-plane database.',
|
||||
'Tenant isolation enforced at the application layer, with workspace identifiers carried on every query and event.',
|
||||
'Idempotency keys on deliverability events and webhook handlers protect against replay and duplicate processing.',
|
||||
],
|
||||
},
|
||||
{
|
||||
cat: 'Operational security',
|
||||
items: [
|
||||
'Rolling encrypted backups of the control-plane database. Restore tested on a documented cadence.',
|
||||
'Vulnerability monitoring across application dependencies, container base images, and infrastructure.',
|
||||
'Documented incident response process, with breach notification triggers and on-call rotation.',
|
||||
'Personnel security training, background checks where lawful, and signed confidentiality obligations.',
|
||||
],
|
||||
},
|
||||
{
|
||||
cat: 'Anti-abuse controls',
|
||||
items: [
|
||||
'CAPTCHA on authentication-sensitive flows, including login, registration, password reset, and confirmation.',
|
||||
'Per-user API rate limiting and websocket rate limiting backed by Redis.',
|
||||
'Warmup token verification with spam-score tracking and auto-blocking of mailboxes from shared pools.',
|
||||
'Mailbox-sync abuse detection on workers, with burst and hourly thresholds.',
|
||||
],
|
||||
},
|
||||
];
|
||||
---
|
||||
<Layout
|
||||
title="Data processing addendum · Warmbly"
|
||||
description="The DPA between Warmbly (Processor) and Customer (Controller), governing how Warmbly processes personal data on behalf of customers."
|
||||
>
|
||||
<!-- ============================================================
|
||||
HERO
|
||||
============================================================ -->
|
||||
<section class="relative isolate overflow-hidden">
|
||||
<HeroAtmosphere />
|
||||
|
||||
<div class="container-page relative pt-14 md:pt-20 pb-16 md:pb-20">
|
||||
<div class="max-w-3xl">
|
||||
<div class="inline-flex items-center gap-2 h-7 pl-1 pr-3 rounded-full bg-white/15 backdrop-blur ring-1 ring-white/25 text-[12px] text-white/95 shadow-[0_4px_14px_-4px_rgba(0,0,0,0.25)]">
|
||||
<span class="inline-flex items-center h-5 px-1.5 rounded-full text-[10.5px] font-semibold uppercase tracking-[0.06em] bg-white" style="color:#0369a1;">Legal</span>
|
||||
Data processing
|
||||
</div>
|
||||
|
||||
<h1 class="mt-8 text-[40px] sm:text-5xl md:text-[60px] lg:text-[68px] font-semibold tracking-[-0.035em] leading-[1.0] text-white">
|
||||
Data processing<br/>addendum.
|
||||
</h1>
|
||||
|
||||
<p class="mt-6 text-[16.5px] md:text-[18px] text-white/85 max-w-2xl leading-relaxed">
|
||||
This addendum applies between Warmbly, acting as Processor, and the Customer, acting as Controller. It is incorporated by reference into the Warmbly Terms of Service and governs how Warmbly processes personal data on Customer’s behalf.
|
||||
</p>
|
||||
|
||||
<div class="mt-8 flex flex-wrap items-center gap-3">
|
||||
<div class="inline-flex items-center gap-2 h-9 px-3 rounded-[10px] bg-white/10 backdrop-blur ring-1 ring-white/30 text-[13px] text-white/95">
|
||||
<span class="text-[10.5px] uppercase tracking-[0.16em] font-mono text-white/65">Last updated</span>
|
||||
<span class="font-mono text-white">{LAST_UPDATED}</span>
|
||||
</div>
|
||||
<a
|
||||
href="#"
|
||||
class="inline-flex h-9 items-center gap-2 px-4 rounded-[10px] text-[13px] font-medium bg-white text-[#075985] hover:-translate-y-0.5 transition-all duration-200 ease-out shadow-[0_4px_14px_-2px_rgba(0,0,0,0.18)]"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="7 10 12 15 17 10"/>
|
||||
<line x1="12" y1="15" x2="12" y2="3"/>
|
||||
</svg>
|
||||
Download as PDF
|
||||
</a>
|
||||
<a
|
||||
href="/terms/"
|
||||
class="inline-flex h-9 items-center px-4 rounded-[10px] text-[13px] font-medium bg-white/10 backdrop-blur ring-1 ring-white/30 text-white hover:bg-white/20 hover:-translate-y-0.5 transition-all duration-200 ease-out"
|
||||
>
|
||||
Read the Terms
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================
|
||||
BODY
|
||||
============================================================ -->
|
||||
<section class="py-12 md:py-16">
|
||||
<div class="container-page grid grid-cols-1 lg:grid-cols-12 gap-10 lg:gap-12">
|
||||
|
||||
<!-- Sidebar TOC ----------------------------------------- -->
|
||||
<aside class="lg:col-span-3">
|
||||
<div class="lg:sticky lg:top-24">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-4">
|
||||
On this page
|
||||
</div>
|
||||
<nav>
|
||||
<ol class="space-y-0.5">
|
||||
{toc.map((s) => (
|
||||
<li>
|
||||
<a
|
||||
href={`#${s.id}`}
|
||||
class="group flex items-baseline gap-2.5 -mx-2 px-2 py-1.5 rounded-md text-[13px] leading-snug text-muted-foreground hover:text-foreground hover:bg-[color:var(--surface-2)]/60 transition-colors"
|
||||
>
|
||||
<span class="font-mono text-[10.5px] text-muted-foreground/70 group-hover:text-[#0369a1] tabular-nums">{s.num}</span>
|
||||
<span class="flex-1">{s.label}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="mt-8 pt-6 border-t border-[color:var(--border)]">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">
|
||||
Related
|
||||
</div>
|
||||
<ul class="space-y-1">
|
||||
<li><a href="/terms/" class="text-[13px] text-muted-foreground hover:text-[color:var(--brand)]">Terms of Service</a></li>
|
||||
<li><a href="/privacy/" class="text-[13px] text-muted-foreground hover:text-[color:var(--brand)]">Privacy Policy</a></li>
|
||||
<li><a href="/subprocessors/" class="text-[13px] text-muted-foreground hover:text-[color:var(--brand)]">Sub-processors</a></li>
|
||||
<li><a href="/trust/" class="text-[13px] text-muted-foreground hover:text-[color:var(--brand)]">Trust and security</a></li>
|
||||
<li><a href="/acceptable-use/" class="text-[13px] text-muted-foreground hover:text-[color:var(--brand)]">Acceptable Use Policy</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main content ---------------------------------------- -->
|
||||
<article class="lg:col-span-9 max-w-3xl">
|
||||
|
||||
<!-- Lead-in -->
|
||||
<div class="pb-8 mb-10 border-b border-[color:var(--border)]">
|
||||
<p class="text-[15.5px] leading-relaxed text-foreground/85">
|
||||
This Data Processing Addendum (the <strong>"DPA"</strong>) supplements the Warmbly <a href="/terms/" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">Terms of Service</a> (the <strong>"Agreement"</strong>) between Warmbly and the Customer. It governs the processing of Personal Data by Warmbly as Processor on behalf of the Customer as Controller in connection with the Warmbly platform. This DPA takes effect on the date the Customer accepts the Agreement, or, if later, on the date this DPA is countersigned.
|
||||
</p>
|
||||
<p class="mt-4 text-[15.5px] leading-relaxed text-foreground/85">
|
||||
Capitalised terms not defined here have the meanings given in the Agreement or, where applicable, in the Data Protection Laws. To the extent there is a conflict with the Agreement on a data protection matter, this DPA controls.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 01 Definitions -->
|
||||
<section id="definitions" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">01</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Definitions</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85 mb-5">
|
||||
The following terms have the meanings set out below. Where a term is also defined in applicable Data Protection Laws, the statutory meaning prevails to the extent required.
|
||||
</p>
|
||||
<dl class="divide-y divide-[color:var(--border)] rounded-xl ring-1 ring-[color:var(--border)] bg-white overflow-hidden">
|
||||
{definitions.map(([term, body]) => (
|
||||
<div class="grid grid-cols-1 md:grid-cols-[200px_minmax(0,1fr)] gap-1 md:gap-6 px-5 py-4">
|
||||
<dt class="text-[13.5px] font-semibold text-heading">{term}</dt>
|
||||
<dd class="text-[14px] leading-relaxed text-foreground/80">{body}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<!-- 02 Scope and roles -->
|
||||
<section id="scope-roles" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">02</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Scope and roles</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
This DPA applies wherever Warmbly processes Personal Data on Customer’s behalf in the course of providing the platform. In that processing, Customer is the Controller and Warmbly is the Processor. Each party will comply with the Data Protection Laws that apply to it in its respective role.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Customer is responsible for the lawfulness of the Personal Data it uploads, imports, or sends through the platform, for having a valid legal basis for processing, and for providing any notices and obtaining any consents required from Data Subjects. Warmbly is responsible for processing that Personal Data only as described in this DPA and on Customer’s instructions.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Where Warmbly determines the means and purposes of processing, for example for billing, fraud prevention, abuse detection, security telemetry, or aggregated product analytics, Warmbly acts as an independent Controller for that processing and the Warmbly <a href="/privacy/" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">Privacy Policy</a> applies.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 03 Subject matter and duration -->
|
||||
<section id="processing" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">03</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Subject matter, nature, purpose, and duration</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
The subject matter, nature, and purpose of the processing are the operation and provision of the Warmbly platform to Customer, as described in the Agreement and in <a href="#annex-1" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">Annex 1</a>.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
The duration of processing is the term of the Agreement plus the wind-down and retention periods described in the Privacy Policy and in this DPA. Customer can shorten that duration at any time by deleting records from within the product or by terminating the Agreement.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 04 Categories of data subjects -->
|
||||
<section id="data-subjects" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">04</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Categories of data subjects</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85 mb-4">
|
||||
The Personal Data processed under this DPA concerns the following categories of Data Subjects:
|
||||
</p>
|
||||
<ul class="space-y-2.5 text-[14.5px] leading-relaxed text-foreground/85 pl-5 list-disc">
|
||||
<li>Customer’s authorised users and team members who access the platform.</li>
|
||||
<li>Customer’s contacts, leads, and recipients to whom Customer sends mail through the platform.</li>
|
||||
<li>Senders and recipients of replies received in Customer’s connected mailboxes.</li>
|
||||
<li>Other natural persons whose Personal Data Customer chooses to upload, import, or otherwise process through the platform.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- 05 Categories of personal data -->
|
||||
<section id="data-categories" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">05</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Categories of personal data</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85 mb-4">
|
||||
The categories of Personal Data processed include:
|
||||
</p>
|
||||
<ul class="space-y-2.5 text-[14.5px] leading-relaxed text-foreground/85 pl-5 list-disc">
|
||||
<li><strong>Identifiers.</strong> Names, email addresses, IP addresses, user-agent strings.</li>
|
||||
<li><strong>Professional contact information.</strong> Company name, job title, phone number, social profile links, and similar business contact attributes Customer chooses to import.</li>
|
||||
<li><strong>Message content.</strong> Subject lines, message bodies, attachments, signatures, and metadata of mail sent or received through Customer’s connected mailboxes.</li>
|
||||
<li><strong>Behavioural signals.</strong> Open events, click events, replies, bounces, unsubscribes, suppression status, and warmup activity.</li>
|
||||
<li><strong>Authentication and configuration data.</strong> OAuth tokens, SMTP credentials, send-rate settings, and mailbox health state, stored using envelope encryption.</li>
|
||||
</ul>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Customer must not upload special categories of Personal Data, government-issued identifiers, payment card data, or data relating to children to the platform. The platform is not designed for that data, and Customer remains responsible if it does so.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 06 Customer instructions -->
|
||||
<section id="instructions" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">06</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Customer instructions</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly processes Personal Data only on documented instructions from Customer, including the instructions Customer issues by configuring and using the platform itself, unless required to process by applicable law. If Warmbly is required by law to process Personal Data outside Customer’s instructions, Warmbly will inform Customer of that requirement before processing, unless the law prohibits that notice on important grounds of public interest.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly will notify Customer if, in its opinion, an instruction infringes the Data Protection Laws. Warmbly may then suspend the affected processing until Customer modifies or confirms the instruction in writing.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 07 Confidentiality -->
|
||||
<section id="confidentiality" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">07</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Confidentiality and personnel</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly limits access to Personal Data to personnel who need it to perform the Agreement. Those personnel are bound by written confidentiality obligations or are under an appropriate statutory obligation of confidentiality. Warmbly trains its personnel on data protection and security responsibilities and applies role-based access control to production systems.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 08 Security measures -->
|
||||
<section id="security" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">08</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Security measures</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly implements and maintains appropriate technical and organisational measures designed to protect Personal Data against accidental or unlawful destruction, loss, alteration, unauthorised disclosure, or access. Those measures are summarised in <a href="#annex-2" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">Annex 2</a> and described in more detail at <a href="/trust/" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">trust and security</a>.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
In summary, sensitive Personal Data is protected by envelope encryption. AWS KMS acts as the root of trust. Each customer is issued a per-customer Data Encryption Key (DEK). DEKs are never stored in plaintext at rest. Sensitive payloads are sealed with AES-256-GCM using the DEK, and the encrypted blobs are stored in dedicated infrastructure. Plaintext DEKs are cached in Redis with a strict TTL so they are not held in memory longer than required. All inter-service and customer-facing traffic uses TLS 1.2 or higher. Access is governed by role-based access control with audit logging of administrative actions.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly reviews and updates its security measures over time. Warmbly may replace a security measure with one that provides an equivalent or higher level of protection, but will not materially reduce the overall protection of Personal Data without Customer’s consent.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 09 Sub-processors -->
|
||||
<section id="subprocessors" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">09</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Sub-processors</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Customer provides general written authorisation for Warmbly to engage Sub-processors to process Personal Data on Customer’s behalf for the purposes described in the Agreement. The current list of approved Sub-processors is published at <a href="/subprocessors/" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">/subprocessors</a>.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly will give Customer at least 30 days’ prior notice of any addition or replacement of a Sub-processor by updating the Sub-processors page and by providing an in-product notice. Customer may object to a new Sub-processor on reasonable data-protection grounds by notifying Warmbly during that 30-day period. If the parties are unable in good faith to reach a workable solution, Customer may terminate the affected services on written notice and receive a pro-rata refund of pre-paid fees for the unused term.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly enters into written agreements with each Sub-processor that impose data protection obligations no less protective than those in this DPA. Warmbly remains liable to Customer for the performance of each Sub-processor’s obligations to the extent required by the Data Protection Laws.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 10 International transfers -->
|
||||
<section id="transfers" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">10</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">International data transfers</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Where Personal Data subject to the EU GDPR is transferred from the European Economic Area to a country that has not been recognised by the European Commission as providing an adequate level of protection, the parties agree that such transfer is governed by the Standard Contractual Clauses (Module Two: Controller to Processor), which are hereby incorporated into this DPA by reference. The annexes to the SCCs are populated using the information in <a href="#annex-1" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">Annex 1</a>, <a href="#annex-2" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">Annex 2</a>, and <a href="#annex-3" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">Annex 3</a> of this DPA.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Where Personal Data subject to the UK GDPR is transferred from the United Kingdom to a country that has not been recognised as providing an adequate level of protection, the parties agree that such transfer is governed by the UK International Data Transfer Agreement, together with the UK Addendum to the SCCs, which are hereby incorporated into this DPA by reference.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Where Personal Data subject to the Swiss Federal Act on Data Protection is transferred outside Switzerland to a country that has not been recognised as providing adequate protection, the SCCs apply with the adjustments published by the Swiss Federal Data Protection and Information Commissioner, including treating references to EU member-state law and supervisory authorities as references to Swiss law and the Swiss authority where relevant.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly assesses, on an ongoing basis, the laws and practices of countries to which Personal Data is transferred, and implements supplementary technical, organisational, and contractual measures where appropriate. Customer can request a summary of the current transfer impact assessment from <a href="mailto:legal@warmbly.com" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">legal@warmbly.com</a>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 11 Data subject rights -->
|
||||
<section id="rights" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">11</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Data subject rights assistance</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Taking into account the nature of the processing and the information available, Warmbly will assist Customer by appropriate technical and organisational measures to respond to requests by Data Subjects to exercise their rights under the Data Protection Laws, including rights of access, rectification, erasure, restriction, portability, and objection.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
The platform provides in-product tooling so Customer can read, edit, export, and delete Personal Data directly. Where a request cannot be satisfied through that tooling, Customer can contact <a href="mailto:legal@warmbly.com" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">legal@warmbly.com</a> for assistance. If a Data Subject contacts Warmbly directly, Warmbly will inform the Data Subject that the request should be directed to Customer, and will notify Customer without undue delay.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 12 Breach notification -->
|
||||
<section id="breach" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">12</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Personal data breach notification</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly will notify Customer without undue delay, and in any event within 72 hours of becoming aware, of a confirmed Personal Data Breach affecting Customer’s Personal Data. Notification will be made to the security or admin contact on file for the workspace, and in parallel by email to the billing contact where appropriate.
|
||||
</p>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85 mt-4 mb-3">
|
||||
The notification will, to the extent then known, include:
|
||||
</p>
|
||||
<ul class="space-y-2.5 text-[14.5px] leading-relaxed text-foreground/85 pl-5 list-disc">
|
||||
<li>The nature of the breach, including the categories and approximate number of Data Subjects and records concerned.</li>
|
||||
<li>The likely consequences of the breach.</li>
|
||||
<li>The measures Warmbly has taken or proposes to take to address the breach, including measures to mitigate its possible adverse effects.</li>
|
||||
<li>The name and contact details of a point of contact for further information.</li>
|
||||
</ul>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly will provide updates as additional information becomes available. Warmbly’s notification or response to a Personal Data Breach is not an acknowledgement of fault or liability.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 13 Audits -->
|
||||
<section id="audits" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">13</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Audits and inspections</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly will make available to Customer information reasonably necessary to demonstrate compliance with this DPA. On reasonable prior written notice, and no more than once in any twelve-month period, Customer may request a copy of the most recent third-party audit report, attestation, or summary held by Warmbly that relates to the platform.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Where a Data Protection Law or supervisory authority requires an on-site audit, the parties will agree in good faith on the scope, timing, and conditions of the audit, taking into account the need to safeguard the confidentiality and security of other customers and the integrity of the platform. Audits will be conducted during normal business hours, with reasonable steps to avoid disruption, by an auditor agreed between the parties, and under written confidentiality obligations. Customer is responsible for the costs of any audit it initiates, unless the audit reveals a material breach of this DPA by Warmbly.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 14 Return or deletion -->
|
||||
<section id="return-deletion" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">14</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Return or deletion at end of services</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
On termination or expiry of the Agreement, at Customer’s choice, Warmbly will return or delete the Personal Data processed under this DPA, unless the Data Protection Laws or another applicable law requires further storage. Customer can export Personal Data directly from the platform at any time during the term.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly will complete deletion within 30 days of termination, except for: backup copies, which are deleted on the rolling backup schedule documented in the Privacy Policy; records that Warmbly is legally required to retain, which are isolated and protected against further processing; and aggregated, deidentified data that does not identify Customer or any Data Subject.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 15 Liability -->
|
||||
<section id="liability" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">15</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Liability and limitations</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Each party’s aggregate liability arising out of or related to this DPA, whether in contract, tort, or under any other theory of liability, is subject to the limitations and exclusions of liability set out in the Agreement. Any reference in the Agreement to the liability of a party means the aggregate liability of that party under the Agreement and this DPA together.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Nothing in this DPA limits or excludes liability that cannot be limited or excluded under applicable law, including liability for Warmbly’s wilful misconduct or fraud, or, where applicable, the rights of Data Subjects under the SCCs.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 16 Order of precedence -->
|
||||
<section id="precedence" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">16</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Order of precedence and severability</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
In the event of any conflict between this DPA and the Agreement on a data protection matter, this DPA controls. Where the SCCs or the UK IDTA apply to a transfer, those instruments prevail over any conflicting terms of the Agreement or this DPA, to the extent required.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
If any provision of this DPA is held to be invalid or unenforceable, the remaining provisions will continue in full force and effect, and the parties will replace the invalid or unenforceable provision with a valid and enforceable provision that achieves, to the greatest extent possible, the same commercial and legal effect.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 17 Governing law -->
|
||||
<section id="governing-law" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">17</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Governing law</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
This DPA is governed by the law and subject to the jurisdiction specified in the Agreement, except that the SCCs, where they apply, are governed by the law of the EU member state designated in the SCCs themselves, and the UK IDTA, where it applies, is governed by the laws of England and Wales as required by that instrument. Where the Agreement does not specify a governing law, the parties will agree a governing law in good faith, taking into account the location of the Controller and the practical requirements of the Data Protection Laws.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 18 Annex 1 -->
|
||||
<section id="annex-1" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">18</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Annex 1 · Processing details</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85 mb-5">
|
||||
This Annex describes the processing carried out by Warmbly on behalf of Customer, in the format expected by the SCCs Annex I.B and equivalent UK and Swiss instruments.
|
||||
</p>
|
||||
<div class="overflow-hidden rounded-xl ring-1 ring-[color:var(--border)] bg-white">
|
||||
<table class="w-full text-[14px]">
|
||||
<thead class="bg-[color:var(--surface-2)]/70 text-[11.5px] uppercase tracking-[0.12em] font-mono text-muted-foreground">
|
||||
<tr>
|
||||
<th class="text-left font-semibold px-5 py-3 w-[200px]">Field</th>
|
||||
<th class="text-left font-semibold px-5 py-3">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[color:var(--border)]">
|
||||
{annex1.map(([field, body]) => (
|
||||
<tr>
|
||||
<td class="px-5 py-4 align-top text-[13.5px] font-semibold text-heading">{field}</td>
|
||||
<td class="px-5 py-4 align-top text-[14px] leading-relaxed text-foreground/80">{body}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 19 Annex 2 -->
|
||||
<section id="annex-2" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">19</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Annex 2 · Security measures</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85 mb-5">
|
||||
The technical and organisational measures Warmbly applies to the processing of Personal Data are summarised below. The current detailed control set is published at <a href="/trust/" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">trust and security</a>.
|
||||
</p>
|
||||
<div class="space-y-3">
|
||||
{annex2.map((group) => (
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-white overflow-hidden">
|
||||
<div class="flex items-center gap-2.5 px-5 py-3 border-b border-[color:var(--border)] bg-[color:var(--surface-2)]/60">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-[color:var(--brand)]"></span>
|
||||
<div class="text-[13px] font-semibold text-heading tracking-[-0.005em]">{group.cat}</div>
|
||||
</div>
|
||||
<ul class="divide-y divide-[color:var(--border)]">
|
||||
{group.items.map((item) => (
|
||||
<li class="px-5 py-3 text-[14px] leading-relaxed text-foreground/80">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 20 Annex 3 -->
|
||||
<section id="annex-3" class="scroll-mt-24 mb-14">
|
||||
<div class="flex items-baseline gap-3 mb-4">
|
||||
<span class="font-mono text-[12px] tracking-[0.18em] text-muted-foreground uppercase">20</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Annex 3 · Approved sub-processors</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
The current list of approved Sub-processors, including the processing they perform, the regions in which they operate, and the countries in which they store Personal Data, is published and maintained at <a href="/subprocessors/" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">/subprocessors</a>. That page is incorporated into this DPA by reference and forms part of Annex 3.
|
||||
</p>
|
||||
<div class="mt-5 rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-2)]/60 p-5">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.16em] font-mono text-muted-foreground mb-2">Subscribe to changes</div>
|
||||
<p class="text-[14px] leading-relaxed text-foreground/85">
|
||||
Email <a href="mailto:legal@warmbly.com?subject=Subprocessor%20updates" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">legal@warmbly.com</a> to receive notice of Sub-processor changes by email. Warmbly will give at least 30 days’ notice before any change that affects the processing of Customer Personal Data.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Closing block -->
|
||||
<div class="mt-16 pt-8 border-t border-[color:var(--border)]">
|
||||
<div class="rounded-2xl ring-1 ring-[color:var(--border)] bg-white p-6 md:p-7">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-2">Signatures</div>
|
||||
<p class="text-[14.5px] leading-relaxed text-foreground/85">
|
||||
This DPA is binding on the parties as soon as Customer accepts the Agreement. A counter-signed copy on Warmbly letterhead is available on request. Send any signature, audit, or transfer-mapping requests to <a href="mailto:legal@warmbly.com" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">legal@warmbly.com</a>.
|
||||
</p>
|
||||
<div class="mt-5 flex flex-wrap items-center gap-x-6 gap-y-2 text-[12px] font-mono text-muted-foreground">
|
||||
<span><span class="text-foreground/55">Version</span> <span class="text-foreground">2026.05.27</span></span>
|
||||
<span><span class="text-foreground/55">Last updated</span> <span class="text-foreground">{LAST_UPDATED}</span></span>
|
||||
<span><span class="text-foreground/55">Contact</span> <a href="mailto:legal@warmbly.com" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">legal@warmbly.com</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
@@ -41,7 +41,7 @@ const groups = [
|
||||
['Where is data stored?', 'AWS regions. us-east-1 by default, eu-west-1 on Grow and Business. Custom residency on Enterprise.'],
|
||||
['How is mailbox auth stored?', 'Refresh tokens are envelope-encrypted with per-user KMS-derived data keys. Decrypted keys are cached briefly in Redis, never persisted to disk.'],
|
||||
['Do you have SOC 2?', 'SOC 2 Type II audit is in progress. We can share the bridge letter once the report is issued.'],
|
||||
['Do you sign DPAs?', 'Yes. Email security@warmbly.com and we will turn it around within 48 hours.'],
|
||||
['Do you sign DPAs?', 'Yes. Email hello@warmbly.com and we will turn it around within 48 hours.'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
+143
-453
@@ -1,473 +1,163 @@
|
||||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import HeroAtmosphere from '../components/HeroAtmosphere.astro';
|
||||
|
||||
const lastUpdated = '2026-05-27';
|
||||
import Legal from '../layouts/Legal.astro';
|
||||
|
||||
const sections = [
|
||||
{ id: 'who-we-are', n: '01', label: 'Who we are' },
|
||||
{ id: 'data-we-collect', n: '02', label: 'Data we collect' },
|
||||
{ id: 'how-we-use-data', n: '03', label: 'How we use your data' },
|
||||
{ id: 'legal-bases', n: '04', label: 'Legal bases' },
|
||||
{ id: 'encryption-storage', n: '05', label: 'Encryption and storage' },
|
||||
{ id: 'subprocessors', n: '06', label: 'Subprocessors' },
|
||||
{ id: 'retention', n: '07', label: 'Data retention' },
|
||||
{ id: 'your-rights', n: '08', label: 'Your rights' },
|
||||
{ id: 'international', n: '09', label: 'International transfers' },
|
||||
{ id: 'cookies', n: '10', label: 'Cookies' },
|
||||
{ id: 'children', n: '11', label: "Children's data" },
|
||||
{ id: 'changes', n: '12', label: 'Changes to this policy' },
|
||||
{ id: 'contact', n: '13', label: 'Contact' },
|
||||
{ id: 'who', num: '01', title: 'Who we are' },
|
||||
{ id: 'scope', num: '02', title: 'Scope of this policy' },
|
||||
{ id: 'data', num: '03', title: 'Data we collect' },
|
||||
{ id: 'use', num: '04', title: 'How we use your data' },
|
||||
{ id: 'legal-basis', num: '05', title: 'Legal bases' },
|
||||
{ id: 'encryption', num: '06', title: 'Encryption and storage' },
|
||||
{ id: 'sharing', num: '07', title: 'Sharing with third parties' },
|
||||
{ id: 'retention', num: '08', title: 'Data retention' },
|
||||
{ id: 'rights', num: '09', title: 'Your rights' },
|
||||
{ id: 'transfers', num: '10', title: 'International transfers' },
|
||||
{ id: 'children', num: '11', title: 'Children' },
|
||||
{ id: 'changes', num: '12', title: 'Changes to this policy' },
|
||||
{ id: 'contact', num: '13', title: 'Contact' },
|
||||
];
|
||||
|
||||
const docs = [
|
||||
{ label: 'Terms of Service', href: '/terms/' },
|
||||
{ label: 'Privacy Policy', href: '/privacy/' },
|
||||
{ label: 'Data Processing Addendum', href: '/dpa/' },
|
||||
{ label: 'Acceptable Use', href: '/acceptable-use/' },
|
||||
{ label: 'Subprocessors', href: '/subprocessors/' },
|
||||
{ label: 'Cookies', href: '/cookies/' },
|
||||
];
|
||||
|
||||
const path = Astro.url.pathname;
|
||||
---
|
||||
<Layout
|
||||
title="Privacy Policy · Warmbly"
|
||||
description="What data Warmbly collects, why we collect it, where we store it, and the controls you have over your information."
|
||||
<Legal
|
||||
title="Privacy policy"
|
||||
description="What Warmbly collects, why, how it is protected, and the choices you have."
|
||||
effective="2026-05-27"
|
||||
updated="2026-05-27"
|
||||
sections={sections}
|
||||
>
|
||||
<!-- ============================================================
|
||||
HERO · HeroAtmosphere (shared)
|
||||
============================================================ -->
|
||||
<section class="relative isolate overflow-hidden print:hidden">
|
||||
<HeroAtmosphere />
|
||||
|
||||
<div class="container-page relative pt-14 md:pt-20 pb-28 md:pb-36">
|
||||
<div class="inline-flex items-center gap-2 h-7 pl-1 pr-3 rounded-full bg-white/15 backdrop-blur ring-1 ring-white/25 text-[12px] text-white/95 shadow-[0_4px_14px_-4px_rgba(0,0,0,0.25)]">
|
||||
<span class="inline-flex items-center h-5 px-1.5 rounded-full text-[10.5px] font-semibold uppercase tracking-[0.06em] bg-white" style="color:#0369a1;">
|
||||
Legal
|
||||
</span>
|
||||
Privacy Policy
|
||||
</div>
|
||||
<section id="who" class="scroll-mt-24">
|
||||
<h2>01. Who we are</h2>
|
||||
<p>
|
||||
Warmbly is operated by Mindroot Ltd, a company registered in England and Wales with company number 16543299. Our registered office is at 71-75 Shelton Street, London, England, WC2H 9JQ. We are the data controller for the personal data we collect about you as a user of Warmbly.
|
||||
</p>
|
||||
<p>
|
||||
For your customers' data that you process through Warmbly, you are the controller and we act as a processor on your behalf, governed by the data processing terms we agree with you.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<h1 class="mt-7 md:mt-9 text-[44px] sm:text-6xl md:text-[72px] font-semibold tracking-[-0.04em] leading-[0.98] text-white max-w-3xl">
|
||||
Privacy.
|
||||
</h1>
|
||||
<section id="scope" class="scroll-mt-24">
|
||||
<h2>02. Scope of this policy</h2>
|
||||
<p>
|
||||
This policy describes how Mindroot Ltd handles personal data through the Warmbly platform, including the marketing website, the web application, the APIs, the workers, and any related services. It does not cover third-party services that you connect to Warmbly, which are governed by their own privacy policies.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<p class="mt-6 text-[17px] md:text-[19px] text-white/80 max-w-2xl leading-relaxed">
|
||||
What we collect, why we need it, where it lives, and what you can ask us to do with it. Plain English, no dark patterns.
|
||||
</p>
|
||||
<section id="data" class="scroll-mt-24">
|
||||
<h2>03. Data we collect</h2>
|
||||
<h3>Account data</h3>
|
||||
<ul>
|
||||
<li>Name and email address you sign up with.</li>
|
||||
<li>Workspace name and role assignments.</li>
|
||||
<li>Billing identifiers provided by our payment processor Stripe. We do not see or store full card numbers.</li>
|
||||
</ul>
|
||||
<h3>Mailbox data</h3>
|
||||
<ul>
|
||||
<li>OAuth refresh and access tokens, or encrypted IMAP and SMTP credentials, for mailboxes you connect.</li>
|
||||
<li>Mailbox metadata such as folder structure, authentication status, and sender identity.</li>
|
||||
</ul>
|
||||
<h3>Message data</h3>
|
||||
<ul>
|
||||
<li>Cold outreach messages, warmup messages, and replies that pass through Warmbly.</li>
|
||||
<li>Recipient addresses and contact records you upload or import.</li>
|
||||
<li>Tracking events such as opens, clicks, bounces, complaints, and unsubscribes.</li>
|
||||
</ul>
|
||||
<h3>Usage data</h3>
|
||||
<ul>
|
||||
<li>Logs, error reports, and session events generated by your use of the Service.</li>
|
||||
<li>Limited diagnostic information such as user agent, IP address, and request timing, retained for security and abuse prevention.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<div class="mt-8 flex flex-wrap items-center gap-3">
|
||||
<div class="inline-flex items-center gap-2 h-9 px-3 rounded-full bg-white/12 backdrop-blur ring-1 ring-white/20 text-[12.5px] font-mono text-white/85">
|
||||
<span class="inline-block w-1.5 h-1.5 rounded-full bg-emerald-300"></span>
|
||||
Last updated {lastUpdated}
|
||||
</div>
|
||||
<a href="#data-we-collect" class="inline-flex items-center gap-1.5 h-9 px-3.5 rounded-full bg-white/10 hover:bg-white/15 ring-1 ring-white/20 text-[12.5px] text-white/90 transition-colors">
|
||||
Jump to data we collect
|
||||
<span aria-hidden="true">↓</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="use" class="scroll-mt-24">
|
||||
<h2>04. How we use your data</h2>
|
||||
<ul>
|
||||
<li>To operate, maintain, and improve the Service.</li>
|
||||
<li>To send mail and warmup traffic on your behalf through your connected mailboxes.</li>
|
||||
<li>To compute deliverability and mailbox health signals such as warmup spam scores, suppression lists, and per-mailbox health states.</li>
|
||||
<li>To prevent abuse, fraud, and breach of our acceptable use rules.</li>
|
||||
<li>To bill you and to keep accurate financial records.</li>
|
||||
<li>To respond to support requests and to communicate service updates.</li>
|
||||
<li>To comply with legal obligations.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================
|
||||
PRINT HEADER · only visible when printed
|
||||
============================================================ -->
|
||||
<header class="hidden print:block px-6 pt-8 pb-4 border-b border-[color:var(--border)]">
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-2">Warmbly Legal</div>
|
||||
<h1 class="text-[28px] font-semibold tracking-[-0.02em] text-heading">Privacy Policy</h1>
|
||||
<div class="mt-1 text-[12px] font-mono text-muted-foreground">Last updated {lastUpdated}</div>
|
||||
</header>
|
||||
<section id="legal-basis" class="scroll-mt-24">
|
||||
<h2>05. Legal bases for processing</h2>
|
||||
<ul>
|
||||
<li><strong>Contract.</strong> Processing necessary to deliver the Service you have signed up for.</li>
|
||||
<li><strong>Legitimate interest.</strong> Processing necessary to keep the platform secure, to prevent abuse, and to improve our product.</li>
|
||||
<li><strong>Consent.</strong> Where required, for optional features such as product analytics or marketing emails.</li>
|
||||
<li><strong>Legal obligation.</strong> Processing required to comply with applicable law, including tax, accounting, and lawful requests from authorities.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================
|
||||
BODY · sticky TOC + numbered sections
|
||||
============================================================ -->
|
||||
<section class="container-page py-14 md:py-20">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-10 lg:gap-14">
|
||||
<section id="encryption" class="scroll-mt-24">
|
||||
<h2>06. Encryption and storage</h2>
|
||||
<p>
|
||||
Sensitive credentials and message payloads are protected using envelope encryption. AWS Key Management Service is the root of trust. Each user gets a 32-byte data encryption key (DEK), generated by KMS. The encrypted DEK ciphertext is stored in DynamoDB. The plaintext DEK is held only in memory, cached briefly in Redis with a short time-to-live, and used to encrypt and decrypt fields at the application layer with AES-256-GCM.
|
||||
</p>
|
||||
<p>
|
||||
Control-plane state lives in PostgreSQL. Object storage uses S3. Workers do not hold a PostgreSQL connection and operate over Kafka, KMS, DynamoDB, S3, and Redis only. All traffic between you and Warmbly is protected in transit by TLS 1.2 or higher.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- TOC sidebar -->
|
||||
<aside class="lg:col-span-3 print:hidden">
|
||||
<div class="lg:sticky lg:top-24">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-3">On this page</div>
|
||||
<nav aria-label="Privacy Policy sections">
|
||||
<ol class="space-y-0.5">
|
||||
{sections.map((s) => (
|
||||
<li>
|
||||
<a
|
||||
href={`#${s.id}`}
|
||||
class="group flex items-baseline gap-2.5 text-[13px] -mx-2 px-2 py-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-[color:var(--surface-2)]/60 transition-colors"
|
||||
>
|
||||
<span class="font-mono text-[10.5px] text-muted-foreground/70 group-hover:text-foreground/70 tabular-nums">{s.n}</span>
|
||||
<span>{s.label}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</nav>
|
||||
<section id="sharing" class="scroll-mt-24">
|
||||
<h2>07. Sharing with third parties</h2>
|
||||
<p>
|
||||
We share personal data with infrastructure and operational providers that we depend on to run Warmbly. These include AWS for compute, storage, encryption, and queues, Cloudflare for edge security and bot protection, Stripe for billing, and the email providers you connect to Warmbly.
|
||||
</p>
|
||||
<p>
|
||||
We do not sell personal data. We do not share personal data with advertisers. We will disclose personal data when required by law, when we have your consent, or when necessary to investigate or stop abuse.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="mt-8 pt-6 border-t border-[color:var(--border)]">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-3">Related</div>
|
||||
<ul class="space-y-0.5">
|
||||
{docs.map((d) => (
|
||||
<li>
|
||||
<a
|
||||
href={d.href}
|
||||
class={
|
||||
'block text-[13px] -mx-2 px-2 py-1.5 rounded-md transition-colors ' +
|
||||
(path === d.href
|
||||
? 'bg-[color:var(--surface-2)] text-foreground font-medium'
|
||||
: 'text-muted-foreground hover:text-foreground hover:bg-[color:var(--surface-2)]/60')
|
||||
}
|
||||
>
|
||||
{d.label}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<section id="retention" class="scroll-mt-24">
|
||||
<h2>08. Data retention</h2>
|
||||
<ul>
|
||||
<li>Account data is retained while your account is active and for a reasonable period after closure to allow recovery and to comply with our legal obligations.</li>
|
||||
<li>Mailbox credentials are deleted promptly when you disconnect a mailbox or close your account.</li>
|
||||
<li>Message and tracking data are deleted on a defined schedule after account closure, except where retention is required by law.</li>
|
||||
<li>Suppression lists are retained for as long as needed to honour unsubscribe and complaint requests on your behalf.</li>
|
||||
<li>Billing records are retained for the period required by applicable accounting and tax law.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<article class="lg:col-span-9 max-w-3xl">
|
||||
<!-- Lead -->
|
||||
<div class="pb-8 mb-10 border-b border-[color:var(--border)]">
|
||||
<p class="text-[16px] md:text-[17px] leading-relaxed text-foreground/85">
|
||||
Warmbly is an open-source email warmup and cold outreach platform. Running the service means we handle account information, mailbox credentials, message bodies, and recipient lists on your behalf. This page explains how that works, where the data goes, and what you can ask us to do with it.
|
||||
</p>
|
||||
<p class="mt-4 text-[14px] text-muted-foreground">
|
||||
We use simple language on purpose. If anything here is unclear, write to <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]" href="mailto:privacy@warmbly.com">privacy@warmbly.com</a> and we will rewrite it.
|
||||
</p>
|
||||
</div>
|
||||
<section id="rights" class="scroll-mt-24">
|
||||
<h2>09. Your rights</h2>
|
||||
<p>
|
||||
Subject to applicable law, you have the right to access, rectify, delete, restrict, port, and object to processing of your personal data. You also have the right to withdraw consent where consent is the basis for processing, and the right to lodge a complaint with a supervisory authority.
|
||||
</p>
|
||||
<p>
|
||||
The UK supervisory authority is the Information Commissioner's Office. You can exercise your rights by emailing <a href="mailto:hello@warmbly.com">hello@warmbly.com</a>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="who-we-are" class="scroll-mt-24 mt-12 first:mt-0">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">01</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Who we are</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly is the operator of the Warmbly email warmup and cold outreach platform. When you use the service we are the controller of the personal data we collect from you about your account, and we are the processor of the data you bring into the platform about your contacts and recipients.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
Privacy questions, data subject requests, and security reports all go to <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] underline-offset-2 hover:underline" href="mailto:privacy@warmbly.com">privacy@warmbly.com</a>. We try to acknowledge within two business days.
|
||||
</p>
|
||||
</section>
|
||||
<section id="transfers" class="scroll-mt-24">
|
||||
<h2>10. International transfers</h2>
|
||||
<p>
|
||||
Warmbly is operated from the United Kingdom and processes data through infrastructure providers that operate globally. Where personal data is transferred outside the UK or the European Economic Area, we rely on appropriate safeguards such as the UK International Data Transfer Agreement, the EU Standard Contractual Clauses, or adequacy decisions where they apply.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="data-we-collect" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">02</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Data we collect</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
We collect the smallest set of information we need to run the product, bill it, and keep it safe to use. Roughly four buckets.
|
||||
</p>
|
||||
<section id="children" class="scroll-mt-24">
|
||||
<h2>11. Children</h2>
|
||||
<p>
|
||||
Warmbly is a business tool and is not intended for use by children. We do not knowingly collect personal data from anyone under 16. If you believe a child has provided personal data to Warmbly, please contact us and we will remove it.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="mt-6 grid gap-4">
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] p-5">
|
||||
<div class="flex items-baseline justify-between gap-3">
|
||||
<h3 class="text-[15.5px] font-semibold text-heading">Account data</h3>
|
||||
<span class="text-[10.5px] font-mono uppercase tracking-[0.12em] text-muted-foreground">Controller</span>
|
||||
</div>
|
||||
<p class="mt-2 text-[14.5px] leading-relaxed text-foreground/85">
|
||||
Your email address, name, workspace name, password hash, role, and team membership. If you pay us, Stripe handles the card details and gives us back a customer identifier, the country we should charge tax in, and the last four digits for receipts.
|
||||
</p>
|
||||
</div>
|
||||
<section id="changes" class="scroll-mt-24">
|
||||
<h2>12. Changes to this policy</h2>
|
||||
<p>
|
||||
We may update this privacy policy from time to time. The "Last updated" date at the top of this page reflects the most recent change. If we make material changes, we will notify you by email or through the Service before they take effect.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] p-5">
|
||||
<div class="flex items-baseline justify-between gap-3">
|
||||
<h3 class="text-[15.5px] font-semibold text-heading">Mailbox data</h3>
|
||||
<span class="text-[10.5px] font-mono uppercase tracking-[0.12em] text-muted-foreground">Processor</span>
|
||||
</div>
|
||||
<p class="mt-2 text-[14.5px] leading-relaxed text-foreground/85">
|
||||
The mailboxes you connect, and the credentials needed to send and receive on your behalf. For Google and Microsoft, that is an OAuth refresh token scoped to the permissions you grant during sign-in. For generic providers, it is the IMAP and SMTP host, port, and username, plus an encrypted copy of the password. Credentials are sealed with envelope encryption before they touch persistent storage.
|
||||
</p>
|
||||
</div>
|
||||
<section id="contact" class="scroll-mt-24">
|
||||
<h2>13. Contact</h2>
|
||||
<p>
|
||||
For privacy questions, data subject requests, or any other matter arising under this policy, email <a href="mailto:hello@warmbly.com">hello@warmbly.com</a> or write to Mindroot Ltd, 71-75 Shelton Street, London, England, WC2H 9JQ.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] p-5">
|
||||
<div class="flex items-baseline justify-between gap-3">
|
||||
<h3 class="text-[15.5px] font-semibold text-heading">Message data</h3>
|
||||
<span class="text-[10.5px] font-mono uppercase tracking-[0.12em] text-muted-foreground">Processor</span>
|
||||
</div>
|
||||
<p class="mt-2 text-[14.5px] leading-relaxed text-foreground/85">
|
||||
The campaigns you send, the warmup mail the platform generates on your behalf, replies and bounces synced back from the mailbox, attachments where you choose to use them, and the tracking events we record when a recipient opens an email or clicks a link. Message bodies are stored encrypted where the design calls for it, and message content is not used to train models.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] p-5">
|
||||
<div class="flex items-baseline justify-between gap-3">
|
||||
<h3 class="text-[15.5px] font-semibold text-heading">Usage data</h3>
|
||||
<span class="text-[10.5px] font-mono uppercase tracking-[0.12em] text-muted-foreground">Controller</span>
|
||||
</div>
|
||||
<p class="mt-2 text-[14.5px] leading-relaxed text-foreground/85">
|
||||
Server logs, request paths, IP addresses, user agent strings, error reports, and session events. We need this to operate the service, debug problems, rate limit abusive clients, and investigate security incidents. We do not use it to build advertising profiles.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="how-we-use-data" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">03</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">How we use your data</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
We use the data above to do the things you actually signed up for, and a small number of things you would reasonably expect a sending platform to do.
|
||||
</p>
|
||||
|
||||
<ul class="mt-5 space-y-3">
|
||||
{[
|
||||
['Operate the service', 'Send the campaigns and warmup mail you scheduled, sync replies, classify them, and surface the results in your inbox and dashboards.'],
|
||||
['Prevent abuse', 'Detect spammy patterns, throttle bad actors, enforce per-mailbox rate limits, and protect shared warmup pools from accounts that damage everyone else\'s reputation.'],
|
||||
['Deliverability analytics', 'Aggregate signals like bounces, complaints, opens, and reply sentiment so you can see how a mailbox is doing and so we can spot platform-wide issues early.'],
|
||||
['Billing', 'Track plan, seats, and connected mailboxes, generate invoices through Stripe, and apply any tax we are required to collect.'],
|
||||
['Support', 'Respond to your messages, debug your account when you ask us to, and follow up on incidents.'],
|
||||
['Compliance', 'Keep the records the law requires us to keep, respond to lawful requests, and document our security and privacy controls.'],
|
||||
].map(([k, v]) => (
|
||||
<li class="flex gap-3">
|
||||
<span class="mt-1.5 inline-block w-1.5 h-1.5 rounded-full bg-[color:var(--brand)] shrink-0" aria-hidden="true"></span>
|
||||
<div>
|
||||
<span class="text-[14.5px] font-semibold text-heading">{k}.</span>
|
||||
<span class="text-[14.5px] text-foreground/85 leading-relaxed"> {v}</span>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<p class="mt-5 text-[14.5px] text-foreground/85 leading-relaxed">
|
||||
We do not sell personal information. We do not rent contact lists. We do not share message content with advertisers.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="legal-bases" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">04</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Legal bases for processing</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Where data protection law requires a legal basis, we rely on one of the four below. Most of what we do sits under contract or legitimate interest.
|
||||
</p>
|
||||
|
||||
<div class="mt-6 divide-y divide-[color:var(--border)] rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] overflow-hidden">
|
||||
<div class="p-5 grid grid-cols-1 sm:grid-cols-[160px_1fr] gap-3 sm:gap-6">
|
||||
<div class="text-[12.5px] font-mono uppercase tracking-[0.1em] text-muted-foreground">Contract</div>
|
||||
<p class="text-[14.5px] leading-relaxed text-foreground/85">We process the data you give us in order to deliver the product you signed up for. Without it we cannot send the mail or show you the results.</p>
|
||||
</div>
|
||||
<div class="p-5 grid grid-cols-1 sm:grid-cols-[160px_1fr] gap-3 sm:gap-6">
|
||||
<div class="text-[12.5px] font-mono uppercase tracking-[0.1em] text-muted-foreground">Legitimate interest</div>
|
||||
<p class="text-[14.5px] leading-relaxed text-foreground/85">We have a legitimate interest in keeping the platform safe and reliable. That covers abuse prevention, security monitoring, deliverability analytics, and core product improvement.</p>
|
||||
</div>
|
||||
<div class="p-5 grid grid-cols-1 sm:grid-cols-[160px_1fr] gap-3 sm:gap-6">
|
||||
<div class="text-[12.5px] font-mono uppercase tracking-[0.1em] text-muted-foreground">Consent</div>
|
||||
<p class="text-[14.5px] leading-relaxed text-foreground/85">For optional features such as product analytics opt-in and non-essential marketing email, we rely on your consent. You can withdraw it at any time without losing access to the service.</p>
|
||||
</div>
|
||||
<div class="p-5 grid grid-cols-1 sm:grid-cols-[160px_1fr] gap-3 sm:gap-6">
|
||||
<div class="text-[12.5px] font-mono uppercase tracking-[0.1em] text-muted-foreground">Legal obligation</div>
|
||||
<p class="text-[14.5px] leading-relaxed text-foreground/85">Some data, like billing records and tax invoices, we have to keep for a period set by law. We also retain the minimum needed to respond to lawful requests.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="encryption-storage" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">05</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Encryption and storage</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Sensitive material is encrypted with an envelope scheme. The root of trust lives in a managed key service, application data is sealed per user with a unique key, and the control plane only ever sees ciphertext for those fields.
|
||||
</p>
|
||||
|
||||
<div class="mt-6 grid gap-4">
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] p-5">
|
||||
<h3 class="text-[14.5px] font-semibold text-heading">Root of trust</h3>
|
||||
<p class="mt-1.5 text-[14px] leading-relaxed text-foreground/85">AWS KMS holds the customer master key. Plaintext data keys are never written to disk and never leave the encryption boundary in clear form.</p>
|
||||
</div>
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] p-5">
|
||||
<h3 class="text-[14.5px] font-semibold text-heading">Per-user data key</h3>
|
||||
<p class="mt-1.5 text-[14px] leading-relaxed text-foreground/85">Every user gets a 32 byte data encryption key (DEK) generated by KMS. Application-level fields such as mailbox credentials are sealed with AES-256-GCM using that key.</p>
|
||||
</div>
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] p-5">
|
||||
<h3 class="text-[14.5px] font-semibold text-heading">Key ciphertext</h3>
|
||||
<p class="mt-1.5 text-[14px] leading-relaxed text-foreground/85">The encrypted (wrapped) DEK is stored in DynamoDB. The plaintext DEK is only obtained by calling KMS to unwrap it, and only when an operation actually needs to decrypt a payload.</p>
|
||||
</div>
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] p-5">
|
||||
<h3 class="text-[14.5px] font-semibold text-heading">Hot key cache</h3>
|
||||
<p class="mt-1.5 text-[14px] leading-relaxed text-foreground/85">To avoid hitting KMS on every send, unwrapped DEKs are held in Redis with a short time-to-live. They expire automatically and can be evicted on demand if a key needs to be rotated.</p>
|
||||
</div>
|
||||
<div class="rounded-xl ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)] p-5">
|
||||
<h3 class="text-[14.5px] font-semibold text-heading">Control plane</h3>
|
||||
<p class="mt-1.5 text-[14px] leading-relaxed text-foreground/85">PostgreSQL holds operational state such as your account, your mailboxes, campaign configuration, and aggregate analytics. Fields marked as encrypted are stored only as ciphertext. Larger message payloads are encrypted where the design calls for it before they are persisted.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="mt-6 text-[14px] text-muted-foreground leading-relaxed">
|
||||
Encryption boundaries are documented in the codebase under <code class="font-mono text-[0.92em] px-1.5 py-0.5 rounded bg-[color:var(--surface-2)] ring-1 ring-[color:var(--border)]">internal/app/cipher</code> and <code class="font-mono text-[0.92em] px-1.5 py-0.5 rounded bg-[color:var(--surface-2)] ring-1 ring-[color:var(--border)]">internal/infrastructure/kms</code>. Warmbly is open source, so the implementation can be inspected.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="subprocessors" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">06</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Subprocessors</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
We use a small set of vetted vendors to run the service: cloud infrastructure, the payment processor, transactional email for account notices, and error reporting. The current list, what each one does, and where it operates is published at <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] underline-offset-2 hover:underline" href="/subprocessors/">/subprocessors</a>.
|
||||
</p>
|
||||
<p class="mt-4 text-[14.5px] leading-relaxed text-foreground/85">
|
||||
If you need notice of changes, customers on paid plans are notified by email when a new subprocessor is added with reasonable lead time before it begins processing data.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="retention" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">07</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Data retention</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
We keep data for as long as you have an account, and then only as long as we need to wind things down cleanly or as the law requires.
|
||||
</p>
|
||||
|
||||
<div class="mt-6 grid gap-3">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-[200px_1fr] gap-3 sm:gap-6 p-4 rounded-lg ring-1 ring-[color:var(--border)]">
|
||||
<div class="text-[12.5px] font-mono uppercase tracking-[0.1em] text-muted-foreground">While the account is active</div>
|
||||
<p class="text-[14.5px] leading-relaxed text-foreground/85">Account data, mailbox credentials, message data, and analytics live in the platform so the product can do its job.</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-[200px_1fr] gap-3 sm:gap-6 p-4 rounded-lg ring-1 ring-[color:var(--border)]">
|
||||
<div class="text-[12.5px] font-mono uppercase tracking-[0.1em] text-muted-foreground">After account deletion</div>
|
||||
<p class="text-[14.5px] leading-relaxed text-foreground/85">Account data and message content are deleted within 30 days. Encrypted backups roll off on their own schedule (up to 35 days). Connected mailbox tokens are revoked and the credentials are erased.</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-[200px_1fr] gap-3 sm:gap-6 p-4 rounded-lg ring-1 ring-[color:var(--border)]">
|
||||
<div class="text-[12.5px] font-mono uppercase tracking-[0.1em] text-muted-foreground">Billing records</div>
|
||||
<p class="text-[14.5px] leading-relaxed text-foreground/85">Invoices and tax records are kept for the period required by applicable tax and accounting law, typically seven years.</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-[200px_1fr] gap-3 sm:gap-6 p-4 rounded-lg ring-1 ring-[color:var(--border)]">
|
||||
<div class="text-[12.5px] font-mono uppercase tracking-[0.1em] text-muted-foreground">Suppression lists</div>
|
||||
<p class="text-[14.5px] leading-relaxed text-foreground/85">If a recipient has unsubscribed, bounced hard, or complained, we keep a minimal record (a hashed address and the suppression reason) so the platform does not send to them again. This is required to honor the unsubscribe.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="your-rights" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">08</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Your rights</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Depending on where you live, you may have some or all of the rights below over your personal data. We honor them regardless of jurisdiction whenever the request is reasonable to fulfill.
|
||||
</p>
|
||||
|
||||
<ul class="mt-5 grid sm:grid-cols-2 gap-3">
|
||||
{[
|
||||
['Access', 'Get a copy of the personal data we hold about you.'],
|
||||
['Rectification', 'Ask us to correct anything that is inaccurate or out of date.'],
|
||||
['Deletion', 'Ask us to erase your personal data. We will, unless we are required to keep it.'],
|
||||
['Portability', 'Receive your data in a structured, machine-readable format.'],
|
||||
['Restriction', 'Ask us to pause processing while a dispute or correction is resolved.'],
|
||||
['Objection', 'Object to processing that is based on legitimate interest.'],
|
||||
['Withdraw consent', 'Withdraw consent for anything you opted into (such as product analytics) at any time.'],
|
||||
['Complaint', 'Lodge a complaint with the supervisory authority in your country.'],
|
||||
].map(([k, v]) => (
|
||||
<li class="p-4 rounded-lg ring-1 ring-[color:var(--border)] bg-[color:var(--surface-1)]">
|
||||
<div class="text-[13.5px] font-semibold text-heading">{k}</div>
|
||||
<p class="mt-1 text-[13.5px] leading-relaxed text-foreground/85">{v}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<p class="mt-6 text-[14.5px] leading-relaxed text-foreground/85">
|
||||
To exercise any of these, email <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] underline-offset-2 hover:underline" href="mailto:privacy@warmbly.com">privacy@warmbly.com</a>. We will verify the request comes from you and respond within 30 days. If we cannot complete the request we will tell you why.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="international" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">09</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">International transfers</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly is operated from data centers in the United States and the European Union. Depending on your plan and region, your data may be stored in either region. Some subprocessors operate globally, which can mean data is transmitted across borders.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
For transfers out of the European Economic Area, the United Kingdom, or Switzerland to a country without an adequacy decision, we rely on the European Commission Standard Contractual Clauses, the UK International Data Transfer Addendum, or an equivalent mechanism. These commitments are incorporated by reference into our Data Processing Addendum.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="cookies" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">10</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Cookies</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly uses a small number of first-party cookies for things like keeping you logged in, remembering your workspace, and protecting forms from cross-site request forgery. We do not run advertising trackers.
|
||||
</p>
|
||||
<p class="mt-4 text-[15px] leading-relaxed text-foreground/85">
|
||||
The full list, including third-party cookies set by Stripe and the CAPTCHA provider on relevant pages, is at <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] underline-offset-2 hover:underline" href="/cookies/">/cookies</a>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="children" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">11</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Children's data</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly is a business tool. It is not intended for use by anyone under 16, or under 18 in jurisdictions where that is the threshold for digital services. We do not knowingly collect personal data from children. If you believe a child has signed up, contact us and we will delete the account.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="changes" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">12</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Changes to this policy</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
We update this policy when the product changes, when the law changes, or when we find a clearer way to say something. Material changes are announced by email or in-app notice at least 30 days before they take effect, and the "Last updated" date at the top of this page always reflects the most recent revision.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<section id="contact" class="scroll-mt-24 mt-14">
|
||||
<div class="flex items-baseline gap-3 mb-3">
|
||||
<span class="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums">13</span>
|
||||
<h2 class="text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] text-heading">Contact</h2>
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Privacy questions, data subject requests, breach reports, and supervisory authority correspondence all go to <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] underline-offset-2 hover:underline" href="mailto:privacy@warmbly.com">privacy@warmbly.com</a>. For general legal matters, write to <a class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] underline-offset-2 hover:underline" href="mailto:legal@warmbly.com">legal@warmbly.com</a>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Footer note -->
|
||||
<div class="mt-16 pt-6 border-t border-[color:var(--border)] flex flex-wrap items-center justify-between gap-3 text-[12.5px] text-muted-foreground">
|
||||
<div>Last updated {lastUpdated}</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<a class="hover:text-foreground transition-colors" href="/terms/">Terms</a>
|
||||
<a class="hover:text-foreground transition-colors" href="/dpa/">DPA</a>
|
||||
<a class="hover:text-foreground transition-colors" href="/subprocessors/">Subprocessors</a>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
@media print {
|
||||
:global(header), :global(footer), :global(nav) { display: none !important; }
|
||||
:global(body) { background: white !important; color: #000 !important; }
|
||||
article { max-width: none !important; }
|
||||
a { color: inherit !important; text-decoration: underline; }
|
||||
section[id] { break-inside: avoid; }
|
||||
h2 { break-after: avoid; }
|
||||
}
|
||||
</style>
|
||||
</Layout>
|
||||
</Legal>
|
||||
|
||||
@@ -1,475 +0,0 @@
|
||||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import HeroAtmosphere from '../components/HeroAtmosphere.astro';
|
||||
import Icon from '../components/Icon.astro';
|
||||
import CTA from '../components/CTA.astro';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
Subprocessors page.
|
||||
|
||||
Layout shape:
|
||||
1. Hero (HeroAtmosphere) with eyebrow, title, last-updated badge,
|
||||
and short copy about notifying customers of material changes.
|
||||
2. Subscribe-to-changes strip with a mailto.
|
||||
3. Designer-grade subprocessor table inside container-page.
|
||||
Desktop: full table with hover state.
|
||||
Mobile: same data collapses into stacked cards.
|
||||
4. "How we evaluate subprocessors" short list.
|
||||
5. "What changes when we add a subprocessor" notice + window.
|
||||
6. "Previous subprocessors" placeholder / empty state.
|
||||
7. Closing CTA.
|
||||
|
||||
Tone rules:
|
||||
- No em dashes.
|
||||
- No fake compliance badges or "certified" claims for vendors.
|
||||
- Vendors are pulled from Warmbly's real architecture per CLAUDE.md.
|
||||
|
||||
Astro JSX parser caveat:
|
||||
`<` and `<=` inside `{}` expression blocks get misread as tag
|
||||
openers. Anything numeric / boolean is hoisted to frontmatter.
|
||||
----------------------------------------------------------------- */
|
||||
|
||||
const lastUpdated = '2026-05-27';
|
||||
const noticeWindowDays = 30;
|
||||
const subscriberEmail = 'subprocessors@warmbly.com';
|
||||
|
||||
// Real vendors that Warmbly's architecture depends on (per CLAUDE.md).
|
||||
// Every link points to the vendor's actual security/DPA/privacy page.
|
||||
type SubRow = {
|
||||
vendor: string;
|
||||
purpose: string;
|
||||
data: string;
|
||||
region: string;
|
||||
link: { label: string; href: string };
|
||||
};
|
||||
|
||||
const subprocessors: SubRow[] = [
|
||||
{
|
||||
vendor: 'Amazon Web Services',
|
||||
purpose: 'Primary infrastructure. Compute, S3 object storage, KMS root of trust for envelope encryption, DynamoDB for encrypted DEK storage, RDS Postgres for relational data, MSK for Kafka.',
|
||||
data: 'Account data, contacts, sequence content, encrypted mailbox payloads, deliverability events, audit logs.',
|
||||
region: 'us-east-1, eu-west-1',
|
||||
link: { label: 'aws.amazon.com/compliance', href: 'https://aws.amazon.com/compliance/' },
|
||||
},
|
||||
{
|
||||
vendor: 'Cloudflare',
|
||||
purpose: 'Edge network, DDoS protection, WAF, marketing-site CDN, and Turnstile CAPTCHA on auth-sensitive routes (login, registration, password reset).',
|
||||
data: 'Request metadata, IP addresses, Turnstile challenge tokens. No mailbox or campaign content.',
|
||||
region: 'Global edge',
|
||||
link: { label: 'cloudflare.com/trust-hub', href: 'https://www.cloudflare.com/trust-hub/' },
|
||||
},
|
||||
{
|
||||
vendor: 'Stripe',
|
||||
purpose: 'Billing, subscription management, tax, and webhook-backed payment events. Card data is collected by Stripe directly via Stripe Elements, never by Warmbly.',
|
||||
data: 'Billing contact, business name, country, last 4 digits of payment method (tokenized by Stripe).',
|
||||
region: 'United States, Ireland',
|
||||
link: { label: 'stripe.com/privacy', href: 'https://stripe.com/privacy' },
|
||||
},
|
||||
{
|
||||
vendor: 'Postmark',
|
||||
purpose: 'Transactional product email only. Account confirmations, password resets, security alerts, billing receipts. Not used for customer campaign sending.',
|
||||
data: 'Recipient email address (customer staff), message body for the transactional event.',
|
||||
region: 'United States',
|
||||
link: { label: 'postmarkapp.com/eu-privacy', href: 'https://postmarkapp.com/eu-privacy' },
|
||||
},
|
||||
{
|
||||
vendor: 'Sentry',
|
||||
purpose: 'Application error monitoring for the backend, worker fleet, and frontend. Stack traces are scrubbed of customer message bodies before transport.',
|
||||
data: 'Error stack traces, request IDs, user IDs, scrubbed request metadata.',
|
||||
region: 'United States',
|
||||
link: { label: 'sentry.io/legal/dpa', href: 'https://sentry.io/legal/dpa/' },
|
||||
},
|
||||
{
|
||||
vendor: 'Plain',
|
||||
purpose: 'Customer support help-desk. Routes inbound customer email and in-app support threads to the team rotation.',
|
||||
data: 'Support correspondence, customer name and email, workspace ID.',
|
||||
region: 'European Union, United States',
|
||||
link: { label: 'plain.com/legal/privacy', href: 'https://www.plain.com/legal/privacy' },
|
||||
},
|
||||
];
|
||||
|
||||
// Evaluation criteria. Short and reviewable, not a marketing list.
|
||||
const criteria = [
|
||||
{
|
||||
icon: 'shield',
|
||||
title: 'Security posture',
|
||||
body: 'Vendor must publish a security overview, support TLS in transit, and offer a DPA. We review SOC 2, ISO 27001, or equivalent attestation where the vendor publishes one.',
|
||||
},
|
||||
{
|
||||
icon: 'globe',
|
||||
title: 'Data residency',
|
||||
body: 'For EU customer data we prefer EU processing regions. Where a vendor is US-only, we rely on Standard Contractual Clauses and document the transfer.',
|
||||
},
|
||||
{
|
||||
icon: 'lock',
|
||||
title: 'Scope of access',
|
||||
body: 'A subprocessor only sees the smallest slice of data the integration requires. Mailbox content stays sealed with KMS-backed envelope encryption and is not handed to third parties.',
|
||||
},
|
||||
{
|
||||
icon: 'cog',
|
||||
title: 'Operational fit',
|
||||
body: 'We pick boring, well-operated vendors with public status pages, predictable change communication, and a real incident response process.',
|
||||
},
|
||||
];
|
||||
|
||||
// "What happens when we add a subprocessor" steps.
|
||||
const noticeSteps = [
|
||||
{
|
||||
n: '01',
|
||||
title: `${noticeWindowDays} days advance notice`,
|
||||
body: 'We update this page and post an in-app banner before any new subprocessor that processes customer Personal Data goes live. Subscribers also receive an email.',
|
||||
},
|
||||
{
|
||||
n: '02',
|
||||
title: 'Objection window',
|
||||
body: `Customers may object on reasonable data-protection grounds during the ${noticeWindowDays}-day window. Send objections to subprocessors@warmbly.com with the affected subprocessor and the basis for the objection.`,
|
||||
},
|
||||
{
|
||||
n: '03',
|
||||
title: 'Resolution',
|
||||
body: 'We work in good faith to resolve objections, which may include scoping the integration, choosing an alternative vendor, or, where the change is material and unresolved, allowing the customer to terminate the affected service.',
|
||||
},
|
||||
];
|
||||
|
||||
// Previous subprocessors. Empty by design at launch; the layout
|
||||
// renders an explicit empty state so the section is still legally
|
||||
// meaningful.
|
||||
const previous: SubRow[] = [];
|
||||
|
||||
// Counts hoisted for the JSX so the parser does not have to evaluate
|
||||
// `<` style expressions inline.
|
||||
const activeCount = subprocessors.length;
|
||||
const previousCount = previous.length;
|
||||
const hasPrevious = previousCount > 0;
|
||||
---
|
||||
<Layout
|
||||
title="Subprocessors · Warmbly"
|
||||
description="The third-party services Warmbly uses to operate the platform. Vendors, purposes, data categories, regions, and links to each vendor's security and DPA pages."
|
||||
>
|
||||
<!-- =====================================================
|
||||
HERO · HeroAtmosphere, shorter than product pages.
|
||||
Eyebrow, title, last-updated badge, short copy.
|
||||
===================================================== -->
|
||||
<section class="relative isolate overflow-hidden">
|
||||
<HeroAtmosphere />
|
||||
|
||||
<div class="container-page relative pt-14 md:pt-20 pb-16 md:pb-20">
|
||||
<div class="max-w-3xl">
|
||||
<div class="inline-flex items-center gap-2 h-7 pl-1 pr-3 rounded-full bg-white/15 backdrop-blur ring-1 ring-white/25 text-[12px] text-white/95 shadow-[0_4px_14px_-4px_rgba(0,0,0,0.25)]">
|
||||
<span class="inline-flex items-center h-5 px-1.5 rounded-full text-[10.5px] font-semibold uppercase tracking-[0.06em] bg-white" style="color:#0369a1;">Legal</span>
|
||||
Subprocessors
|
||||
</div>
|
||||
|
||||
<h1 class="mt-6 md:mt-8 text-[40px] sm:text-[52px] md:text-[64px] font-semibold tracking-[-0.035em] leading-[1.02] text-white">
|
||||
The vendors behind<br/>the platform.
|
||||
</h1>
|
||||
|
||||
<p class="mt-5 text-[16px] md:text-[17.5px] text-white/80 max-w-2xl leading-relaxed">
|
||||
These are the third-party services Warmbly uses to operate the platform. We notify customers of material changes.
|
||||
</p>
|
||||
|
||||
<div class="mt-7 flex flex-wrap items-center gap-3 text-[12.5px]">
|
||||
<span class="inline-flex items-center gap-2 h-8 px-3 rounded-[8px] bg-white/12 backdrop-blur ring-1 ring-white/25 text-white font-mono">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-400"></span>
|
||||
Last updated {lastUpdated}
|
||||
</span>
|
||||
<span class="inline-flex items-center gap-2 h-8 px-3 rounded-[8px] bg-white/10 backdrop-blur ring-1 ring-white/20 text-white/85 font-mono">
|
||||
{activeCount} active subprocessors
|
||||
</span>
|
||||
<a
|
||||
href="/dpa/"
|
||||
class="inline-flex items-center gap-1.5 h-8 px-3 rounded-[8px] bg-white/10 backdrop-blur ring-1 ring-white/20 text-white/90 hover:bg-white/20 hover:text-white transition-colors"
|
||||
>
|
||||
See the DPA
|
||||
<Icon name="arrowUpRight" size={12} />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- =====================================================
|
||||
SUBSCRIBE TO CHANGES · narrow strip above the table.
|
||||
Short copy + a mailto. We keep this above the table so
|
||||
the reader sees how to follow updates before scanning.
|
||||
===================================================== -->
|
||||
<section class="relative -mt-8 md:-mt-12 z-10">
|
||||
<div class="container-page">
|
||||
<div
|
||||
class="rounded-[14px] bg-white ring-1 ring-[color:var(--border)] p-5 md:p-6 flex flex-col md:flex-row md:items-center md:justify-between gap-4"
|
||||
style="box-shadow: var(--shadow-sm);"
|
||||
>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="w-10 h-10 rounded-[10px] bg-[color:var(--brand-soft)] text-[color:var(--brand)] ring-1 ring-[color:var(--brand)]/15 inline-flex items-center justify-center shrink-0">
|
||||
<Icon name="bell" size={18} />
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-[14.5px] font-semibold text-heading">Subscribe to changes</div>
|
||||
<p class="mt-1 text-[13px] text-foreground/70 leading-relaxed max-w-xl">
|
||||
Get a {noticeWindowDays}-day advance notice whenever a new subprocessor is added or an existing one changes scope. One email per change, never marketing.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href={`mailto:${subscriberEmail}?subject=Subscribe%20to%20subprocessor%20updates`}
|
||||
class="inline-flex h-10 px-4 items-center gap-2 rounded-[10px] text-[13.5px] font-semibold bg-[color:var(--brand)] hover:bg-[color:var(--brand-strong)] text-white transition-colors shrink-0"
|
||||
>
|
||||
<Icon name="mail" size={14} />
|
||||
{subscriberEmail}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- =====================================================
|
||||
SUBPROCESSORS TABLE · full-width, designer-grade.
|
||||
Desktop: real <table> with hover rows and a sticky-feeling
|
||||
header. Mobile: same data restated as stacked cards.
|
||||
===================================================== -->
|
||||
<section class="pt-14 md:pt-20 pb-16 md:pb-20">
|
||||
<div class="container-page">
|
||||
<div class="flex flex-col md:flex-row md:items-end md:justify-between gap-4 mb-8">
|
||||
<div>
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">Active subprocessors</div>
|
||||
<h2 class="text-[26px] md:text-[34px] font-semibold tracking-[-0.025em] text-heading leading-[1.1] max-w-2xl">
|
||||
Who touches your data, and why.
|
||||
</h2>
|
||||
</div>
|
||||
<p class="text-[13.5px] text-muted-foreground max-w-sm md:text-right">
|
||||
Region listed is where the vendor processes Warmbly customer data. Link points to the vendor's own security or DPA page.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- DESKTOP TABLE -->
|
||||
<div
|
||||
class="hidden md:block rounded-[14px] bg-white ring-1 ring-[color:var(--border)] overflow-hidden"
|
||||
style="box-shadow: var(--shadow-sm);"
|
||||
>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left text-[13.5px]">
|
||||
<thead>
|
||||
<tr class="bg-[color:var(--surface-1)] border-b border-[color:var(--border)] text-[10.5px] uppercase tracking-[0.16em] font-mono text-muted-foreground">
|
||||
<th scope="col" class="font-semibold px-5 py-3.5 w-[18%]">Vendor</th>
|
||||
<th scope="col" class="font-semibold px-5 py-3.5 w-[30%]">Purpose</th>
|
||||
<th scope="col" class="font-semibold px-5 py-3.5 w-[24%]">Data categories</th>
|
||||
<th scope="col" class="font-semibold px-5 py-3.5 w-[14%]">Region</th>
|
||||
<th scope="col" class="font-semibold px-5 py-3.5 w-[14%]">Reference</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[color:var(--border)]">
|
||||
{subprocessors.map((s) => (
|
||||
<tr class="hover:bg-[color:var(--surface-1)]/60 transition-colors align-top">
|
||||
<td class="px-5 py-4">
|
||||
<div class="font-semibold text-heading tracking-[-0.005em]">{s.vendor}</div>
|
||||
</td>
|
||||
<td class="px-5 py-4 text-foreground/80 leading-relaxed">{s.purpose}</td>
|
||||
<td class="px-5 py-4 text-foreground/75 leading-relaxed">{s.data}</td>
|
||||
<td class="px-5 py-4">
|
||||
<span class="inline-flex items-center font-mono text-[12px] text-foreground/75">
|
||||
{s.region}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-5 py-4">
|
||||
<a
|
||||
href={s.link.href}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
class="inline-flex items-center gap-1.5 text-[12.5px] font-mono text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] break-all"
|
||||
>
|
||||
{s.link.label}
|
||||
<Icon name="arrowUpRight" size={11} />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MOBILE STACKED CARDS -->
|
||||
<div class="md:hidden space-y-3">
|
||||
{subprocessors.map((s) => (
|
||||
<div
|
||||
class="rounded-[14px] bg-white ring-1 ring-[color:var(--border)] p-5"
|
||||
style="box-shadow: var(--shadow-sm);"
|
||||
>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="text-[15px] font-semibold text-heading tracking-[-0.005em]">{s.vendor}</div>
|
||||
<span class="font-mono text-[11px] text-foreground/65 shrink-0">{s.region}</span>
|
||||
</div>
|
||||
|
||||
<dl class="mt-4 space-y-3">
|
||||
<div>
|
||||
<dt class="text-[10.5px] uppercase tracking-[0.14em] font-mono text-muted-foreground mb-1">Purpose</dt>
|
||||
<dd class="text-[13px] text-foreground/80 leading-relaxed">{s.purpose}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-[10.5px] uppercase tracking-[0.14em] font-mono text-muted-foreground mb-1">Data categories</dt>
|
||||
<dd class="text-[13px] text-foreground/75 leading-relaxed">{s.data}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<a
|
||||
href={s.link.href}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
class="mt-4 inline-flex items-center gap-1.5 text-[12.5px] font-mono text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] break-all"
|
||||
>
|
||||
{s.link.label}
|
||||
<Icon name="arrowUpRight" size={11} />
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p class="mt-5 text-[12px] text-muted-foreground font-mono">
|
||||
Links open the vendor's own security or privacy page. Warmbly does not republish or endorse those documents.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- =====================================================
|
||||
HOW WE EVALUATE · short list, four cards.
|
||||
===================================================== -->
|
||||
<section class="bg-[color:var(--surface-2)] border-y border-[color:var(--border)] py-16 md:py-20">
|
||||
<div class="container-page">
|
||||
<div class="grid lg:grid-cols-[1fr_2fr] gap-12 lg:gap-16">
|
||||
<div class="lg:sticky lg:top-24 self-start">
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">How we evaluate</div>
|
||||
<h2 class="text-[24px] md:text-[32px] font-semibold tracking-[-0.025em] text-heading leading-[1.1]">
|
||||
Boring, well-operated, scoped tight.
|
||||
</h2>
|
||||
<p class="mt-4 text-[14.5px] text-foreground/75 leading-relaxed max-w-sm">
|
||||
New subprocessors are added when an integration genuinely needs them, not because a vendor is on a procurement list. Every entry above passed the same review.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ul class="grid sm:grid-cols-2 gap-4">
|
||||
{criteria.map((c) => (
|
||||
<li
|
||||
class="rounded-[12px] bg-white ring-1 ring-[color:var(--border)] p-6"
|
||||
style="box-shadow: var(--shadow-sm);"
|
||||
>
|
||||
<div class="w-10 h-10 rounded-[10px] bg-[color:var(--brand-soft)] text-[color:var(--brand)] ring-1 ring-[color:var(--brand)]/15 inline-flex items-center justify-center mb-4">
|
||||
<Icon name={c.icon} size={18} />
|
||||
</div>
|
||||
<div class="text-[14.5px] font-semibold text-heading">{c.title}</div>
|
||||
<p class="mt-2 text-[13.5px] text-foreground/75 leading-relaxed">{c.body}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- =====================================================
|
||||
WHAT CHANGES WHEN WE ADD A SUBPROCESSOR · notice + window
|
||||
===================================================== -->
|
||||
<section class="py-16 md:py-20">
|
||||
<div class="container-page">
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">When this list changes</div>
|
||||
<h2 class="text-[26px] md:text-[34px] font-semibold tracking-[-0.025em] text-heading leading-[1.1] max-w-2xl">
|
||||
{noticeWindowDays} days notice. Real objection window.
|
||||
</h2>
|
||||
<p class="mt-4 text-[14.5px] text-foreground/75 leading-relaxed max-w-2xl">
|
||||
Adding a subprocessor is a contract change, not a backend tweak. We treat it like one.
|
||||
</p>
|
||||
|
||||
<ol class="mt-10 grid md:grid-cols-3 gap-5">
|
||||
{noticeSteps.map((s) => (
|
||||
<li
|
||||
class="rounded-[12px] bg-white ring-1 ring-[color:var(--border)] p-6 relative"
|
||||
style="box-shadow: var(--shadow-sm);"
|
||||
>
|
||||
<div class="text-[11px] font-mono text-[color:var(--brand)] tracking-[0.16em]">{s.n}</div>
|
||||
<div class="mt-3 text-[15px] font-semibold text-heading">{s.title}</div>
|
||||
<p class="mt-2 text-[13.5px] text-foreground/75 leading-relaxed">{s.body}</p>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
|
||||
<div
|
||||
class="mt-8 rounded-[12px] bg-[color:var(--brand-soft)]/40 ring-1 ring-[color:var(--brand)]/20 p-5 flex items-start gap-4"
|
||||
>
|
||||
<div class="w-8 h-8 rounded-[8px] bg-[color:var(--brand)] text-white inline-flex items-center justify-center shrink-0">
|
||||
<Icon name="shield" size={15} />
|
||||
</div>
|
||||
<div class="text-[13.5px] text-foreground/85 leading-relaxed">
|
||||
The {noticeWindowDays}-day notice is contractual. It is restated in the <a href="/dpa/" class="font-semibold text-[color:var(--brand)] hover:text-[color:var(--brand-strong)]">Data Processing Addendum</a> section 7. The objection process there controls if there is any conflict with this page.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- =====================================================
|
||||
PREVIOUS SUBPROCESSORS · empty-state aware.
|
||||
===================================================== -->
|
||||
<section class="bg-[color:var(--surface-2)] border-y border-[color:var(--border)] py-16 md:py-20">
|
||||
<div class="container-page">
|
||||
<div class="flex flex-col md:flex-row md:items-end md:justify-between gap-4 mb-8">
|
||||
<div>
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">Previous subprocessors</div>
|
||||
<h2 class="text-[24px] md:text-[30px] font-semibold tracking-[-0.025em] text-heading leading-[1.1] max-w-2xl">
|
||||
Vendors we have removed or replaced.
|
||||
</h2>
|
||||
</div>
|
||||
<p class="text-[13.5px] text-muted-foreground max-w-sm md:text-right">
|
||||
When a vendor is retired, the row moves here with the date it was removed and the reason.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{hasPrevious ? (
|
||||
<div
|
||||
class="rounded-[14px] bg-white ring-1 ring-[color:var(--border)] overflow-hidden"
|
||||
style="box-shadow: var(--shadow-sm);"
|
||||
>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left text-[13.5px]">
|
||||
<thead>
|
||||
<tr class="bg-[color:var(--surface-1)] border-b border-[color:var(--border)] text-[10.5px] uppercase tracking-[0.16em] font-mono text-muted-foreground">
|
||||
<th scope="col" class="font-semibold px-5 py-3.5">Vendor</th>
|
||||
<th scope="col" class="font-semibold px-5 py-3.5">Purpose</th>
|
||||
<th scope="col" class="font-semibold px-5 py-3.5">Region</th>
|
||||
<th scope="col" class="font-semibold px-5 py-3.5">Removed</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[color:var(--border)]">
|
||||
{previous.map((p) => (
|
||||
<tr class="align-top">
|
||||
<td class="px-5 py-4 font-semibold text-heading">{p.vendor}</td>
|
||||
<td class="px-5 py-4 text-foreground/80">{p.purpose}</td>
|
||||
<td class="px-5 py-4 font-mono text-[12px] text-foreground/70">{p.region}</td>
|
||||
<td class="px-5 py-4 font-mono text-[12px] text-foreground/70">{p.data}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
class="rounded-[14px] bg-white ring-1 ring-[color:var(--border)] p-8 md:p-10 text-center"
|
||||
style="box-shadow: var(--shadow-sm);"
|
||||
>
|
||||
<div class="w-12 h-12 mx-auto rounded-[12px] bg-[color:var(--surface-1)] text-muted-foreground ring-1 ring-[color:var(--border)] inline-flex items-center justify-center">
|
||||
<Icon name="layers" size={20} />
|
||||
</div>
|
||||
<div class="mt-4 text-[15px] font-semibold text-heading">No previous subprocessors yet.</div>
|
||||
<p class="mt-2 text-[13.5px] text-foreground/70 max-w-md mx-auto leading-relaxed">
|
||||
Warmbly has not removed or replaced a subprocessor since this page was first published. When that changes, the retired vendor will appear here with the date and reason.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CTA
|
||||
title="Want the contract version of this list?"
|
||||
description="The Data Processing Addendum restates the subprocessor commitments above and the 30-day notice in contract form. We sign customer paper or our own."
|
||||
primaryLabel="Read the DPA"
|
||||
primaryHref="/dpa/"
|
||||
secondaryLabel="Email subprocessors team"
|
||||
secondaryHref={`mailto:${subscriberEmail}`}
|
||||
/>
|
||||
</Layout>
|
||||
+179
-397
@@ -1,421 +1,203 @@
|
||||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import HeroAtmosphere from '../components/HeroAtmosphere.astro';
|
||||
|
||||
const lastUpdated = '2026-05-27';
|
||||
const effectiveFrom = '2026-05-27';
|
||||
import Legal from '../layouts/Legal.astro';
|
||||
|
||||
const sections = [
|
||||
{ id: 'acceptance', num: '01', label: 'Acceptance of terms' },
|
||||
{ id: 'definitions', num: '02', label: 'Definitions' },
|
||||
{ id: 'account', num: '03', label: 'Account registration and security' },
|
||||
{ id: 'acceptable-use', num: '04', label: 'Acceptable use' },
|
||||
{ id: 'availability', num: '05', label: 'Service availability and changes' },
|
||||
{ id: 'billing', num: '06', label: 'Subscription, billing, refunds' },
|
||||
{ id: 'ip', num: '07', label: 'Intellectual property' },
|
||||
{ id: 'user-content', num: '08', label: 'User content and your data' },
|
||||
{ id: 'confidentiality', num: '09', label: 'Confidentiality' },
|
||||
{ id: 'third-party', num: '10', label: 'Third-party services' },
|
||||
{ id: 'disclaimers', num: '11', label: 'Disclaimers' },
|
||||
{ id: 'liability', num: '12', label: 'Limitation of liability' },
|
||||
{ id: 'indemnification', num: '13', label: 'Indemnification' },
|
||||
{ id: 'termination', num: '14', label: 'Termination' },
|
||||
{ id: 'governing-law', num: '15', label: 'Governing law and jurisdiction' },
|
||||
{ id: 'changes', num: '16', label: 'Changes to these terms' },
|
||||
{ id: 'contact', num: '17', label: 'Contact' },
|
||||
];
|
||||
|
||||
const legalDocs = [
|
||||
{ label: 'Terms of service', href: '/terms/' },
|
||||
{ label: 'Privacy policy', href: '/privacy/' },
|
||||
{ label: 'Acceptable use', href: '/acceptable-use/' },
|
||||
{ label: 'Data processing addendum', href: '/dpa/' },
|
||||
{ label: 'Subprocessors', href: '/subprocessors/' },
|
||||
{ label: 'Cookies', href: '/cookies/' },
|
||||
{ id: 'acceptance', num: '01', title: 'Acceptance of terms' },
|
||||
{ id: 'who-we-are', num: '02', title: 'Who we are' },
|
||||
{ id: 'definitions', num: '03', title: 'Definitions' },
|
||||
{ id: 'account', num: '04', title: 'Your account' },
|
||||
{ id: 'use', num: '05', title: 'Acceptable use' },
|
||||
{ id: 'plans', num: '06', title: 'Plans, billing, refunds' },
|
||||
{ id: 'service', num: '07', title: 'Service availability' },
|
||||
{ id: 'data', num: '08', title: 'Your content and data' },
|
||||
{ id: 'ip', num: '09', title: 'Intellectual property' },
|
||||
{ id: 'third-party', num: '10', title: 'Third-party services' },
|
||||
{ id: 'warranties', num: '11', title: 'Disclaimers' },
|
||||
{ id: 'liability', num: '12', title: 'Limitation of liability' },
|
||||
{ id: 'indemnity', num: '13', title: 'Indemnification' },
|
||||
{ id: 'termination', num: '14', title: 'Termination' },
|
||||
{ id: 'law', num: '15', title: 'Governing law' },
|
||||
{ id: 'changes', num: '16', title: 'Changes to these terms' },
|
||||
{ id: 'contact', num: '17', title: 'Contact' },
|
||||
];
|
||||
---
|
||||
<Layout
|
||||
title="Terms of service · Warmbly"
|
||||
description="The terms that govern your use of Warmbly. Plain English, scannable, with clearly numbered sections."
|
||||
<Legal
|
||||
title="Terms of service"
|
||||
description="The agreement between you and Mindroot Ltd, the company behind Warmbly."
|
||||
effective="2026-05-27"
|
||||
updated="2026-05-27"
|
||||
sections={sections}
|
||||
>
|
||||
<!-- ============================================================
|
||||
HERO · HeroAtmosphere (shorter than product heroes)
|
||||
============================================================ -->
|
||||
<section class="relative isolate overflow-hidden">
|
||||
<HeroAtmosphere />
|
||||
|
||||
<div class="container-page relative pt-14 md:pt-20 pb-16 md:pb-20">
|
||||
<div class="inline-flex items-center gap-2 h-7 pl-1 pr-3 rounded-full bg-white/15 backdrop-blur ring-1 ring-white/25 text-[12px] text-white/95 shadow-[0_4px_14px_-4px_rgba(0,0,0,0.25)]">
|
||||
<span class="inline-flex items-center h-5 px-1.5 rounded-full text-[10.5px] font-semibold uppercase tracking-[0.06em] bg-white" style="color:#0369a1;">
|
||||
Legal
|
||||
</span>
|
||||
The agreement between you and Warmbly
|
||||
</div>
|
||||
<section id="acceptance" class="scroll-mt-24">
|
||||
<h2>01. Acceptance of terms</h2>
|
||||
<p>
|
||||
These terms of service (the "Terms") govern your access to and use of Warmbly, an open-source cold outreach and email warmup platform operated by Mindroot Ltd. By creating an account, accessing the service, or using the platform in any way, you agree to be bound by these Terms. If you do not agree, do not use the service.
|
||||
</p>
|
||||
<p>
|
||||
If you are using the service on behalf of an organisation, you confirm that you have authority to bind that organisation, and "you" in these Terms refers to both you and that organisation.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<h1 class="mt-6 md:mt-8 text-[40px] sm:text-5xl md:text-[60px] font-semibold tracking-[-0.035em] leading-[1.02] text-white max-w-3xl">
|
||||
Terms of service.
|
||||
</h1>
|
||||
<section id="who-we-are" class="scroll-mt-24">
|
||||
<h2>02. Who we are</h2>
|
||||
<p>
|
||||
Warmbly is operated by Mindroot Ltd, a company registered in England and Wales with company number 16543299. Our registered office is at 71-75 Shelton Street, London, England, WC2H 9JQ.
|
||||
</p>
|
||||
<p>
|
||||
You can reach us at <a href="mailto:hello@warmbly.com">hello@warmbly.com</a> for any matter arising under these Terms.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<p class="mt-5 text-[16px] md:text-[17px] text-white/80 max-w-2xl leading-relaxed">
|
||||
These terms govern how you use Warmbly. We have written them in plain English so you can read them in one sitting. Read them.
|
||||
</p>
|
||||
<section id="definitions" class="scroll-mt-24">
|
||||
<h2>03. Definitions</h2>
|
||||
<ul>
|
||||
<li><strong>Service</strong> means the Warmbly platform, including the web application, APIs, workers, and any related software or content we make available.</li>
|
||||
<li><strong>Account</strong> means the credentials and workspace associated with your use of the Service.</li>
|
||||
<li><strong>Customer content</strong> means recipients, message bodies, contact lists, and other data you upload, send, or generate through the Service.</li>
|
||||
<li><strong>Connected mailbox</strong> means any email account you connect to Warmbly for sending, syncing, or warmup.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<div class="mt-8 flex flex-wrap items-center gap-x-6 gap-y-3 text-[12.5px] font-mono text-white/85">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex h-1.5 w-1.5 rounded-full bg-white/80"></span>
|
||||
<span class="uppercase tracking-[0.14em] text-white/55">Last updated</span>
|
||||
<span class="text-white">{lastUpdated}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex h-1.5 w-1.5 rounded-full bg-white/80"></span>
|
||||
<span class="uppercase tracking-[0.14em] text-white/55">Effective from</span>
|
||||
<span class="text-white">{effectiveFrom}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="account" class="scroll-mt-24">
|
||||
<h2>04. Your account</h2>
|
||||
<p>
|
||||
You are responsible for keeping your login credentials confidential and for all activity that happens under your account. You must provide accurate registration information, keep it up to date, and notify us promptly if you suspect unauthorised access.
|
||||
</p>
|
||||
<p>
|
||||
You may not share an account across multiple individuals. Each named user in your workspace must use their own credentials.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============================================================
|
||||
BODY · Sticky sidebar TOC + numbered sections
|
||||
============================================================ -->
|
||||
<section class="relative bg-white">
|
||||
<div class="container-page py-14 md:py-20">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-10 lg:gap-14">
|
||||
<section id="use" class="scroll-mt-24">
|
||||
<h2>05. Acceptable use</h2>
|
||||
<p>
|
||||
Warmbly is built for legitimate business-to-business cold outreach, mailbox warmup, and reply handling. You agree to use the Service in compliance with all applicable laws, including but not limited to GDPR, CAN-SPAM, CASL, and ePrivacy where they apply to you.
|
||||
</p>
|
||||
<p>You agree not to use the Service to:</p>
|
||||
<ul>
|
||||
<li>Send unlawful, harassing, defamatory, or fraudulent content.</li>
|
||||
<li>Send unsolicited commercial email to consumer addresses or to addresses sourced from purchased or scraped lists without lawful basis.</li>
|
||||
<li>Impersonate any person or organisation, including impersonating Warmbly or Mindroot Ltd.</li>
|
||||
<li>Distribute malware, phishing content, sextortion, romance scams, crypto pump-and-dump schemes, multi-level marketing recruitment, or content sexualising minors.</li>
|
||||
<li>Probe, scan, or test the vulnerability of the Service, or attempt to bypass authentication or rate limits.</li>
|
||||
<li>Use the Service to coordinate distributed bulk sending across accounts you do not control, or to circumvent per-mailbox sending budgets, warmup pool safety controls, or suppression rules.</li>
|
||||
<li>Forge warmup verification tokens, abuse the shared warmup pool, or otherwise undermine pool integrity.</li>
|
||||
</ul>
|
||||
<p>
|
||||
We may suspend, throttle, quarantine, or terminate accounts that breach these rules. We may also remove or block any content or sending activity that we reasonably believe violates them.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Sticky sidebar TOC -->
|
||||
<aside class="lg:col-span-3 print:hidden">
|
||||
<div class="lg:sticky lg:top-24">
|
||||
<section id="plans" class="scroll-mt-24">
|
||||
<h2>06. Plans, billing, and refunds</h2>
|
||||
<p>
|
||||
Paid plans are billed in advance on a recurring basis through Stripe. Fees, included usage, and billing cadence are shown on the pricing page and reflected in your invoice at the time of purchase.
|
||||
</p>
|
||||
<p>
|
||||
Subscriptions renew automatically until cancelled. You can cancel at any time from the billing area of your workspace, and your plan will remain active until the end of the current billing period. Except where required by law, fees already paid are non-refundable.
|
||||
</p>
|
||||
<p>
|
||||
We may change pricing, plans, or feature inclusions with reasonable notice. Continued use of the Service after the effective date of a price change constitutes acceptance of the new price.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-3">
|
||||
On this page
|
||||
</div>
|
||||
<section id="service" class="scroll-mt-24">
|
||||
<h2>07. Service availability and changes</h2>
|
||||
<p>
|
||||
We work hard to keep Warmbly available and reliable, but the Service is provided without uptime guarantees beyond what is described in any separate service-level agreement we agree with you in writing.
|
||||
</p>
|
||||
<p>
|
||||
We may add, modify, or discontinue features. If we materially reduce a paid feature you depend on, we will give reasonable notice and offer a prorated refund where appropriate.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<nav aria-label="Table of contents" class="border-l border-[color:var(--border)]">
|
||||
<ul class="space-y-0.5">
|
||||
{sections.map((s) => (
|
||||
<li>
|
||||
<a
|
||||
href={`#${s.id}`}
|
||||
class="group flex items-baseline gap-3 -ml-px pl-4 pr-2 py-1.5 border-l border-transparent hover:border-[color:var(--brand)] hover:bg-[color:var(--surface-2)]/60 transition-colors rounded-r-md"
|
||||
>
|
||||
<span class="text-[10.5px] font-mono text-muted-foreground/70 group-hover:text-[color:var(--brand)] tabular-nums">{s.num}</span>
|
||||
<span class="text-[13px] text-foreground/80 group-hover:text-[color:var(--brand-strong)] leading-snug">{s.label}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
<section id="data" class="scroll-mt-24">
|
||||
<h2>08. Your content and data</h2>
|
||||
<p>
|
||||
You retain ownership of Customer content. You grant us a limited, non-exclusive licence to host, process, transmit, and display that content solely to operate the Service for you, to enforce these Terms, and to comply with law.
|
||||
</p>
|
||||
<p>
|
||||
For details on what we collect, why, and how it is protected, see our <a href="/privacy/">privacy policy</a>. Sensitive credentials, including OAuth tokens and mailbox passwords, are encrypted at the application layer using envelope encryption.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="mt-8 pt-6 border-t border-[color:var(--border)]">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-muted-foreground mb-3">
|
||||
Related
|
||||
</div>
|
||||
<ul class="space-y-1">
|
||||
{legalDocs.map((d) => (
|
||||
<li>
|
||||
<a
|
||||
href={d.href}
|
||||
class={
|
||||
'block text-[13px] py-1 rounded-md transition-colors ' +
|
||||
(d.href === '/terms/'
|
||||
? 'text-foreground font-medium'
|
||||
: 'text-muted-foreground hover:text-[color:var(--brand-strong)]')
|
||||
}
|
||||
>
|
||||
{d.label}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<section id="ip" class="scroll-mt-24">
|
||||
<h2>09. Intellectual property</h2>
|
||||
<p>
|
||||
Warmbly and Mindroot Ltd retain all rights in the Service, including the brand, the trademarks, the visual identity, the documentation, and the proprietary parts of the platform. Open-source components are licensed under their respective licences and are not subject to this clause.
|
||||
</p>
|
||||
<p>
|
||||
Nothing in these Terms transfers any of your intellectual property to us, except for the limited operational licence in Section 08.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</aside>
|
||||
<section id="third-party" class="scroll-mt-24">
|
||||
<h2>10. Third-party services</h2>
|
||||
<p>
|
||||
Warmbly integrates with third-party services, including email providers, OAuth identity providers, payment processors such as Stripe, and infrastructure providers. Your use of those third-party services is governed by their own terms, and we are not responsible for their availability, content, or actions.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Main content column -->
|
||||
<article class="lg:col-span-9 max-w-3xl">
|
||||
<section id="warranties" class="scroll-mt-24">
|
||||
<h2>11. Disclaimers</h2>
|
||||
<p>
|
||||
Except where prohibited by mandatory law, the Service is provided on an "as is" and "as available" basis without warranties of any kind, whether express or implied, including warranties of merchantability, fitness for a particular purpose, non-infringement, accuracy, or uninterrupted operation.
|
||||
</p>
|
||||
<p>
|
||||
Email deliverability is influenced by many factors outside our control, including the behaviour of recipients, mailbox providers, blocklists, and your own sending practices. We make no guarantee that any specific email will reach a recipient's inbox.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Intro card -->
|
||||
<div class="rounded-[14px] bg-[color:var(--surface-2)] ring-1 ring-[color:var(--border)] p-6 md:p-7 mb-12 print:bg-white print:ring-0 print:p-0 print:mb-8">
|
||||
<div class="text-[10.5px] uppercase tracking-[0.18em] font-mono text-[color:var(--brand-strong)] mb-2">
|
||||
Summary
|
||||
</div>
|
||||
<p class="text-[15px] leading-relaxed text-foreground/85">
|
||||
Warmbly is a software service. You bring your mailboxes, your contacts, and your campaigns. We run the infrastructure that warms inboxes, sends mail, and reports on what happened. You agree not to use Warmbly for spam or anything illegal. We agree to keep the lights on, treat your data with care, and tell you before we change anything important.
|
||||
</p>
|
||||
</div>
|
||||
<section id="liability" class="scroll-mt-24">
|
||||
<h2>12. Limitation of liability</h2>
|
||||
<p>
|
||||
To the maximum extent permitted by law, neither party will be liable to the other for any indirect, incidental, special, consequential, or punitive damages, or for any loss of profits, revenue, goodwill, or data, even if advised of the possibility of such damages.
|
||||
</p>
|
||||
<p>
|
||||
Each party's total aggregate liability arising out of or relating to these Terms, whether in contract, tort, or otherwise, is limited to the fees you actually paid to Warmbly for the Service during the twelve months preceding the event giving rise to the claim.
|
||||
</p>
|
||||
<p>
|
||||
Nothing in these Terms limits liability for fraud, gross negligence, or for any liability that cannot lawfully be limited.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Reusable type rules for all sections -->
|
||||
<div class="
|
||||
[&_h2]:scroll-mt-28 [&_h2]:text-[24px] [&_h2]:md:text-[28px] [&_h2]:font-semibold [&_h2]:tracking-[-0.022em] [&_h2]:text-heading [&_h2]:mt-14 [&_h2]:mb-4 [&_h2]:first:mt-0 [&_h2]:flex [&_h2]:items-baseline [&_h2]:gap-3
|
||||
[&_h3]:text-[15.5px] [&_h3]:font-semibold [&_h3]:tracking-[-0.01em] [&_h3]:text-heading [&_h3]:mt-7 [&_h3]:mb-2
|
||||
[&_p]:text-[15px] [&_p]:leading-[1.7] [&_p]:text-foreground/85 [&_p]:mt-3
|
||||
[&_ul]:list-disc [&_ul]:pl-5 [&_ul]:mt-3 [&_ul]:space-y-1.5 [&_ul]:text-[14.5px] [&_ul]:text-foreground/85
|
||||
[&_ol]:list-decimal [&_ol]:pl-5 [&_ol]:mt-3 [&_ol]:space-y-1.5 [&_ol]:text-[14.5px] [&_ol]:text-foreground/85
|
||||
[&_a]:text-[color:var(--brand)] [&_a]:underline [&_a]:underline-offset-[3px] [&_a]:decoration-[color:var(--brand)]/30 hover:[&_a]:decoration-[color:var(--brand)] hover:[&_a]:text-[color:var(--brand-strong)]
|
||||
[&_code]:font-mono [&_code]:text-[0.92em] [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:bg-[color:var(--surface-2)] [&_code]:ring-1 [&_code]:ring-[color:var(--border)]
|
||||
">
|
||||
<section id="indemnity" class="scroll-mt-24">
|
||||
<h2>13. Indemnification</h2>
|
||||
<p>
|
||||
You agree to defend, indemnify, and hold harmless Mindroot Ltd, its officers, employees, and affiliates from and against any claims, damages, liabilities, and reasonable legal costs arising from your Customer content, your use of the Service in breach of these Terms, or your violation of any law or third-party right.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 01 Acceptance -->
|
||||
<h2 id="acceptance">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">01</span>
|
||||
<span>Acceptance of terms</span>
|
||||
</h2>
|
||||
<p>
|
||||
These Terms of Service ("Terms") form a binding agreement between you and Warmbly ("Warmbly", "we", "us"). By creating an account, signing in, or using any part of the Warmbly platform, websites, APIs, dashboards, or worker software (together, the "Service"), you agree to these Terms.
|
||||
</p>
|
||||
<p>
|
||||
If you are accepting on behalf of a company, you confirm that you have authority to bind that company, and "you" then refers to that company. If you do not agree to these Terms, do not use the Service.
|
||||
</p>
|
||||
<p>
|
||||
You must be at least 18 years old and legally able to enter into a contract.
|
||||
</p>
|
||||
<section id="termination" class="scroll-mt-24">
|
||||
<h2>14. Termination</h2>
|
||||
<p>
|
||||
You may cancel your account at any time from the billing area of your workspace. We may suspend or terminate your access if you breach these Terms, if your use of the Service creates a security or deliverability risk to other users, or if we are required to do so by law.
|
||||
</p>
|
||||
<p>
|
||||
On termination, your right to use the Service ends immediately. We will retain or delete Customer content as described in our <a href="/privacy/">privacy policy</a>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 02 Definitions -->
|
||||
<h2 id="definitions">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">02</span>
|
||||
<span>Definitions</span>
|
||||
</h2>
|
||||
<ul>
|
||||
<li><strong class="text-heading font-semibold">Account</strong>. The login and workspace you create on Warmbly.</li>
|
||||
<li><strong class="text-heading font-semibold">Service</strong>. The hosted Warmbly product, including the dashboard, API, worker software, and supporting infrastructure.</li>
|
||||
<li><strong class="text-heading font-semibold">Customer content</strong>. The data you upload or connect, such as contacts, mailbox credentials, campaigns, replies, and message bodies.</li>
|
||||
<li><strong class="text-heading font-semibold">Subscription</strong>. A paid plan billed on a recurring basis through our payment processor.</li>
|
||||
<li><strong class="text-heading font-semibold">Mailbox</strong>. An email account you connect to Warmbly for warmup or sending.</li>
|
||||
</ul>
|
||||
<section id="law" class="scroll-mt-24">
|
||||
<h2>15. Governing law and jurisdiction</h2>
|
||||
<p>
|
||||
These Terms are governed by and construed in accordance with the laws of England and Wales. You and Mindroot Ltd agree to submit to the exclusive jurisdiction of the courts of London, United Kingdom, for any dispute arising out of or relating to these Terms or your use of the Service.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 03 Account -->
|
||||
<h2 id="account">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">03</span>
|
||||
<span>Account registration and security</span>
|
||||
</h2>
|
||||
<p>
|
||||
You agree to provide accurate information when you register, and to keep that information current. You are responsible for everything that happens under your account, including actions taken by team members or API clients you authorize.
|
||||
</p>
|
||||
<p>
|
||||
You agree to protect your credentials, use a strong password, and enable available account-security features. Notify us promptly at <a href="mailto:security@warmbly.com">security@warmbly.com</a> if you suspect unauthorized access.
|
||||
</p>
|
||||
<p>
|
||||
We may suspend access to your account if we reasonably believe it has been compromised, until you can confirm it is secure.
|
||||
</p>
|
||||
<section id="changes" class="scroll-mt-24">
|
||||
<h2>16. Changes to these terms</h2>
|
||||
<p>
|
||||
We may update these Terms from time to time. If we make material changes, we will notify you by email or through the Service before the changes take effect. Your continued use of the Service after the effective date constitutes acceptance of the updated Terms.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 04 Acceptable use -->
|
||||
<h2 id="acceptable-use">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">04</span>
|
||||
<span>Acceptable use</span>
|
||||
</h2>
|
||||
<p>
|
||||
Your use of the Service must follow our <a href="/acceptable-use/">Acceptable Use Policy</a>. In short, do not use Warmbly to send unsolicited bulk mail outside what is permitted by the law in the relevant jurisdiction, do not forge sender identity, do not attempt to bypass authentication, and do not send content that is fraudulent, deceptive, or illegal.
|
||||
</p>
|
||||
<p>
|
||||
You are also responsible for keeping your sender domain configured correctly, including SPF, DKIM, and DMARC alignment where relevant.
|
||||
</p>
|
||||
<p>
|
||||
We may remove content, throttle traffic, or suspend the account if your use threatens the platform's shared infrastructure or recipient trust. Where it is reasonable, we will tell you what is wrong and give you a chance to fix it before we act.
|
||||
</p>
|
||||
<section id="contact" class="scroll-mt-24">
|
||||
<h2>17. Contact</h2>
|
||||
<p>
|
||||
Questions or concerns about these Terms can be sent to <a href="mailto:hello@warmbly.com">hello@warmbly.com</a> or by post to Mindroot Ltd, 71-75 Shelton Street, London, England, WC2H 9JQ.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 05 Service availability -->
|
||||
<h2 id="availability">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">05</span>
|
||||
<span>Service availability and changes</span>
|
||||
</h2>
|
||||
<p>
|
||||
We work to keep the Service available, but we do not guarantee uninterrupted access. Maintenance windows, third-party outages, and unexpected incidents will happen. We try to communicate planned downtime in advance through the status page or in-app notice.
|
||||
</p>
|
||||
<p>
|
||||
We may add, change, deprecate, or remove features over time. If a change materially reduces functionality you depend on, we will give reasonable notice through email or an in-app notice before the change takes effect.
|
||||
</p>
|
||||
|
||||
<!-- 06 Billing -->
|
||||
<h2 id="billing">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">06</span>
|
||||
<span>Subscription, billing, refunds</span>
|
||||
</h2>
|
||||
<h3>Subscriptions</h3>
|
||||
<p>
|
||||
Paid plans are billed in advance on a recurring basis (monthly or annual, depending on the plan you choose). Subscriptions automatically renew at the end of each billing period until you cancel.
|
||||
</p>
|
||||
<h3>Payment processor</h3>
|
||||
<p>
|
||||
Payments are processed by Stripe. By providing a payment method, you authorize us, through Stripe, to charge the fees due for your plan. We do not store full card numbers. The complete list of providers that handle data on our behalf is at <a href="/subprocessors/">/subprocessors</a>.
|
||||
</p>
|
||||
<h3>Cancellation</h3>
|
||||
<p>
|
||||
You can cancel at any time from the dashboard. Cancellation takes effect at the end of the current billing period. You keep access to the paid plan until then.
|
||||
</p>
|
||||
<h3>Refunds</h3>
|
||||
<p>
|
||||
We offer a 14-day refund on a new paid subscription if the Service has not worked for you. After 14 days, fees are non-refundable except where required by law. Usage-based or overage charges are not refundable.
|
||||
</p>
|
||||
<h3>Taxes</h3>
|
||||
<p>
|
||||
Prices do not include taxes unless stated. You are responsible for any sales tax, VAT, GST, or similar charges, except for taxes based on our net income.
|
||||
</p>
|
||||
|
||||
<!-- 07 IP -->
|
||||
<h2 id="ip">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">07</span>
|
||||
<span>Intellectual property</span>
|
||||
</h2>
|
||||
<p>
|
||||
Warmbly and its licensors own the Service, including its software, design, documentation, trademarks, and the trademarks "Warmbly" and the Warmbly logo. We grant you a limited, non-exclusive, non-transferable, revocable right to access and use the Service during the term of your subscription.
|
||||
</p>
|
||||
<p>
|
||||
You are not granted any other rights, including the right to copy, redistribute, sublicense, or create derivative works from the Service, except where permitted by an open-source license that applies to a specific component.
|
||||
</p>
|
||||
<p>
|
||||
If you send us feedback or suggestions, you grant us a perpetual, worldwide, royalty-free right to use that feedback to improve the Service. We will not identify you as the source without your permission.
|
||||
</p>
|
||||
|
||||
<!-- 08 User content -->
|
||||
<h2 id="user-content">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">08</span>
|
||||
<span>User content and your data</span>
|
||||
</h2>
|
||||
<p>
|
||||
You retain all rights in your customer content. You grant Warmbly a limited license to host, transmit, process, and store that content as needed to deliver the Service, support your account, prevent abuse, and meet our legal obligations.
|
||||
</p>
|
||||
<p>
|
||||
You confirm that you have the right to use the customer content you upload (including contact lists), that recipients are in scope for the law that applies to your sending, and that you will honor opt-outs and unsubscribe requests promptly.
|
||||
</p>
|
||||
<p>
|
||||
How we handle personal data is explained in our <a href="/privacy/">Privacy Policy</a>. If you are a controller of personal data processed through the Service, our <a href="/dpa/">Data Processing Addendum</a> applies.
|
||||
</p>
|
||||
|
||||
<!-- 09 Confidentiality -->
|
||||
<h2 id="confidentiality">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">09</span>
|
||||
<span>Confidentiality</span>
|
||||
</h2>
|
||||
<p>
|
||||
Each party may receive information from the other that is marked confidential, or that a reasonable person would treat as confidential. Each party will protect the other's confidential information with the same care it uses for its own, and will not disclose it except as needed to perform under these Terms or as required by law.
|
||||
</p>
|
||||
<p>
|
||||
Confidential information does not include information that is public through no fault of the receiving party, that the receiving party already had without confidentiality obligations, or that is independently developed.
|
||||
</p>
|
||||
|
||||
<!-- 10 Third party -->
|
||||
<h2 id="third-party">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">10</span>
|
||||
<span>Third-party services</span>
|
||||
</h2>
|
||||
<p>
|
||||
The Service connects to third-party providers, such as email providers (Google, Microsoft, custom SMTP), payment processors, and analytics platforms. Your use of those providers is governed by their own terms and policies, which you accept when you connect them.
|
||||
</p>
|
||||
<p>
|
||||
We are not responsible for the availability, accuracy, or behavior of third-party services. If a third-party provider changes its API or pricing, we will adapt as quickly as we reasonably can.
|
||||
</p>
|
||||
|
||||
<!-- 11 Disclaimers -->
|
||||
<h2 id="disclaimers">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">11</span>
|
||||
<span>Disclaimers</span>
|
||||
</h2>
|
||||
<p>
|
||||
The Service is provided "as is" and "as available". To the maximum extent permitted by law, Warmbly disclaims all warranties, express or implied, including warranties of merchantability, fitness for a particular purpose, non-infringement, and any warranty that arises from a course of dealing or usage of trade.
|
||||
</p>
|
||||
<p>
|
||||
We do not guarantee a specific deliverability outcome, inbox placement rate, reply rate, or revenue result. Email deliverability depends on authentication, content, recipient behavior, and provider-side reputation, much of which is outside our direct control.
|
||||
</p>
|
||||
<p>
|
||||
Nothing in these Terms limits any warranty or right that cannot be limited under applicable law.
|
||||
</p>
|
||||
|
||||
<!-- 12 Liability -->
|
||||
<h2 id="liability">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">12</span>
|
||||
<span>Limitation of liability</span>
|
||||
</h2>
|
||||
<p>
|
||||
To the maximum extent permitted by law, Warmbly's total liability for any claim arising out of or related to these Terms or the Service will not exceed the fees you paid to Warmbly in the 12 months before the event that gave rise to the claim.
|
||||
</p>
|
||||
<p>
|
||||
Neither party will be liable for indirect, incidental, consequential, special, exemplary, or punitive damages, or for loss of profits, revenue, goodwill, or data, even if advised of the possibility.
|
||||
</p>
|
||||
<p>
|
||||
These limits do not apply to liability that cannot be limited under applicable law, including liability for gross negligence or willful misconduct where the law does not allow exclusion.
|
||||
</p>
|
||||
|
||||
<!-- 13 Indemnification -->
|
||||
<h2 id="indemnification">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">13</span>
|
||||
<span>Indemnification</span>
|
||||
</h2>
|
||||
<p>
|
||||
You agree to defend, indemnify, and hold harmless Warmbly, its affiliates, and its employees from any third-party claim, loss, or expense (including reasonable legal fees) arising from your customer content, your use of the Service in breach of these Terms, or your violation of applicable law.
|
||||
</p>
|
||||
<p>
|
||||
We will tell you promptly about any claim, give you reasonable control of the defense, and cooperate with you at your expense. You may not settle a claim that imposes any obligation on us without our prior written consent.
|
||||
</p>
|
||||
|
||||
<!-- 14 Termination -->
|
||||
<h2 id="termination">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">14</span>
|
||||
<span>Termination</span>
|
||||
</h2>
|
||||
<p>
|
||||
You may stop using the Service at any time and cancel your subscription from the dashboard.
|
||||
</p>
|
||||
<p>
|
||||
We may suspend or terminate your access if you breach these Terms or the Acceptable Use Policy, if your use generates complaint, bounce, or abuse signals that threaten the platform's shared infrastructure, or if we are required to do so by law. Where it is reasonable, we will tell you the reason and give you a chance to fix it first.
|
||||
</p>
|
||||
<p>
|
||||
On termination, your right to use the Service ends. We will keep customer content for a reasonable wind-down period (typically up to 30 days) so you can export it, after which we may delete it. Provisions that by their nature should survive termination will survive, including the sections on intellectual property, confidentiality, disclaimers, limitation of liability, indemnification, and governing law.
|
||||
</p>
|
||||
|
||||
<!-- 15 Governing law -->
|
||||
<h2 id="governing-law">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">15</span>
|
||||
<span>Governing law and jurisdiction</span>
|
||||
</h2>
|
||||
<p>
|
||||
These Terms are governed by the laws of the jurisdiction of Warmbly's principal place of business, without regard to its conflict-of-laws rules. The courts located in that jurisdiction have exclusive jurisdiction over any dispute arising out of or related to these Terms or the Service, except where local consumer-protection law gives you the right to bring a claim in your own jurisdiction.
|
||||
</p>
|
||||
<p>
|
||||
Nothing in this section limits either party's right to seek injunctive relief in any court of competent jurisdiction to protect intellectual-property or confidential information.
|
||||
</p>
|
||||
|
||||
<!-- 16 Changes -->
|
||||
<h2 id="changes">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">16</span>
|
||||
<span>Changes to these terms</span>
|
||||
</h2>
|
||||
<p>
|
||||
We may update these Terms over time. When we make a material change, we will give at least 30 days notice through email or an in-app notice before the change takes effect. The "Last updated" date at the top of this page always reflects the most recent version.
|
||||
</p>
|
||||
<p>
|
||||
If you keep using the Service after the change takes effect, you accept the updated Terms. If you do not agree, you can stop using the Service and cancel your subscription before the effective date.
|
||||
</p>
|
||||
|
||||
<!-- 17 Contact -->
|
||||
<h2 id="contact">
|
||||
<span class="font-mono text-[14px] text-muted-foreground tabular-nums pt-1">17</span>
|
||||
<span>Contact</span>
|
||||
</h2>
|
||||
<p>
|
||||
Questions about these Terms? Email <a href="mailto:legal@warmbly.com">legal@warmbly.com</a> and we will get back to you.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Footer note -->
|
||||
<div class="mt-16 pt-6 border-t border-[color:var(--border)] flex flex-wrap items-baseline justify-between gap-3 text-[12.5px] text-muted-foreground">
|
||||
<div>
|
||||
Last updated <span class="font-mono text-foreground/80">{lastUpdated}</span>. Effective <span class="font-mono text-foreground/80">{effectiveFrom}</span>.
|
||||
</div>
|
||||
<a href="#" class="text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] print:hidden">Back to top</a>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
@media print {
|
||||
aside { display: none !important; }
|
||||
section { padding: 0 !important; }
|
||||
h2 { break-after: avoid; page-break-after: avoid; }
|
||||
p, li { orphans: 3; widows: 3; }
|
||||
}
|
||||
</style>
|
||||
</Layout>
|
||||
</Legal>
|
||||
|
||||
+13
-16
@@ -44,7 +44,7 @@ const posture = [
|
||||
},
|
||||
{
|
||||
label: 'GDPR-aligned data handling',
|
||||
note: 'DPA on request. Subprocessor notice via /subprocessors/.',
|
||||
note: 'Plain-English privacy policy and data processing terms on request.',
|
||||
state: 'shipped',
|
||||
},
|
||||
{
|
||||
@@ -107,7 +107,7 @@ const neverCollect = [
|
||||
'Cross-customer data sharing. Tenancy is enforced at the query layer.',
|
||||
];
|
||||
|
||||
// Subprocessor summary. Full list lives at /subprocessors/.
|
||||
// Subprocessor summary. The infrastructure Warmbly relies on to run.
|
||||
const subs = [
|
||||
{ name: 'AWS', use: 'Compute, KMS, DynamoDB, S3, MSK, RDS', region: 'us-east-1, eu-west-1' },
|
||||
{ name: 'Cloudflare', use: 'Edge, DDoS, Turnstile CAPTCHA', region: 'Global' },
|
||||
@@ -196,7 +196,7 @@ const disclosure = [
|
||||
</p>
|
||||
|
||||
<div class="mt-8 flex flex-wrap items-center justify-center gap-3">
|
||||
<a href="mailto:security@warmbly.com" class="inline-flex h-11 px-5 items-center gap-2 rounded-[10px] text-[14.5px] font-semibold bg-white hover:-translate-y-0.5 hover:shadow-[0_12px_28px_-6px_rgba(0,0,0,0.3)] transition-all duration-200 ease-out shadow-[0_4px_14px_-2px_rgba(0,0,0,0.18)]">
|
||||
<a href="mailto:hello@warmbly.com" class="inline-flex h-11 px-5 items-center gap-2 rounded-[10px] text-[14.5px] font-semibold bg-white hover:-translate-y-0.5 hover:shadow-[0_12px_28px_-6px_rgba(0,0,0,0.3)] transition-all duration-200 ease-out shadow-[0_4px_14px_-2px_rgba(0,0,0,0.18)]">
|
||||
<span style="color:#075985;">Report a vulnerability</span>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#075985" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>
|
||||
@@ -223,8 +223,8 @@ const disclosure = [
|
||||
<div class="text-[10px] uppercase tracking-[0.14em] text-slate-400 font-medium">Posture</div>
|
||||
<div class="mt-0.5 text-[13px] text-slate-900 font-medium">What we have shipped, and what is on the roadmap.</div>
|
||||
</div>
|
||||
<a href="/subprocessors/" class="ml-auto text-[12px] font-medium text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] inline-flex items-center gap-1">
|
||||
Subprocessors <Icon name="arrowUpRight" size={11} />
|
||||
<a href="/changelog/" class="ml-auto text-[12px] font-medium text-[color:var(--brand)] hover:text-[color:var(--brand-strong)] inline-flex items-center gap-1">
|
||||
Changelog <Icon name="arrowUpRight" size={11} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -462,12 +462,9 @@ const disclosure = [
|
||||
<div class="text-[11px] uppercase tracking-[0.18em] text-muted-foreground font-mono mb-3">Subprocessors</div>
|
||||
<h2 class="text-[28px] md:text-[40px] font-semibold tracking-[-0.03em] leading-[1.05] text-heading">Who else touches your data.</h2>
|
||||
<p class="mt-4 text-[15px] text-foreground/75 leading-relaxed">
|
||||
A short summary of the third parties Warmbly engages. The full list, with regions and country of processing, lives at /subprocessors/.
|
||||
The infrastructure and operational providers Warmbly relies on to run.
|
||||
</p>
|
||||
</div>
|
||||
<a href="/subprocessors/" class="inline-flex h-10 px-4 items-center gap-2 rounded-[10px] text-[13px] font-medium bg-white ring-1 ring-[color:var(--border)] text-heading hover:bg-[color:var(--surface-2)]">
|
||||
Full subprocessor list <Icon name="arrowUpRight" size={12} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="rounded-[14px] bg-white ring-1 ring-[color:var(--border)] overflow-hidden" style="box-shadow: var(--shadow-sm);">
|
||||
@@ -502,7 +499,7 @@ const disclosure = [
|
||||
Found something. Tell us first.
|
||||
</h2>
|
||||
<p class="mt-4 text-[15px] text-foreground/75 leading-relaxed">
|
||||
We welcome reports from security researchers and operators. Send a description, a proof of concept, and any logs to <span class="font-mono text-heading">security@warmbly.com</span>. We will acknowledge quickly, triage in the open, and keep you posted until the fix ships.
|
||||
We welcome reports from security researchers and operators. Send a description, a proof of concept, and any logs to <span class="font-mono text-heading">hello@warmbly.com</span>. We will acknowledge quickly, triage in the open, and keep you posted until the fix ships.
|
||||
</p>
|
||||
<p class="mt-3 text-[14.5px] text-foreground/70 leading-relaxed">
|
||||
Please avoid testing that degrades service for other customers, accesses data that is not your own, or relies on social engineering of employees or contractors. Good faith research is welcome.
|
||||
@@ -510,7 +507,7 @@ const disclosure = [
|
||||
|
||||
<div class="mt-6 inline-flex items-center gap-2 px-3 py-2 rounded-[10px] bg-white ring-1 ring-[color:var(--border)]">
|
||||
<Icon name="mail" size={14} class="text-[color:var(--sky-5)]" />
|
||||
<a href="mailto:security@warmbly.com" class="font-mono text-[13px] text-heading hover:text-[color:var(--brand-strong)]">security@warmbly.com</a>
|
||||
<a href="mailto:hello@warmbly.com" class="font-mono text-[13px] text-heading hover:text-[color:var(--brand-strong)]">hello@warmbly.com</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -561,11 +558,11 @@ const disclosure = [
|
||||
|
||||
<CTA
|
||||
title="Want the full security package?"
|
||||
description="DPA, security questionnaire, and architecture deep dive on request. Replies from a human within one business day."
|
||||
primaryLabel="Email security@warmbly.com"
|
||||
primaryHref="mailto:security@warmbly.com"
|
||||
secondaryLabel="See subprocessors"
|
||||
secondaryHref="/subprocessors/"
|
||||
description="Data processing terms, security questionnaire, and architecture deep dive on request. Replies from a human within one business day."
|
||||
primaryLabel="Email hello@warmbly.com"
|
||||
primaryHref="mailto:hello@warmbly.com"
|
||||
secondaryLabel="Read the privacy policy"
|
||||
secondaryHref="/privacy/"
|
||||
/>
|
||||
</Layout>
|
||||
</content>
|
||||
|
||||
Reference in New Issue
Block a user