80<=KCw<Ke?lw%5KA)%MBcn&Y?FxiwvGwa1R-olXiXGUj#1
zcQvI(zG7N-rqe7halB+;t}N39q+XOvhD#zH3R@oeQk
zwlL?I%QoX>680W3iI<_-^_olpro#~V7|T*+Kz4B4olmsiGO
k@hoSq_IEq){V~~l18Sojew48@=yrSU6OC$y9J1H{AOB6`d;kCd
diff --git a/locale/de/LC_MESSAGES/messages.po b/locale/de/LC_MESSAGES/messages.po
index b4a92f9..db4b0de 100644
--- a/locale/de/LC_MESSAGES/messages.po
+++ b/locale/de/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FileMorph VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2026-09-28 19:39+0200\n"
+"POT-Creation-Date: 2026-09-29 08:59+0200\n"
"PO-Revision-Date: 2026-05-08 11:00+0200\n"
"Last-Translator: FileMorph \n"
"Language: de\n"
@@ -56,13 +56,13 @@ msgid "+ New Key"
msgstr "+ Neuer Key"
msgid ""
-", hosted in Frankfurt, EU). Zoho receives the recipient address and the "
-"email contents (including the reset link). Legal basis: Art. 6(1)(b) "
-"GDPR. See"
+", EU data centres in Amsterdam (NL) and Dublin (IE)). Zoho receives the "
+"recipient address and the email contents (including the reset link). "
+"Legal basis: Art. 6(1)(b) GDPR. See"
msgstr ""
-", gehostet in Frankfurt, EU). Zoho erhält die Empfänger-Adresse und die E"
-"-Mail-Inhalte (einschließlich des Reset-Links). Rechtsgrundlage: Art. "
-"6(1)(b) DSGVO. Siehe"
+", EU-Rechenzentren in Amsterdam (NL) und Dublin (IE)). Zoho erhält die "
+"Empfänger-Adresse und die E-Mail-Inhalte (einschließlich des Reset-"
+"Links). Rechtsgrundlage: Art. 6(1)(b) DSGVO. Siehe"
msgid ""
". To exercise other rights (access, rectification, restriction), contact "
@@ -179,6 +179,13 @@ msgstr "9. Admin-Zugriff (Transparenz)"
msgid "9. Right of Withdrawal (Consumers)"
msgstr "9. Widerrufsrecht (Verbraucher)"
+msgid ""
+"; cancellation takes effect at the end of the current billing period and "
+"you retain access for the remainder of that period."
+msgstr ""
+" — die Kündigung wird dann zum Ende der laufenden Abrechnungsperiode "
+"wirksam, und du behältst für den Rest dieser Periode Zugriff."
+
msgid "A description of the vulnerability and its potential impact."
msgstr ""
"Eine Beschreibung der Sicherheitslücke und ihrer potenziellen "
@@ -205,6 +212,9 @@ msgstr "API-Doku ↗"
msgid "API Keys"
msgstr "API-Schlüssel"
+msgid "API access without a key"
+msgstr "API-Zugriff ohne Schlüssel"
+
msgid "API calls / month"
msgstr "API-Aufrufe / Monat"
@@ -420,17 +430,18 @@ msgstr "Behörden · Krankenhäuser · Kanzleien"
msgid ""
"Being transparent about what is not done yet: no external ISO 27001 "
"certification and no external penetration test yet (both planned once a "
-"paying pilot justifies the cost), and no tagged release cut yet — the "
-"signing/SBOM pipeline is wired in CI and produces those artefacts on the "
-"first tag. Everything else above is in the repository today and "
-"auditable."
+"paying pilot justifies the cost). v1.1.0, tagged 2026-06-01, is the "
+"latest signed release with a CycloneDX SBOM and an image digest; changes "
+"since then ship in the continuously built image ahead of the next tag. "
+"Everything else above is in the repository today and auditable."
msgstr ""
"Transparent zu dem, was noch fehlt: noch keine externe "
"ISO-27001-Zertifizierung und kein externer Penetrationstest (beide "
-"geplant, sobald ein zahlender Pilot den Aufwand rechtfertigt), und noch "
-"kein getaggtes Release — die Signier-/SBOM-Pipeline ist in der CI "
-"verdrahtet und erzeugt diese Artefakte beim ersten Tag. Alles andere oben"
-" liegt heute im Repository und ist prüfbar."
+"geplant, sobald ein zahlender Pilot den Aufwand rechtfertigt). v1.1.0, "
+"getaggt am 1. Juni 2026, ist das aktuelle signierte Release mit "
+"CycloneDX-SBOM und Image-Digest; Änderungen seitdem laufen im fortlaufend"
+" gebauten Image, bis zum nächsten Git-Tag. Alles andere oben liegt heute "
+"im Repository und ist prüfbar."
msgid "Best quality"
msgstr "Beste Qualität"
@@ -576,8 +587,8 @@ msgstr "Kompressions-Modus"
msgid "Concurrent slots"
msgstr "Gleichzeitige Slots"
-msgid "Confidential inquiries via"
-msgstr "Vertrauliche Anfragen über"
+msgid "Confidential inquiries: email"
+msgstr "Vertrauliche Anfragen: E-Mail an"
msgid "Confirm Password"
msgstr "Passwort bestätigen"
@@ -610,11 +621,11 @@ msgid "Confirming your email…"
msgstr "Deine E-Mail-Adresse wird bestätigt…"
msgid ""
-"Conformance gate runs as CI workflow. No release without green veraPDF "
-"against a worst-case source PDF."
+"Conformance check runs in CI on every push to main and every pull "
+"request, against a worst-case source PDF."
msgstr ""
-"Konformitäts-Gate läuft als CI-Workflow. Kein Release ohne grünes veraPDF"
-" gegen einen Worst-Case-Source-PDF."
+"Die Konformitätsprüfung läuft in der CI bei jedem Push auf main und jedem"
+" Pull Request, gegen ein Worst-Case-Quell-PDF."
msgid ""
"Conformance secured by veraPDF CI gate against a worst-case source PDF — "
@@ -888,13 +899,6 @@ msgstr ""
"Alle Konvertierungen von FileMorph — Bilder, Dokumente, Tabellen, Audio "
"und Video, plus Komprimierung auf eine Zielgröße. Kostenlos, Open Source."
-msgid ""
-"Every operation in a continuous hash chain. Tampering with an old row "
-"breaks every following one."
-msgstr ""
-"Jede Operation in einer fortlaufenden Hash-Chain. Manipulation an einer "
-"alten Zeile bricht die nachfolgende Kette."
-
msgid ""
"External ISO 27001 certification and external pen test are planned as "
"Year-2 roadmap items — both will be implemented as soon as the first "
@@ -935,34 +939,38 @@ msgstr "FileMorph Compliance Edition"
msgid ""
"FileMorph can shrink a JPEG, WebP or AVIF image to an exact target size "
"(for example 5 MB) using a binary search — useful for upload limits and "
-"email attachments."
+"email attachments. PNG, TIFF and video below compress by quality only, "
+"not to an exact size."
msgstr ""
"FileMorph kann ein JPEG-, WebP- oder AVIF-Bild per Binärsuche auf eine "
"exakte Zielgröße verkleinern (zum Beispiel 5 MB) — praktisch für Upload-"
-"Limits und E-Mail-Anhänge."
+"Limits und E-Mail-Anhänge. PNG, TIFF und Video darunter werden nur per "
+"Qualität komprimiert, nicht auf eine exakte Größe."
msgid ""
-"FileMorph closes this gap: the open-source engine covers 16+ format pairs"
-" and runs on your own Hetzner / on-premises / air-gap infrastructure. The"
-" Compliance Edition additionally provides the contracts, SLAs and roadmap"
-" guarantees that an EVB-IT-compliant procurement requires."
+"FileMorph closes this gap: the open-source engine covers 180+ format "
+"pairs and runs on your own Hetzner / on-premises / air-gap "
+"infrastructure. The Compliance Edition additionally provides the "
+"contracts, SLAs and roadmap guarantees that an EVB-IT-compliant "
+"procurement requires."
msgstr ""
-"FileMorph schließt diese Lücke: Die Open-Source-Engine deckt 16+ Format-"
+"FileMorph schließt diese Lücke: Die Open-Source-Engine deckt 180+ Format-"
"Paare ab und läuft auf Ihrer eigenen Hetzner / On-Premise / Air-Gap-"
"Infrastruktur. Die Compliance-Edition liefert zusätzlich die Verträge, "
"die SLAs und die Roadmap-Garantien, die ein EVB-IT-konformer Einkauf "
"voraussetzt."
msgid ""
-"FileMorph converts between the formats below and compresses images to an "
-"exact target size (video too, by quality). Everything runs for free, with"
-" no account — or self-host it under AGPLv3. Pick any pair and start on "
-"the"
+"FileMorph converts between the formats below and compresses JPEG, WebP "
+"and AVIF images to an exact target size — PNG, TIFF and video use "
+"quality-based compression instead. Everything runs for free, with no "
+"account — or self-host it under AGPLv3. Pick any pair and start on the"
msgstr ""
"FileMorph konvertiert zwischen den folgenden Formaten und komprimiert "
-"Bilder auf eine exakte Zielgröße (Video ebenfalls, per Qualität). Alles "
-"läuft kostenlos und ohne Konto — oder hoste es selbst unter AGPLv3. Wähle"
-" ein beliebiges Paar und starte im"
+"JPEG-, WebP- und AVIF-Bilder auf eine exakte Zielgröße — PNG, TIFF und "
+"Video werden stattdessen per Qualität komprimiert. Alles läuft kostenlos "
+"und ohne Konto — oder hoste es selbst unter AGPLv3. Wähle ein beliebiges "
+"Paar und starte im"
msgid ""
"FileMorph is a file conversion and compression service. The Community "
@@ -1022,10 +1030,11 @@ msgstr "FileMorph unterliegt deutschem Recht (Hamburg)."
msgid ""
"FileMorph pricing: the open-source converter is free to self-host. Paid "
-"plans add volume, higher limits and API access."
+"plans add volume, higher limits and larger API quotas."
msgstr ""
"FileMorph-Preise: Der Open-Source-Konverter ist kostenlos selbst hostbar."
-" Bezahlte Tarife bieten mehr Volumen, höhere Limits und API-Zugang."
+" Bezahlte Tarife bieten mehr Volumen, höhere Limits und größere API-"
+"Kontingente."
msgid "FileMorph sets"
msgstr "FileMorph setzt"
@@ -1114,9 +1123,6 @@ msgstr ""
msgid "For developers & SaaS"
msgstr "Für Entwickler & SaaS"
-msgid "For issues in the open-source codebase itself, you may alternatively use"
-msgstr "Für Probleme im Open-Source-Codebase selbst kannst du alternativ"
-
msgid "For public sector & compliance"
msgstr "Für Behörden & Compliance"
@@ -1189,9 +1195,6 @@ msgstr "API-Key holen →"
msgid "Get started free"
msgstr "Kostenlos starten"
-msgid "GitHub Security Advisories"
-msgstr "GitHub Security Advisories"
-
msgid "GitHub ↗"
msgstr "GitHub ↗"
@@ -1314,43 +1317,53 @@ msgstr ""
msgid ""
"If you register an account, we store your email address, a bcrypt hash of"
" your password (never the plaintext), your subscription tier, your "
-"account creation timestamp, and — once you upgrade to a paid tier — the "
-"Stripe customer identifier that links your account to Stripe. Account "
-"data is persisted in our PostgreSQL database for the lifetime of your "
-"account. You can delete your account at any time through the dashboard's "
-"\"Delete account\" flow, or by request to privacy@filemorph.io. On "
-"deletion we erase your password hash and API keys, and cancel any active "
-"paid subscription. Conversion-job records are anonymised — your account "
-"ID is removed — and the resulting anonymous rows are retained for "
-"aggregate service-quality analytics; under GDPR Art. 4(1), they no longer"
-" relate to you. Stripe transaction records are retained by Stripe under "
-"their own tax-retention obligations. For accounts that have made at least"
-" one payment, German tax law (HGB §257, AO §147) obliges us to retain a "
-"minimal invoice-link record — your email address, Stripe customer "
-"identifier, and last billing tier — for 10 years from the end of the "
-"calendar year of your last payment; all other personal data is erased on "
-"deletion. This retention is the legal-obligation exception under GDPR "
-"Art. 17(3)(b); the data is held solely for tax audit and is hard-deleted "
-"at the end of the retention period. Erasure otherwise complies with GDPR "
-"Art. 17."
+"account creation timestamp, your preferred language for account emails, "
+"the timestamp your email address was verified (once you complete that "
+"step), and — once you upgrade to a paid tier — the Stripe customer "
+"identifier that links your account to Stripe. We also record one row per "
+"API/conversion request you make — the endpoint, the file size, and how "
+"long it took, never the file content — to enforce your monthly quota and "
+"show usage in your dashboard. Account data is persisted in our PostgreSQL"
+" database for the lifetime of your account. You can delete your account "
+"at any time through the dashboard's \"Delete account\" flow, or by "
+"request to privacy@filemorph.io. On deletion we erase your password hash "
+"and API keys, and cancel any active paid subscription. Conversion-job "
+"records are anonymised — your account ID is removed — and the resulting "
+"anonymous rows are retained for aggregate service-quality analytics; "
+"under GDPR Art. 4(1), they no longer relate to you. Stripe transaction "
+"records are retained by Stripe under their own tax-retention obligations."
+" For accounts that have made at least one payment, German tax law (HGB "
+"§257, AO §147) obliges us to retain a minimal invoice-link record — your "
+"email address, Stripe customer identifier, and last billing tier — for 10"
+" years from the end of the calendar year of your last payment; all other "
+"personal data is erased on deletion. This retention is the legal-"
+"obligation exception under GDPR Art. 17(3)(b); the data is held solely "
+"for tax audit and is hard-deleted at the end of the retention period. "
+"Erasure otherwise complies with GDPR Art. 17."
msgstr ""
"Wenn du ein Konto registrierst, speichern wir deine E-Mail-Adresse, einen"
" bcrypt-Hash deines Passworts (niemals den Klartext), deinen Abonnement-"
-"Tarif, den Zeitstempel deiner Kontoerstellung und — sobald du auf einen "
+"Tarif, den Zeitstempel deiner Kontoerstellung, deine bevorzugte Sprache "
+"für Konto-E-Mails, den Zeitstempel der Bestätigung deiner E-Mail-Adresse "
+"(sobald du diesen Schritt abschließt) und — sobald du auf einen "
"kostenpflichtigen Tarif upgradest — den Stripe-Kunden-Identifikator, der "
-"dein Konto mit Stripe verknüpft. Kontodaten werden für die Lebensdauer "
-"deines Kontos in unserer PostgreSQL-Datenbank gespeichert. Du kannst dein"
-" Konto jederzeit über den \"Konto löschen\"-Vorgang im Dashboard oder per"
-" Anfrage an privacy@filemorph.io löschen. Bei der Löschung entfernen wir "
-"deinen Passwort-Hash und deine API-Schlüssel und kündigen ein etwaiges "
-"aktives kostenpflichtiges Abonnement. Konvertierungs-Job-Datensätze "
-"werden anonymisiert — deine Konto-ID wird entfernt — und die so "
-"entstehenden anonymen Zeilen werden zur aggregierten Service-"
-"Qualitätsanalyse aufbewahrt; nach DSGVO Art. 4 Abs. 1 beziehen sie sich "
-"nicht mehr auf dich. Stripe-Transaktionsdatensätze werden von Stripe "
-"aufgrund eigener steuerrechtlicher Aufbewahrungspflichten aufbewahrt. Bei"
-" Konten, die mindestens eine Zahlung getätigt haben, verpflichtet uns "
-"deutsches Steuerrecht (HGB §257, AO §147), einen minimalen Rechnungs-"
+"dein Konto mit Stripe verknüpft. Außerdem erfassen wir pro "
+"API-/Konvertierungsanfrage eine Zeile — den Endpunkt, die Dateigröße und "
+"die Dauer, nie den Dateiinhalt —, um dein monatliches Kontingent "
+"durchzusetzen und die Nutzung in deinem Dashboard anzuzeigen. Kontodaten "
+"werden für die Lebensdauer deines Kontos in unserer PostgreSQL-Datenbank "
+"gespeichert. Du kannst dein Konto jederzeit über den \"Konto "
+"löschen\"-Vorgang im Dashboard oder per Anfrage an privacy@filemorph.io "
+"löschen. Bei der Löschung entfernen wir deinen Passwort-Hash und deine "
+"API-Schlüssel und kündigen ein etwaiges aktives kostenpflichtiges "
+"Abonnement. Konvertierungs-Job-Datensätze werden anonymisiert — deine "
+"Konto-ID wird entfernt — und die so entstehenden anonymen Zeilen werden "
+"zur aggregierten Service-Qualitätsanalyse aufbewahrt; nach DSGVO Art. 4 "
+"Abs. 1 beziehen sie sich nicht mehr auf dich. Stripe-"
+"Transaktionsdatensätze werden von Stripe aufgrund eigener "
+"steuerrechtlicher Aufbewahrungspflichten aufbewahrt. Bei Konten, die "
+"mindestens eine Zahlung getätigt haben, verpflichtet uns deutsches "
+"Steuerrecht (HGB §257, AO §147), einen minimalen Rechnungs-"
"Verknüpfungsdatensatz — deine E-Mail-Adresse, deinen Stripe-Kunden-"
"Identifikator und deinen letzten Abrechnungstarif — für 10 Jahre ab Ende "
"des Kalenderjahres deiner letzten Zahlung aufzubewahren; alle übrigen "
@@ -1490,11 +1503,8 @@ msgstr ""
msgid "Language"
msgstr "Sprache"
-msgid "Last updated: 2026-06-22 · Community + Cloud Edition"
-msgstr "Stand: 22.06.2026 · Community + Cloud Edition"
-
-msgid "Last updated: 2026-08-18 · Community + Cloud Edition"
-msgstr "Stand: 18.08.2026 · Community + Cloud Edition"
+msgid "Last updated: 2026-09-28 · Community + Cloud Edition"
+msgstr "Stand: 28.09.2026 · Community + Cloud Edition"
msgid "Last used"
msgstr "Zuletzt verwendet"
@@ -1778,18 +1788,14 @@ msgid "Pages to keep"
msgstr "Zu behaltende Seiten"
msgid ""
-"Paid plans (Pro €7/month, Business €19/month) are billed monthly via "
-"Stripe and renew automatically until cancelled. You may cancel at any "
-"time through the Stripe customer portal linked from your account "
-"dashboard; cancellation takes effect at the end of the current billing "
-"period and you retain access for the remainder of that period."
+"Paid plans are billed monthly via Stripe, at the prices shown on the "
+"pricing page at the time of your order, and renew automatically until "
+"cancelled. You may cancel at any time by emailing"
msgstr ""
-"Bezahlte Pläne (Pro 7 €/Monat, Business 19 €/Monat) werden monatlich über"
-" Stripe abgerechnet und verlängern sich automatisch bis zur Kündigung. Du"
-" kannst jederzeit über das im Account-Dashboard verlinkte Stripe-"
-"Kundenportal kündigen; die Kündigung wird zum Ende des laufenden "
-"Abrechnungszeitraums wirksam, und der Zugang bleibt bis zum Periodenende "
-"erhalten."
+"Kostenpflichtige Tarife werden monatlich über Stripe abgerechnet, zu den "
+"Preisen, die zum Zeitpunkt deiner Bestellung auf der Preisseite angezeigt"
+" werden, und verlängern sich automatisch bis zur Kündigung. Zum Kündigen "
+"genügt jederzeit eine E-Mail an"
msgid "Paid tiers — coming soon"
msgstr "Bezahlte Tarife — demnächst verfügbar"
@@ -1828,12 +1834,15 @@ msgstr "Gemäß § 18 Abs. 2 MStV: Lennart Seidel, Reetwerder 25b, 21029 Hamburg
msgid ""
"Permanently delete your account, API keys, and cancel any active "
-"subscription. Conversion-job records are anonymised. This cannot be "
-"undone."
+"subscription. Conversion-job records are anonymised. If you've made a "
+"payment, we keep a minimal invoice-link record for 10 years (German tax "
+"law). This cannot be undone."
msgstr ""
"Lösche dauerhaft dein Konto und deine API-Schlüssel und kündige ein "
"etwaiges aktives Abonnement. Konvertierungs-Job-Datensätze werden "
-"anonymisiert. Dies kann nicht rückgängig gemacht werden."
+"anonymisiert. Wenn du eine Zahlung getätigt hast, behalten wir einen "
+"minimalen Rechnungs-Verknüpfungsdatensatz für 10 Jahre (deutsches "
+"Steuerrecht). Dies kann nicht rückgängig gemacht werden."
msgid "Phone number"
msgstr "Telefonnummer"
@@ -2110,13 +2119,11 @@ msgid "Reset your password"
msgstr "Setze dein Passwort zurück"
msgid ""
-"Response-time targets by severity — critical 4 h, high 24 h, medium/low "
-"in the next regular release. Targets apply Mon–Fri 09:00–18:00 CET, "
-"excluding German public holidays."
+"Response-time targets by severity are individually agreed in the support "
+"contract."
msgstr ""
-"Reaktionszeiten nach Schweregrad — kritisch 4 h, hoch 24 h, "
-"mittel/niedrig im nächsten regulären Release. Die Zielwerte gelten Mo–Fr "
-"09:00–18:00 MEZ, ausgenommen gesetzliche Feiertage in Deutschland."
+"Reaktionszeit-Ziele nach Schweregrad werden individuell im Support-"
+"Vertrag vereinbart."
msgid "Responsible party"
msgstr "Verantwortlich"
@@ -2340,6 +2347,16 @@ msgstr "Anmeldung …"
msgid "Signups over time"
msgstr "Registrierungen über Zeit"
+msgid ""
+"Single-file format conversions and image/video compressions, plus "
+"account, contact, billing and redaction events, go into a continuous hash"
+" chain. Tampering with an old row breaks every following one."
+msgstr ""
+"Einzeldatei-Formatkonvertierungen und Bild-/Video-Kompressionen sowie "
+"Konto-, Kontakt-, Abrechnungs- und Schwärzungs-Ereignisse fließen in eine"
+" fortlaufende Hash-Chain. Manipulation an einer alten Zeile bricht die "
+"nachfolgende Kette."
+
msgid ""
"Small-business status under § 19 UStG — no VAT is charged and no USt-"
"IdNr. is held."
@@ -2497,15 +2514,6 @@ msgstr "Nutzungsbedingungen"
msgid "Thanks — your message has been sent. We will reply soon."
msgstr "Danke — deine Nachricht wurde gesendet. Wir antworten in Kürze."
-msgid ""
-"That channel is preferred for issues that affect every self-hosted "
-"instance, since the repository maintainers can coordinate a CVE and "
-"release a patched version centrally."
-msgstr ""
-"Dieser Kanal ist bevorzugt für Probleme, die jede selbst gehostete "
-"Instanz betreffen, da die Repository-Maintainer eine CVE koordinieren und"
-" eine gepatchte Version zentral veröffentlichen können."
-
msgid ""
"The Compliance Edition is for when you need a contract behind it: DPA, "
"support SLA, signed releases, and someone accountable — not "
@@ -2648,13 +2656,13 @@ msgstr ""
"neue Bestätigungs-E-Mail vom Dashboard an."
msgid ""
-"This service is hosted by Hetzner Online GmbH, Germany (Frankfurt data "
-"centre). Your requests are routed through Cloudflare's network for DDoS "
-"protection and performance. See"
+"This service is hosted by Hetzner Online GmbH — data centre in the EU. "
+"Your requests are routed through Cloudflare's network for DDoS protection"
+" and performance. See"
msgstr ""
-"Dieser Dienst wird gehostet von Hetzner Online GmbH, Deutschland "
-"(Rechenzentrum Frankfurt). Deine Anfragen werden über Cloudflares "
-"Netzwerk für DDoS-Schutz und Performance geroutet. Siehe"
+"Dieser Dienst wird gehostet von Hetzner Online GmbH — Rechenzentrum in "
+"der EU. Deine Anfragen werden über Cloudflares Netzwerk für DDoS-Schutz "
+"und Performance geroutet. Siehe"
msgid ""
"This tool compresses images and video. To shrink a PDF, use the dedicated"
@@ -2805,18 +2813,24 @@ msgid "Video"
msgstr "Video"
msgid ""
-"We apply a temporary in-memory rate limit (max. 10 requests per minute "
-"per IP address) to protect the service from abuse. IP addresses used by "
-"the rate limiter are processed transiently in memory only and are never "
-"written to disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate "
-"interest in service stability and security."
+"We apply in-memory rate limits to protect the service from abuse — set "
+"per route, from 5 contact-form messages per hour up to 120 requests per "
+"minute. Several account routes count the limit per signed-in account "
+"rather than per IP address, and failed API-key attempts get a separate "
+"per-IP budget. IP addresses and account identifiers used by the rate "
+"limiter are processed transiently in memory only and are never written to"
+" disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate interest in "
+"service stability and security."
msgstr ""
-"Wir wenden ein temporäres In-Memory-Rate-Limit (max. 10 Anfragen pro "
-"Minute pro IP-Adresse) an, um den Dienst vor Missbrauch zu schützen. Vom "
-"Rate-Limiter verwendete IP-Adressen werden nur transient im Speicher "
-"verarbeitet und niemals auf Disk oder in Logs geschrieben. "
-"Rechtsgrundlage: Art. 6(1)(f) DSGVO — berechtigtes Interesse an Dienst-"
-"Stabilität und Sicherheit."
+"Wir wenden In-Memory-Rate-Limits an, um den Dienst vor Missbrauch zu "
+"schützen — je nach Route von 5 Kontaktformular-Nachrichten pro Stunde bis"
+" zu 120 Anfragen pro Minute. Mehrere Konto-Routen zählen das Limit pro "
+"angemeldetem Konto statt pro IP-Adresse, und fehlgeschlagene API-"
+"Schlüssel-Versuche erhalten ein separates Budget pro IP-Adresse. Vom "
+"Rate-Limiter verwendete IP-Adressen und Konto-Kennungen werden nur "
+"transient im Speicher verarbeitet und niemals auf Disk oder in Logs "
+"geschrieben. Rechtsgrundlage: Art. 6(1)(f) DSGVO — berechtigtes Interesse"
+" an Dienst-Stabilität und Sicherheit."
msgid ""
"We are neither willing nor obliged to participate in dispute-resolution "
@@ -2826,15 +2840,15 @@ msgstr ""
" einer Verbraucherschlichtungsstelle teilzunehmen (§ 36 VSBG)."
msgid ""
-"We may update this policy when the service changes. Accounts and billing "
-"are live as of April 2026; persistent file history (Cloud Edition Phase "
-"2) is planned but not yet implemented. The date at the top indicates the "
-"current version."
+"We may update this policy when the service changes. Accounts are live; "
+"paid plans are not yet available. Persistent file history (Cloud Edition "
+"Phase 2) is planned but not yet implemented. The date at the top "
+"indicates the current version."
msgstr ""
"Wir können diese Richtlinie aktualisieren, wenn sich der Dienst ändert. "
-"Accounts und Billing sind seit April 2026 live; persistente Datei-"
-"Historie (Cloud Edition Phase 2) ist geplant aber noch nicht "
-"implementiert. Das Datum oben zeigt die aktuelle Version an."
+"Accounts sind live; kostenpflichtige Tarife sind noch nicht verfügbar. "
+"Persistente Datei-Historie (Cloud Edition Phase 2) ist geplant, aber noch"
+" nicht implementiert. Das Datum oben zeigt die aktuelle Version an."
msgid ""
"We name it because an RFP reviewer would notice anyway — and because we "
@@ -2928,13 +2942,15 @@ msgid "When to use this conversion"
msgstr "Wann diese Umwandlung sinnvoll ist"
msgid ""
-"When you request a password reset, we generate a single-use token (valid "
-"for 30 minutes) and send it to your registered email address as a reset "
-"link. The outgoing message is delivered from"
+"When you register, we send a verification link to your email address "
+"(valid for 7 days). When you request a password reset, we generate a "
+"separate single-use token (valid for 30 minutes) and send it as a reset "
+"link. Outgoing messages are delivered from"
msgstr ""
-"Wenn du ein Passwort-Reset anforderst, generieren wir einen Einmal-Token "
-"(gültig für 30 Minuten) und senden ihn als Reset-Link an deine "
-"registrierte E-Mail-Adresse. Die ausgehende Nachricht wird verschickt von"
+"Wenn du dich registrierst, senden wir einen Bestätigungs-Link an deine E"
+"-Mail-Adresse (gültig für 7 Tage). Wenn du ein Passwort-Reset anforderst,"
+" generieren wir einen separaten Einmal-Token (gültig für 30 Minuten) und "
+"senden ihn als Reset-Link. Ausgehende Nachrichten werden verschickt von"
msgid ""
"When you start a paid-tier upgrade, you are redirected to Stripe Checkout"
@@ -3207,9 +3223,6 @@ msgstr "und"
msgid "anonymous)"
msgstr "anonym)"
-msgid "are encrypted with the same key."
-msgstr "werden mit demselben Schlüssel verschlüsselt."
-
msgid "calls / month"
msgstr "Aufrufe / Monat"
@@ -3296,12 +3309,18 @@ msgstr ""
"Hinweis. Große Batches werden sequentiell innerhalb der Anfrage "
"verarbeitet."
+msgid ""
+"legacy; current versions no longer write it, but a value saved by an "
+"older version is still read. Cleared on logout and when you delete your "
+"account."
+msgstr ""
+"veraltet; aktuelle Versionen schreiben ihn nicht mehr, ein von einer "
+"älteren Version gespeicherter Wert wird aber noch gelesen. Wird beim "
+"Abmelden und beim Löschen deines Kontos entfernt."
+
msgid "min 0.05 MB"
msgstr "min. 0,05 MB"
-msgid "no API access"
-msgstr "kein API-Zugriff"
-
msgid "no cookies"
msgstr "keine Cookies"
@@ -3333,14 +3352,6 @@ msgstr ""
msgid "on request"
msgstr "auf Anfrage"
-msgid ""
-"optional; remembers the API key shown in your dashboard across reloads so"
-" you don't need to paste it again. Cleared on logout."
-msgstr ""
-"optional; merkt sich den im Dashboard angezeigten API-Key über Reloads "
-"hinweg, damit du ihn nicht erneut einfügen musst. Wird beim Logout "
-"gelöscht."
-
msgid "or apply directly as design partner →"
msgstr "oder direkt als Design-Partner bewerben →"
@@ -3496,6 +3507,9 @@ msgstr "© 2026 FileMorph — AGPLv3 Open Source"
msgid "±3% tolerance"
msgstr "±3% Toleranz"
+msgid "— a PGP key is available on request."
+msgstr "— ein PGP-Schlüssel ist auf Anfrage erhältlich."
+
msgid "— select a file first —"
msgstr "— erst eine Datei wählen —"
diff --git a/locale/en/LC_MESSAGES/messages.mo b/locale/en/LC_MESSAGES/messages.mo
index d043bf3b4fb8ba5f1c11c6dc899fb1973c8e02fa..372d34e69647e6b817d4ee9b9c98b3407fa99ed0 100644
GIT binary patch
delta 37
ncmZ24v0h@s31((XU8BvXnG>1VEENnatV}l>vHgb${$>OK;qVK@
delta 37
ncmZ24v0h@s31(&sUBk_%nG>1VEEEhat&BGtvHgb${$>OK;hPJ;
diff --git a/locale/en/LC_MESSAGES/messages.po b/locale/en/LC_MESSAGES/messages.po
index 45fdf68..96fd9a7 100644
--- a/locale/en/LC_MESSAGES/messages.po
+++ b/locale/en/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FileMorph VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2026-09-28 19:39+0200\n"
+"POT-Creation-Date: 2026-09-29 08:59+0200\n"
"PO-Revision-Date: 2026-05-07 13:43+0200\n"
"Last-Translator: FULL NAME \n"
"Language: en\n"
@@ -45,9 +45,9 @@ msgid "+ New Key"
msgstr ""
msgid ""
-", hosted in Frankfurt, EU). Zoho receives the recipient address and the "
-"email contents (including the reset link). Legal basis: Art. 6(1)(b) "
-"GDPR. See"
+", EU data centres in Amsterdam (NL) and Dublin (IE)). Zoho receives the "
+"recipient address and the email contents (including the reset link). "
+"Legal basis: Art. 6(1)(b) GDPR. See"
msgstr ""
msgid ""
@@ -163,6 +163,11 @@ msgstr ""
msgid "9. Right of Withdrawal (Consumers)"
msgstr ""
+msgid ""
+"; cancellation takes effect at the end of the current billing period and "
+"you retain access for the remainder of that period."
+msgstr ""
+
msgid "A description of the vulnerability and its potential impact."
msgstr ""
@@ -187,6 +192,9 @@ msgstr ""
msgid "API Keys"
msgstr ""
+msgid "API access without a key"
+msgstr ""
+
msgid "API calls / month"
msgstr ""
@@ -374,10 +382,10 @@ msgstr ""
msgid ""
"Being transparent about what is not done yet: no external ISO 27001 "
"certification and no external penetration test yet (both planned once a "
-"paying pilot justifies the cost), and no tagged release cut yet — the "
-"signing/SBOM pipeline is wired in CI and produces those artefacts on the "
-"first tag. Everything else above is in the repository today and "
-"auditable."
+"paying pilot justifies the cost). v1.1.0, tagged 2026-06-01, is the "
+"latest signed release with a CycloneDX SBOM and an image digest; changes "
+"since then ship in the continuously built image ahead of the next tag. "
+"Everything else above is in the repository today and auditable."
msgstr ""
msgid "Best quality"
@@ -510,7 +518,7 @@ msgstr ""
msgid "Concurrent slots"
msgstr ""
-msgid "Confidential inquiries via"
+msgid "Confidential inquiries: email"
msgstr ""
msgid "Confirm Password"
@@ -544,8 +552,8 @@ msgid "Confirming your email…"
msgstr ""
msgid ""
-"Conformance gate runs as CI workflow. No release without green veraPDF "
-"against a worst-case source PDF."
+"Conformance check runs in CI on every push to main and every pull "
+"request, against a worst-case source PDF."
msgstr ""
msgid ""
@@ -799,11 +807,6 @@ msgid ""
"audio and video, plus compression to a target size. Free, open source."
msgstr ""
-msgid ""
-"Every operation in a continuous hash chain. Tampering with an old row "
-"breaks every following one."
-msgstr ""
-
msgid ""
"External ISO 27001 certification and external pen test are planned as "
"Year-2 roadmap items — both will be implemented as soon as the first "
@@ -839,21 +842,23 @@ msgstr ""
msgid ""
"FileMorph can shrink a JPEG, WebP or AVIF image to an exact target size "
"(for example 5 MB) using a binary search — useful for upload limits and "
-"email attachments."
+"email attachments. PNG, TIFF and video below compress by quality only, "
+"not to an exact size."
msgstr ""
msgid ""
-"FileMorph closes this gap: the open-source engine covers 16+ format pairs"
-" and runs on your own Hetzner / on-premises / air-gap infrastructure. The"
-" Compliance Edition additionally provides the contracts, SLAs and roadmap"
-" guarantees that an EVB-IT-compliant procurement requires."
+"FileMorph closes this gap: the open-source engine covers 180+ format "
+"pairs and runs on your own Hetzner / on-premises / air-gap "
+"infrastructure. The Compliance Edition additionally provides the "
+"contracts, SLAs and roadmap guarantees that an EVB-IT-compliant "
+"procurement requires."
msgstr ""
msgid ""
-"FileMorph converts between the formats below and compresses images to an "
-"exact target size (video too, by quality). Everything runs for free, with"
-" no account — or self-host it under AGPLv3. Pick any pair and start on "
-"the"
+"FileMorph converts between the formats below and compresses JPEG, WebP "
+"and AVIF images to an exact target size — PNG, TIFF and video use "
+"quality-based compression instead. Everything runs for free, with no "
+"account — or self-host it under AGPLv3. Pick any pair and start on the"
msgstr ""
msgid ""
@@ -896,7 +901,7 @@ msgstr ""
msgid ""
"FileMorph pricing: the open-source converter is free to self-host. Paid "
-"plans add volume, higher limits and API access."
+"plans add volume, higher limits and larger API quotas."
msgstr ""
msgid "FileMorph sets"
@@ -963,9 +968,6 @@ msgstr ""
msgid "For developers & SaaS"
msgstr ""
-msgid "For issues in the open-source codebase itself, you may alternatively use"
-msgstr ""
-
msgid "For public sector & compliance"
msgstr ""
@@ -1032,9 +1034,6 @@ msgstr ""
msgid "Get started free"
msgstr ""
-msgid "GitHub Security Advisories"
-msgstr ""
-
msgid "GitHub ↗"
msgstr ""
@@ -1127,25 +1126,29 @@ msgstr ""
msgid ""
"If you register an account, we store your email address, a bcrypt hash of"
" your password (never the plaintext), your subscription tier, your "
-"account creation timestamp, and — once you upgrade to a paid tier — the "
-"Stripe customer identifier that links your account to Stripe. Account "
-"data is persisted in our PostgreSQL database for the lifetime of your "
-"account. You can delete your account at any time through the dashboard's "
-"\"Delete account\" flow, or by request to privacy@filemorph.io. On "
-"deletion we erase your password hash and API keys, and cancel any active "
-"paid subscription. Conversion-job records are anonymised — your account "
-"ID is removed — and the resulting anonymous rows are retained for "
-"aggregate service-quality analytics; under GDPR Art. 4(1), they no longer"
-" relate to you. Stripe transaction records are retained by Stripe under "
-"their own tax-retention obligations. For accounts that have made at least"
-" one payment, German tax law (HGB §257, AO §147) obliges us to retain a "
-"minimal invoice-link record — your email address, Stripe customer "
-"identifier, and last billing tier — for 10 years from the end of the "
-"calendar year of your last payment; all other personal data is erased on "
-"deletion. This retention is the legal-obligation exception under GDPR "
-"Art. 17(3)(b); the data is held solely for tax audit and is hard-deleted "
-"at the end of the retention period. Erasure otherwise complies with GDPR "
-"Art. 17."
+"account creation timestamp, your preferred language for account emails, "
+"the timestamp your email address was verified (once you complete that "
+"step), and — once you upgrade to a paid tier — the Stripe customer "
+"identifier that links your account to Stripe. We also record one row per "
+"API/conversion request you make — the endpoint, the file size, and how "
+"long it took, never the file content — to enforce your monthly quota and "
+"show usage in your dashboard. Account data is persisted in our PostgreSQL"
+" database for the lifetime of your account. You can delete your account "
+"at any time through the dashboard's \"Delete account\" flow, or by "
+"request to privacy@filemorph.io. On deletion we erase your password hash "
+"and API keys, and cancel any active paid subscription. Conversion-job "
+"records are anonymised — your account ID is removed — and the resulting "
+"anonymous rows are retained for aggregate service-quality analytics; "
+"under GDPR Art. 4(1), they no longer relate to you. Stripe transaction "
+"records are retained by Stripe under their own tax-retention obligations."
+" For accounts that have made at least one payment, German tax law (HGB "
+"§257, AO §147) obliges us to retain a minimal invoice-link record — your "
+"email address, Stripe customer identifier, and last billing tier — for 10"
+" years from the end of the calendar year of your last payment; all other "
+"personal data is erased on deletion. This retention is the legal-"
+"obligation exception under GDPR Art. 17(3)(b); the data is held solely "
+"for tax audit and is hard-deleted at the end of the retention period. "
+"Erasure otherwise complies with GDPR Art. 17."
msgstr ""
msgid ""
@@ -1246,11 +1249,8 @@ msgstr ""
msgid "Language"
msgstr ""
-msgid "Last updated: 2026-06-22 · Community + Cloud Edition"
-msgstr ""
-
-msgid "Last updated: 2026-08-18 · Community + Cloud Edition"
-msgstr "Last updated: 2026-08-18 · Community + Cloud Edition"
+msgid "Last updated: 2026-09-28 · Community + Cloud Edition"
+msgstr "Last updated: 2026-09-28 · Community + Cloud Edition"
msgid "Last used"
msgstr ""
@@ -1503,11 +1503,9 @@ msgid "Pages to keep"
msgstr ""
msgid ""
-"Paid plans (Pro €7/month, Business €19/month) are billed monthly via "
-"Stripe and renew automatically until cancelled. You may cancel at any "
-"time through the Stripe customer portal linked from your account "
-"dashboard; cancellation takes effect at the end of the current billing "
-"period and you retain access for the remainder of that period."
+"Paid plans are billed monthly via Stripe, at the prices shown on the "
+"pricing page at the time of your order, and renew automatically until "
+"cancelled. You may cancel at any time by emailing"
msgstr ""
msgid "Paid tiers — coming soon"
@@ -1543,8 +1541,9 @@ msgstr ""
msgid ""
"Permanently delete your account, API keys, and cancel any active "
-"subscription. Conversion-job records are anonymised. This cannot be "
-"undone."
+"subscription. Conversion-job records are anonymised. If you've made a "
+"payment, we keep a minimal invoice-link record for 10 years (German tax "
+"law). This cannot be undone."
msgstr ""
msgid "Phone number"
@@ -1772,9 +1771,8 @@ msgid "Reset your password"
msgstr ""
msgid ""
-"Response-time targets by severity — critical 4 h, high 24 h, medium/low "
-"in the next regular release. Targets apply Mon–Fri 09:00–18:00 CET, "
-"excluding German public holidays."
+"Response-time targets by severity are individually agreed in the support "
+"contract."
msgstr ""
msgid "Responsible party"
@@ -1983,6 +1981,12 @@ msgstr ""
msgid "Signups over time"
msgstr ""
+msgid ""
+"Single-file format conversions and image/video compressions, plus "
+"account, contact, billing and redaction events, go into a continuous hash"
+" chain. Tampering with an old row breaks every following one."
+msgstr ""
+
msgid ""
"Small-business status under § 19 UStG — no VAT is charged and no USt-"
"IdNr. is held."
@@ -2119,12 +2123,6 @@ msgstr ""
msgid "Thanks — your message has been sent. We will reply soon."
msgstr ""
-msgid ""
-"That channel is preferred for issues that affect every self-hosted "
-"instance, since the repository maintainers can coordinate a CVE and "
-"release a patched version centrally."
-msgstr ""
-
msgid ""
"The Compliance Edition is for when you need a contract behind it: DPA, "
"support SLA, signed releases, and someone accountable — not "
@@ -2224,9 +2222,9 @@ msgid ""
msgstr ""
msgid ""
-"This service is hosted by Hetzner Online GmbH, Germany (Frankfurt data "
-"centre). Your requests are routed through Cloudflare's network for DDoS "
-"protection and performance. See"
+"This service is hosted by Hetzner Online GmbH — data centre in the EU. "
+"Your requests are routed through Cloudflare's network for DDoS protection"
+" and performance. See"
msgstr ""
msgid ""
@@ -2356,11 +2354,14 @@ msgid "Video"
msgstr ""
msgid ""
-"We apply a temporary in-memory rate limit (max. 10 requests per minute "
-"per IP address) to protect the service from abuse. IP addresses used by "
-"the rate limiter are processed transiently in memory only and are never "
-"written to disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate "
-"interest in service stability and security."
+"We apply in-memory rate limits to protect the service from abuse — set "
+"per route, from 5 contact-form messages per hour up to 120 requests per "
+"minute. Several account routes count the limit per signed-in account "
+"rather than per IP address, and failed API-key attempts get a separate "
+"per-IP budget. IP addresses and account identifiers used by the rate "
+"limiter are processed transiently in memory only and are never written to"
+" disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate interest in "
+"service stability and security."
msgstr ""
msgid ""
@@ -2369,10 +2370,10 @@ msgid ""
msgstr ""
msgid ""
-"We may update this policy when the service changes. Accounts and billing "
-"are live as of April 2026; persistent file history (Cloud Edition Phase "
-"2) is planned but not yet implemented. The date at the top indicates the "
-"current version."
+"We may update this policy when the service changes. Accounts are live; "
+"paid plans are not yet available. Persistent file history (Cloud Edition "
+"Phase 2) is planned but not yet implemented. The date at the top "
+"indicates the current version."
msgstr ""
msgid ""
@@ -2455,9 +2456,10 @@ msgid "When to use this conversion"
msgstr ""
msgid ""
-"When you request a password reset, we generate a single-use token (valid "
-"for 30 minutes) and send it to your registered email address as a reset "
-"link. The outgoing message is delivered from"
+"When you register, we send a verification link to your email address "
+"(valid for 7 days). When you request a password reset, we generate a "
+"separate single-use token (valid for 30 minutes) and send it as a reset "
+"link. Outgoing messages are delivered from"
msgstr ""
msgid ""
@@ -2656,9 +2658,6 @@ msgstr ""
msgid "anonymous)"
msgstr ""
-msgid "are encrypted with the same key."
-msgstr ""
-
msgid "calls / month"
msgstr ""
@@ -2734,10 +2733,13 @@ msgstr ""
msgid "hint. Large batches are processed sequentially inside the request."
msgstr ""
-msgid "min 0.05 MB"
+msgid ""
+"legacy; current versions no longer write it, but a value saved by an "
+"older version is still read. Cleared on logout and when you delete your "
+"account."
msgstr ""
-msgid "no API access"
+msgid "min 0.05 MB"
msgstr ""
msgid "no cookies"
@@ -2771,11 +2773,6 @@ msgstr ""
msgid "on request"
msgstr ""
-msgid ""
-"optional; remembers the API key shown in your dashboard across reloads so"
-" you don't need to paste it again. Cleared on logout."
-msgstr ""
-
msgid "or apply directly as design partner →"
msgstr ""
@@ -2907,6 +2904,9 @@ msgstr ""
msgid "±3% tolerance"
msgstr ""
+msgid "— a PGP key is available on request."
+msgstr ""
+
msgid "— select a file first —"
msgstr ""
diff --git a/locale/messages.pot b/locale/messages.pot
index 8673c24..cc8ec6d 100644
--- a/locale/messages.pot
+++ b/locale/messages.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FileMorph 1.1.0\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2026-09-28 19:39+0200\n"
+"POT-Creation-Date: 2026-09-29 08:59+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -44,9 +44,9 @@ msgid "+ New Key"
msgstr ""
msgid ""
-", hosted in Frankfurt, EU). Zoho receives the recipient address and the "
-"email contents (including the reset link). Legal basis: Art. 6(1)(b) "
-"GDPR. See"
+", EU data centres in Amsterdam (NL) and Dublin (IE)). Zoho receives the "
+"recipient address and the email contents (including the reset link). "
+"Legal basis: Art. 6(1)(b) GDPR. See"
msgstr ""
msgid ""
@@ -162,6 +162,11 @@ msgstr ""
msgid "9. Right of Withdrawal (Consumers)"
msgstr ""
+msgid ""
+"; cancellation takes effect at the end of the current billing period and "
+"you retain access for the remainder of that period."
+msgstr ""
+
msgid "A description of the vulnerability and its potential impact."
msgstr ""
@@ -186,6 +191,9 @@ msgstr ""
msgid "API Keys"
msgstr ""
+msgid "API access without a key"
+msgstr ""
+
msgid "API calls / month"
msgstr ""
@@ -366,10 +374,10 @@ msgstr ""
msgid ""
"Being transparent about what is not done yet: no external ISO 27001 "
"certification and no external penetration test yet (both planned once a "
-"paying pilot justifies the cost), and no tagged release cut yet — the "
-"signing/SBOM pipeline is wired in CI and produces those artefacts on the "
-"first tag. Everything else above is in the repository today and "
-"auditable."
+"paying pilot justifies the cost). v1.1.0, tagged 2026-06-01, is the "
+"latest signed release with a CycloneDX SBOM and an image digest; changes "
+"since then ship in the continuously built image ahead of the next tag. "
+"Everything else above is in the repository today and auditable."
msgstr ""
msgid "Best quality"
@@ -502,7 +510,7 @@ msgstr ""
msgid "Concurrent slots"
msgstr ""
-msgid "Confidential inquiries via"
+msgid "Confidential inquiries: email"
msgstr ""
msgid "Confirm Password"
@@ -536,8 +544,8 @@ msgid "Confirming your email…"
msgstr ""
msgid ""
-"Conformance gate runs as CI workflow. No release without green veraPDF "
-"against a worst-case source PDF."
+"Conformance check runs in CI on every push to main and every pull "
+"request, against a worst-case source PDF."
msgstr ""
msgid ""
@@ -791,11 +799,6 @@ msgid ""
"audio and video, plus compression to a target size. Free, open source."
msgstr ""
-msgid ""
-"Every operation in a continuous hash chain. Tampering with an old row "
-"breaks every following one."
-msgstr ""
-
msgid ""
"External ISO 27001 certification and external pen test are planned as "
"Year-2 roadmap items — both will be implemented as soon as the first "
@@ -831,21 +834,23 @@ msgstr ""
msgid ""
"FileMorph can shrink a JPEG, WebP or AVIF image to an exact target size "
"(for example 5 MB) using a binary search — useful for upload limits and "
-"email attachments."
+"email attachments. PNG, TIFF and video below compress by quality only, "
+"not to an exact size."
msgstr ""
msgid ""
-"FileMorph closes this gap: the open-source engine covers 16+ format pairs"
-" and runs on your own Hetzner / on-premises / air-gap infrastructure. The"
-" Compliance Edition additionally provides the contracts, SLAs and roadmap"
-" guarantees that an EVB-IT-compliant procurement requires."
+"FileMorph closes this gap: the open-source engine covers 180+ format "
+"pairs and runs on your own Hetzner / on-premises / air-gap "
+"infrastructure. The Compliance Edition additionally provides the "
+"contracts, SLAs and roadmap guarantees that an EVB-IT-compliant "
+"procurement requires."
msgstr ""
msgid ""
-"FileMorph converts between the formats below and compresses images to an "
-"exact target size (video too, by quality). Everything runs for free, with"
-" no account — or self-host it under AGPLv3. Pick any pair and start on "
-"the"
+"FileMorph converts between the formats below and compresses JPEG, WebP "
+"and AVIF images to an exact target size — PNG, TIFF and video use "
+"quality-based compression instead. Everything runs for free, with no "
+"account — or self-host it under AGPLv3. Pick any pair and start on the"
msgstr ""
msgid ""
@@ -888,7 +893,7 @@ msgstr ""
msgid ""
"FileMorph pricing: the open-source converter is free to self-host. Paid "
-"plans add volume, higher limits and API access."
+"plans add volume, higher limits and larger API quotas."
msgstr ""
msgid "FileMorph sets"
@@ -952,9 +957,6 @@ msgstr ""
msgid "For developers & SaaS"
msgstr ""
-msgid "For issues in the open-source codebase itself, you may alternatively use"
-msgstr ""
-
msgid "For public sector & compliance"
msgstr ""
@@ -1021,9 +1023,6 @@ msgstr ""
msgid "Get started free"
msgstr ""
-msgid "GitHub Security Advisories"
-msgstr ""
-
msgid "GitHub ↗"
msgstr ""
@@ -1116,25 +1115,29 @@ msgstr ""
msgid ""
"If you register an account, we store your email address, a bcrypt hash of"
" your password (never the plaintext), your subscription tier, your "
-"account creation timestamp, and — once you upgrade to a paid tier — the "
-"Stripe customer identifier that links your account to Stripe. Account "
-"data is persisted in our PostgreSQL database for the lifetime of your "
-"account. You can delete your account at any time through the dashboard's "
-"\"Delete account\" flow, or by request to privacy@filemorph.io. On "
-"deletion we erase your password hash and API keys, and cancel any active "
-"paid subscription. Conversion-job records are anonymised — your account "
-"ID is removed — and the resulting anonymous rows are retained for "
-"aggregate service-quality analytics; under GDPR Art. 4(1), they no longer"
-" relate to you. Stripe transaction records are retained by Stripe under "
-"their own tax-retention obligations. For accounts that have made at least"
-" one payment, German tax law (HGB §257, AO §147) obliges us to retain a "
-"minimal invoice-link record — your email address, Stripe customer "
-"identifier, and last billing tier — for 10 years from the end of the "
-"calendar year of your last payment; all other personal data is erased on "
-"deletion. This retention is the legal-obligation exception under GDPR "
-"Art. 17(3)(b); the data is held solely for tax audit and is hard-deleted "
-"at the end of the retention period. Erasure otherwise complies with GDPR "
-"Art. 17."
+"account creation timestamp, your preferred language for account emails, "
+"the timestamp your email address was verified (once you complete that "
+"step), and — once you upgrade to a paid tier — the Stripe customer "
+"identifier that links your account to Stripe. We also record one row per "
+"API/conversion request you make — the endpoint, the file size, and how "
+"long it took, never the file content — to enforce your monthly quota and "
+"show usage in your dashboard. Account data is persisted in our PostgreSQL"
+" database for the lifetime of your account. You can delete your account "
+"at any time through the dashboard's \"Delete account\" flow, or by "
+"request to privacy@filemorph.io. On deletion we erase your password hash "
+"and API keys, and cancel any active paid subscription. Conversion-job "
+"records are anonymised — your account ID is removed — and the resulting "
+"anonymous rows are retained for aggregate service-quality analytics; "
+"under GDPR Art. 4(1), they no longer relate to you. Stripe transaction "
+"records are retained by Stripe under their own tax-retention obligations."
+" For accounts that have made at least one payment, German tax law (HGB "
+"§257, AO §147) obliges us to retain a minimal invoice-link record — your "
+"email address, Stripe customer identifier, and last billing tier — for 10"
+" years from the end of the calendar year of your last payment; all other "
+"personal data is erased on deletion. This retention is the legal-"
+"obligation exception under GDPR Art. 17(3)(b); the data is held solely "
+"for tax audit and is hard-deleted at the end of the retention period. "
+"Erasure otherwise complies with GDPR Art. 17."
msgstr ""
msgid ""
@@ -1235,10 +1238,7 @@ msgstr ""
msgid "Language"
msgstr ""
-msgid "Last updated: 2026-06-22 · Community + Cloud Edition"
-msgstr ""
-
-msgid "Last updated: 2026-08-18 · Community + Cloud Edition"
+msgid "Last updated: 2026-09-28 · Community + Cloud Edition"
msgstr ""
msgid "Last used"
@@ -1492,11 +1492,9 @@ msgid "Pages to keep"
msgstr ""
msgid ""
-"Paid plans (Pro €7/month, Business €19/month) are billed monthly via "
-"Stripe and renew automatically until cancelled. You may cancel at any "
-"time through the Stripe customer portal linked from your account "
-"dashboard; cancellation takes effect at the end of the current billing "
-"period and you retain access for the remainder of that period."
+"Paid plans are billed monthly via Stripe, at the prices shown on the "
+"pricing page at the time of your order, and renew automatically until "
+"cancelled. You may cancel at any time by emailing"
msgstr ""
msgid "Paid tiers — coming soon"
@@ -1532,8 +1530,9 @@ msgstr ""
msgid ""
"Permanently delete your account, API keys, and cancel any active "
-"subscription. Conversion-job records are anonymised. This cannot be "
-"undone."
+"subscription. Conversion-job records are anonymised. If you've made a "
+"payment, we keep a minimal invoice-link record for 10 years (German tax "
+"law). This cannot be undone."
msgstr ""
msgid "Phone number"
@@ -1761,9 +1760,8 @@ msgid "Reset your password"
msgstr ""
msgid ""
-"Response-time targets by severity — critical 4 h, high 24 h, medium/low "
-"in the next regular release. Targets apply Mon–Fri 09:00–18:00 CET, "
-"excluding German public holidays."
+"Response-time targets by severity are individually agreed in the support "
+"contract."
msgstr ""
msgid "Responsible party"
@@ -1970,6 +1968,12 @@ msgstr ""
msgid "Signups over time"
msgstr ""
+msgid ""
+"Single-file format conversions and image/video compressions, plus "
+"account, contact, billing and redaction events, go into a continuous hash"
+" chain. Tampering with an old row breaks every following one."
+msgstr ""
+
msgid ""
"Small-business status under § 19 UStG — no VAT is charged and no USt-"
"IdNr. is held."
@@ -2106,12 +2110,6 @@ msgstr ""
msgid "Thanks — your message has been sent. We will reply soon."
msgstr ""
-msgid ""
-"That channel is preferred for issues that affect every self-hosted "
-"instance, since the repository maintainers can coordinate a CVE and "
-"release a patched version centrally."
-msgstr ""
-
msgid ""
"The Compliance Edition is for when you need a contract behind it: DPA, "
"support SLA, signed releases, and someone accountable — not "
@@ -2211,9 +2209,9 @@ msgid ""
msgstr ""
msgid ""
-"This service is hosted by Hetzner Online GmbH, Germany (Frankfurt data "
-"centre). Your requests are routed through Cloudflare's network for DDoS "
-"protection and performance. See"
+"This service is hosted by Hetzner Online GmbH — data centre in the EU. "
+"Your requests are routed through Cloudflare's network for DDoS protection"
+" and performance. See"
msgstr ""
msgid ""
@@ -2343,11 +2341,14 @@ msgid "Video"
msgstr ""
msgid ""
-"We apply a temporary in-memory rate limit (max. 10 requests per minute "
-"per IP address) to protect the service from abuse. IP addresses used by "
-"the rate limiter are processed transiently in memory only and are never "
-"written to disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate "
-"interest in service stability and security."
+"We apply in-memory rate limits to protect the service from abuse — set "
+"per route, from 5 contact-form messages per hour up to 120 requests per "
+"minute. Several account routes count the limit per signed-in account "
+"rather than per IP address, and failed API-key attempts get a separate "
+"per-IP budget. IP addresses and account identifiers used by the rate "
+"limiter are processed transiently in memory only and are never written to"
+" disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate interest in "
+"service stability and security."
msgstr ""
msgid ""
@@ -2356,10 +2357,10 @@ msgid ""
msgstr ""
msgid ""
-"We may update this policy when the service changes. Accounts and billing "
-"are live as of April 2026; persistent file history (Cloud Edition Phase "
-"2) is planned but not yet implemented. The date at the top indicates the "
-"current version."
+"We may update this policy when the service changes. Accounts are live; "
+"paid plans are not yet available. Persistent file history (Cloud Edition "
+"Phase 2) is planned but not yet implemented. The date at the top "
+"indicates the current version."
msgstr ""
msgid ""
@@ -2442,9 +2443,10 @@ msgid "When to use this conversion"
msgstr ""
msgid ""
-"When you request a password reset, we generate a single-use token (valid "
-"for 30 minutes) and send it to your registered email address as a reset "
-"link. The outgoing message is delivered from"
+"When you register, we send a verification link to your email address "
+"(valid for 7 days). When you request a password reset, we generate a "
+"separate single-use token (valid for 30 minutes) and send it as a reset "
+"link. Outgoing messages are delivered from"
msgstr ""
msgid ""
@@ -2641,9 +2643,6 @@ msgstr ""
msgid "anonymous)"
msgstr ""
-msgid "are encrypted with the same key."
-msgstr ""
-
msgid "calls / month"
msgstr ""
@@ -2719,10 +2718,13 @@ msgstr ""
msgid "hint. Large batches are processed sequentially inside the request."
msgstr ""
-msgid "min 0.05 MB"
+msgid ""
+"legacy; current versions no longer write it, but a value saved by an "
+"older version is still read. Cleared on logout and when you delete your "
+"account."
msgstr ""
-msgid "no API access"
+msgid "min 0.05 MB"
msgstr ""
msgid "no cookies"
@@ -2754,11 +2756,6 @@ msgstr ""
msgid "on request"
msgstr ""
-msgid ""
-"optional; remembers the API key shown in your dashboard across reloads so"
-" you don't need to paste it again. Cleared on logout."
-msgstr ""
-
msgid "or apply directly as design partner →"
msgstr ""
@@ -2887,6 +2884,9 @@ msgstr ""
msgid "±3% tolerance"
msgstr ""
+msgid "— a PGP key is available on request."
+msgstr ""
+
msgid "— select a file first —"
msgstr ""
diff --git a/tests/test_cookie_notice.py b/tests/test_cookie_notice.py
index a177d90..422dd77 100644
--- a/tests/test_cookie_notice.py
+++ b/tests/test_cookie_notice.py
@@ -35,6 +35,20 @@ def test_notice_is_not_a_consent_dialog(client):
assert "cookie-notice-reject" not in html
+def test_logout_clears_every_signed_in_localstorage_key():
+ """privacy.html §6 promises that the keys written while signed in go on
+ logout — including the legacy ``filemorph_api_key`` older versions stored."""
+ from pathlib import Path
+
+ js = (Path(__file__).parent.parent / "app" / "static" / "js" / "auth.js").read_text(
+ encoding="utf-8"
+ )
+ body = re.search(r"function logout\(\) \{(.*?)\n \}", js, re.S)
+ assert body, "logout() not found in auth.js"
+ for key in ("ACCESS_KEY", "REFRESH_KEY", "'filemorph_api_key'"):
+ assert f"localStorage.removeItem({key})" in body.group(1), f"logout keeps {key}"
+
+
def test_notice_deep_links_privacy_cookies_section(client):
assert 'href="/privacy#cookies"' in client.get("/").text
assert 'id="cookies"' in client.get("/privacy").text
diff --git a/tests/test_format_lists_match_registry.py b/tests/test_format_lists_match_registry.py
index b965fd0..31ca30f 100644
--- a/tests/test_format_lists_match_registry.py
+++ b/tests/test_format_lists_match_registry.py
@@ -238,3 +238,21 @@ def test_formats_md_any_to_any_lists_match_registry():
"docs/formats.md: these formats don't convert to exactly the other formats "
"of their Audio/Video list:\n" + "\n".join(drift)
)
+
+
+def test_enterprise_page_format_pair_claim_is_not_an_overclaim(client, monkeypatch):
+ """enterprise.html claims "180+ format pairs" — counted from the same
+ get_public_conversions() that /formats renders from, with spelling
+ variants (jpg/jpeg, tif/tiff, htm/html, …) merged so they don't count
+ twice. If the registry ever shrinks below 180 distinct pairs the claim
+ becomes false; fail loudly here instead of overclaiming on a public page."""
+ from app.core.config import settings
+
+ monkeypatch.setattr(settings, "pricing_page_enabled", True)
+ distinct = {
+ (_alias(src), _alias(tgt)) for src, tgts in get_public_conversions().items() for tgt in tgts
+ }
+ pairs = len({pair for pair in distinct if pair[0] != pair[1]})
+ assert pairs >= 180, f"registry only has {pairs} distinct pairs — enterprise.html claims 180+"
+ for path in ("/en/enterprise", "/de/enterprise"):
+ assert "180+" in client.get(path).text, f"{path} lost its '180+ format pairs' claim"
diff --git a/tests/test_pricing_centralized.py b/tests/test_pricing_centralized.py
index d031bac..c395f7b 100644
--- a/tests/test_pricing_centralized.py
+++ b/tests/test_pricing_centralized.py
@@ -16,6 +16,8 @@
from __future__ import annotations
+import re
+
from app.core.config import settings
@@ -79,3 +81,13 @@ def test_commercial_pages_make_no_false_certification_claims(client, monkeypatch
body = client.get(url).text
assert "ISO 27001 certified" not in body
assert "SOC 2" not in body
+
+
+def test_terms_page_has_no_hardcoded_euro_price(client):
+ """Terms §8 must point to /pricing for the current amount, never hardcode
+ a euro price that can drift from app/core/pricing.py / settings (it used
+ to quote "Pro €7/month, Business €19/month" — already stale)."""
+ for url in ("/de/terms", "/en/terms"):
+ body = client.get(url).text
+ # "€7" (en) as well as "7 €" (de)
+ assert not re.search(r"€\s?\d|\d\s?€", body), f"{url} hardcodes a euro price in Terms"
From 3f19de95abf00d6db3bfbfc8f6c5e3afc6987916 Mon Sep 17 00:00:00 2001
From: MrChengLen
Date: Tue, 29 Sep 2026 09:11:50 +0200
Subject: [PATCH 2/3] =?UTF-8?q?=EF=BB=BFchore(changelog):=20take=20the=20e?=
=?UTF-8?q?ntry=20out=20to=20merge=20main=20in=20=C3=A2=E2=82=AC=E2=80=9D?=
=?UTF-8?q?=20back=20in=20two=20commits?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
main gained two CHANGELOG entries (#170) after this branch was cut,
and every PR adds its entry at the same place. Removing this PR's entry lets
GitHub merge main in without a conflict; the next commit puts it back on top.
Co-Authored-By: Claude Opus 5.5
---
CHANGELOG.md | 28 ----------------------------
1 file changed, 28 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83d2b80..a9fcfe0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,34 +9,6 @@ Versions follow [Semantic Versioning](https://semver.org/).
## [Unreleased]
-### Fixed — website texts match what the service does
-
-The public pages were checked claim by claim against the code:
-
-- **Terms §8** no longer quotes subscription prices (they come from the
- pricing page) and describes cancellation by email.
-- **Privacy policy:** the rate-limit description is accurate (set per route,
- from 5 contact messages per hour to 120 requests per minute); the list of
- stored data adds the preferred language, the email-verification timestamp
- and per-request usage rows; sub-processor locations are corrected (Hetzner:
- a data centre in the EU; Zoho: Amsterdam and Dublin); paid plans are not
- yet available; the date is refreshed. Logging out now also removes the
- legacy `filemorph_api_key` browser entry (`auth.js`), as §6 says — a test
- in `tests/test_cookie_notice.py` pins it.
-- **/pricing and /enterprise:** API access without a key, v1.1.0 as the
- tagged release, the audit log's scope, the veraPDF gate, "180+ format
- pairs" (distinct pairs, pinned by a test), support response times agreed
- per contract, and a PGP key on request.
-- **/formats** limits exact target-size compression to JPEG, WebP and AVIF.
-- **Dashboard:** account deletion names the 10-year tax-retention record.
-- **/security** and `/.well-known/security.txt` drop the GitHub Security
- Advisories option, which is not enabled on this repository.
-- The redaction page no longer calls its engine AGPL open source (`app/ee`
- is commercially licensed); the JSON-LD `featureList` adds the PDF tools
- and PDF → PDF/A.
-- `tests/test_pricing_centralized.py` fails if the terms page hardcodes a
- euro price in either language.
-
### Fixed — API docs: keys are optional, video compression and converter registration described correctly
The API reference marked every file route "Authentication: Required", and the
From f0b32de847eaed71b18355f029fe7ab2e6f8c0e6 Mon Sep 17 00:00:00 2001
From: MrChengLen
Date: Tue, 29 Sep 2026 09:12:19 +0200
Subject: [PATCH 3/3] docs(changelog): website entry back on top of the merged
changelog
Co-Authored-By: Claude Opus 5.5
---
CHANGELOG.md | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a510c34..7998f19 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,34 @@ Versions follow [Semantic Versioning](https://semver.org/).
## [Unreleased]
+### Fixed — website texts match what the service does
+
+The public pages were checked claim by claim against the code:
+
+- **Terms §8** no longer quotes subscription prices (they come from the
+ pricing page) and describes cancellation by email.
+- **Privacy policy:** the rate-limit description is accurate (set per route,
+ from 5 contact messages per hour to 120 requests per minute); the list of
+ stored data adds the preferred language, the email-verification timestamp
+ and per-request usage rows; sub-processor locations are corrected (Hetzner:
+ a data centre in the EU; Zoho: Amsterdam and Dublin); paid plans are not
+ yet available; the date is refreshed. Logging out now also removes the
+ legacy `filemorph_api_key` browser entry (`auth.js`), as §6 says — a test
+ in `tests/test_cookie_notice.py` pins it.
+- **/pricing and /enterprise:** API access without a key, v1.1.0 as the
+ tagged release, the audit log's scope, the veraPDF gate, "180+ format
+ pairs" (distinct pairs, pinned by a test), support response times agreed
+ per contract, and a PGP key on request.
+- **/formats** limits exact target-size compression to JPEG, WebP and AVIF.
+- **Dashboard:** account deletion names the 10-year tax-retention record.
+- **/security** and `/.well-known/security.txt` drop the GitHub Security
+ Advisories option, which is not enabled on this repository.
+- The redaction page no longer calls its engine AGPL open source (`app/ee`
+ is commercially licensed); the JSON-LD `featureList` adds the PDF tools
+ and PDF → PDF/A.
+- `tests/test_pricing_centralized.py` fails if the terms page hardcodes a
+ euro price in either language.
+
### Security — the Docker image is built without a restored build cache
`docker.yml` restored BuildKit's GitHub Actions cache (`cache-from: type=gha`)