Compare commits

...
4 Commits
Author SHA1 Message Date
JUSNandClaude Opus 5.5 a5d237eca5 STAND: Sprach-Durchlauf aller 27 Sprachen dokumentiert
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 22:36:54 +02:00
JUSNandClaude Opus 5.5 808d0dbbfe STAND: zweiter Deploy live
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 22:32:04 +02:00
JUSNandClaude Opus 5.5 f5eea8ca66 Praesentation MBE: Datenschutz-Blatt (Traeger), Kurzanleitung Beratungs-PC, Spickzettel, STAND
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 22:30:33 +02:00
JUSNandClaude Opus 5.5 82235dc529 Handy-Bedienung in 27 Sprachen, Kopf im Einrichtungs-Modus, schmale Handys
- ui-texte.js: 74 Bedientexte je Sprache (uebersetzt + lektoriert), t() in
  demo.html; am PC bleibt alles deutsch, am Handy Sprache der Person,
  RTL fuer ar/fa/ur/ps, verbundene Schriften ohne Sperrsatz
- Servermeldungen am Handy nach Code in der Bediensprache
- Seitenkopf "Fuer Sie kostenlos ueber ..." statt "2 Analysen gratis"
- Turnstile passt auf schmale Handys (Abstaende, compact unter 350 px)
- Knopf fuer Mitarbeitende eindeutig: "Zugang dauerhaft auf ein Handy geben"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 22:30:33 +02:00
9 changed files with 2866 additions and 89 deletions

No files matched your search

+23 -10
View File
@@ -5,14 +5,14 @@
>
> Ausführlicher Prüfbericht mit allen 61 Funden: [plan-bis-29-10.md](plan-bis-29-10.md)
**Zuletzt aktualisiert:** Do 22.10.2026, spätabends: **bereit für den Deploy**
**Zuletzt aktualisiert:** Do 22.10.2026, nachts: **alles live**, inklusive Handy-Bedienung in 27 Sprachen. Nächster Schritt: deine Generalprobe.
---
## Wo wir stehen (in einem Satz)
Alles ist gebaut, zweimal geprüft und lokal getestet, aber **noch nicht live**.
**Jetzt fehlt nur noch dein „deploy“**, danach kommen die echten Generalproben.
**Live auf behoerdenklar.de** (Gesundheits-Check 10/10 grün). Dein Vorführ-Code: **`VORF-2EDF`**
(30 Briefe, bis 30.11.). Morgen: Generalprobe 1 mit deinem Laptop und Handy.
---
@@ -71,10 +71,23 @@ Alles ist gebaut, zweimal geprüft und lokal getestet, aber **noch nicht live**.
> ⚠️ **Hinweis für die Generalproben:** Beim Musterbrief zeigt die Ampel **am Sa 24.10. Gelb** („Noch 10 Tage“) und am Mo 26.10. ebenfalls Gelb. Das ist richtig so. **Ab Di 27.10. ist sie rot.** Bildschirmfotos für den Notfall deshalb erst am Mi 28.10. machen.
## 2b. Zweiter Deploy (Do 22.10., nachts): live ✅
- ✅ **Bedienung am Handy in 27 Sprachen.** Einwilligung, Knöpfe, Hinweise, Fehlermeldungen, Ergebnis-Überschriften, Ampel, Kalender und Anruf-Hilfe kommen in der Sprache der Person, Arabisch/Farsi/Urdu/Paschtu von rechts nach links. **Am PC bleibt alles deutsch.** Je Sprache übersetzt und von einem Lektor geprüft, maschinell auf Vollständigkeit geprüft (0 Fehler).
- ✅ Cloudflare-Kästchen passt auf schmale Handys. Oben steht „Für Sie kostenlos über …“ statt „2 Analysen gratis“.
- ✅ Knopf für die Beratung umbenannt: „🔑 Zugang dauerhaft auf ein Handy geben (nur für Mitarbeitende)“, damit man ihn nicht mit „Lieber mit dem Handy fotografieren“ verwechselt.
- ✅ **[Datenschutz-Blatt](datenschutz-blatt.pdf)** für die Datenschutzbeauftragte des Trägers (2 Seiten, gegen den Code geprüft).
- ✅ **[Kurzanleitung](kurzanleitung-beratung.pdf)** für Beraterinnen (1 Seite). Der Code wird am Di 27.10. eingetragen.
- ✅ **Webseite veröffentlicht**, Gesundheits-Check 12/12 grün.
- ℹ️ Der Live-Test im automatisierten Browser ging nicht, weil Cloudflare ferngesteuerte Browser blockt. Deshalb ist der echte Test die **Generalprobe morgen mit deinen Geräten**.
- ✅ **Sprach-Durchlauf (lokal, Handy-Größe 375 px):** alle 27 Sprachen nacheinander eingestellt. In jeder Sprache ist **kein deutscher Text mehr übrig**, **nichts ragt über den Rand**, die Schreibrichtung stimmt (Arabisch, Farsi, Urdu und Paschtu von rechts). Tigrinya und Hindi zusätzlich mit Bildschirmfoto angeschaut: Schrift sauber.
- Noch offen: die **echte KI-Erklärung** in den Sprachen (kommt erst mit der Generalprobe) und eine Prüfung durch Muttersprachler für Tigrinya, Somali, Paschtu und Kurdisch (nach dem Termin).
## 3. Was du tun musst
- 👤 **„deploy“ schreiben.** Dann veröffentliche ich zuerst den Worker und danach die Webseite. Ohne das ist nichts davon auf behoerdenklar.de.
- 👤 **Mo 26.10.: MBE anrufen.** Wer ist der Träger (Diakonie, Caritas …)? Gibt es eine eigene AVV-Vorlage? Und bestätigen: Do 29.10., wie viele Leute, gibt es einen Bildschirm?
- ✅ ~~„deploy“ schreiben~~: erledigt, live seit Do 22.10. abends.
- 👤 **Fr 23.10.: Generalprobe 1** mit Laptop und Handy: `behoerdenklar.de/demo?code=VORF-2EDF`, Arabisch, Musterbrief (Ampel noch gelb = richtig).
- ✅ ~~Mo 26.10. MBE anrufen~~: Entscheidung vom 22.10.: Träger und AVV klärst du **erst, wenn die MBE Interesse hat**, also im Termin oder danach. Den Satz dafür findest du im Spickzettel.
- 👤 **Entscheiden: Testzeitraum.** „1 Monat“ (deine Wahl) oder ein festes Datum „bis 18.12.“ (mein Vorschlag, damit der Code nicht mitten in der Bestellung abläuft). Wichtig ist das erst beim Anlegen des Codes am Di 27.10.
- 👤 **Generalproben mitmachen** (mit deinem Handy und Laptop, siehe unten).
- 👤 🔴 **Alten Anthropic-Schlüssel tauschen**, der im Juli im Chat gepostet wurde (console.anthropic.com → API Keys).
@@ -86,10 +99,10 @@ Alles ist gebaut, zweimal geprüft und lokal getestet, aber **noch nicht live**.
| Tag | Was | Wer |
|---|---|---|
| **Do 22.** | Korrekturen ✅, Gegenprüfung ✅, alles gesichert ✅ | Claude |
| **Do 22. / Fr 23.** | **Deploy**, sobald du „deploy“ sagst. Danach Vorführ-Code anlegen und `npm run pruefung`. | Claude, nach deinem OK |
| **Do 22.** | **Deploy** ✅, Vorführ-Code `VORF-2EDF` ✅, `npm run pruefung` ✅ | Claude |
| **Fr 23. / Sa 24.** | **Generalprobe 1 mit echter KI:** Musterbrief, Arabisch **und** Farsi, mit Stoppuhr, Bildschirmfotos für den Notfall | du und Claude |
| **So 25.** | Fehler aus der Probe beheben. Neues **Datenschutz-Blatt** für den Datenschutzbeauftragten des Trägers. **Kurzanleitung** für Beraterinnen (1 Seite). | Claude |
| **Mo 26.** | MBE anrufen. **Generalprobe 2.** Spätester Tag für Code-Änderungen am Worker. | du und Claude |
| **So 25.** | Fehler aus der Probe beheben. (Datenschutz-Blatt und Kurzanleitung sind schon fertig ✅) | Claude |
| **Mo 26.** | **Generalprobe 2.** Spätester Tag für Code-Änderungen am Worker. | du und Claude |
| **Di 27.** | **MBE-Code anlegen**, in den Handzettel eintragen, gedruckten QR mit dem Handy testen, alles drucken (Handzettel 5×, Musterbrief 2×, Kurzanleitung 5×, Datenschutz-Blatt 2×). Ab abends **nichts mehr am Code ändern.** | du und Claude |
| **Mi 28.** | **Generalprobe 3**, genau wie am Termin. Geräte laden, Checkliste vom Spickzettel. | du |
| **Do 29.** | **Termin.** Ziel: Code übergeben und Auswertungstermin am 26.11. ausmachen. | du |
@@ -98,8 +111,8 @@ Alles ist gebaut, zweimal geprüft und lokal getestet, aber **noch nicht live**.
## 5. Wenn noch Zeit ist (vor dem Termin)
- ⏳ **Arabische Bedienung** am Handy (Einwilligung, Knöpfe, Hinweise). Bisher ist nur die Erklärung arabisch. Ca. 2–3 Std.
- ⏳ Den Hinweis „Kostenlos über …“ auch oben im Seitenkopf zeigen (dort steht noch „2 Analysen gratis“).
- ✅ ~~Arabische Bedienung~~: erledigt, sogar in allen 27 Sprachen.
- ✅ ~~„Kostenlos über …“ im Seitenkopf~~: erledigt.
---
@@ -85,6 +85,7 @@
<div class="schritt"><span class="zeit">9–11'</span><div>
<h3>Das Angebot: Handzettel übergeben</h3>
<p class="sag">„Ich möchte Ihnen einen Testzugang dalassen: einen Monat, bis zu 100 Briefe, kostenlos. Ihre Ratsuchenden zahlen nichts. Der Code steht hier auf dem Zettel.“</p>
<p><b>Wenn Interesse da ist:</b> „Zu welchem Träger gehören Sie, und gibt es bei Ihnen eine Datenschutzbeauftragte? Dann schicke ich ihr unser Datenschutz-Blatt und auf Wunsch einen AVV.“</p>
<p><b>Gleich den Auswertungstermin ausmachen:</b> „Darf ich in vier Wochen wiederkommen, am <b>Do 26.11.</b>, und hören, was es gebracht hat?“</p>
</div></div>
Binary file not shown.
@@ -0,0 +1,357 @@
<!DOCTYPE html>
<!--
Datenschutz-Blatt für die Datenschutzbeauftragte des Trägers (2 Seiten A4).
Beschreibt die WEBSEITE behoerdenklar.de/demo inkl. Einrichtungs-Code und
Übergabe PC <-> Handy. Ersetzt für die Webseite das alte Factsheet vom Juli
(rechtliches/datenschutz-factsheet.md beschreibt die App).
Quellen: webseite/datenschutz.html (Stand 22.10.2026), proxy/src/index.ts,
webseite/demo.html, webseite/uebergabe.js, proxy/wrangler.toml.
PDF: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless=new \
--disable-gpu --allow-file-access-from-files --no-pdf-header-footer \
--print-to-pdf=datenschutz-blatt.pdf "file://$PWD/datenschutz-blatt.html"
-->
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Datenschutz auf einen Blick</title>
<script src="../../webseite/qrcode.js"></script>
<style>
@page { size: A4; margin: 0; }
:root {
--papier: #faf7f0; --tinte: #21211d; --grau: #6b675e; --text: #3a3833;
--amtsblau: #1d4e89; --stempelrot: #b3372b; --marker: #ffe66b; --gruen: #2e7d4f;
}
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
body { font-family: Georgia, 'Times New Roman', serif; color: var(--tinte); background: #fff; }
.seite {
width: 210mm; height: 297mm; overflow: hidden; position: relative;
padding: 11mm 14mm 0;
background: repeating-linear-gradient(0deg, transparent 0 6.5mm, rgba(33,33,29,0.03) 6.5mm 6.7mm), var(--papier);
font-size: 8.8pt; line-height: 1.36;
page-break-after: always; break-after: page;
}
.seite:last-child { page-break-after: auto; break-after: auto; }
.mono { font-family: 'Courier New', ui-monospace, monospace; }
.briefkopf { display: flex; justify-content: space-between; align-items: baseline; padding-bottom: 2mm; border-bottom: 0.6mm solid var(--tinte); }
.absender { font-weight: 700; font-size: 12.5pt; }
.absender small { font-weight: 400; font-size: 8pt; opacity: .6; letter-spacing: .04em; }
.az { color: var(--grau); font-size: 8pt; }
.betreff { margin-top: 4mm; font-size: 8pt; color: var(--grau); text-transform: uppercase; letter-spacing: .14em; }
h1 { font-size: 22pt; line-height: 1.14; margin-top: 1mm; letter-spacing: -0.01em; }
.markiert { background: linear-gradient(104deg, transparent 2%, var(--marker) 4%, var(--marker) 96%, transparent 98%); padding: 0 1.5mm; }
.anrede { margin-top: 2mm; font-size: 9.6pt; line-height: 1.4; }
.anrede i { color: var(--grau); }
h2 { font-size: 8pt; text-transform: uppercase; letter-spacing: .14em; color: var(--grau); font-weight: 400;
margin: 3.8mm 0 2mm; display: flex; align-items: center; gap: 2.5mm; }
h2 .nr { font-family: 'Courier New', monospace; font-weight: 700; color: var(--amtsblau); letter-spacing: 0; font-size: 9pt; }
h2::after { content: ''; flex: 1; border-top: 0.25mm solid rgba(33,33,29,.25); }
.zwei { display: grid; grid-template-columns: 1fr 1fr; gap: 5mm; }
.eins-box { display: grid; grid-template-columns: 1fr 81mm; gap: 5mm; align-items: start; }
.kasten { background: #fff; border: 0.5mm solid var(--tinte); padding: 3.4mm 3.6mm 2.4mm; position: relative; }
.kasten .label { position: absolute; top: -2.6mm; left: 3.5mm; font-family: 'Courier New', monospace; font-size: 7pt;
text-transform: uppercase; letter-spacing: .1em; background: var(--tinte); color: var(--papier); padding: .4mm 2mm; }
ul.haken { list-style: none; font-size: 8.5pt; line-height: 1.32; }
ul.haken li { padding-left: 4mm; position: relative; margin-bottom: .9mm; }
ul.haken li::before { content: '✓'; position: absolute; left: 0; color: var(--gruen); font-weight: 700; }
ul.haken li.ehrlich::before { content: '!'; color: var(--stempelrot); left: .8mm; }
/* Datenfluss */
.schritte { display: grid; grid-template-columns: 1fr 1fr; gap: 2mm 5mm; }
.schritt { display: grid; grid-template-columns: 6mm 1fr; gap: 1.2mm; font-size: 8.5pt; line-height: 1.32; color: var(--text); }
.schritt .n { font-family: 'Courier New', monospace; font-weight: 700; font-size: 10.5pt; color: var(--amtsblau);
border: 0.35mm solid var(--amtsblau); background: #fff; width: 5.4mm; height: 5.4mm; display: flex; align-items: center; justify-content: center; }
.schritt b { color: var(--tinte); }
.wege { display: grid; grid-template-columns: 1fr 1fr; gap: 5mm; margin-top: 2.6mm; }
.weg { border: 0.3mm solid rgba(33,33,29,.35); background: #fff; padding: 1.5mm 2.4mm; font-size: 8pt; line-height: 1.3; color: var(--text); }
.weg b { color: var(--tinte); }
/* Tabellen */
table { width: 100%; border-collapse: collapse; font-size: 8pt; line-height: 1.24; }
th { font-family: 'Courier New', monospace; font-weight: 400; font-size: 7pt; text-transform: uppercase; letter-spacing: .1em;
color: var(--grau); text-align: left; padding: 0 2mm .8mm 0; border-bottom: 0.4mm solid var(--tinte); }
td { padding: .8mm 2mm .8mm 0; vertical-align: top; border-bottom: 0.25mm dotted rgba(33,33,29,.35); color: var(--text); }
td:first-child { color: var(--tinte); font-weight: 700; }
td.dauer { color: var(--tinte); }
td.dauer b { color: var(--amtsblau); }
tr.gruppe td { font-family: 'Courier New', monospace; font-weight: 400; font-size: 7pt; text-transform: uppercase; letter-spacing: .1em;
color: var(--papier); background: var(--tinte); padding: .4mm 2mm; border-bottom: none; }
tr.gruppe.hell td { background: rgba(33,33,29,.12); color: var(--grau); }
tr.nebensache td { color: var(--grau); }
tr.nebensache td:first-child { color: #4d4a43; }
.tabfuss { font-size: 7.8pt; color: var(--grau); margin-top: 1.4mm; line-height: 1.32; }
.tabfuss b { color: var(--tinte); }
/* Rollen */
.fall h3 { font-size: 9.8pt; line-height: 1.22; margin-bottom: .9mm; }
.fall p { font-size: 8.4pt; line-height: 1.32; color: var(--text); margin-bottom: 1mm; }
.fall p:last-child { margin-bottom: 0; }
.fall .folge { color: var(--tinte); border-left: 0.8mm solid var(--amtsblau); padding-left: 2.2mm; }
.fall .folge b { color: var(--amtsblau); }
.absprache { margin-top: 3mm; font-size: 8.4pt; line-height: 1.34; color: var(--text); }
.absprache .gross { font-weight: 700; font-size: 10.4pt; color: var(--tinte); display: inline-block; margin-bottom: .8mm; }
/* Einwilligung */
.zitat { background: #fff; border-left: 1mm solid var(--amtsblau); padding: 2mm 3mm; font-style: italic; font-size: 8.5pt; line-height: 1.36; }
.zitat .quelle { display: block; font-style: normal; font-family: 'Courier New', monospace; font-size: 6.8pt; color: var(--grau); margin-top: .8mm; letter-spacing: .04em; }
ul.punkte { list-style: none; font-size: 8.4pt; line-height: 1.32; color: var(--text); }
ul.punkte li { padding-left: 3.5mm; position: relative; margin-bottom: .9mm; }
ul.punkte li::before { content: '›'; position: absolute; left: 0; color: var(--amtsblau); font-weight: 700; }
ul.punkte b { color: var(--tinte); }
/* Grenzen */
.grenzen { display: grid; grid-template-columns: 1fr 1fr; gap: 1.3mm 5mm; list-style: none; font-size: 8.4pt; line-height: 1.32; color: var(--text); }
.grenzen li { padding-left: 4mm; position: relative; }
.grenzen li::before { content: '!'; position: absolute; left: .8mm; color: var(--stempelrot); font-weight: 700; }
.grenzen b { color: var(--tinte); }
/* Kontakt (Seite 2 unten, ersetzt dort die Fußzeile) */
.kontakt-unten { position: absolute; left: 14mm; right: 14mm; bottom: 9mm; }
.kontakt-unten h2 { margin-top: 0; }
.kontakt { display: grid; grid-template-columns: 1fr 1fr 19mm; gap: 5mm; align-items: center; border: 0.7mm solid var(--tinte);
box-shadow: 1.6mm 1.8mm 0 rgba(33,33,29,.9); background: #fff; padding: 2.8mm 4mm; }
.kontakt .name { font-size: 11pt; font-weight: 700; line-height: 1.2; }
.kontakt p { font-size: 8.4pt; line-height: 1.36; }
.kontakt .link { font-family: 'Courier New', monospace; color: var(--amtsblau); font-size: 9.5pt; font-weight: 700; }
.kontakt .klein { color: var(--grau); font-size: 7.8pt; }
#qr { width: 19mm; height: 19mm; }
#qr svg { width: 100%; height: 100%; display: block; }
.stempel { display: inline-block; padding: .8mm 2.2mm; border: 0.5mm solid var(--stempelrot); color: var(--stempelrot);
font-family: 'Courier New', monospace; font-weight: 700; font-size: 7pt; letter-spacing: .1em;
text-transform: uppercase; transform: rotate(-3deg); }
.fuss { position: absolute; left: 14mm; right: 14mm; bottom: 8mm; border-top: 0.4mm solid var(--tinte); padding-top: 2mm;
display: flex; justify-content: space-between; align-items: flex-end; font-size: 8pt; line-height: 1.4; }
.fuss .wer b { font-size: 9.5pt; }
.fuss .seitenzahl { font-family: 'Courier New', monospace; font-size: 7.5pt; color: var(--grau); letter-spacing: .06em; }
</style>
</head>
<body>
<!-- ============================ SEITE 1 ============================ -->
<div class="seite">
<div class="briefkopf">
<span class="absender">📬 BehördenKlar <small>by Webklar</small></span>
<span class="az mono">Az: KLAR-DATENSCHUTZ/2026 · Stand: 22.10.2026</span>
</div>
<p class="betreff">Für die Datenschutzbeauftragte Ihres Trägers · Webseite behoerdenklar.de/demo</p>
<h1>Datenschutz <span class="markiert">auf einen Blick</span></h1>
<p class="anrede">
Was mit den Daten passiert, wenn Ihre Beratungsstelle BehördenKlar im Browser nutzt, geprüft am
Server-Code und an der Datenschutzerklärung. <i>Das Blatt vom Juli 2026 beschrieb die App, nicht die Webseite.</i>
</p>
<h2><span class="nr">1</span> Was BehördenKlar tut</h2>
<div class="eins-box">
<p>
BehördenKlar erklärt Behördenbriefe in einfacher Sprache, auf Wunsch in 27 Sprachen.
Ein Foto oder PDF genügt: Eine KI (Claude von Anthropic) schreibt auf, was das Amt will,
was zu tun ist und bis wann. Kein Nutzerkonto, keine Anmeldung. Mit einem
<b>Einrichtungs-Code</b> ist der Dienst für Ihre Ratsuchenden kostenlos. Über den Code erfährt
Ihre Stelle nichts über Briefe, nur Zahlen: übrige Analysen und Nutzung pro Woche und Sprache.
</p>
<div class="kasten">
<span class="label">Kurz gesagt</span>
<ul class="haken">
<li>Briefe speichern wir nicht, Erklärungen nur verschlüsselt zur Übergabe (max. 15&nbsp;Min.).</li>
<li>Mit Code: kein Konto, keine E-Mail-Adresse nötig.</li>
<li class="ehrlich">Den Brief liest die KI: Anthropic (USA), in der Regel 30&nbsp;Tage gespeichert, kein Training.</li>
</ul>
</div>
</div>
<h2><span class="nr">2</span> So läuft ein Brief durch das System · Knopf „Lieber mit dem Handy fotografieren“</h2>
<div class="schritte">
<div class="schritt"><span class="n">1</span><div>
<b>QR-Code am Beratungs-PC.</b> Der Browser des PCs erzeugt eine zufällige Kennung und einen
neuen AES-256-Schlüssel. Beides steht im QR-Code hinter dem
„#“ der Adresse. <b>Den Schlüssel bekommt unser Server nie.</b>
</div></div>
<div class="schritt"><span class="n">4</span><div>
<b>Erklärung.</b> Anthropic (Modell Claude) erklärt den Brief auf Deutsch. Für eine andere
Sprache übersetzt ein zweiter KI-Aufruf die Erklärung. Die Antwort geht über unseren Server
zurück ans Handy, ohne dort gespeichert zu werden.
</div></div>
<div class="schritt"><span class="n">2</span><div>
<b>Einwilligung am eigenen Handy.</b> Die ratsuchende Person scannt den Code, setzt das
Häkchen für diesen einen Brief (Abschnitt&nbsp;6) und fotografiert ihn. Kein Konto, keine App.
</div></div>
<div class="schritt"><span class="n">5</span><div>
<b>Übergabe, Ende-zu-Ende verschlüsselt.</b> Das Handy verschlüsselt die Erklärung mit dem
Schlüssel aus dem QR-Code (AES-256-GCM) und legt sie bei uns ab. Der PC holt sie und
entschlüsselt sie. <b>Unser Server kann sie nicht lesen.</b>
</div></div>
<div class="schritt"><span class="n">3</span><div>
<b>Weg zur KI.</b> Das Foto geht über eine verschlüsselte Verbindung (TLS) an unseren Server
(Cloudflare). Er prüft Bot-Schutz und Guthaben und reicht es an Anthropic weiter,
<b>ohne es zu speichern</b>.
</div></div>
<div class="schritt"><span class="n">6</span><div>
<b>Löschen.</b> Der Zwischenspeicher wird beim Abholen gelöscht, sonst <b>spätestens
15&nbsp;Minuten</b> nach dem letzten Päckchen. Am PC bleibt die Erklärung nur in der offenen
Seite, bis diese neu geladen wird.
</div></div>
</div>
<div class="wege">
<div class="weg"><b>Beraterin lädt am Dienst-PC hoch:</b> nur Schritt 3 und 4. Das Häkchen setzt
dann die Beraterin (zur Rolle siehe Abschnitt&nbsp;4).</div>
<div class="weg"><b>„Ergebnis aufs Handy mitnehmen“:</b> genauso verschlüsselt, beim Abholen
gelöscht, sonst nach spätestens 15&nbsp;Minuten.</div>
</div>
<h2><span class="nr">3</span> Was gespeichert wird und wie lange</h2>
<table>
<colgroup><col style="width: 37mm"><col><col style="width: 45mm"></colgroup>
<thead><tr><th>Was</th><th>Was genau</th><th>Wie lange</th></tr></thead>
<tbody>
<tr class="gruppe"><td colspan="3">Beim Zugang über einen Einrichtungs-Code</td></tr>
<tr><td>Brief und Erklärung</td><td>Laufen nur durch unseren Server. Ausnahme: Übergabe, nächste Zeile.</td><td class="dauer"><b>bei uns: gar nicht</b></td></tr>
<tr><td>Übergabe-Päckchen</td><td>Erklärung und Statusmeldungen, verschlüsselt, für uns nicht lesbar. Dazu eine Schreib-Bremse pro IP-Adresse (Zeitfenster 1 Minute).</td><td class="dauer">beim Abholen, <b>spätestens 15 Min.</b> nach dem letzten Päckchen</td></tr>
<tr><td>Bei Anthropic (KI)</td><td>Foto und Erklärung. Keine Nutzung zum Training der KI.</td><td class="dauer"><b>in der Regel 30 Tage</b>, länger nur bei Missbrauchsverdacht</td></tr>
<tr><td>Einrichtungs-Guthaben</td><td>Code, Kennung, Name der Stelle, Ablaufdatum, Restbriefe. Nichts über Ratsuchende.</td><td class="dauer">ohne automatische Frist</td></tr>
<tr><td>Nutzungszähler</td><td>Je Analyse nur Datum und Sprache. Kein Briefinhalt, kein Personenbezug.</td><td class="dauer"><b>max. 13 Monate</b></td></tr>
<tr><td>Code-Fehlversuche</td><td>Zähler pro IP-Adresse und Tag, nur bei falscher Eingabe.</td><td class="dauer"><b>48 Stunden</b></td></tr>
<tr><td>Server-Protokolle</td><td>Zeitpunkt, aufgerufene Adresse, Fehlerart, technische Metadaten. Kein Briefinhalt.</td><td class="dauer"><b>max. 7 Tage</b></td></tr>
<tr><td>Im Browser des Geräts</td><td>Zugangs-Nachweis, Code und Name der Stelle, Ablaufdatum, Zahl übriger Briefe, Sprache. Keine Briefe.</td><td class="dauer">bis zum Löschen im Browser</td></tr>
<tr class="gruppe hell"><td colspan="3">Nur ohne Einrichtungs-Code: 2 Gratis-Analysen für Privatpersonen</td></tr>
<tr class="nebensache"><td>Gratis-Zähler</td><td>Zähler pro IP-Adresse und Tag, dazu die Tagessumme aller Gratis-Analysen.</td><td class="dauer">48 Stunden (Datenschutz&shy;erklärung: „max. 30 Tage“)</td></tr>
<tr class="nebensache"><td>E-Mail-Prüfsumme</td><td>Nur für die 2. Gratis-Analyse: SHA-256-Prüfsumme, die Adresse selbst nicht.</td><td class="dauer">unbefristet</td></tr>
</tbody>
</table>
<p class="tabfuss">
<b>Rechtsgrundlagen laut Datenschutzerklärung:</b> Brief und Erklärung: Einwilligung (Art. 6 Abs. 1 lit. a,
Art. 9 Abs. 2 lit. a DSGVO). Zähler, Schutz vor Missbrauch, Protokolle: berechtigtes Interesse (Art. 6 Abs. 1 lit. f DSGVO).
</p>
<div class="fuss">
<div class="wer">
<b>Justin Klein</b> · Webklar GbR · Am Schwimmbad 10, 67722 Winnweiler<br>
Tel. 0170 4969375 · justin@webklar.com · <b>behoerdenklar.de/datenschutz</b>
</div>
<span class="seitenzahl">Seite 1 von 2 · bitte wenden</span>
</div>
</div>
<!-- ============================ SEITE 2 ============================ -->
<div class="seite">
<div class="briefkopf">
<span class="absender">📬 BehördenKlar <small>by Webklar</small></span>
<span class="az mono">Datenschutz auf einen Blick · Seite 2 von 2</span>
</div>
<h2 style="margin-top: 5mm; margin-bottom: 3mm;"><span class="nr">4</span> Wer ist verantwortlich? Das hängt davon ab, wer hochlädt</h2>
<div class="zwei">
<div class="kasten fall">
<span class="label">Fall A · Die Person selbst</span>
<h3>Die ratsuchende Person nutzt den Dienst selbst</h3>
<p>Eigenes Handy, eigenes Häkchen für jeden Brief: zu Hause oder in der Beratung über
„Lieber mit dem Handy fotografieren“.</p>
<p class="folge"><b>Verantwortlich ist die Webklar GbR</b> (BehördenKlar). Grundlage ist die
Einwilligung der Person.</p>
<p>Bitte beachten: In der Beratung erscheint die Erklärung auch am Bildschirm Ihrer Stelle.
Gespeichert wird sie dort nicht.</p>
</div>
<div class="kasten fall">
<span class="label">Fall B · Ihre Stelle</span>
<h3>Ihre Beratungsstelle lädt den Brief selbst hoch</h3>
<p>Die Beraterin lädt den Brief einer Klientin am Dienst-PC hoch.</p>
<p class="folge">Dann arbeiten <b>wir als Auftragsverarbeiter</b> für Ihre Stelle (Art. 28 DSGVO),
mit Cloudflare und Anthropic als Unterauftragsverarbeitern. Einen <b>AVV mit
Verschwiegenheitsklausel</b> stellen wir auf Wunsch.</p>
<p>Das Häkchen am Dienst-PC setzt dann die Beraterin. Es ersetzt keine Einwilligung der Klientin.</p>
</div>
</div>
<p class="absprache">
<span class="gross"><span class="markiert">Vor dem ersten echten Brief am Dienst-PC sprechen wir das ab.</span></span><br>
Unser Vorschlag für den Test: Fall A. Haben Sie eine eigene AVV-Vorlage (z. B. nach DSG-EKD oder KDG),
schicken Sie sie uns gern.
</p>
<h2><span class="nr">5</span> Dienstleister</h2>
<table>
<colgroup><col style="width: 37mm"><col><col style="width: 30mm"></colgroup>
<thead><tr><th>Wer</th><th>Wofür</th><th>Beim Code-Zugang</th></tr></thead>
<tbody>
<tr><td>Cloudflare, Inc. (USA)</td><td>Unser Server (Cloudflare Workers), Zwischenspeicher und Zähler, Bot-Schutz (Turnstile), Hosting der Webseite, Besucherstatistik ohne Cookies</td><td class="dauer"><b>ja</b></td></tr>
<tr><td>Anthropic PBC (USA)</td><td>KI-Erklärung und Übersetzung (Modell Claude), keine Nutzung zum Training</td><td class="dauer"><b>ja</b></td></tr>
<tr class="nebensache"><td>Stripe und Brevo</td><td>Nur für Privatpersonen: Bezahlung beim Kauf von Guthaben (Stripe, Irland/USA), E-Mail mit dem Guthaben-Link und Warteliste (Brevo, Deutschland/Frankreich)</td><td class="dauer">nein, nicht relevant</td></tr>
</tbody>
</table>
<p class="tabfuss" style="color: var(--text); font-size: 8.2pt;">
<b>Übermittlung in die USA:</b> gestützt auf EU-Standardvertragsklauseln (Art. 46 Abs. 2 lit. c DSGVO).
Sie sind Teil der Auftragsverarbeitungsverträge (DPA) von Cloudflare und Anthropic, die mit deren
Geschäftsbedingungen gelten. Die Fundstellen nennen wir Ihnen gern.
</p>
<h2><span class="nr">6</span> Einwilligung: für jeden Brief neu</h2>
<div class="zwei" style="grid-template-columns: 1.12fr 1fr;">
<p class="zitat">
„Ich bin einverstanden, dass das Foto dieses Briefs zur Erklärung an den Server von BehördenKlar
und an den KI-Dienst Anthropic (USA) geschickt wird. Briefe können sehr persönliche Angaben
enthalten, zum Beispiel zu Gesundheit, Herkunft oder Aufenthalt. BehördenKlar speichert den Brief
nicht. Anthropic löscht ihn in der Regel nach 30 Tagen und nutzt ihn nicht zum Training.“
<span class="quelle">Text am Häkchen vor dem Hochladen, mit Link zur Datenschutzerklärung</span>
</p>
<ul class="punkte">
<li><b>Ohne Häkchen wird nichts hochgeladen.</b></li>
<li><b>Für genau einen Brief:</b> Nach jeder Erklärung ist das Häkchen wieder leer. Die nächste Person wird neu gefragt.</li>
<li><b>Grundlage:</b> Art. 6 Abs. 1 lit. a und Art. 9 Abs. 2 lit. a DSGVO.</li>
<li><b>Sprache:</b> Der Text steht derzeit nur auf Deutsch, Übersetzungen sind in Arbeit.
Bis dahin erklärt die Beraterin ihn bei Bedarf mündlich.</li>
</ul>
</div>
<h2><span class="nr">7</span> Ehrliche Grenzen</h2>
<ul class="grenzen">
<li><b>USA.</b> Anthropic und Cloudflare sitzen in den USA. Eine Beschränkung auf Rechenzentren
in der EU ist nicht eingestellt.</li>
<li><b>30 Tage bei Anthropic</b> in der Regel, bei Verdacht auf Missbrauch länger. Darauf haben
wir keinen Einfluss.</li>
<li><b>Ende-zu-Ende gilt nur für die Übergabe.</b> Der Brief selbst geht per TLS über unseren
Server zur KI.</li>
<li><b>QR-Code nur der richtigen Person zeigen.</b> Wer ihn abfotografiert, kann die Erklärung
in diesen 15 Minuten öffnen.</li>
<li><b>Gemeinsamer Dienst-PC.</b> Nach jedem Gespräch die Seite neu laden. Kalender-Einträge am
Handy der Person anlegen, am PC landet sonst eine Datei mit der Frist im Download-Ordner.</li>
<li><b>Keine Rechtsberatung.</b> BehördenKlar erklärt Briefe, ersetzt aber keine Beratung. Auch
eine KI kann sich irren.</li>
<li><b>Selbstauskunft, kein Zertifikat.</b> Eine anwaltliche Prüfung von Datenschutzerklärung und
Blatt steht noch aus.</li>
<li><b>Noch offen:</b> AVV-Entwurf, TOMs und ein Textbaustein fürs Verarbeitungsverzeichnis.
Sie kommen vor dem ersten echten Brief am Dienst-PC.</li>
</ul>
<div class="kontakt-unten">
<h2><span class="nr">8</span> Kontakt und vollständige Datenschutzerklärung</h2>
<div class="kontakt">
<div>
<p class="name">Justin Klein</p>
<p>Webklar GbR, vertreten durch<br>Justin Klein und Kenso Grimm<br>
Am Schwimmbad 10, 67722 Winnweiler<br>
Tel. 0170 4969375 · justin@webklar.com</p>
</div>
<div>
<p class="link">behoerdenklar.de/datenschutz</p>
<p class="klein">Für die Webseite besonders die Abschnitte 3a, 4, 5, 8, 9a, 9b und 10.
Rückfragen beantworten wir gern, auch im Gespräch mit Ihnen.</p>
<p style="margin-top: 1.4mm;"><span class="stempel">Selbstauskunft · Stand 22.10.2026</span></p>
</div>
<div id="qr"></div>
</div>
</div>
</div>
<script>
var qr = qrcode(0, 'M');
qr.addData('https://behoerdenklar.de/datenschutz');
qr.make();
document.getElementById('qr').innerHTML = qr.createSvgTag({ cellSize: 4, margin: 0, scalable: true });
</script>
</body>
</html>
Binary file not shown.
@@ -0,0 +1,203 @@
<!DOCTYPE html>
<!--
Kurzanleitung „So geht's am Beratungs-PC“ (DIN A4, 1 Seite, für Beraterinnen).
CODE (und ggf. STELLE) unten im Skript eintragen, sobald der Einrichtungs-Code
angelegt ist, dann neu als PDF ausgeben (im Ordner marketing/praesentation-mbe):
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless=new --disable-gpu \
--allow-file-access-from-files --no-pdf-header-footer \
--print-to-pdf=kurzanleitung-beratung.pdf "file://$PWD/kurzanleitung-beratung.html"
Knopf- und Meldungstexte stammen wörtlich aus webseite/demo.html, „Der Zugang über …
ist abgelaufen“ aus proxy/src/index.ts (Stand 22.10.2026).
-->
<html lang="de">
<head>
<meta charset="UTF-8">
<title>So geht's am Beratungs-PC</title>
<script src="../../webseite/qrcode.js"></script>
<style>
@page { size: A4; margin: 0; }
:root {
--papier: #faf7f0; --tinte: #21211d; --grau: #6b675e;
--amtsblau: #1d4e89; --stempelrot: #b3372b; --marker: #ffe66b; --gruen: #2e7d4f;
}
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
body { font-family: Georgia, 'Times New Roman', serif; color: var(--tinte); background: #fff; }
.seite {
width: 210mm; height: 297mm; overflow: hidden; position: relative;
padding: 10mm 14mm 0;
background: repeating-linear-gradient(0deg, transparent 0 6.5mm, rgba(33,33,29,0.03) 6.5mm 6.7mm), var(--papier);
font-size: 11pt; line-height: 1.36;
}
.mono { font-family: 'Courier New', ui-monospace, monospace; }
.briefkopf { display: flex; justify-content: space-between; align-items: baseline; padding-bottom: 2mm; border-bottom: 0.6mm solid var(--tinte); }
.absender { font-weight: 700; font-size: 12.5pt; }
.absender small { font-weight: 400; font-size: 8pt; opacity: .6; letter-spacing: .04em; }
.az { color: var(--grau); font-size: 8pt; }
.betreff { margin-top: 3.5mm; font-size: 8pt; color: var(--grau); text-transform: uppercase; letter-spacing: .14em; }
h1 { font-size: 23pt; line-height: 1.12; margin-top: 1mm; letter-spacing: -0.01em; }
.markiert { background: linear-gradient(104deg, transparent 2%, var(--marker) 4%, var(--marker) 96%, transparent 98%); padding: 0 1.5mm; }
.anrede { margin-top: 2mm; font-size: 11.5pt; line-height: 1.36; }
/* Knöpfe und Bildschirm-Texte so, wie man sie auf der Seite wiedererkennt */
.k { font-weight: 700; background: #fff; border: 0.35mm solid var(--tinte); border-radius: 1mm;
padding: 0 1.3mm; margin-right: .5mm; box-shadow: 0.5mm 0.5mm 0 var(--tinte);
-webkit-box-decoration-break: clone; box-decoration-break: clone; }
.m { background: rgba(29,78,137,.09); padding: 0 .8mm; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.kasten { background: #fff; border: 0.5mm solid var(--tinte); padding: 3.6mm 4mm 3.2mm; position: relative; }
.kasten .label { position: absolute; top: -2.6mm; left: 3.5mm; font-family: 'Courier New', monospace; font-size: 7.5pt;
text-transform: uppercase; letter-spacing: .1em; background: var(--tinte); color: var(--papier); padding: .4mm 2mm; }
.einmalig { margin-top: 4.4mm; display: grid; grid-template-columns: 1fr 27mm; gap: 5mm; align-items: start; }
.einmalig p { font-size: 10.6pt; line-height: 1.34; }
.adresse { font-family: 'Courier New', monospace; font-weight: 700; font-size: 12.5pt; color: var(--amtsblau);
background: var(--marker); display: inline-block; padding: .4mm 2mm; margin: 1.2mm 0 1.6mm; word-break: break-all; }
.luecke { display: inline-block; width: 26mm; border-bottom: 0.35mm solid var(--amtsblau); height: 4.2mm; vertical-align: -0.6mm; }
.einmalig ul { list-style: none; font-size: 10pt; line-height: 1.32; }
.einmalig li { padding-left: 4mm; position: relative; margin-top: .9mm; }
.einmalig li::before { content: '›'; position: absolute; left: .5mm; color: var(--amtsblau); font-weight: 700; }
.qrteil { text-align: center; }
#qr { width: 25mm; height: 25mm; margin: 0 auto 1.2mm; }
#qr svg { width: 100%; height: 100%; display: block; }
.qrteil .klein { font-size: 7.8pt; color: var(--grau); line-height: 1.3; }
.code { font-family: 'Courier New', monospace; font-weight: 700; font-size: 11pt; letter-spacing: .08em; background: var(--marker); padding: 0 1.5mm; margin-right: 1mm; }
h2 { font-size: 8pt; text-transform: uppercase; letter-spacing: .14em; color: var(--grau); font-weight: 400;
margin: 3.6mm 0 1.4mm; display: flex; align-items: center; gap: 3mm; }
h2::after { content: ''; flex: 1; border-top: 0.25mm solid rgba(33,33,29,.25); order: 1; }
h2 .legende { order: 2; text-transform: none; letter-spacing: 0; font-size: 9.5pt; color: var(--grau); }
.schritte { list-style: none; }
.schritte li { display: grid; grid-template-columns: 9mm 1fr; gap: 1.5mm; padding: 0.8mm 0; border-bottom: 0.25mm dashed rgba(33,33,29,.22); }
.schritte li:last-child { border-bottom: none; }
.nr { font-family: 'Courier New', monospace; font-weight: 700; font-size: 17pt; line-height: 1; color: var(--amtsblau); padding-top: .4mm; }
.schritte b.t { font-size: 11.6pt; }
.schritte p { font-size: 11pt; line-height: 1.34; }
.schritte .zusatz { font-size: 9.6pt; color: #3a3833; margin-top: .4mm; }
.wichtig { margin-top: 3.8mm; border-color: var(--stempelrot); border-width: 0.6mm; }
.wichtig .label { background: var(--stempelrot); }
.wichtig > p { font-size: 10.4pt; line-height: 1.33; padding-left: 4.5mm; position: relative; margin-bottom: .8mm; }
.wichtig > p::before { content: '!'; position: absolute; left: .6mm; color: var(--stempelrot); font-weight: 700; }
.meldungen { width: 100%; border-collapse: collapse; margin-top: 1.4mm; font-size: 9.6pt; line-height: 1.28; }
.meldungen caption { text-align: left; font-family: 'Courier New', monospace; font-size: 7.5pt; text-transform: uppercase; letter-spacing: .1em; color: var(--grau); padding-bottom: .8mm; }
.meldungen td { padding: .4mm 0; vertical-align: top; border-top: 0.25mm solid rgba(33,33,29,.15); }
.meldungen td:first-child { width: 39%; padding-right: 3mm; }
.meldungen tr.leer td { background: rgba(255,230,107,.45); }
.meldungen tr.leer td:first-child { padding-left: 1mm; }
.fuss { position: absolute; left: 14mm; right: 14mm; bottom: 8mm; border-top: 0.4mm solid var(--tinte); padding-top: 2mm;
display: flex; justify-content: space-between; align-items: flex-end; font-size: 8pt; line-height: 1.4; }
.fuss .anruf { font-size: 12.5pt; font-weight: 700; line-height: 1.3; }
.fuss .anruf .nummer { font-family: 'Courier New', monospace; background: var(--marker); padding: 0 1.5mm; }
.stempel { display: inline-block; padding: 1mm 2.5mm; border: 0.5mm solid var(--stempelrot); color: var(--stempelrot);
font-family: 'Courier New', monospace; font-weight: 700; font-size: 7.5pt; letter-spacing: .1em;
text-transform: uppercase; transform: rotate(-4deg); margin-bottom: 1mm; }
</style>
</head>
<body>
<div class="seite">
<div class="briefkopf">
<span class="absender">📬 BehördenKlar <small>by Webklar</small></span>
<span class="az mono">Az: KLAR-BERATUNG/2026 · Kurzanleitung Beratungs-PC</span>
</div>
<p class="betreff">Kurzanleitung · Für Beraterinnen und Berater</p>
<h1>So geht's am <span class="markiert">Beratungs-PC</span></h1>
<p class="anrede">
Die Person fotografiert ihren Brief mit dem eigenen Handy. Sie lesen am PC mit.
</p>
<div class="kasten einmalig">
<span class="label">Einmal einrichten: Lesezeichen</span>
<div>
<p>Diese Adresse am Beratungs-PC als Lesezeichen speichern, genau so, mit Code:</p>
<p><span class="adresse" id="adresseText"></span></p>
<ul>
<li><b>Lesezeichen von Hand anlegen</b> und die Adresse eintragen. Nicht nur den Stern ☆ klicken: Nach dem Öffnen ist der Code aus der Adresszeile verschwunden.</li>
<li>Ihr Code: <span class="code" id="codeText"></span> Nur für die Beratungsstelle: nicht an Ratsuchende weitergeben, Blatt nicht offen auslegen.</li>
</ul>
</div>
<div class="qrteil">
<div id="qr"></div>
<p class="klein">Gleiche Adresse als QR-Code</p>
</div>
</div>
<h2><span>Ablauf für jede Person</span><span class="legende"><span class="k">Knopf</span> = klicken oder tippen · <span class="m">„Text“</span> = steht so auf dem Bildschirm</span></h2>
<ol class="schritte">
<li><span class="nr">1</span><div>
<p><b class="t">Seite öffnen.</b> Lesezeichen anklicken. Oben steht <span class="m">„🤝 Kostenlos über <span id="stelleText"></span> …“</span></p>
<p class="zusatz">Fehlt das? Unten <span class="k">🤝 Sie haben einen Code von einer Beratungsstelle?</span> öffnen und den Code einlösen.</p>
</div></li>
<li><span class="nr">2</span><div>
<p><b class="t">Sprache wählen.</b> Bei <span class="m">„🌐 Erklärung in dieser Sprache:“</span> die Sprache der Person einstellen.
Oder <span class="m">„Deutsch“</span> lassen: Dann erkennt das Handy seine Sprache selbst.</p>
</div></li>
<li><span class="nr">3</span><div>
<p><b class="t">QR-Code zeigen.</b> <span class="k">📱 Lieber mit dem Handy fotografieren</span> klicken. Die Person scannt den QR-Code mit der Handy-Kamera.
Am PC steht dann <span class="m">„✅ Handy verbunden …“</span></p>
<p class="zusatz">Nicht <span class="k">🔑 Zugang dauerhaft auf ein Handy geben</span> klicken: Das gibt Ihren Zugang dauerhaft aufs Handy.</p>
</div></li>
<li><span class="nr">4</span><div>
<p><b class="t">Am Handy: Häkchen und Foto.</b> Das Häkchen setzt <b>die Person selbst</b>. Es ist ihre Einwilligung: Das Foto geht an BehördenKlar und an den KI-Dienst Anthropic (USA).
Dann tippt sie auf <span class="k">📷 Brief auswählen &amp; erklären lassen</span> und fotografiert den Brief.</p>
<p class="zusatz">Häkchen-Text unklar? Kurz erklären. Ein Foto pro Brief, bei mehreren Seiten die mit Betreff und Frist.</p>
</div></li>
<li><span class="nr">5</span><div>
<p><b class="t">1 bis 2 Minuten warten.</b> Dann steht die Erklärung am PC auf Deutsch und am Handy in der Sprache der Person.
Umschalten über dem Ergebnis, z. B. <span class="k">Deutsch</span> <span class="k">العربية</span></p>
</div></li>
<li><span class="nr">6</span><div>
<p><b class="t">Kalender am Handy.</b> Die Person tippt am Handy auf <span class="k">📅 In meinen Kalender eintragen</span>. Nicht am PC, sonst landet die Datei auf dem Dienst-PC.</p>
<p class="zusatz">Seite am Handy schon zu? Am PC <span class="k">📱 Ergebnis aufs Handy mitnehmen</span> klicken.</p>
</div></li>
<li><span class="nr">7</span><div>
<p><b class="t">Fertig: Seite neu laden (Taste F5).</b> Nächste Person: Sprache neu wählen.</p>
</div></li>
</ol>
<div class="kasten wichtig">
<span class="label">Wichtig</span>
<p><b>Beim Warten nicht neu laden.</b> Falls doch: Das Ergebnis steht am Handy, dort <span class="k">Deutsch</span> tippen.</p>
<p><b>Ein QR-Code gilt für einen Brief.</b> Nächster Brief: ab Schritt 3.</p>
<table class="meldungen">
<caption>Meldungen am PC und was sie bedeuten</caption>
<tr><td><span class="m">„⚠️ Am Handy hat es nicht geklappt: …“</span></td><td>Am Handy steht, warum. Dort neu fotografieren.</td></tr>
<tr><td><span class="m">„⚠️ Das dauert ungewöhnlich lange …“</span></td><td>Am Handy: <span class="k">🔁 Noch einmal an den Computer senden</span><br>Kein Knopf da? Am PC <span class="k">Abbrechen</span>, dann ab Schritt 3.</td></tr>
<tr><td><span class="m">„Der QR-Code ist abgelaufen …“</span></td><td>Schritt 3 wiederholen.</td></tr>
<tr><td><span class="m">„⚠️ Keine Verbindung zum Server …“</span></td><td>Internet am PC prüfen, sonst Ihre IT fragen.</td></tr>
<tr class="leer"><td><span class="m">„Die kostenlosen Analysen sind aufgebraucht oder abgelaufen …“</span><br><span class="m">„Der Zugang über … ist abgelaufen …“</span></td><td><b>Kontingent leer oder Test zu Ende: Justin anrufen, <span style="white-space: nowrap;">0170 4969375</span>.</b> Danach das Lesezeichen neu öffnen.</td></tr>
</table>
</div>
<div class="fuss">
<div class="wer">
<span class="anruf">Bei Fragen einfach anrufen: Justin Klein · <span class="nummer">0170 4969375</span></span><br>
Webklar GbR · Am Schwimmbad 10, 67722 Winnweiler · justin@webklar.com · <b>behoerdenklar.de</b>
</div>
<span class="stempel">Stand Oktober 2026</span>
</div>
</div>
<script>
// Einrichtungs-Code hier eintragen, sobald er angelegt ist (z. B. 'MBE-K7QX').
var CODE = '';
// Name der Einrichtung, so wie er beim Anlegen des Codes vergeben wurde (steht oben auf der Seite).
var STELLE = 'MBE Donnersberg';
var url = CODE ? 'https://behoerdenklar.de/demo?code=' + CODE : 'https://behoerdenklar.de/demo';
var qr = qrcode(0, 'M');
qr.addData(url);
qr.make();
document.getElementById('qr').innerHTML = qr.createSvgTag({ cellSize: 4, margin: 0, scalable: true });
var codeEl = document.getElementById('codeText');
codeEl.textContent = CODE || 'wird beim Termin eingetragen';
if (!CODE) { codeEl.style.fontSize = '9pt'; codeEl.style.letterSpacing = '0'; }
var adresseEl = document.getElementById('adresseText');
adresseEl.textContent = 'behoerdenklar.de/demo?code=' + CODE;
if (!CODE) { var l = document.createElement('span'); l.className = 'luecke'; adresseEl.appendChild(l); }
document.getElementById('stelleText').textContent = STELLE || 'Ihre Beratungsstelle';
</script>
</body>
</html>
+144 -79
View File
@@ -68,6 +68,17 @@
}
.mono { font-family: 'Courier New', ui-monospace, monospace; letter-spacing: 0.02em; }
.wrap { max-width: 720px; margin: 0 auto; padding: 0 20px 72px; }
/* Schriften mit verbundenen Buchstaben (Arabisch, Devanagari …): kein
Buchstabenabstand und keine Schreibmaschine — sonst reißen Wörter auseinander */
html.verbundene-schrift .formular-kopf, html.verbundene-schrift .betreff-label,
html.verbundene-schrift h2, html.verbundene-schrift .karten-label {
font-family: inherit; letter-spacing: 0; text-transform: none;
}
@media (max-width: 420px) {
/* Cloudflare-Prüfung ist fest 300 px breit — sonst ragt sie aus dem Kasten */
.wrap { padding: 0 14px 56px; }
.antrag { padding: 22px 14px; }
}
.briefkopf {
display: flex; justify-content: space-between; align-items: baseline;
@@ -265,23 +276,23 @@
<div class="briefkopf">
<span class="absender"><a href="index.html">📬 BehördenKlar</a> <span style="font-weight:400;font-size:.62em;opacity:.6;letter-spacing:.04em;">by Webklar</span></span>
<span class="az mono">Formular D-01 · Gratis-Demo</span>
<span class="az mono" id="kopfAz">Formular D-01 · Gratis-Demo</span>
</div>
<header>
<p class="betreff-label">Betreff</p>
<h1>Probieren Sie es aus —<br><span class="markiert">mit Ihrem eigenen Brief.</span></h1>
<p class="betreff-label" data-t="betreff">Betreff</p>
<h1><span data-t="titel1">Probieren Sie es aus —</span><br><span class="markiert" data-t="titel2">mit Ihrem eigenen Brief.</span></h1>
<p class="anrede">
Kein Konto. Keine App-Installation. Laden Sie ein Foto Ihres
Behördenbriefs hoch — in etwa einer Minute lesen Sie ihn in einfacher
Sprache. <strong>2 Analysen gratis.</strong>
<span data-t="anrede">Kein Konto. Keine App-Installation. Laden Sie ein Foto Ihres
Behördenbriefs hoch — nach ein bis zwei Minuten lesen Sie ihn in einfacher
Sprache.</span> <strong id="anredeAngebot" data-t="anredeGratis">2 Analysen gratis.</strong>
</p>
</header>
<section id="demo">
<h2><span class="nr">§ 1</span> Brief hochladen</h2>
<h2><span class="nr">§ 1</span> <span data-t="abschnittHochladen">Brief hochladen</span></h2>
<div class="antrag">
<p class="formular-kopf">Antrag auf Klartext · 2 Gratis-Analysen</p>
<p class="formular-kopf" data-t="formKopfGratis">Brief erklären lassen · 2 kostenlose Analysen</p>
<p class="verbunden" id="verbundenBanner"></p>
@@ -290,7 +301,7 @@
✅ Kauf erfolgreich! Ihr Guthaben wurde aktiviert.
</p>
<p id="guthabenBanner" class="bonus-zeile" style="display: none;">
<span id="guthabenText">💳 Ihr Guthaben:</span> <strong id="guthabenZahl">0</strong> Analysen — laden Sie den nächsten Brief hoch.
<span id="guthabenText">💳 Ihr Guthaben:</span> <strong id="guthabenZahl">0</strong> <span data-t="bannerRest">Analysen — laden Sie den nächsten Brief hoch.</span>
<br><button type="button" class="link-knopf" id="guthabenHandyKnopf" style="font-size: 14.5px;">📱 Auch auf dem Handy nutzen</button>
</p>
<div class="qr-box" id="guthabenQrBox">
@@ -299,20 +310,20 @@
<p class="klein" style="margin-top: 0;">Mit der Handy-Kamera scannen. Danach können Sie Briefe auch direkt am Handy erklären lassen.</p>
</div>
<p style="margin-bottom: 14px; font-size: 15.5px;">
🌐 <label for="sprachWahl">Erklärung in dieser Sprache:</label>
🌐 <label for="sprachWahl" data-t="spracheLabel">Erklärung in dieser Sprache:</label>
<select id="sprachWahl" style="font-family: inherit; font-size: 15.5px; padding: 5px 8px; border: 1.5px solid var(--tinte); background: #fff; margin-inline-start: 6px;"></select>
</p>
<label class="konsens">
<input type="checkbox" id="konsens">
<span>
Ich bin einverstanden, dass das Foto dieses Briefs zur Erklärung
<span data-t="konsens">Ich bin einverstanden, dass das Foto dieses Briefs zur Erklärung
an den Server von BehördenKlar und an den KI-Dienst Anthropic
(USA) geschickt wird. Briefe können sehr persönliche Angaben
enthalten, zum Beispiel zu Gesundheit, Herkunft oder Aufenthalt.
BehördenKlar speichert den Brief nicht. Anthropic löscht ihn in
der Regel nach 30 Tagen und nutzt ihn nicht zum Training.
<a href="datenschutz.html" target="_blank">Datenschutzerklärung</a>
der Regel nach 30 Tagen und nutzt ihn nicht zum Training.</span>
<a href="datenschutz.html" target="_blank" data-t="datenschutzLink">Datenschutzerklärung</a>
</span>
</label>
@@ -330,7 +341,7 @@
</div>
<input type="file" id="datei" accept="image/jpeg,image/png,application/pdf" style="display: none;">
<button class="cta" id="startKnopf">📷 Brief auswählen &amp; erklären lassen</button>
<button class="cta" id="startKnopf" data-t="startKnopf">📷 Brief auswählen &amp; erklären lassen</button>
<button class="cta cta-zwei" id="handyKnopf" type="button" style="display: none;">📱 Lieber mit dem Handy fotografieren</button>
<div class="qr-box" id="handyBox">
<strong>Mit dem Handy fotografieren</strong>
@@ -355,36 +366,38 @@
if (/^(localhost|127\.0\.0\.1)$/.test(location.hostname)) {
document.querySelector('.cf-turnstile').setAttribute('data-sitekey', '1x00000000000000000000AA');
}
// Sehr schmale Handys (< 350 px): kompakte Cloudflare-Prüfung
if (window.innerWidth < 350) document.querySelector('.cf-turnstile').setAttribute('data-size', 'compact');
</script>
<p class="klein">
<p class="klein" data-t="tippFoto">
Geht mit Foto (JPG/PNG) oder PDF, max. 5 MB. Tipp: gutes Licht,
Brief von oben, ganzer Text im Bild.
</p>
<p class="klein">
📱 <strong>Am Handy:</strong> Wählen Sie „Galerie" oder „Dateien",
<strong data-t="tippHandyTitel">📱 Am Handy:</strong> <span data-t="tippHandy">Wählen Sie „Galerie" oder „Dateien",
wenn Sie den Brief schon fotografiert haben. Tippen Sie auf
„Kamera", öffnet sich die Kamera-App Ihres Handys — und die fragt
nach ihren eigenen Berechtigungen. <strong>Diese Abfrage kommt von
Ihrem Handy, nicht von uns:</strong> Diese Seite greift weder auf
Kamera noch auf Mikrofon zu.
nach ihren eigenen Berechtigungen. Diese Abfrage kommt von
Ihrem Handy, nicht von uns: Diese Seite greift weder auf
Kamera noch auf Mikrofon zu.</span>
</p>
</div>
<div class="status" id="status">
<span class="sanduhr">⏳</span>
<p class="gross">Ihr Brief wird analysiert…</p>
<p class="sub">Das dauert bis zu einer Minute. Bitte lassen Sie die Seite geöffnet.</p>
<p class="gross">Ihr Brief wird erklärt …</p>
<p class="sub" data-t="statusDauer">Das dauert ein bis zwei Minuten. Bitte lassen Sie die Seite geöffnet.</p>
</div>
<div class="fehlerbox" id="fehler"></div>
<details id="codeTeil" style="margin-top: 16px; border-top: 1px solid rgba(33, 33, 29, 0.2);">
<summary>🤝 Sie haben einen Code von einer Beratungsstelle?</summary>
<p>Dann ist BehördenKlar für Sie kostenlos. Geben Sie den Code hier ein:</p>
<summary data-t="codeFrage">🤝 Sie haben einen Code von einer Beratungsstelle?</summary>
<p data-t="codeText">Dann ist BehördenKlar für Sie kostenlos. Geben Sie den Code hier ein:</p>
<input class="wl-input" id="codeFeld" placeholder="z. B. MBE-K7QX" autocapitalize="characters" autocomplete="off" spellcheck="false" style="margin-top: 10px; text-transform: uppercase;">
<button class="cta" id="codeKnopf" type="button">Code einlösen</button>
<button class="cta" id="codeKnopf" type="button" data-t="codeKnopf">Code einlösen</button>
</details>
</div>
</section>
@@ -435,7 +448,7 @@
</section>
<section id="ergebnis">
<h2><span class="nr">§ 3</span> Ihr Brief in Klartext</h2>
<h2><span class="nr">§ 3</span> <span data-t="ergebnisTitel">Ihr Brief in Klartext</span></h2>
<div class="umschalter" id="sprachUmschalter" role="group" aria-label="Sprache der Erklärung"></div>
<div class="brief-karte">
@@ -447,31 +460,31 @@
<div class="brief-karte" id="ergKalenderKarte" style="display: none;">
<span class="karten-label" id="ergKalenderLabel">Nicht vergessen</span>
<div id="ergKalenderText" style="margin-top: 6px;"></div>
<button class="cta" id="kalenderKnopf" type="button" style="margin-top: 12px;">📅 In meinen Kalender eintragen</button>
<p class="klein" id="ergKalenderHinweis">
Ihr Handy erinnert Sie <strong>3 Tage</strong> und <strong>1 Tag</strong> vorher.
<button class="cta" id="kalenderKnopf" type="button" style="margin-top: 12px;" data-t="kalenderKnopf">📅 In meinen Kalender eintragen</button>
<p class="klein" id="ergKalenderHinweis" data-t="kalenderHinweis">
Ihr Handy erinnert Sie 3 Tage und 1 Tag vorher.
Der Eintrag landet nur in Ihrem eigenen Kalender — wir speichern nichts.
</p>
</div>
<div class="brief-karte">
<span class="karten-label">Einfach erklärt</span>
<span class="karten-label" data-t="labelEinfach">Einfach erklärt</span>
<p id="ergErklaerung" dir="auto" style="white-space: pre-line;"></p>
</div>
<div class="brief-karte" id="ergChecklisteKarte" style="display: none;">
<span class="karten-label neutral">Das müssen Sie tun</span>
<span class="karten-label neutral" data-t="labelTun">Das müssen Sie tun</span>
<div id="ergCheckliste"></div>
</div>
<div class="brief-karte" id="ergAnrufKarte" style="display: none;">
<span class="karten-label neutral">Anrufen</span>
<span class="karten-label neutral" data-t="labelAnrufen">Anrufen</span>
<div id="ergAnrufKontakt" style="margin-top: 6px;"></div>
<div id="ergAnrufSaetze"></div>
</div>
<div class="brief-karte" id="ergBegriffeKarte" style="display: none;">
<span class="karten-label neutral">Schwere Wörter erklärt</span>
<span class="karten-label neutral" data-t="labelWoerter">Schwere Wörter erklärt</span>
<div id="ergBegriffe"></div>
</div>
@@ -484,9 +497,9 @@
</div>
</div>
<p class="hinweis-recht">
<p class="hinweis-recht" data-t="rechtHinweis">
⚖️ BehördenKlar erklärt Briefe, ersetzt aber keine Rechtsberatung. Bei
wichtigen Entscheidungen hilft eine Beratungsstelle oder ein Anwalt.
wichtigen Entscheidungen hilft eine Beratungsstelle oder eine Anwältin bzw. ein Anwalt.
</p>
</section>
@@ -536,6 +549,7 @@
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script src="qrcode.js"></script>
<script src="uebergabe.js"></script>
<script src="ui-texte.js"></script>
<script>
(function () {
'use strict';
@@ -639,6 +653,42 @@
if (name) speicher.set(EINRICHTUNG_SCHLUESSEL, name);
else { speicher.remove(EINRICHTUNG_SCHLUESSEL); speicher.remove(ABLAUF_SCHLUESSEL); speicher.remove(CODE_SCHLUESSEL); }
}
// ── Bediensprache ─────────────────────────────────────────────────
// Am PC (Beratung) bleibt alles deutsch. Am Handy richtet sich die
// Bedienung nach der gewählten Erklärungssprache (Texte: ui-texte.js).
var UI = window.BK_UI_TEXTE || { de: {} };
var RTL = { ar: 1, fa: 1, ur: 1, ps: 1 };
var VERBUNDEN = { ar: 1, fa: 1, ur: 1, ps: 1, hi: 1, ti: 1, zh: 1 };
var uiSprache = 'de';
function t(schluessel, werte) {
var text = (UI[uiSprache] && UI[uiSprache][schluessel]) || (UI.de && UI.de[schluessel]) || schluessel;
if (werte) for (var k in werte) text = text.split('{' + k + '}').join(werte[k]);
return text;
}
function wendeUiSpracheAn() {
var amPc = window.matchMedia && window.matchMedia('(hover: hover) and (pointer: fine)').matches;
var gewuenscht = amPc ? 'de' : zielsprache();
uiSprache = UI[gewuenscht] ? gewuenscht : 'de';
document.documentElement.lang = uiSprache;
document.documentElement.dir = RTL[uiSprache] ? 'rtl' : 'ltr';
document.documentElement.classList.toggle('verbundene-schrift', !!VERBUNDEN[uiSprache]);
var elemente = document.querySelectorAll('[data-t]');
for (var i = 0; i < elemente.length; i++) {
var el = elemente[i], key = el.getAttribute('data-t');
if (UI.de && UI.de[key]) el.textContent = t(key);
}
// Was gerade dynamisch angezeigt wird, in der neuen Sprache neu setzen
var stelle = (typeof handyModus !== 'undefined' && handyModus && handyModus.e) || (einrichtung() && hatGuthaben() ? einrichtung() : '');
if (stelle) zeigeEinrichtungImKopf(stelle);
if (typeof handyModus !== 'undefined' && handyModus && !handyModus.fertig) verbundenBanner.textContent = t('verbunden');
}
/** Meldung des Servers: am Handy in der Bediensprache, sonst die genaue deutsche. */
function serverMeldung(daten) {
var zuordnung = { turnstile: 'srvTurnstile', ki: 'srvKi', ki_konfig: 'srvDienst', dienst: 'srvDienst', datei: 'srvDatei', inhalt: 'srvInhalt', aufgebraucht: 'srvAufgebraucht' };
if (uiSprache !== 'de' && zuordnung[daten.code]) return t(zuordnung[daten.code]);
return daten.meldung || t('srvKi');
}
// Handy ↔ PC: Ist dieses Gerät gerade das Handy, das für einen PC
// fotografiert? Ein Guthaben aus dem QR-Code (w) gilt nur für diese
// Sitzung und wird hier NICHT gespeichert.
@@ -665,8 +715,11 @@
}
function zeigeGuthabenBanner(n) {
var bis = einrichtungBis();
document.getElementById('guthabenHandyKnopf').textContent = einrichtung()
? '🔑 Zugang dauerhaft auf ein Handy geben (nur für Mitarbeitende)'
: '📱 Auch auf dem Handy nutzen';
guthabenText.textContent = einrichtung()
? '🤝 Kostenlos über ' + einrichtung() + (bis ? ' (bis ' + deDatum(bis) + ')' : '') + ':'
? t('bannerKostenlos', { name: einrichtung() + (bis ? ' ' + t('bannerBis', { datum: deDatum(bis) }) : '') })
: '💳 Ihr Guthaben:';
guthabenZahl.textContent = n;
guthabenBanner.style.display = 'block';
@@ -678,8 +731,19 @@
function benutzt() { return parseInt(speicher.get(SPEICHER_SCHLUESSEL) || '0', 10); }
function setzeBenutzt(n) { speicher.set(SPEICHER_SCHLUESSEL, String(n)); }
var LEER_HINWEIS = 'Die kostenlosen Analysen sind aufgebraucht oder abgelaufen. Ratsuchende: Bitte fragen Sie bei Ihrer Beratungsstelle nach. Beratungsstelle: Ein Anruf genügt, Justin Klein, 0170 4969375. Nach dem Aufladen einfach diese Seite neu laden oder den Code unten noch einmal eingeben.';
var KEIN_ZUGANG_HANDY = 'Auf diesem Handy sind die kostenlosen Analysen verbraucht. Bitte am Computer den Code der Beratungsstelle einlösen und dann einen neuen QR-Code erzeugen.';
/** Text mit {name}: der Name kommt in ein <bdi>, damit „(Test)." in arabischem Text richtig steht. */
function mitName(el, vorlage, name) {
var teile = vorlage.split('{name}');
el.textContent = teile[0];
var b = document.createElement('bdi'); b.textContent = name; el.appendChild(b);
if (teile[1]) el.appendChild(document.createTextNode(teile[1]));
}
/** Einrichtungs-Zugang: oben nicht mehr „2 Analysen gratis" anpreisen. */
function zeigeEinrichtungImKopf(name) {
mitName(document.querySelector('#demo .formular-kopf'), t('formKopfKostenlos'), name);
mitName(document.getElementById('anredeAngebot'), t('anredeKostenlos'), name);
document.getElementById('kopfAz').textContent = 'Formular D-01 · ' + name;
}
function zeigeStand() {
if (handyModus && handyModus.fertig) return;
// Handy-Modus: nie Kaufangebot oder Code-Feld (die Beratung ist dabei)
@@ -690,7 +754,7 @@
if (benutzt() >= 2) {
eingabe.style.display = 'none';
fehlerBox.style.display = 'block';
fehlerBox.textContent = KEIN_ZUGANG_HANDY;
fehlerBox.textContent = t('keinZugangHandy');
meldeAnPc({ schritt: 'fehler', code: 'kein_zugang', meldung: 'Am Handy sind die kostenlosen Analysen verbraucht.' });
} else {
eingabe.style.display = 'block';
@@ -706,12 +770,10 @@
kaufBlock.style.display = 'none';
codeTeil.style.display = 'block';
fehlerBox.style.display = 'block';
fehlerBox.textContent = LEER_HINWEIS;
fehlerBox.textContent = t('leerHinweis');
return;
}
if (einrichtung() && hatGuthaben()) {
document.querySelector('#demo .formular-kopf').textContent = 'Antrag auf Klartext · kostenlos über ' + einrichtung();
}
if (einrichtung() && hatGuthaben()) zeigeEinrichtungImKopf(einrichtung());
if (handyModus && handyModus.w) {
eingabe.style.display = 'block';
guthabenBanner.style.display = 'none';
@@ -752,7 +814,7 @@
startKnopf.addEventListener('click', function () {
fehlerBox.style.display = 'none';
if (!konsens.checked) {
zeigeFehler('Bitte zuerst oben das Häkchen bei der Einwilligung setzen.');
zeigeFehler(t('fehlerKonsens'));
fehlerBox.dataset.art = 'konsens';
konsens.closest('label').scrollIntoView({ behavior: 'smooth', block: 'center' });
konsens.focus();
@@ -781,16 +843,14 @@
function zeigeFertigBanner(angekommen, ohneUebersetzung, paket) {
verbundenBanner.innerHTML = '';
verbundenBanner.appendChild(document.createTextNode(angekommen
? '✅ Fertig. Die Erklärung steht hier und auf dem Computer. Für einen weiteren Brief tippt die Beratung am Computer noch einmal auf „Lieber mit dem Handy fotografieren".'
: '⚠️ Die Erklärung steht hier, ist aber am Computer nicht angekommen.'));
if (ohneUebersetzung) verbundenBanner.appendChild(document.createTextNode(' Die Übersetzung hat diesmal nicht geklappt, deshalb steht die Erklärung auf Deutsch.'));
verbundenBanner.appendChild(document.createTextNode(angekommen ? t('fertig') : t('nichtAngekommen')));
if (ohneUebersetzung) verbundenBanner.appendChild(document.createTextNode(' ' + t('ohneUebersetzung')));
if (!angekommen) {
var knopf = document.createElement('button');
knopf.type = 'button'; knopf.className = 'cta cta-zwei';
knopf.textContent = '🔁 Noch einmal an den Computer senden';
knopf.textContent = t('nochmalSenden');
knopf.addEventListener('click', async function () {
knopf.disabled = true; knopf.textContent = 'Wird gesendet …';
knopf.disabled = true; knopf.textContent = t('wirdGesendet');
var ok = await ergebnisAnPc(paket);
zeigeFertigBanner(ok, ohneUebersetzung, paket);
});
@@ -840,17 +900,17 @@
async function starteAnalyse(datei) {
fehlerBox.style.display = 'none';
if (datei.size > 5 * 1024 * 1024 && datei.type === 'application/pdf') {
zeigeFehler('Die PDF-Datei ist zu groß (max. 5 MB). Tipp: Fotografieren Sie den Brief stattdessen.');
zeigeFehler(t('fehlerPdfGross'));
return;
}
var token = turnstileToken();
if (!token) {
zeigeFehler('Die Sicherheitsprüfung lädt noch — bitte warten Sie 2 Sekunden und versuchen Sie es erneut.');
zeigeFehler(t('fehlerTurnstileLaedt'));
return;
}
eingabe.style.display = 'none';
status.querySelector('.gross').textContent = 'Ihr Brief wird analysiert…';
status.querySelector('.gross').textContent = t('statusLaeuft');
status.style.display = 'block';
try {
@@ -884,7 +944,7 @@
meldeAnPc({ schritt: 'fehler', code: daten.code || '', meldung: daten.meldung || '' });
// Guthaben vom PC: Fehler nur anzeigen, am Handy nichts umstellen
if (handyModus && handyModus.w) {
zeigeFehler(daten.meldung || 'Etwas ist schiefgelaufen. Bitte erneut versuchen.');
zeigeFehler(serverMeldung(daten));
return;
}
// Handy ohne Zugang vom PC: Kontingent-Fehler nicht als Kaufangebot zeigen
@@ -892,7 +952,7 @@
if (daten.code === 'aufgebraucht') setzeBenutzt(2);
eingabe.style.display = 'none';
fehlerBox.style.display = 'block';
fehlerBox.textContent = KEIN_ZUGANG_HANDY;
fehlerBox.textContent = t('keinZugangHandy');
meldeAnPc({ schritt: 'fehler', code: 'kein_zugang', meldung: 'Am Handy sind die kostenlosen Analysen verbraucht.' });
return;
}
@@ -922,7 +982,7 @@
kaufBlock.scrollIntoView({ behavior: 'smooth' });
return;
}
zeigeFehler(daten.meldung || 'Etwas ist schiefgelaufen. Bitte erneut versuchen.');
zeigeFehler(serverMeldung(daten));
return;
}
@@ -972,7 +1032,7 @@
eingabe.style.display = 'block';
if (window.turnstile) window.turnstile.reset();
meldeAnPc({ schritt: 'fehler', code: 'verbindung', meldung: 'Verbindung fehlgeschlagen.' });
zeigeFehler('Verbindung fehlgeschlagen. Bitte prüfen Sie Ihr Internet und versuchen Sie es erneut.');
zeigeFehler(t('fehlerVerbindung'));
}
}
@@ -1001,11 +1061,11 @@
var farbe = tage <= 7 ? 'var(--rot)' : tage <= 21 ? 'var(--gelb)' : 'var(--gruen)';
var punkt = tage <= 7 ? '🔴' : tage <= 21 ? '🟡' : '🟢';
var datum = deDatum(erstes.iso);
var wann = erstes.art === 'Termin' ? 'Termin am ' + datum : 'Frist bis ' + datum;
var text = tage < 0 ? (erstes.art === 'Termin' ? 'Der Termin war am ' + datum + '!' : 'Die Frist ist womöglich schon vorbei (' + datum + ')!') :
tage === 0 ? 'HEUTE: ' + wann + '!' :
tage === 1 ? 'Morgen: ' + wann :
'Noch ' + tage + ' Tage · ' + wann;
var wann = erstes.art === 'Termin' ? t('ampelTerminAm', { datum: datum }) : t('ampelFristBis', { datum: datum });
var text = tage < 0 ? (erstes.art === 'Termin' ? t('ampelTerminWar', { datum: datum }) : t('ampelFristVorbei', { datum: datum })) :
tage === 0 ? t('ampelHeute') + ': ' + wann + '!' :
tage === 1 ? t('ampelMorgen') + ': ' + wann :
t('ampelNoch', { n: tage }) + ' · ' + wann;
return { farbe: farbe, text: punkt + ' ' + text, istFrist: erstes.art === 'Frist' };
}
@@ -1240,9 +1300,9 @@
// oder bedingte Fristen ("bis zum 10. Tag nach jedem Vierteljahr"),
// aus denen sich kein einzelnes Datum machen laesst. Ein Haekchen
// wuerde dann "alles erledigt" signalisieren — gefaehrlich falsch.
label.textContent = 'Kalender';
zeile('ℹ️ Kein festes Datum zum Eintragen gefunden.');
zeile('Wichtig: Manche Fristen haben kein festes Datum, zum Beispiel „jedes Vierteljahr" oder nur unter bestimmten Bedingungen. Lesen Sie dazu die Erklärung oben.');
label.textContent = t('labelKalender');
zeile(t('keinDatum1'));
zeile(t('keinDatum2'));
knopf.style.display = 'none';
hinweis.style.display = 'none';
karte.style.border = '';
@@ -1250,12 +1310,12 @@
return;
}
letzteAnalyse = a;
label.textContent = 'Nicht vergessen';
label.textContent = t('labelNichtVergessen');
knopf.style.display = '';
hinweis.style.display = '';
karte.style.border = '2px solid var(--amtsblau)';
if (frist) zeile('⚠️ Frist: ' + deDatum(frist.datum), frist.aktion);
if (termin) zeile('📅 Termin: ' + deDatum(termin.datum) + (termin.uhrzeit ? ', ' + termin.uhrzeit + ' Uhr' : ''), termin.ort);
if (frist) zeile(t('fristZeile', { datum: deDatum(frist.datum) }), frist.aktion);
if (termin) zeile(t('terminZeile', { datum: deDatum(termin.datum) }) + (termin.uhrzeit ? ', ' + t('uhrzeit', { zeit: termin.uhrzeit }) : ''), termin.ort);
karte.style.display = 'block';
}
@@ -1293,22 +1353,23 @@
if (hervorheben) w.className = 'az-wert';
p.appendChild(b); p.appendChild(w); box.appendChild(p);
}
angabe('Ansprechpartner', k.ansprechpartner);
angabe('Erreichbar', k.sprechzeiten);
angabe('Danach werden Sie gefragt', k.aktenzeichen, true);
angabe(t('ansprechpartner'), k.ansprechpartner);
angabe(t('erreichbar'), k.sprechzeiten);
angabe(t('gefragt'), k.aktenzeichen, true);
var liste = document.getElementById('ergAnrufSaetze');
liste.innerHTML = '';
if (saetze.length) {
var kopf = document.createElement('p');
kopf.style.marginTop = '12px';
kopf.innerHTML = '<strong>Das können Sie am Telefon sagen:</strong>';
var stark = document.createElement('strong'); stark.textContent = t('amTelefon'); kopf.appendChild(stark);
liste.appendChild(kopf);
var angezeigt = versionen.length ? versionen[aktiveVersion].code : zielsprache();
var mitBedeutung = angezeigt !== 'de';
saetze.forEach(function (s) {
var d = document.createElement('div'); d.className = 'anruf-satz';
var de = document.createElement('p'); de.className = 'anruf-de';
de.setAttribute('dir', 'ltr'); // wird auf Deutsch gesagt — auch auf arabischer Seite links-nach-rechts
de.textContent = '„' + s.deutsch + '“';
d.appendChild(de);
if (mitBedeutung && s.bedeutung && s.bedeutung !== s.deutsch) {
@@ -1442,7 +1503,7 @@
zeichneHandyQr();
zeigeStand();
if (res.d.guthaben <= 0) return; // zeigeStand zeigt den Leer-Hinweis mit Telefonnummer
kaufOk.textContent = '✅ Code eingelöst. BehördenKlar ist für Sie kostenlos, über ' + res.d.einrichtung + '.';
kaufOk.textContent = t('codeEingeloest', { name: res.d.einrichtung });
kaufOk.style.display = 'block';
})
.catch(function () {
@@ -1625,7 +1686,7 @@
if (h.a === 'g') { uebernehmeGuthaben(h); return; }
var ue = await BKUebergabe.oeffne(h.s, h.k).catch(function () { return null; });
if (!ue) {
zeigeFehler('Dieser QR-Code ist ungültig. Bitte am Computer einen neuen erzeugen.');
zeigeFehler(t('qrUngueltig'));
return;
}
@@ -1636,10 +1697,11 @@
sitzungsSprache = h.l;
document.getElementById('sprachWahl').value = h.l;
}
verbundenBanner.textContent = '🔗 Mit dem Computer verbunden. Setzen Sie das Häkchen und fotografieren Sie Ihren Brief. Die Erklärung erscheint hier und auf dem Bildschirm.';
wendeUiSpracheAn();
verbundenBanner.textContent = t('verbunden');
verbundenBanner.style.display = 'block';
handyKnopf.style.display = 'none';
if (handyModus.e) document.querySelector('#demo .formular-kopf').textContent = 'Antrag auf Klartext · kostenlos über ' + handyModus.e;
if (handyModus.e) zeigeEinrichtungImKopf(handyModus.e);
// „verbunden" zuerst melden — zeigeStand meldet danach ggf. „kein Zugang",
// und das darf nicht von „verbunden" überschrieben werden
await meldeAnPc({ schritt: 'verbunden' });
@@ -1653,7 +1715,7 @@
leseModus = true;
eingabe.style.display = 'none';
kaufBlock.style.display = 'none';
status.querySelector('.gross').textContent = 'Das Ergebnis wird geladen …';
status.querySelector('.gross').textContent = t('statusLaden');
status.style.display = 'block';
var f = null;
try { f = await BKUebergabe.holen(ue); } catch (e) {}
@@ -1661,13 +1723,13 @@
if (!f || !f.ergebnis) {
leseModus = false;
zeigeStand();
zeigeFehler('Dieser QR-Code ist abgelaufen oder wurde schon benutzt (er gilt ' + BKUebergabe.LEBENSDAUER_MIN + ' Minuten und nur einmal). Bitte am Computer einen neuen erzeugen.');
zeigeFehler(t('qrAbgelaufen', { min: BKUebergabe.LEBENSDAUER_MIN }));
return;
}
BKUebergabe.loeschen(ue);
codeTeil.style.display = 'none';
kaufBlock.style.display = 'none';
verbundenBanner.textContent = '📱 Vom Computer übernommen. Tragen Sie die Frist gleich in Ihren Kalender ein, dann vergessen Sie nichts.';
verbundenBanner.textContent = t('mitgenommen');
verbundenBanner.style.display = 'block';
zeigeAnalyse(bereiteVersionen(f.ergebnis, false));
document.getElementById('ergebnis').scrollIntoView({ behavior: 'smooth' });
@@ -1683,7 +1745,7 @@
setzeWallet(h.w);
setzeGuthaben(parseInt(h.n, 10) || 1);
setzeEinrichtung(h.e || null);
kaufOk.textContent = h.e ? '✅ Übernommen. BehördenKlar ist für Sie kostenlos, über ' + h.e + '.' : '✅ Guthaben übernommen.';
kaufOk.textContent = h.e ? t('uebernommen', { name: h.e }) : '✅ Guthaben übernommen.';
kaufOk.style.display = 'block';
zeigeStand();
}
@@ -1731,6 +1793,8 @@
feld.addEventListener('change', function () {
speicher.set(SPRACH_SCHLUESSEL, feld.value);
sitzungsSprache = null;
wendeUiSpracheAn();
zeigeStand();
if (/[?&]sprache=/.test(window.location.search) && window.history.replaceState) {
var u = new URL(window.location.href);
u.searchParams.delete('sprache');
@@ -1741,6 +1805,7 @@
})();
rendrePakete();
wendeUiSpracheAn();
var startHash = BKUebergabe.ausAdresse();
var startSuche = window.location.search; // vor pruefeRueckkehr, das die Adresse aufräumt
// Handy-Verbindung übersteht ein Neuladen (z. B. wenn Android den Tab beim
+2138
View File
File diff suppressed because it is too large. Load diff