diff options
| author | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2026-08-23 09:05:05 +0200 |
|---|---|---|
| committer | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2026-08-23 09:05:05 +0200 |
| commit | 1db8201439680474bf7d0b98721af8011e67d494 (patch) | |
| tree | fbabf28f478c04088f2102cf1c1e7293552be834 | |
| parent | d10ce7c1fb2a1d60e4fcccbf93f2629e96ab63ff (diff) | |
Die Startseite tritt fortan als amtliches Formblatt auf
Die Browserfassung trug ein schmuckloses Kleid: Antiqua auf Weiß, eine Spalte,
drei dünn gerahmte Kästen. Sauber, aber austauschbar — es sah aus wie ein
Aufsatz und nicht wie das, was das Erzeugnis ist: eine Stelle, die
Änderungsbefehle abarbeitet und darüber Rechenschaft ablegt.
Der Satzspiegel liegt nunmehr als umrandeter Bogen auf einer Unterlage. Oben
steht ein Briefkopf: links die ausstellende Stelle, rechts die Kennung des
Vordrucks als Verzeichnis — Formblatt ÄG-1, Vorgang oder Anlage, Geltung
nichtamtlich. Die Kennung steht im Text und nicht im Stilblatt, damit sie sich
auswählen und vorlesen lässt; der Zusatz „nichtamtlich“ hält fest, dass die
amtliche Anmutung keine amtliche Herkunft behauptet. Darunter die Doppellinie,
kräftig in Amtsrot über dünn in Rasterfarbe.
Das Formular ist ein Feldblock mit der Legende „Antrag auf Erstellung einer
Synopse“ als schwarzem Balken im Rahmen. Die Feldziffern entstehen aus einem
Zähler des Stilblattes und stehen im Steg links, sodass die Auszeichnung der
Felder unangetastet bleibt. Die Meldung führt ihr Zeichen mit — ✓ und ! —,
damit der Zustand auch ohne Farbe erkennbar ist; es setzt das Stilblatt, weil
die Textverarbeitung den Text ersetzt. Zwei Dinge treten hinzu, die gänzlich
fehlten: eine sichtbare Fokusanzeige und ein Druckbild.
Sämtliche Angriffspunkte der Textverarbeitung bleiben wörtlich erhalten;
app.js, worker.js und der Java-Teil sind nicht angetastet. Aufgenommen sind
ferner aria-describedby für die Erläuterungssätze der Felder und aria-live für
die Meldung, die ihren Text bislang stumm wechselte.
Geprüft an allen drei Seiten in hellem und dunklem Gewand, in schmaler Breite
und in der Druckvorschau, ferner mit den drei Zuständen der Meldung; reuse lint
meldet 154/154, mvnw test dreihundertfünfundzwanzig Testfälle ohne Fehler.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Icc469062e28966384f25598750e198df2fbb29f7
| -rw-r--r-- | FASSUNGEN.txt | 71 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/datenschutz.html | 21 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/favicon.svg | 14 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/impressum.html | 21 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/index.html | 130 | ||||
| -rw-r--r-- | src/main/resources/eu/mulk/aendggner/web/style.css | 430 |
6 files changed, 561 insertions, 126 deletions
diff --git a/FASSUNGEN.txt b/FASSUNGEN.txt index 0e4879d..1bb3fb2 100644 --- a/FASSUNGEN.txt +++ b/FASSUNGEN.txt @@ -142,6 +142,77 @@ Nachweis „.gitattributes“ nimmt den Prüfbestand von ihm aus. +Artikel 7 +Gestaltung der Browserfassung + +Die Startseite trug bislang ein schmuckloses Kleid: Antiqua auf Weiß, eine +Spalte, drei dünn gerahmte Kästen. Das war sauber, aber austauschbar; es sah aus +wie ein Aufsatz und nicht wie das, was das Erzeugnis ist — eine Stelle, die +Änderungsbefehle abarbeitet und darüber Rechenschaft ablegt. Die Gestaltung folgt +fortan dem Vorbild des amtlichen Formblatts. + +(1) Der Satzspiegel tritt als Bogen auf einer Unterlage auf: umrandet, auf + sechsundvierzig Halbgevierten Breite, auf schmalen Geräten ohne Rand. An die + Stelle der Antiqua tritt eine Systemgroteske; Kennungen und Feldbezeichner + stehen in gesperrten Versalien. + +(2) Das Farbgerüst wird um „Papier“ (Unterlage), „Raster“ (Formularlinien), + „Kasten“ (Feldgrund) und „Amt“ ergänzt. Das Amtsrot führt das Auge zu den + Kennungen, den Feldziffern und dem Tastaturhalt; die bisherige Bedeutung von + Rot und Grün — warnen und bestätigen — bleibt unberührt, und keine Aussage + ruht auf der Farbe allein. + +(3) Der Kopf der Seiten ist ein Briefkopf: links die ausstellende Stelle mit + ihrer Langbezeichnung, rechts die Kennung des Vordrucks als Verzeichnis + („Formblatt ÄG-1“, „Vorgang“ oder „Anlage“, „Geltung: nichtamtlich“). Die + Kennung steht im Text und nicht im Stilblatt, damit sie sich auswählen und + vorlesen lässt; der Zusatz „nichtamtlich“ hält fest, dass die amtliche + Anmutung keine amtliche Herkunft behauptet. Darunter läuft die Doppellinie, + kräftig in Amtsrot über dünn in Rasterfarbe. + +(4) Das Formular wird zum Feldblock: „fieldset“ mit der Legende „Antrag auf + Erstellung einer Synopse“ als schwarzem Balken im oberen Rahmen, darin drei + gerahmte Felder. Ihre Ziffern entstehen aus einem Zähler des Stilblattes und + stehen im Steg links, sodass die Auszeichnung der Felder unangetastet bleibt. + Der Dateiwähler trägt über „::file-selector-button“ die Form des Knopfes in + der Umkehrung; der Absendeknopf erhält eine Prägekante und fährt beim Drücken + in seinen eigenen Schatten. + +(5) Der Hinweis für abgeschaltetes JavaScript und der Haftungsausschluss treten + als „aside“ mit eigener Überschrift („Hinweis“, „Haftungsausschluss“) auf; + ihr Wortlaut bleibt unverändert. Die Meldung führt ihr Zeichen nunmehr im + Steg mit — ✓ für die fertige, ! für die fehlgeschlagene Auswertung —, damit + der Zustand auch ohne Farbe erkennbar ist. Das Zeichen setzt das Stilblatt, + nicht der Text, weil die Textverarbeitung den Text ersetzt. + +(6) Neu hinzu treten zwei Dinge, die bisher gänzlich fehlten: eine sichtbare + Fokusanzeige für den Tastaturgang und ein Druckbild. Gedruckt entfallen + Unterlage, Bogenrand, Merkblatt und Knopf; die Linien stehen in Schwarz. + +(7) Das Zeichen der Seite (favicon.svg) übernimmt Rahmen und Schrift des neuen + Gerüstes. + + +Artikel 8 +Unberührte Bestandteile + +(1) Sämtliche Angriffspunkte der Textverarbeitung bleiben wörtlich erhalten: + „#synopse-formular“, „#stamm“, „#aenderung“, „#vollstaendig“, „#meldung“ + nebst den Zustandsklassen sowie der eine Knopf des Formulars. „app.js“, + „worker.js“ und der Java-Teil sind nicht angetastet. + +(2) Die von „HtmlRenderer“ erzeugte Synopse behält ihr eigenes Aussehen; ihre + Angleichung bleibt einem späteren Zeitpunkt vorbehalten. + +(3) Aufgenommen sind ferner die Beschreibungsverweise „aria-describedby“ auf die + Erläuterungssätze der Felder und die Ansage „aria-live“ für die Meldung, die + ihren Text bislang stumm wechselte. + +(4) Die Prüfung nach der REUSE-Spezifikation meldet unverändert + einhundertvierundfünfzig von einhundertvierundfünfzig Dateien; dreihundert- + fünfundzwanzig Testfälle bestehen fort. + + ════════════════════════════════════════════════════════════════════════════════ Fassung vom 22. August 2026, zuletzt geändert durch die am 22. August 2026 vorgenommenen Änderungen diff --git a/src/main/resources/eu/mulk/aendggner/web/datenschutz.html b/src/main/resources/eu/mulk/aendggner/web/datenschutz.html index 1a57392..b217b89 100644 --- a/src/main/resources/eu/mulk/aendggner/web/datenschutz.html +++ b/src/main/resources/eu/mulk/aendggner/web/datenschutz.html @@ -10,6 +10,22 @@ <link rel="stylesheet" href="style.css"> </head> <body> + <header class="briefkopf"> + <div class="dienststelle"> + <p class="langname"> + Nichtamtliche Zentralstelle für die maschinelle Fortschreibung von Stammgesetzen + anhand von Änderungsvorschriften des Bundes und der Länder + </p> + <p class="wortmarke"><a href="index.html">ÄndGgner</a></p> + </div> + + <dl class="kennung"> + <dt>Formblatt</dt><dd>ÄG‑1/B</dd> + <dt>Anlage</dt><dd>Datenschutz</dd> + <dt>Geltung</dt><dd>nichtamtlich</dd> + </dl> + </header> + <main> <h1>Datenschutzerklärung</h1> @@ -109,6 +125,9 @@ <p>Stand: 22. August 2026.</p> </main> - <footer><a href="index.html">Zurück zum Formular</a></footer> + <footer> + <nav><a href="index.html">Zurück zum Formular</a></nav> + <span class="nebenquelle">(<a href="https://gerrit.benkard.de/plugins/gitiles/aendggner">Git</a>)</span> + </footer> </body> </html> diff --git a/src/main/resources/eu/mulk/aendggner/web/favicon.svg b/src/main/resources/eu/mulk/aendggner/web/favicon.svg index 6293ddf..2f54d8f 100644 --- a/src/main/resources/eu/mulk/aendggner/web/favicon.svg +++ b/src/main/resources/eu/mulk/aendggner/web/favicon.svg @@ -1,11 +1,13 @@ <!-- SPDX-FileCopyrightText: 2020 Matthias Andreas Benkard <code@mail.matthias.benkard.de> SPDX-License-Identifier: AGPL-3.0-or-later --> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="ÄndGgner"> - <!-- Farben wie in style.css: Papier, Haarlinie, schwarzes Zeichen. Ein Favicon erbt keine - CSS-Variablen, deshalb stehen die Werte hier ausgeschrieben. --> + <!-- Farben wie in style.css: Papier, Amtsrot als Rahmen des Vordrucks, schwarzes + Zeichen. Ein Favicon erbt keine CSS-Variablen, deshalb stehen die Werte hier + ausgeschrieben. --> <rect width="32" height="32" fill="#fff"/> - <rect x="0.75" y="0.75" width="30.5" height="30.5" fill="none" stroke="#bbb" - stroke-width="1.5"/> - <text x="16" y="17" fill="#111" font-family="Georgia, 'Times New Roman', serif" - font-size="22" text-anchor="middle" dominant-baseline="central">§</text> + <rect x="1" y="1" width="30" height="30" fill="none" stroke="#8b0f21" stroke-width="2"/> + <text x="16" y="17.5" fill="#111" + font-family="system-ui, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif" + font-size="21" font-weight="bold" text-anchor="middle" + dominant-baseline="central">§</text> </svg> diff --git a/src/main/resources/eu/mulk/aendggner/web/impressum.html b/src/main/resources/eu/mulk/aendggner/web/impressum.html index 8003af0..cce8797 100644 --- a/src/main/resources/eu/mulk/aendggner/web/impressum.html +++ b/src/main/resources/eu/mulk/aendggner/web/impressum.html @@ -10,6 +10,22 @@ <link rel="stylesheet" href="style.css"> </head> <body> + <header class="briefkopf"> + <div class="dienststelle"> + <p class="langname"> + Nichtamtliche Zentralstelle für die maschinelle Fortschreibung von Stammgesetzen + anhand von Änderungsvorschriften des Bundes und der Länder + </p> + <p class="wortmarke"><a href="index.html">ÄndGgner</a></p> + </div> + + <dl class="kennung"> + <dt>Formblatt</dt><dd>ÄG‑1/A</dd> + <dt>Anlage</dt><dd>Impressum</dd> + <dt>Geltung</dt><dd>nichtamtlich</dd> + </dl> + </header> + <main> <h1>Impressum</h1> @@ -55,6 +71,9 @@ <a href="https://gerrit.benkard.de/plugins/gitiles/aendggner">Gerrit</a>. </p> </main> - <footer><a href="index.html">Zurück zum Formular</a></footer> + <footer> + <nav><a href="index.html">Zurück zum Formular</a></nav> + <span class="nebenquelle">(<a href="https://gerrit.benkard.de/plugins/gitiles/aendggner">Git</a>)</span> + </footer> </body> </html> diff --git a/src/main/resources/eu/mulk/aendggner/web/index.html b/src/main/resources/eu/mulk/aendggner/web/index.html index 8b85f52..26ff522 100644 --- a/src/main/resources/eu/mulk/aendggner/web/index.html +++ b/src/main/resources/eu/mulk/aendggner/web/index.html @@ -15,25 +15,37 @@ <script src="app.js" defer></script> </head> <body> - <header> - <h1>ÄndGgner</h1> - <p class="langname"> - Nichtamtliche Zentralstelle für die maschinelle Fortschreibung von Stammgesetzen - anhand von Änderungsvorschriften des Bundes und der Länder - </p> - <p class="tagline"> - Änderungsgesetze automatisch auf ein Stammgesetz anwenden und als Synopse darstellen. - </p> + <header class="briefkopf"> + <div class="dienststelle"> + <p class="langname"> + Nichtamtliche Zentralstelle für die maschinelle Fortschreibung von Stammgesetzen + anhand von Änderungsvorschriften des Bundes und der Länder + </p> + <h1>ÄndGgner</h1> + </div> + + <dl class="kennung"> + <dt>Formblatt</dt><dd>ÄG‑1</dd> + <dt>Vorgang</dt><dd>Synopse</dd> + <dt>Geltung</dt><dd>nichtamtlich</dd> + </dl> </header> <main> + <p class="betreff"> + Änderungsgesetze automatisch auf ein Stammgesetz anwenden und als Synopse darstellen. + </p> + <noscript> - <p class="noscript"> - Dieses Werkzeug rechnet im Browser statt auf dem Server: Es braucht JavaScript und - WebAssembly. Ohne sie bleibt das nachstehende Formular wirkungslos. Wer beides nicht - einschalten möchte, verwende die Befehlszeilenfassung — sie liegt dem - <a href="aendggner-quelltext.tar.gz">Quelltext</a> bei und leistet dasselbe. - </p> + <aside class="kasten warnung"> + <h2>Hinweis</h2> + <p> + Dieses Werkzeug rechnet im Browser statt auf dem Server: Es braucht JavaScript und + WebAssembly. Ohne sie bleibt das nachstehende Formular wirkungslos. Wer beides nicht + einschalten möchte, verwende die Befehlszeilenfassung — sie liegt dem + <a href="aendggner-quelltext.tar.gz">Quelltext</a> bei und leistet dasselbe. + </p> + </aside> </noscript> <details class="einfuehrung"> @@ -89,53 +101,65 @@ </details> <form id="synopse-formular"> - <div class="field"> - <label for="stamm">Stammgesetz</label> - <input type="file" id="stamm" name="stamm" required> - <p class="hint"> - gii-Norm-XML von gesetze-im-internet.de — auch als heruntergeladenes xml.zip, ohne - Entpacken —, oder für Landesrecht die konsolidierte Fassung aus dem Landesportal (PDF - oder Klartext). - </p> - </div> + <fieldset> + <legend>Antrag auf Erstellung einer Synopse</legend> - <div class="field"> - <label for="aenderung">Änderungsdokument(e)</label> - <input type="file" id="aenderung" name="aenderung" multiple required> - <p class="hint"> - Ein oder mehrere PDFs oder Klartextdateien: Änderungsgesetze aus BGBl und GVBl, - Gesetzentwürfe (Referenten-, Regierungs- und Fraktionsentwürfe, Drucksachen) sowie - Änderungsanträge — letztere zusammen mit dem Entwurf hochladen, den sie ändern. Die - Dokumentart wird aus dem Text erkannt. Bei Mehrfachauswahl wird in der gewählten - Reihenfolge nacheinander angewendet. - </p> - </div> + <div class="field"> + <label for="stamm">Stammgesetz</label> + <input type="file" id="stamm" name="stamm" required aria-describedby="stamm-hinweis"> + <p class="hint" id="stamm-hinweis"> + gii-Norm-XML von gesetze-im-internet.de — auch als heruntergeladenes xml.zip, ohne + Entpacken —, oder für Landesrecht die konsolidierte Fassung aus dem Landesportal (PDF + oder Klartext). + </p> + </div> - <div class="field checkbox"> - <label> - <input type="checkbox" id="vollstaendig" name="vollstaendig"> - Unveränderte Vorschriften mit in die Synopse aufnehmen - </label> - </div> + <div class="field"> + <label for="aenderung">Änderungsdokument(e)</label> + <input type="file" id="aenderung" name="aenderung" multiple required + aria-describedby="aenderung-hinweis"> + <p class="hint" id="aenderung-hinweis"> + Ein oder mehrere PDFs oder Klartextdateien: Änderungsgesetze aus BGBl und GVBl, + Gesetzentwürfe (Referenten-, Regierungs- und Fraktionsentwürfe, Drucksachen) sowie + Änderungsanträge — letztere zusammen mit dem Entwurf hochladen, den sie ändern. Die + Dokumentart wird aus dem Text erkannt. Bei Mehrfachauswahl wird in der gewählten + Reihenfolge nacheinander angewendet. + </p> + </div> - <button type="submit">Synopse erzeugen</button> + <div class="field checkbox"> + <label> + <input type="checkbox" id="vollstaendig" name="vollstaendig"> + Unveränderte Vorschriften mit in die Synopse aufnehmen + </label> + </div> + </fieldset> + + <div class="absenden"> + <button type="submit">Synopse erzeugen</button> + </div> </form> - <p id="meldung" class="meldung" hidden></p> + <p id="meldung" class="meldung" hidden aria-live="polite" aria-atomic="true"></p> - <p class="disclaimer"> - Die Synopse wird automatisch erstellt und ist <strong>ohne Gewähr</strong> für Vollständigkeit - und Richtigkeit; sie ersetzt keine Rechtsberatung. Uneindeutige Änderungsbefehle werden zur - manuellen Prüfung markiert statt stillschweigend verworfen. Die gewählten Dateien - <strong>verlassen Ihren Rechner nicht</strong>: Die Auswertung läuft vollständig im Browser, - es wird nichts hochgeladen und nichts gespeichert. - </p> + <aside class="kasten disclaimer"> + <h2>Haftungsausschluss</h2> + <p> + Die Synopse wird automatisch erstellt und ist <strong>ohne Gewähr</strong> für Vollständigkeit + und Richtigkeit; sie ersetzt keine Rechtsberatung. Uneindeutige Änderungsbefehle werden zur + manuellen Prüfung markiert statt stillschweigend verworfen. Die gewählten Dateien + <strong>verlassen Ihren Rechner nicht</strong>: Die Auswertung läuft vollständig im Browser, + es wird nichts hochgeladen und nichts gespeichert. + </p> + </aside> </main> <footer> - <a href="impressum.html">Impressum</a> · - <a href="datenschutz.html">Datenschutz</a> · - <a href="aendggner-quelltext.tar.gz">Quelltext dieser Fassung (AGPLv3 oder später)</a> + <nav> + <a href="impressum.html">Impressum</a> · + <a href="datenschutz.html">Datenschutz</a> · + <a href="aendggner-quelltext.tar.gz">Quelltext dieser Fassung (AGPLv3 oder später)</a> + </nav> <span class="nebenquelle">(<a href="https://gerrit.benkard.de/plugins/gitiles/aendggner">Git</a>)</span> </footer> </body> diff --git a/src/main/resources/eu/mulk/aendggner/web/style.css b/src/main/resources/eu/mulk/aendggner/web/style.css index 69fd246..46d583f 100644 --- a/src/main/resources/eu/mulk/aendggner/web/style.css +++ b/src/main/resources/eu/mulk/aendggner/web/style.css @@ -1,16 +1,21 @@ /* SPDX-FileCopyrightText: 2020 Matthias Andreas Benkard <code@mail.matthias.benkard.de> SPDX-License-Identifier: AGPL-3.0-or-later */ -/* Schwarz auf Papier wie ein Gesetzblatt. Farbe tritt allein an den Balken der - Hinweiskästen auf und meint dort dasselbe wie in der Synopse: rot warnt, grün - bestätigt. Die Kästen bleiben auch ohne den Balken lesbar; er hebt sie hervor, - er trägt nicht allein. */ +/* Ein Vordruck, kein Aufsatz: Der Bogen liegt auf einer Unterlage, trägt oben einen + Briefkopf mit Formblattkennung und darunter einen Feldblock mit numerierten Feldern. + Farbe tritt an drei Stellen auf und meint dort jeweils dasselbe: Behördenrot führt + das Auge zu den Kennungen und Feldziffern, rot warnt, grün bestätigt. Kein Kasten + verlässt sich auf seine Farbe allein; Wort und Zeichen tragen die Aussage mit. */ :root { color-scheme: light dark; --fg: #111; --bg: #fff; + --papier: #f3f1ea; --muted: #595959; --border: #bbb; + --raster: #d6d2c6; + --kasten: #f0ede4; + --amt: #8b0f21; --warnung: #8b0000; --bestaetigung: #005f00; } @@ -18,9 +23,13 @@ @media (prefers-color-scheme: dark) { :root { --fg: #e6e6e6; - --bg: #141414; + --bg: #1c1c1c; + --papier: #0f0f0f; --muted: #a0a0a0; --border: #4a4a4a; + --raster: #3c3c3c; + --kasten: #242424; + --amt: #e79aa4; --warnung: #ffb3b3; --bestaetigung: #b3ffb3; } @@ -30,40 +39,129 @@ box-sizing: border-box; } +/* Die Unterlage endet nie, auch wenn der Bogen kürzer ist als das Fenster. */ +html { + background: var(--papier); +} + body { - margin: 0 auto; - padding: 2rem 1.25rem 3rem; - max-width: 40rem; - font-family: "Georgia", "Times New Roman", serif; + margin: 2rem auto 3rem; + padding: 2rem 2.25rem 2.5rem; + max-width: 46rem; + border: 1px solid var(--fg); + font-family: system-ui, "Segoe UI", "Helvetica Neue", Arial, sans-serif; + font-size: 1rem; color: var(--fg); background: var(--bg); - line-height: 1.5; + line-height: 1.55; } -header { - margin-bottom: 2rem; +/* Auf schmalen Geräten wäre der Bogenrand nur ein Verlust an Satzbreite. */ +@media (max-width: 48rem) { + body { + margin: 0; + padding: 1.25rem 1rem 2rem; + border: none; + } } -h1 { - margin: 0 0 0.25rem; - font-size: 1.75rem; +/* Der Briefkopf: links die ausstellende Stelle, rechts die Kennung des Vordrucks. + Darunter die Doppellinie — kräftig in Amtsrot, dünn in Rasterfarbe —, deren zweite + Linie der Oberrand des Satzspiegels ist. */ +.briefkopf { + display: grid; + grid-template-columns: 1fr auto; + gap: 1rem 2rem; + align-items: end; + padding-bottom: 0.7rem; + border-bottom: 3px solid var(--amt); +} + +/* Gestapelt zöge die Kennung sonst über die ganze Breite und sähe aus wie ein Kasten + des Satzspiegels statt wie ein Stempel am Kopfrand. */ +@media (max-width: 34rem) { + .briefkopf { + grid-template-columns: 1fr; + align-items: start; + } + + .kennung { + justify-self: start; + } +} + +h1, +.wortmarke { + margin: 0; + font-size: 1.9rem; + font-weight: bold; + letter-spacing: 0.06em; + line-height: 1.1; +} + +.wortmarke a { + text-decoration: none; } .langname { + margin: 0 0 0.3rem; + max-width: 26rem; + font-size: 0.75rem; + letter-spacing: 0.05em; + text-transform: uppercase; + line-height: 1.35; color: var(--muted); - margin: 0 0 0.35rem; - font-size: 0.9rem; } -.tagline { +/* Die Kennung steht als Verzeichnis im Text und nicht als Zierrat im Stilblatt: Sie + lässt sich damit auswählen und vorlesen. „Nichtamtlich“ ist dabei keine Pointe, + sondern die Klarstellung, die die amtliche Anmutung nötig macht. */ +.kennung { + display: grid; + grid-template-columns: auto auto; + gap: 0 0.6rem; + margin: 0; + padding: 0.4rem 0.6rem; + border: 1px solid var(--raster); + font-size: 0.75rem; + line-height: 1.5; +} + +.kennung dt { + letter-spacing: 0.06em; + text-transform: uppercase; color: var(--muted); +} + +.kennung dd { margin: 0; + font-weight: bold; + color: var(--amt); + white-space: nowrap; +} + +main { + margin-top: 3px; + padding-top: 1.5rem; + border-top: 1px solid var(--raster); +} + +.betreff { + margin: 0 0 1.75rem; + font-size: 1.05rem; } /* Impressum und Datenschutz. */ +main > h1 { + margin-bottom: 1.25rem; + font-size: 1.4rem; +} + h2 { margin: 1.75rem 0 0.5rem; - font-size: 1.125rem; + font-size: 0.9rem; + letter-spacing: 0.06em; + text-transform: uppercase; } address { @@ -71,50 +169,143 @@ address { margin: 0.5rem 0; } +code { + font-size: 0.9375em; +} + /* Ohne Schmuckfarbe trägt allein die Unterstreichung das Klick-Signal. */ a { color: var(--fg); text-decoration: underline; } +/* Der Vorgabe-Umriss verschwindet auf dem hellen Bogen fast; im Amtsrot ist der Halt + der Tastatur überall zu sehen. */ +:focus-visible { + outline: 2px solid var(--amt); + outline-offset: 2px; +} + +/* Der Feldblock. Die Legende sitzt als schwarzer Balken im oberen Rahmen, wie die + Abschnittsüberschrift eines Vordrucks. */ +fieldset { + counter-reset: feld; + margin: 0 0 1.5rem; + padding: 1.25rem 1.25rem 0.5rem; + border: 1px solid var(--fg); + background: var(--kasten); +} + +legend { + margin-left: -0.25rem; + padding: 0.3rem 0.8rem; + background: var(--fg); + color: var(--bg); + font-size: 0.8rem; + font-weight: bold; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +/* Die Feldziffer entsteht aus dem Zähler und steht im Steg links, damit sie die + Beschriftung nicht verschiebt und in jedem Feld an derselben Stelle sitzt. */ .field { + position: relative; margin-bottom: 1.25rem; + padding: 0.9rem 1rem 0.9rem 3rem; + border: 1px solid var(--raster); + background: var(--bg); + counter-increment: feld; +} + +.field::before { + content: counter(feld); + position: absolute; + top: 0.85rem; + left: 0.85rem; + width: 1.5rem; + height: 1.5rem; + border: 1px solid var(--amt); + color: var(--amt); + font-size: 0.8rem; + font-weight: bold; + line-height: 1.4rem; + text-align: center; } label { display: block; font-weight: bold; - margin-bottom: 0.35rem; + letter-spacing: 0.04em; + margin-bottom: 0.4rem; } .field.checkbox label { font-weight: normal; + letter-spacing: normal; + margin-bottom: 0; display: flex; align-items: center; gap: 0.5rem; } +.field.checkbox input { + accent-color: var(--amt); + width: 1rem; + height: 1rem; + flex: none; +} + .hint { - margin: 0.35rem 0 0; - font-size: 0.875rem; + margin: 0.4rem 0 0; + font-size: 0.8125rem; color: var(--muted); } input[type="file"] { width: 100%; - padding: 0.4rem; + padding: 0.35rem; border: 1px solid var(--border); background: transparent; color: inherit; + font: inherit; + font-size: 0.875rem; +} + +/* Der Dateiwähler ist der zweite Knopf des Vordrucks und trägt deshalb dessen Form, + nur in der Umkehrung, damit er dem Absenden nicht den Rang abläuft. */ +input[type="file"]::file-selector-button { + margin-right: 0.75rem; + padding: 0.3rem 0.9rem; + border: 1px solid var(--fg); + background: var(--bg); + color: var(--fg); + font: inherit; + font-size: 0.8125rem; + font-weight: bold; + letter-spacing: 0.04em; + cursor: pointer; +} + +input[type="file"]::file-selector-button:hover { + background: var(--fg); + color: var(--bg); +} + +.absenden { + margin-bottom: 0.5rem; } button { font: inherit; font-weight: bold; - padding: 0.6rem 1.5rem; + letter-spacing: 0.08em; + text-transform: uppercase; + padding: 0.7rem 1.75rem; border: 1px solid var(--fg); background: var(--fg); color: var(--bg); + box-shadow: 3px 3px 0 var(--raster); cursor: pointer; } @@ -124,27 +315,74 @@ button:hover { color: var(--fg); } -.noscript { - margin: 0 0 2rem; - padding: 1rem; - border: 1px solid var(--border); - border-left: 4px solid var(--warnung); +/* Gedrückt fährt der Knopf in seinen eigenen Schatten. */ +button:active { + transform: translate(3px, 3px); + box-shadow: none; +} + +/* grayscale() ist an einem grauen Knopf wirkungslos. */ +button[disabled] { + opacity: 0.5; + cursor: progress; +} + +/* Hinweiskästen und Meldungen teilen einen Zuschnitt, damit erkennbar bleibt, dass sie + dasselbe sind: Text am Rande des Vordrucks. Der Balken links zeigt den Zustand an. */ +.kasten, +.einfuehrung, +.meldung { + padding: 0.9rem 1.1rem; + border: 1px solid var(--raster); + border-left: 4px solid var(--raster); + background: var(--kasten); font-size: 0.875rem; } +.kasten { + margin: 0 0 1.75rem; +} + +.kasten.warnung { + border-left-color: var(--warnung); +} + +.kasten h2 { + margin: 0 0 0.5rem; + font-size: 0.75rem; +} + +.kasten p { + margin: 0; +} + /* Zugeklappt eine Zeile, damit das Formular oben bleibt; aufgeklappt im Zuschnitt der - übrigen Kästen. */ + übrigen Kästen. Der eigene Marker steht vor dem Wort statt daneben, sonst hinge er + außerhalb des Kastenrahmens. */ .einfuehrung { margin: 0 0 1.75rem; - padding: 0.75rem 1rem; - border: 1px solid var(--border); - font-size: 0.875rem; } .einfuehrung summary { font-weight: bold; - text-decoration: underline; + letter-spacing: 0.04em; cursor: pointer; + list-style: none; +} + +.einfuehrung summary::-webkit-details-marker { + display: none; +} + +.einfuehrung summary::before { + content: "\25B8"; + display: inline-block; + width: 1em; + color: var(--amt); +} + +.einfuehrung[open] summary::before { + content: "\25BE"; } .einfuehrung > :not(summary) { @@ -157,7 +395,9 @@ button:hover { .einfuehrung dt { font-weight: bold; - margin-top: 0.75rem; + margin-top: 0.9rem; + padding-top: 0.5rem; + border-top: 1px solid var(--raster); } .einfuehrung dd { @@ -172,55 +412,115 @@ button:hover { .disclaimer { margin-top: 2rem; - padding: 1rem; - border: 1px solid var(--border); - font-size: 0.875rem; color: var(--muted); } -footer { - margin-top: 2.5rem; - padding-top: 1rem; - border-top: 1px solid var(--border); - font-size: 0.875rem; - color: var(--muted); +/* Die Meldung führt ihr Zeichen im Balken mit: Wer die Farbe nicht sieht, liest ✓ oder ! + Das Zeichen steht im Stilblatt und nicht im Text, weil app.js den Text ersetzt. + Während der Arbeit steht weder Balken noch Zeichen, weil noch nichts feststeht. */ +.meldung { + margin: 1.5rem 0 0; + font-size: 0.9375rem; } -footer a { +.meldung.arbeit { color: var(--muted); } -.nebenquelle { - font-size: 0.8125rem; -} - -/* Der Balken links zeigt den Zustand an; der Text benennt ihn ohnehin, sodass die - Meldung auch ohne Farbe verständlich bleibt. Während der Arbeit steht kein Balken, - weil noch nichts feststeht. */ -.meldung { - margin-top: 1.25rem; - padding: 0.75rem 1rem; - border: 1px solid var(--border); - border-left-width: 4px; - border-left-color: var(--border); - font-size: 0.9375rem; +.meldung.fertig, +.meldung.fehler { + position: relative; + padding-left: 2.5rem; } -.meldung.arbeit { - color: var(--muted); +.meldung.fertig::before, +.meldung.fehler::before { + position: absolute; + left: 1.1rem; + font-weight: bold; } .meldung.fertig { border-left-color: var(--bestaetigung); } +.meldung.fertig::before { + content: "\2713"; + color: var(--bestaetigung); +} + .meldung.fehler { border-left-color: var(--warnung); font-weight: bold; } -/* grayscale() ist an einem grauen Knopf wirkungslos. */ -button[disabled] { - opacity: 0.5; - cursor: progress; +.meldung.fehler::before { + content: "!"; + color: var(--warnung); +} + +/* Der Fußsteg trägt die Pflichtangaben und die Herkunft — links das Verzeichnis, rechts + die Quelle, so wie ein Vordruck unten seine Herkunft nennt. */ +footer { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + gap: 0.5rem 1.5rem; + margin-top: 2.5rem; + padding-top: 0.9rem; + border-top: 1px solid var(--fg); + font-size: 0.8125rem; + color: var(--muted); +} + +footer a { + color: var(--muted); +} + +footer nav { + max-width: 32rem; +} + +.nebenquelle { + white-space: nowrap; +} + +/* Ein Formblatt gehört ausgedruckt: ohne Unterlage, ohne Bogenrand, mit Linien in + Schwarz. Der Knopf und das Merkblatt entfallen, weil auf Papier weder gedrückt noch + aufgeklappt wird. */ +@media print { + :root { + --fg: #000; + --bg: #fff; + --papier: #fff; + --muted: #333; + --border: #666; + --raster: #999; + --kasten: #fff; + --amt: #000; + } + + body { + margin: 0; + padding: 0; + max-width: none; + border: none; + font-size: 10pt; + } + + .einfuehrung, + .absenden, + .meldung[hidden] { + display: none; + } + + a { + text-decoration: none; + } + + fieldset, + .field, + .kasten { + break-inside: avoid; + } } |
