Files
Christian Krakau-Louis 8bb9888e4c Polish bilingual landing page
2026-05-22 19:13:14 +02:00

1726 lines
58 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>InboxConverge | Self-hosted Gmail mailbox consolidation</title>
<meta
name="description"
content="InboxConverge is a self-hosted replacement for Gmail POP import and Gmailify, built for reliable mailbox consolidation into Gmail."
>
<meta property="og:title" content="InboxConverge">
<meta
property="og:description"
content="Keep external mailboxes flowing into Gmail after POP import and Gmailify go away."
>
<meta property="og:type" content="website">
<meta property="og:url" content="https://www.inboxconverge.com/">
<meta name="theme-color" content="#0b63f6">
<link rel="canonical" href="https://www.inboxconverge.com/">
<link rel="alternate" hreflang="en" href="https://www.inboxconverge.com/?lang=en">
<link rel="alternate" hreflang="de" href="https://www.inboxconverge.com/?lang=de">
<style>
:root {
color-scheme: light;
--bg: #ffffff;
--bg-soft: #f7faff;
--bg-blue: #eef5ff;
--ink: #10213f;
--ink-strong: #07162f;
--muted: #52617a;
--muted-2: #6c7890;
--line: #d9e3f2;
--line-strong: #b8c8df;
--blue: #0b63f6;
--blue-deep: #0649bf;
--green: #11834d;
--green-soft: #e8f7ef;
--shadow: 0 24px 70px rgba(16, 33, 63, 0.11);
--radius: 8px;
--max: 1180px;
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
background:
linear-gradient(180deg, rgba(238, 245, 255, 0.82), rgba(255, 255, 255, 0) 380px),
var(--bg);
color: var(--ink);
font-family:
Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
sans-serif;
letter-spacing: 0;
}
a {
color: inherit;
text-decoration: none;
}
button {
font: inherit;
}
.site-header {
position: sticky;
top: 0;
z-index: 10;
border-bottom: 1px solid rgba(217, 227, 242, 0.82);
background: rgba(255, 255, 255, 0.92);
backdrop-filter: blur(18px);
}
.nav {
display: flex;
align-items: center;
justify-content: space-between;
gap: 22px;
max-width: var(--max);
min-height: 76px;
margin: 0 auto;
padding: 0 28px;
}
.brand {
display: inline-flex;
align-items: center;
gap: 11px;
color: var(--ink-strong);
font-size: 1.25rem;
font-weight: 800;
white-space: nowrap;
}
.brand-mark,
.icon-box {
display: inline-grid;
place-items: center;
width: 34px;
height: 34px;
border: 2px solid var(--blue);
border-radius: 6px;
color: var(--blue);
background: #ffffff;
}
.brand-mark svg,
.icon-box svg,
.mini-icon svg {
width: 20px;
height: 20px;
}
.nav-links {
display: flex;
align-items: center;
gap: 25px;
color: #1d2c49;
font-size: 0.94rem;
font-weight: 650;
}
.nav-links a {
color: #24344f;
}
.nav-actions {
display: flex;
align-items: center;
gap: 12px;
}
.button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 9px;
min-height: 46px;
padding: 0 18px;
border: 1px solid transparent;
border-radius: var(--radius);
background: var(--blue);
color: #ffffff;
font-size: 0.95rem;
font-weight: 760;
box-shadow: 0 14px 28px rgba(11, 99, 246, 0.18);
transition:
transform 170ms ease,
border-color 170ms ease,
background 170ms ease,
box-shadow 170ms ease;
}
.button:hover {
transform: translateY(-1px);
background: var(--blue-deep);
box-shadow: 0 18px 34px rgba(11, 99, 246, 0.22);
}
.button.secondary {
border-color: var(--line-strong);
background: #ffffff;
color: var(--ink);
box-shadow: none;
}
.button.secondary:hover {
border-color: #8aa5ca;
background: #f9fbff;
}
.button.wide {
width: 100%;
}
.lang-toggle {
display: inline-grid;
grid-template-columns: 1fr 1fr;
overflow: hidden;
min-width: 88px;
height: 42px;
border: 1px solid var(--line-strong);
border-radius: var(--radius);
background: #ffffff;
}
.lang-toggle button {
border: 0;
background: transparent;
color: var(--muted);
font-size: 0.86rem;
font-weight: 760;
cursor: pointer;
}
.lang-toggle button[aria-pressed="true"] {
background: var(--ink);
color: #ffffff;
}
.hero {
position: relative;
max-width: var(--max);
min-height: calc(100vh - 76px);
margin: 0 auto;
padding: 84px 28px 36px;
}
.hero::before {
position: absolute;
inset: 32px 28px auto auto;
width: min(56vw, 700px);
height: 440px;
pointer-events: none;
content: "";
background-image:
linear-gradient(rgba(11, 99, 246, 0.08) 1px, transparent 1px),
linear-gradient(90deg, rgba(11, 99, 246, 0.08) 1px, transparent 1px);
background-size: 24px 24px;
mask-image: radial-gradient(circle at center, #000 0%, rgba(0, 0, 0, 0.55) 45%, transparent 74%);
}
.hero-grid {
position: relative;
display: grid;
grid-template-columns: minmax(0, 0.95fr) minmax(420px, 1fr);
gap: 42px;
align-items: center;
}
.hero-grid > * {
min-width: 0;
}
.hero-copy {
max-width: 620px;
min-width: 0;
}
h1,
h2,
h3,
p {
margin-top: 0;
}
h1 {
margin-bottom: 24px;
color: var(--ink-strong);
font-size: 4.35rem;
font-weight: 850;
line-height: 0.98;
letter-spacing: 0;
overflow-wrap: break-word;
}
.lead {
max-width: 585px;
margin-bottom: 30px;
color: var(--muted);
font-size: 1.2rem;
line-height: 1.68;
}
.hero-actions {
display: flex;
flex-wrap: wrap;
gap: 13px;
margin-bottom: 29px;
}
.proof-list {
display: flex;
flex-wrap: wrap;
gap: 18px;
margin: 0;
padding: 0;
color: #30405d;
list-style: none;
}
.proof-list li {
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 0.96rem;
font-weight: 600;
}
.check {
color: var(--green);
font-weight: 900;
}
.workflow-panel {
position: relative;
min-width: 0;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(255, 255, 255, 0.94);
box-shadow: var(--shadow);
padding: 26px;
}
.workflow-panel::after {
position: absolute;
right: 24px;
bottom: -20px;
left: 24px;
height: 20px;
border: 1px solid rgba(217, 227, 242, 0.9);
border-top: 0;
border-radius: 0 0 var(--radius) var(--radius);
background: rgba(247, 250, 255, 0.78);
content: "";
}
.panel-title {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 16px;
margin-bottom: 23px;
}
.panel-title strong {
color: var(--ink-strong);
font-size: 1rem;
}
.status {
display: inline-flex;
align-items: center;
gap: 7px;
color: var(--green);
font-size: 0.82rem;
font-weight: 800;
}
.status::before {
width: 8px;
height: 8px;
border-radius: 999px;
background: currentColor;
content: "";
}
.flow-canvas {
display: grid;
grid-template-columns: minmax(180px, 1fr) 88px minmax(150px, 0.82fr) 88px minmax(132px, 0.7fr);
align-items: center;
gap: 0;
}
.source-stack,
.server-card,
.gmail-card,
.task-card,
.flow-strip {
border: 1px solid var(--line);
border-radius: var(--radius);
background: #ffffff;
}
.source-stack {
min-width: 0;
padding: 15px;
}
.source-title,
.server-card strong,
.gmail-card strong,
.flow-step strong {
display: block;
color: var(--ink-strong);
font-size: 0.88rem;
font-weight: 820;
}
.source-row {
display: grid;
grid-template-columns: 34px 1fr;
gap: 10px;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid #edf2f8;
}
.source-row:last-child {
border-bottom: 0;
}
.mini-icon {
display: inline-grid;
place-items: center;
width: 34px;
height: 34px;
border: 1px solid var(--line-strong);
border-radius: 7px;
color: var(--blue);
background: #fbfdff;
font-weight: 820;
}
.source-row span,
.task-card span,
.gmail-card span,
.server-card span,
.flow-step span {
display: block;
min-width: 0;
color: var(--muted);
font-size: 0.77rem;
line-height: 1.4;
}
.source-row b {
display: block;
color: #1c2d49;
font-size: 0.83rem;
}
.server-card,
.gmail-card {
display: grid;
place-items: center;
min-height: 138px;
padding: 16px 12px;
text-align: center;
}
.server-card {
border-color: rgba(11, 99, 246, 0.48);
box-shadow: inset 0 0 0 1px rgba(11, 99, 246, 0.15);
}
.gmail-logo {
width: 47px;
height: 36px;
margin-bottom: 12px;
}
.connector {
position: relative;
height: 2px;
background-image: linear-gradient(90deg, var(--blue) 45%, transparent 0);
background-size: 10px 2px;
}
.connector::after {
position: absolute;
top: 50%;
right: -1px;
width: 10px;
height: 10px;
border-top: 2px solid var(--blue);
border-right: 2px solid var(--blue);
content: "";
transform: translateY(-50%) rotate(45deg);
}
.task-card {
position: absolute;
right: 190px;
bottom: 24px;
width: 176px;
padding: 14px;
box-shadow: 0 16px 38px rgba(16, 33, 63, 0.1);
}
.task-card ul {
display: grid;
gap: 9px;
margin: 0;
padding: 0;
list-style: none;
}
.task-card li {
display: flex;
gap: 8px;
color: #263754;
font-size: 0.82rem;
font-weight: 650;
}
.flow-strip {
display: grid;
grid-template-columns: 1fr 0.38fr 1fr 0.38fr 1fr;
align-items: center;
gap: 18px;
max-width: var(--max);
margin: 52px auto 0;
padding: 26px 32px;
background: linear-gradient(180deg, #ffffff, #fbfdff);
}
.flow-step {
display: grid;
justify-items: center;
gap: 11px;
text-align: center;
}
.flow-icons {
display: flex;
gap: 8px;
}
.flow-arrow {
display: grid;
place-items: center;
color: var(--blue);
}
.section {
max-width: var(--max);
margin: 0 auto;
padding: 74px 28px 0;
}
.section-heading {
max-width: 760px;
margin: 0 auto 42px;
text-align: center;
}
h2 {
margin-bottom: 16px;
color: var(--ink-strong);
font-size: clamp(2rem, 3vw, 2.75rem);
font-weight: 830;
line-height: 1.1;
letter-spacing: 0;
}
.section-heading p {
margin: 0;
color: var(--muted);
font-size: 1.08rem;
line-height: 1.62;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line);
}
.feature-card {
min-height: 352px;
padding: 34px 38px;
border-right: 1px solid var(--line);
}
.feature-card:last-child {
border-right: 0;
}
.feature-card .icon-box {
width: 50px;
height: 50px;
margin-bottom: 26px;
border-color: var(--line-strong);
color: var(--blue);
}
.feature-card h3 {
margin-bottom: 14px;
color: var(--ink-strong);
font-size: 1.24rem;
line-height: 1.25;
}
.feature-card p {
margin-bottom: 22px;
color: var(--muted);
line-height: 1.6;
}
.tick-list {
display: grid;
gap: 9px;
margin: 0;
padding: 0;
list-style: none;
}
.tick-list li {
display: flex;
gap: 10px;
color: #24344f;
font-size: 0.92rem;
}
.control-section {
display: grid;
grid-template-columns: minmax(0, 0.84fr) minmax(390px, 1.16fr);
gap: 42px;
align-items: center;
}
.control-copy h2 {
text-align: left;
}
.control-copy p {
max-width: 520px;
color: var(--muted);
font-size: 1.08rem;
line-height: 1.66;
}
.mini-metrics {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
margin-top: 28px;
}
.metric {
border: 1px solid var(--line);
border-radius: var(--radius);
background: #ffffff;
padding: 16px;
}
.metric strong {
display: block;
color: var(--ink-strong);
font-size: 1.25rem;
}
.metric span {
color: var(--muted-2);
font-size: 0.8rem;
font-weight: 650;
}
.dashboard {
overflow: hidden;
border: 1px solid var(--line);
border-radius: var(--radius);
background: #ffffff;
box-shadow: var(--shadow);
}
.dashboard-top {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 16px 18px;
border-bottom: 1px solid var(--line);
background: #fbfdff;
}
.window-dots {
display: flex;
gap: 7px;
}
.window-dots span {
width: 10px;
height: 10px;
border-radius: 999px;
background: #c4d2e5;
}
.dashboard-body {
display: grid;
grid-template-columns: 170px 1fr;
min-height: 355px;
}
.side-rail {
border-right: 1px solid var(--line);
background: #f7faff;
padding: 18px;
}
.rail-item {
display: flex;
align-items: center;
gap: 10px;
min-height: 38px;
border-radius: 7px;
color: #34435d;
font-size: 0.84rem;
font-weight: 730;
}
.rail-item.active {
padding: 0 10px;
background: #e7f0ff;
color: var(--blue-deep);
}
.activity {
padding: 18px;
}
.activity-row {
display: grid;
grid-template-columns: 34px 1fr auto;
gap: 12px;
align-items: center;
min-height: 66px;
border-bottom: 1px solid #edf2f8;
}
.activity-row:last-child {
border-bottom: 0;
}
.activity-row b {
display: block;
color: #1b2c48;
font-size: 0.9rem;
}
.activity-row span {
color: var(--muted);
font-size: 0.78rem;
}
.sync-state {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 82px;
min-height: 28px;
border-radius: 7px;
background: var(--green-soft);
color: var(--green);
font-size: 0.76rem;
font-weight: 850;
}
.steps {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 28px;
}
.step {
position: relative;
display: grid;
justify-items: center;
min-height: 230px;
text-align: center;
}
.step:not(:last-child)::after {
position: absolute;
top: 54px;
left: calc(50% + 76px);
width: calc(100% - 124px);
height: 2px;
background-image: linear-gradient(90deg, var(--blue) 45%, transparent 0);
background-size: 12px 2px;
content: "";
}
.step-number {
display: grid;
place-items: center;
width: 36px;
height: 36px;
margin-bottom: 14px;
border-radius: 999px;
background: var(--blue);
color: #ffffff;
font-weight: 850;
}
.step .icon-box {
width: 58px;
height: 58px;
margin-bottom: 20px;
border-color: var(--line-strong);
}
.step h3 {
margin-bottom: 10px;
color: var(--ink-strong);
font-size: 1rem;
}
.step p {
max-width: 260px;
color: var(--muted);
font-size: 0.92rem;
line-height: 1.55;
}
.cta-band {
display: grid;
grid-template-columns: 1fr minmax(280px, 430px);
gap: 32px;
align-items: center;
border: 1px solid var(--line);
border-radius: var(--radius);
background: linear-gradient(135deg, #f8fbff, #ffffff);
padding: 38px 44px;
}
.cta-band h2 {
margin-bottom: 12px;
font-size: clamp(1.8rem, 2.8vw, 2.45rem);
}
.cta-band p {
max-width: 560px;
margin-bottom: 0;
color: var(--muted);
font-size: 1.04rem;
line-height: 1.6;
}
.cta-actions {
display: grid;
gap: 12px;
}
.site-footer {
margin-top: 82px;
border-top: 1px solid var(--line);
background: #fbfdff;
}
.footer-inner {
display: grid;
grid-template-columns: 1.4fr repeat(3, minmax(130px, 0.5fr));
gap: 42px;
max-width: var(--max);
margin: 0 auto;
padding: 38px 28px 24px;
}
.footer-intro p {
max-width: 280px;
margin: 15px 0 18px;
color: var(--muted);
line-height: 1.58;
}
.footer-col strong {
display: block;
margin-bottom: 14px;
color: var(--ink-strong);
font-size: 0.88rem;
}
.footer-col a {
display: block;
margin-bottom: 10px;
color: var(--muted);
font-size: 0.9rem;
}
.footer-bottom {
max-width: var(--max);
margin: 0 auto;
padding: 0 28px 34px;
color: var(--muted-2);
font-size: 0.84rem;
text-align: center;
}
.sr-only {
position: absolute;
overflow: hidden;
width: 1px;
height: 1px;
padding: 0;
border: 0;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
}
@media (max-width: 1040px) {
.nav {
flex-wrap: wrap;
padding: 16px 22px;
}
.nav-links {
order: 3;
width: 100%;
justify-content: center;
gap: 18px;
}
.hero {
padding-top: 56px;
}
.hero-grid,
.control-section {
grid-template-columns: 1fr;
}
.hero-copy {
max-width: 720px;
}
h1 {
max-width: 760px;
font-size: 4rem;
}
.workflow-panel {
max-width: 760px;
}
.task-card {
right: 112px;
}
.feature-card {
padding: 28px 24px;
}
}
@media (max-width: 820px) {
.nav-actions {
width: 100%;
justify-content: space-between;
}
.nav-links {
justify-content: flex-start;
overflow-x: auto;
padding-bottom: 2px;
}
.hero {
min-height: auto;
padding: 44px 20px 20px;
}
.lead {
font-size: 1.07rem;
}
h1 {
font-size: 3.35rem;
line-height: 1.02;
}
.flow-canvas {
grid-template-columns: 1fr;
gap: 14px;
min-width: 0;
}
.connector {
width: 2px;
height: 38px;
margin: 0 auto;
background-image: linear-gradient(180deg, var(--blue) 45%, transparent 0);
background-size: 2px 10px;
}
.connector::after {
top: auto;
right: 50%;
bottom: -1px;
transform: translateX(50%) rotate(135deg);
}
.task-card {
position: static;
width: 100%;
margin-top: 14px;
}
.flow-strip,
.feature-grid,
.steps,
.cta-band,
.footer-inner {
grid-template-columns: 1fr;
}
.flow-strip {
gap: 16px;
margin-top: 34px;
padding: 22px;
}
.flow-arrow {
transform: rotate(90deg);
}
.feature-card {
min-height: auto;
border-right: 0;
border-bottom: 1px solid var(--line);
}
.feature-card:last-child {
border-bottom: 0;
}
.mini-metrics {
grid-template-columns: 1fr;
}
.dashboard-body {
grid-template-columns: 1fr;
}
.side-rail {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
border-right: 0;
border-bottom: 1px solid var(--line);
}
.rail-item.active {
padding: 0 8px;
}
.step:not(:last-child)::after {
display: none;
}
.cta-band {
padding: 28px 22px;
}
.section {
padding: 60px 20px 0;
}
}
@media (max-width: 540px) {
.brand {
font-size: 1.1rem;
}
.nav {
gap: 14px;
}
.nav-actions .button {
flex: 1;
padding: 0 12px;
}
.hero-actions .button,
.hero-actions {
width: 100%;
}
h1 {
font-size: 2.76rem;
line-height: 1.05;
}
.proof-list {
display: grid;
grid-template-columns: 1fr;
gap: 10px;
}
.workflow-panel {
padding: 18px;
}
.activity-row {
grid-template-columns: 34px 1fr;
}
.sync-state {
grid-column: 2;
justify-self: start;
}
.footer-bottom {
text-align: left;
}
}
</style>
</head>
<body>
<header class="site-header">
<nav class="nav" aria-label="Primary">
<a class="brand" href="#top" aria-label="InboxConverge home">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M3 6.5h18v11H3v-11Z" stroke="currentColor" stroke-width="2" />
<path d="m4 7 8 6 8-6" stroke="currentColor" stroke-width="2" />
</svg>
</span>
InboxConverge
</a>
<div class="nav-links">
<a href="#features" data-i18n="nav.features">Features</a>
<a href="#control" data-i18n="nav.control">Control</a>
<a href="#how" data-i18n="nav.how">How it works</a>
<a href="https://github.com/christianlouis/InboxConverge">GitHub</a>
</div>
<div class="nav-actions">
<a class="button" href="https://app.inboxconverge.com/">
<span data-i18n="cta.openApp">Open app</span>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M7 17 17 7M9 7h8v8" stroke="currentColor" stroke-width="2" />
</svg>
</a>
<div class="lang-toggle" aria-label="Language">
<button type="button" data-lang="en" aria-pressed="true">EN</button>
<button type="button" data-lang="de" aria-pressed="false">DE</button>
</div>
</div>
</nav>
</header>
<main id="top">
<section class="hero" aria-labelledby="hero-title">
<div class="hero-grid">
<div class="hero-copy">
<h1 id="hero-title" data-i18n="hero.title">Consolidate external mailboxes into Gmail. On your infrastructure.</h1>
<p class="lead" data-i18n="hero.lead">
InboxConverge replaces Gmail POP import and Gmailify with a self-hosted delivery layer for external mailboxes. Fetch, normalize, de-duplicate, and deliver mail into Gmail without handing the data path to another proxy.
</p>
<div class="hero-actions">
<a class="button" href="https://app.inboxconverge.com/">
<span data-i18n="cta.openInstance">Open InboxConverge</span>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M7 17 17 7M9 7h8v8" stroke="currentColor" stroke-width="2" />
</svg>
</a>
<a class="button secondary" href="https://github.com/christianlouis/InboxConverge">
<svg width="17" height="17" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M12 .5a12 12 0 0 0-3.8 23.39c.6.11.82-.26.82-.58v-2.04c-3.34.73-4.04-1.42-4.04-1.42-.55-1.4-1.34-1.77-1.34-1.77-1.09-.75.08-.73.08-.73 1.2.08 1.84 1.24 1.84 1.24 1.08 1.83 2.82 1.3 3.5.99.11-.78.42-1.3.76-1.6-2.66-.3-5.46-1.33-5.46-5.93 0-1.31.47-2.38 1.24-3.22-.13-.3-.54-1.52.11-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0C17.66 4.83 18.67 5.15 18.67 5.15c.65 1.66.24 2.88.12 3.18.77.84 1.23 1.91 1.23 3.22 0 4.61-2.8 5.62-5.48 5.92.43.38.82 1.11.82 2.24v3.32c0 .32.21.7.83.58A12 12 0 0 0 12 .5Z" />
</svg>
<span data-i18n="cta.github">View on GitHub</span>
</a>
</div>
<ul class="proof-list" aria-label="Project qualities">
<li><span class="check"></span><span data-i18n="proof.open">Open source</span></li>
<li><span class="check"></span><span data-i18n="proof.hosted">Self-hosted</span></li>
<li><span class="check"></span><span data-i18n="proof.proxy">No third-party proxy</span></li>
</ul>
</div>
<div class="workflow-panel" aria-label="InboxConverge mail flow">
<div class="panel-title">
<strong data-i18n="visual.title">Mailbox delivery path</strong>
<span class="status" data-i18n="visual.status">Sync healthy</span>
</div>
<div class="flow-canvas">
<div class="source-stack">
<strong class="source-title" data-i18n="visual.sources">Source mailboxes</strong>
<div class="source-row">
<span class="mini-icon" aria-hidden="true">O</span>
<span><b>Outlook</b><span>ops@company.com</span></span>
</div>
<div class="source-row">
<span class="mini-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="m3 8 9-5 9 5v9H3V8Z" stroke="currentColor" stroke-width="2" />
<path d="m4 9 8 6 8-6" stroke="currentColor" stroke-width="2" />
</svg>
</span>
<span><b>Zoho Mail</b><span>info@company.com</span></span>
</div>
<div class="source-row">
<span class="mini-icon" aria-hidden="true">G</span>
<span><b>Workspace</b><span>support@company.com</span></span>
</div>
<div class="source-row">
<span class="mini-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M3 6.5h18v11H3v-11Z" stroke="currentColor" stroke-width="2" />
<path d="m4 7 8 6 8-6" stroke="currentColor" stroke-width="2" />
</svg>
</span>
<span><b data-i18n="visual.custom">Custom IMAP</b><span>sales@company.com</span></span>
</div>
</div>
<div class="connector" aria-hidden="true"></div>
<div class="server-card">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M3 6.5h18v11H3v-11Z" stroke="currentColor" stroke-width="2" />
<path d="m4 7 8 6 8-6" stroke="currentColor" stroke-width="2" />
</svg>
</span>
<strong>InboxConverge</strong>
<span data-i18n="visual.server">Your server</span>
</div>
<div class="connector" aria-hidden="true"></div>
<div class="gmail-card">
<svg class="gmail-logo" viewBox="0 0 64 48" aria-hidden="true">
<path fill="#4285f4" d="M6 42h10V17L6 9z" />
<path fill="#34a853" d="M48 42h10V9l-10 8z" />
<path fill="#fbbc04" d="M16 17 32 29 48 17v-8L32 21 16 9z" />
<path fill="#ea4335" d="M6 9v6l10 8V17zM58 9v6l-10 8v-6z" />
</svg>
<strong>Gmail</strong>
<span data-i18n="visual.gmail">Unified inbox</span>
</div>
</div>
<div class="task-card" aria-label="Processing steps">
<ul>
<li><span class="check"></span><span data-i18n="visual.fetch">Fetch and normalize</span></li>
<li><span class="check"></span><span data-i18n="visual.dedupe">De-duplicate</span></li>
<li><span class="check"></span><span data-i18n="visual.folder">Folder mapping</span></li>
</ul>
</div>
</div>
</div>
<div class="flow-strip" aria-label="Mailbox flow summary">
<div class="flow-step">
<div class="flow-icons" aria-hidden="true">
<span class="mini-icon">O</span>
<span class="mini-icon">G</span>
<span class="mini-icon">•••</span>
</div>
<strong data-i18n="strip.connect">Connect sources</strong>
<span data-i18n="strip.connectText">Secure IMAP/POP connections</span>
</div>
<div class="flow-arrow" aria-hidden="true">
<svg width="46" height="20" viewBox="0 0 46 20" fill="none">
<path d="M1 10h42m-8-8 9 8-9 8" stroke="currentColor" stroke-width="2" />
</svg>
</div>
<div class="flow-step">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M3 6.5h18v11H3v-11Z" stroke="currentColor" stroke-width="2" />
<path d="m4 7 8 6 8-6" stroke="currentColor" stroke-width="2" />
</svg>
</span>
<strong>InboxConverge</strong>
<span data-i18n="strip.server">Your server processes delivery</span>
</div>
<div class="flow-arrow" aria-hidden="true">
<svg width="46" height="20" viewBox="0 0 46 20" fill="none">
<path d="M1 10h42m-8-8 9 8-9 8" stroke="currentColor" stroke-width="2" />
</svg>
</div>
<div class="flow-step">
<svg class="gmail-logo" viewBox="0 0 64 48" aria-hidden="true">
<path fill="#4285f4" d="M6 42h10V17L6 9z" />
<path fill="#34a853" d="M48 42h10V9l-10 8z" />
<path fill="#fbbc04" d="M16 17 32 29 48 17v-8L32 21 16 9z" />
<path fill="#ea4335" d="M6 9v6l10 8V17zM58 9v6l-10 8v-6z" />
</svg>
<strong data-i18n="strip.gmail">Everything in Gmail</strong>
<span data-i18n="strip.gmailText">Messages delivered via API</span>
</div>
</div>
</section>
<section class="section" id="features" aria-labelledby="features-title">
<div class="section-heading">
<h2 id="features-title" data-i18n="features.title">Built for reliability and control</h2>
<p data-i18n="features.lead">
Mailbox consolidation should be boring in the best way: visible, repeatable, and owned by you.
</p>
</div>
<div class="feature-grid">
<article class="feature-card">
<span class="icon-box" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M5 5h14v4H5zM5 10h14v4H5zM5 15h14v4H5z" stroke="currentColor" stroke-width="2" />
<path d="M16 7h.01M16 12h.01M16 17h.01" stroke="currentColor" stroke-width="3" />
</svg>
</span>
<h3 data-i18n="features.reliabilityTitle">Operational reliability</h3>
<p data-i18n="features.reliabilityText">
Resilient fetching with retries, rate-limit awareness, and incremental sync for unattended operation.
</p>
<ul class="tick-list">
<li><span class="check"></span><span data-i18n="features.reliabilityA">Incremental sync</span></li>
<li><span class="check"></span><span data-i18n="features.reliabilityB">Retry with backoff</span></li>
<li><span class="check"></span><span data-i18n="features.reliabilityC">Idempotent delivery</span></li>
</ul>
</article>
<article class="feature-card">
<span class="icon-box" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M7 11V8a5 5 0 0 1 10 0v3" stroke="currentColor" stroke-width="2" />
<path d="M5 11h14v9H5z" stroke="currentColor" stroke-width="2" />
</svg>
</span>
<h3 data-i18n="features.controlTitle">Self-hosted. In control.</h3>
<p data-i18n="features.controlText">
Run InboxConverge on your own infrastructure. Credentials, logs, and the mail path stay in systems you choose.
</p>
<ul class="tick-list">
<li><span class="check"></span><span data-i18n="features.controlA">No mailbox intermediaries</span></li>
<li><span class="check"></span><span data-i18n="features.controlB">Secrets stay with you</span></li>
<li><span class="check"></span><span data-i18n="features.controlC">Network isolation ready</span></li>
</ul>
</article>
<article class="feature-card">
<span class="icon-box" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M12 4v6m0 0H6m6 0h6M6 10v6m12-6v6M4 18h4v3H4zM10 18h4v3h-4zM16 18h4v3h-4z" stroke="currentColor" stroke-width="2" />
</svg>
</span>
<h3 data-i18n="features.sourcesTitle">Many sources, one destination</h3>
<p data-i18n="features.sourcesText">
Consolidate legacy providers, custom domains, and personal mailboxes into one Gmail account.
</p>
<ul class="tick-list">
<li><span class="check"></span><span data-i18n="features.sourcesA">IMAP and POP3 support</span></li>
<li><span class="check"></span><span data-i18n="features.sourcesB">Folder mapping</span></li>
<li><span class="check"></span><span data-i18n="features.sourcesC">Per-source rules</span></li>
</ul>
</article>
</div>
</section>
<section class="section control-section" id="control" aria-labelledby="control-title">
<div class="control-copy">
<h2 id="control-title" data-i18n="control.title">See the parts Gmail import used to hide</h2>
<p data-i18n="control.text">
InboxConverge is designed for operators who want to know what happened when a mailbox fails, slows down, or starts sending duplicates. Every source can be observed, retried, and adjusted without losing the unified Gmail workflow.
</p>
<div class="mini-metrics" aria-label="Operational highlights">
<div class="metric"><strong data-i18n="control.metricAValue">24/7</strong><span data-i18n="control.metricALabel">scheduled polling</span></div>
<div class="metric"><strong data-i18n="control.metricBValue">API</strong><span data-i18n="control.metricBLabel">Gmail delivery</span></div>
<div class="metric"><strong data-i18n="control.metricCValue">OSS</strong><span data-i18n="control.metricCLabel">MIT licensed</span></div>
</div>
</div>
<div class="dashboard" aria-label="InboxConverge source dashboard mockup">
<div class="dashboard-top">
<div class="window-dots" aria-hidden="true"><span></span><span></span><span></span></div>
<strong data-i18n="dashboard.title">Sources</strong>
<span class="status" data-i18n="dashboard.status">Live</span>
</div>
<div class="dashboard-body">
<aside class="side-rail" aria-label="Dashboard sections">
<div class="rail-item active" data-i18n="dashboard.navSources">Sources</div>
<div class="rail-item" data-i18n="dashboard.navRuns">Runs</div>
<div class="rail-item" data-i18n="dashboard.navMappings">Mappings</div>
<div class="rail-item" data-i18n="dashboard.navLogs">Logs</div>
</aside>
<div class="activity">
<div class="activity-row">
<span class="mini-icon" aria-hidden="true">O</span>
<span><b>ops@company.com</b><span data-i18n="dashboard.rowA">128 messages delivered, 0 failed</span></span>
<span class="sync-state" data-i18n="dashboard.synced">Synced</span>
</div>
<div class="activity-row">
<span class="mini-icon" aria-hidden="true">Z</span>
<span><b>info@company.com</b><span data-i18n="dashboard.rowB">Folder mapping applied</span></span>
<span class="sync-state" data-i18n="dashboard.synced">Synced</span>
</div>
<div class="activity-row">
<span class="mini-icon" aria-hidden="true">G</span>
<span><b>support@company.com</b><span data-i18n="dashboard.rowC">Waiting for next polling window</span></span>
<span class="sync-state" data-i18n="dashboard.queued">Queued</span>
</div>
<div class="activity-row">
<span class="mini-icon" aria-hidden="true">I</span>
<span><b>sales@company.com</b><span data-i18n="dashboard.rowD">Last retry completed successfully</span></span>
<span class="sync-state" data-i18n="dashboard.synced">Synced</span>
</div>
</div>
</div>
</div>
</section>
<section class="section" id="how" aria-labelledby="how-title">
<div class="section-heading">
<h2 id="how-title" data-i18n="how.title">How it works</h2>
<p data-i18n="how.lead">Keep Gmail as the daily workspace while InboxConverge handles the delivery work behind it.</p>
</div>
<div class="steps">
<article class="step">
<span class="step-number">1</span>
<span class="icon-box" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M5 7h14M5 17h14M8 4v6M16 14v6" stroke="currentColor" stroke-width="2" />
<circle cx="8" cy="7" r="2" stroke="currentColor" stroke-width="2" />
<circle cx="16" cy="17" r="2" stroke="currentColor" stroke-width="2" />
</svg>
</span>
<h3 data-i18n="how.stepATitle">Add your sources</h3>
<p data-i18n="how.stepAText">Connect every IMAP or POP3 mailbox, test connectivity, and decide how folders should land in Gmail.</p>
</article>
<article class="step">
<span class="step-number">2</span>
<span class="icon-box" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M12 4v10m0 0 4-4m-4 4-4-4M5 18h14" stroke="currentColor" stroke-width="2" />
</svg>
</span>
<h3 data-i18n="how.stepBTitle">Sync and process</h3>
<p data-i18n="how.stepBText">Messages are fetched incrementally, normalized, de-duplicated, and prepared for Gmail delivery.</p>
</article>
<article class="step">
<span class="step-number">3</span>
<svg class="gmail-logo" viewBox="0 0 64 48" aria-hidden="true">
<path fill="#4285f4" d="M6 42h10V17L6 9z" />
<path fill="#34a853" d="M48 42h10V9l-10 8z" />
<path fill="#fbbc04" d="M16 17 32 29 48 17v-8L32 21 16 9z" />
<path fill="#ea4335" d="M6 9v6l10 8V17zM58 9v6l-10 8v-6z" />
</svg>
<h3 data-i18n="how.stepCTitle">Delivered to Gmail</h3>
<p data-i18n="how.stepCText">InboxConverge delivers messages through the Gmail API so everything remains in the inbox people already use.</p>
</article>
</div>
</section>
<section class="section" aria-labelledby="cta-title">
<div class="cta-band">
<div>
<h2 id="cta-title" data-i18n="final.title">Consolidate on your terms</h2>
<p data-i18n="final.text">
Keep Gmail as the destination, move mailbox import into infrastructure you trust, and avoid silent failures from legacy POP workflows.
</p>
</div>
<div class="cta-actions">
<a class="button wide" href="https://app.inboxconverge.com/">
<span data-i18n="cta.openInstance">Open InboxConverge</span>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M7 17 17 7M9 7h8v8" stroke="currentColor" stroke-width="2" />
</svg>
</a>
<a class="button secondary wide" href="https://github.com/christianlouis/InboxConverge">
<svg width="17" height="17" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M12 .5a12 12 0 0 0-3.8 23.39c.6.11.82-.26.82-.58v-2.04c-3.34.73-4.04-1.42-4.04-1.42-.55-1.4-1.34-1.77-1.34-1.77-1.09-.75.08-.73.08-.73 1.2.08 1.84 1.24 1.84 1.24 1.08 1.83 2.82 1.3 3.5.99.11-.78.42-1.3.76-1.6-2.66-.3-5.46-1.33-5.46-5.93 0-1.31.47-2.38 1.24-3.22-.13-.3-.54-1.52.11-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0C17.66 4.83 18.67 5.15 18.67 5.15c.65 1.66.24 2.88.12 3.18.77.84 1.23 1.91 1.23 3.22 0 4.61-2.8 5.62-5.48 5.92.43.38.82 1.11.82 2.24v3.32c0 .32.21.7.83.58A12 12 0 0 0 12 .5Z" />
</svg>
<span data-i18n="cta.github">View on GitHub</span>
</a>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="footer-inner">
<div class="footer-intro">
<a class="brand" href="#top">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M3 6.5h18v11H3v-11Z" stroke="currentColor" stroke-width="2" />
<path d="m4 7 8 6 8-6" stroke="currentColor" stroke-width="2" />
</svg>
</span>
InboxConverge
</a>
<p data-i18n="footer.summary">Open-source mailbox consolidation for Gmail. Self-hosted, private, and reliable.</p>
</div>
<div class="footer-col">
<strong data-i18n="footer.product">Product</strong>
<a href="#features" data-i18n="nav.features">Features</a>
<a href="#control" data-i18n="nav.control">Control</a>
<a href="#how" data-i18n="nav.how">How it works</a>
</div>
<div class="footer-col">
<strong data-i18n="footer.resources">Resources</strong>
<a href="https://github.com/christianlouis/InboxConverge">GitHub</a>
<a href="https://github.com/christianlouis/InboxConverge/issues">Issues</a>
<a href="mailto:christianlouis@gmail.com">Contact</a>
</div>
<div class="footer-col">
<strong data-i18n="footer.legal">Legal</strong>
<a href="https://github.com/christianlouis/InboxConverge/blob/main/LICENSE">MIT License</a>
<a href="https://github.com/christianlouis/InboxConverge" data-i18n="footer.source">Source code</a>
</div>
</div>
<div class="footer-bottom" data-i18n="footer.bottom">© 2026 InboxConverge. Open source under the MIT License.</div>
</footer>
<script>
const translations = {
en: {
metaTitle: "InboxConverge | Self-hosted Gmail mailbox consolidation",
metaDescription:
"InboxConverge is a self-hosted replacement for Gmail POP import and Gmailify, built for reliable mailbox consolidation into Gmail.",
"nav.features": "Features",
"nav.control": "Control",
"nav.how": "How it works",
"cta.openApp": "Open app",
"cta.openInstance": "Open InboxConverge",
"cta.github": "View on GitHub",
"hero.title": "Consolidate external mailboxes into Gmail. On your infrastructure.",
"hero.lead":
"InboxConverge replaces Gmail POP import and Gmailify with a self-hosted delivery layer for external mailboxes. Fetch, normalize, de-duplicate, and deliver mail into Gmail without handing the data path to another proxy.",
"proof.open": "Open source",
"proof.hosted": "Self-hosted",
"proof.proxy": "No third-party proxy",
"visual.title": "Mailbox delivery path",
"visual.status": "Sync healthy",
"visual.sources": "Source mailboxes",
"visual.custom": "Custom IMAP",
"visual.server": "Your server",
"visual.gmail": "Unified inbox",
"visual.fetch": "Fetch and normalize",
"visual.dedupe": "De-duplicate",
"visual.folder": "Folder mapping",
"strip.connect": "Connect sources",
"strip.connectText": "Secure IMAP/POP connections",
"strip.server": "Your server processes delivery",
"strip.gmail": "Everything in Gmail",
"strip.gmailText": "Messages delivered via API",
"features.title": "Built for reliability and control",
"features.lead":
"Mailbox consolidation should be boring in the best way: visible, repeatable, and owned by you.",
"features.reliabilityTitle": "Operational reliability",
"features.reliabilityText":
"Resilient fetching with retries, rate-limit awareness, and incremental sync for unattended operation.",
"features.reliabilityA": "Incremental sync",
"features.reliabilityB": "Retry with backoff",
"features.reliabilityC": "Idempotent delivery",
"features.controlTitle": "Self-hosted. In control.",
"features.controlText":
"Run InboxConverge on your own infrastructure. Credentials, logs, and the mail path stay in systems you choose.",
"features.controlA": "No mailbox intermediaries",
"features.controlB": "Secrets stay with you",
"features.controlC": "Network isolation ready",
"features.sourcesTitle": "Many sources, one destination",
"features.sourcesText":
"Consolidate legacy providers, custom domains, and personal mailboxes into one Gmail account.",
"features.sourcesA": "IMAP and POP3 support",
"features.sourcesB": "Folder mapping",
"features.sourcesC": "Per-source rules",
"control.title": "See the parts Gmail import used to hide",
"control.text":
"InboxConverge is designed for operators who want to know what happened when a mailbox fails, slows down, or starts sending duplicates. Every source can be observed, retried, and adjusted without losing the unified Gmail workflow.",
"control.metricAValue": "24/7",
"control.metricALabel": "scheduled polling",
"control.metricBValue": "API",
"control.metricBLabel": "Gmail delivery",
"control.metricCValue": "OSS",
"control.metricCLabel": "MIT licensed",
"dashboard.title": "Sources",
"dashboard.status": "Live",
"dashboard.navSources": "Sources",
"dashboard.navRuns": "Runs",
"dashboard.navMappings": "Mappings",
"dashboard.navLogs": "Logs",
"dashboard.rowA": "128 messages delivered, 0 failed",
"dashboard.rowB": "Folder mapping applied",
"dashboard.rowC": "Waiting for next polling window",
"dashboard.rowD": "Last retry completed successfully",
"dashboard.synced": "Synced",
"dashboard.queued": "Queued",
"how.title": "How it works",
"how.lead":
"Keep Gmail as the daily workspace while InboxConverge handles the delivery work behind it.",
"how.stepATitle": "Add your sources",
"how.stepAText":
"Connect every IMAP or POP3 mailbox, test connectivity, and decide how folders should land in Gmail.",
"how.stepBTitle": "Sync and process",
"how.stepBText":
"Messages are fetched incrementally, normalized, de-duplicated, and prepared for Gmail delivery.",
"how.stepCTitle": "Delivered to Gmail",
"how.stepCText":
"InboxConverge delivers messages through the Gmail API so everything remains in the inbox people already use.",
"final.title": "Consolidate on your terms",
"final.text":
"Keep Gmail as the destination, move mailbox import into infrastructure you trust, and avoid silent failures from legacy POP workflows.",
"footer.summary":
"Open-source mailbox consolidation for Gmail. Self-hosted, private, and reliable.",
"footer.product": "Product",
"footer.resources": "Resources",
"footer.legal": "Legal",
"footer.source": "Source code",
"footer.bottom": "© 2026 InboxConverge. Open source under the MIT License."
},
de: {
metaTitle: "InboxConverge | Selbst gehostete Gmail-Mailbox-Konsolidierung",
metaDescription:
"InboxConverge ersetzt Gmail POP-Import und Gmailify durch eine selbst gehostete Lösung für zuverlässige Mailbox-Konsolidierung nach Gmail.",
"nav.features": "Funktionen",
"nav.control": "Kontrolle",
"nav.how": "Ablauf",
"cta.openApp": "App öffnen",
"cta.openInstance": "InboxConverge öffnen",
"cta.github": "Auf GitHub ansehen",
"hero.title": "Externe Postfächer in Gmail bündeln. Auf deiner Infrastruktur.",
"hero.lead":
"InboxConverge ersetzt Gmail POP-Import und Gmailify durch eine selbst gehostete Zustellschicht für externe Postfächer. Nachrichten werden abgeholt, normalisiert, dedupliziert und nach Gmail zugestellt, ohne den Datenpfad an einen weiteren Proxy abzugeben.",
"proof.open": "Open Source",
"proof.hosted": "Selbst gehostet",
"proof.proxy": "Kein Drittanbieter-Proxy",
"visual.title": "Zustellpfad der Postfächer",
"visual.status": "Sync stabil",
"visual.sources": "Quellpostfächer",
"visual.custom": "Eigenes IMAP",
"visual.server": "Dein Server",
"visual.gmail": "Ein gemeinsamer Posteingang",
"visual.fetch": "Abrufen und normalisieren",
"visual.dedupe": "Deduplizieren",
"visual.folder": "Ordner zuordnen",
"strip.connect": "Quellen verbinden",
"strip.connectText": "Sichere IMAP/POP-Verbindungen",
"strip.server": "Dein Server verarbeitet die Zustellung",
"strip.gmail": "Alles in Gmail",
"strip.gmailText": "Nachrichten per API zugestellt",
"features.title": "Gebaut für Verlässlichkeit und Kontrolle",
"features.lead":
"Mailbox-Konsolidierung sollte im besten Sinne unspektakulär sein: sichtbar, wiederholbar und unter deiner Kontrolle.",
"features.reliabilityTitle": "Operativ verlässlich",
"features.reliabilityText":
"Robustes Abrufen mit Wiederholungen, Rate-Limit-Bewusstsein und inkrementellem Sync für unbeaufsichtigten Betrieb.",
"features.reliabilityA": "Inkrementeller Sync",
"features.reliabilityB": "Wiederholung mit Backoff",
"features.reliabilityC": "Idempotente Zustellung",
"features.controlTitle": "Selbst gehostet. Unter Kontrolle.",
"features.controlText":
"Betreibe InboxConverge auf eigener Infrastruktur. Zugangsdaten, Logs und Mailpfad bleiben in Systemen, die du auswählst.",
"features.controlA": "Keine Mailbox-Zwischenstationen",
"features.controlB": "Secrets bleiben bei dir",
"features.controlC": "Für Netzwerkisolation geeignet",
"features.sourcesTitle": "Viele Quellen, ein Ziel",
"features.sourcesText":
"Bündle alte Provider, eigene Domains und persönliche Postfächer in einem Gmail-Konto.",
"features.sourcesA": "IMAP- und POP3-Unterstützung",
"features.sourcesB": "Ordnerzuordnung",
"features.sourcesC": "Regeln pro Quelle",
"control.title": "Sieh die Teile, die Gmail-Import bisher versteckt hat",
"control.text":
"InboxConverge ist für Betreiber gemacht, die nachvollziehen wollen, was passiert, wenn ein Postfach ausfällt, langsamer wird oder Duplikate sendet. Jede Quelle kann beobachtet, erneut versucht und angepasst werden, ohne den gewohnten Gmail-Workflow zu verlieren.",
"control.metricAValue": "24/7",
"control.metricALabel": "geplanter Abruf",
"control.metricBValue": "API",
"control.metricBLabel": "Gmail-Zustellung",
"control.metricCValue": "OSS",
"control.metricCLabel": "MIT-lizenziert",
"dashboard.title": "Quellen",
"dashboard.status": "Live",
"dashboard.navSources": "Quellen",
"dashboard.navRuns": "Läufe",
"dashboard.navMappings": "Zuordnungen",
"dashboard.navLogs": "Logs",
"dashboard.rowA": "128 Nachrichten zugestellt, 0 Fehler",
"dashboard.rowB": "Ordnerzuordnung angewendet",
"dashboard.rowC": "Wartet auf das nächste Abruffenster",
"dashboard.rowD": "Letzter Wiederholungsversuch erfolgreich",
"dashboard.synced": "Synchron",
"dashboard.queued": "Wartet",
"how.title": "So funktioniert es",
"how.lead":
"Gmail bleibt der tägliche Arbeitsplatz, während InboxConverge die Zustellung im Hintergrund übernimmt.",
"how.stepATitle": "Quellen hinzufügen",
"how.stepAText":
"Verbinde jedes IMAP- oder POP3-Postfach, teste die Verbindung und lege fest, wie Ordner in Gmail landen.",
"how.stepBTitle": "Synchronisieren und verarbeiten",
"how.stepBText":
"Nachrichten werden inkrementell abgeholt, normalisiert, dedupliziert und für die Gmail-Zustellung vorbereitet.",
"how.stepCTitle": "Nach Gmail zugestellt",
"how.stepCText":
"InboxConverge stellt Nachrichten über die Gmail API zu, damit alles im Posteingang bleibt, den die Nutzer bereits verwenden.",
"final.title": "Konsolidieren nach deinen Regeln",
"final.text":
"Behalte Gmail als Ziel, verlege den Mailbox-Import in Infrastruktur, der du vertraust, und vermeide stille Ausfälle alter POP-Workflows.",
"footer.summary":
"Open-Source-Mailbox-Konsolidierung für Gmail. Selbst gehostet, privat und verlässlich.",
"footer.product": "Produkt",
"footer.resources": "Ressourcen",
"footer.legal": "Rechtliches",
"footer.source": "Quellcode",
"footer.bottom": "© 2026 InboxConverge. Open Source unter der MIT-Lizenz."
}
};
const langButtons = Array.from(document.querySelectorAll("[data-lang]"));
const translatable = Array.from(document.querySelectorAll("[data-i18n]"));
const description = document.querySelector('meta[name="description"]');
const ogDescription = document.querySelector('meta[property="og:description"]');
function getInitialLanguage() {
const params = new URLSearchParams(window.location.search);
const requested = params.get("lang");
if (requested === "de" || requested === "en") return requested;
const stored = window.localStorage.getItem("inboxconverge-language");
if (stored === "de" || stored === "en") return stored;
return navigator.language && navigator.language.toLowerCase().startsWith("de") ? "de" : "en";
}
function setLanguage(lang, pushState = true) {
const dictionary = translations[lang] || translations.en;
document.documentElement.lang = lang;
document.title = dictionary.metaTitle;
description.setAttribute("content", dictionary.metaDescription);
ogDescription.setAttribute("content", dictionary.metaDescription);
translatable.forEach((node) => {
const key = node.getAttribute("data-i18n");
if (dictionary[key]) node.textContent = dictionary[key];
});
langButtons.forEach((button) => {
button.setAttribute("aria-pressed", button.dataset.lang === lang ? "true" : "false");
});
window.localStorage.setItem("inboxconverge-language", lang);
if (pushState) {
const url = new URL(window.location.href);
url.searchParams.set("lang", lang);
window.history.replaceState({}, "", url);
}
}
langButtons.forEach((button) => {
button.addEventListener("click", () => setLanguage(button.dataset.lang));
});
setLanguage(getInitialLanguage(), false);
</script>
</body>
</html>