aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2026-08-23 09:41:36 +0200
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2026-08-23 09:41:36 +0200
commit4c8dee7ea32cd72188643f62021d903deb84aab2 (patch)
treef402c8b1d195ce0bb9cede4d6cf6f94a17949634 /src
parent18f85ced396b6eadfe0823e97ac6ed944d593f58 (diff)
Der Vordruck richtet sich nach einem wirklichen Vordruck
Die bisherige Gestaltung hatte sich am Begriff des amtlichen Formulars orientiert, nicht an einem solchen. Der Abgleich mit einem wirklichen Bundesvordruck — dem Antrag auf Erteilung einer Bescheinigung für den Lohnsteuerabzug bei erweiterter unbeschränkter Einkommensteuerpflicht — hat ergeben, dass sie in fast jedem Merkmal danebenlag. Maßgeblich ist eine einzige Regel, und sie steht im Muster ausgeschrieben: „Weiße Felder bitte ausfüllen“. Grau ist, was die Stelle gedruckt hat — Beschriftungen, Leitspalten, Abschnittsköpfe, die Verfügung am Ende; weiß ist, was der Antragsteller beiträgt. Bisher war es umgekehrt. Diese Regel trägt nun die gesamte Gestaltung und ist im Vordruck selbst benannt. Alles Übrige folgt daraus. Die Zellen stoßen aneinander, ohne Abstand und ohne Rundung, verbunden durch schwarze Haarlinien; die Rahmen sind halbiert, damit zwischen zwei Zellen eine einzige Linie steht. Die Beschriftung sitzt klein im Feld oben links, die Erläuterung in Klammern dahinter. Links läuft die Leitspalte mit den Abschnittsbezeichnungen. Das Ankreuzfeld wird angekreuzt, nicht angehakt. Der Abschnitt „Zur Beachtung:“ nimmt auf, was bisher über Tagline, Haftungsabsatz und noscript-Kasten verstreut war. Und die Meldung wird zur „Verfügung der Zentralstelle“, die auch dann schon dasteht, wenn sie noch leer ist — ein Vordruck zeigt seine Abschnitte, bevor sie ausgefüllt sind. Die Schmuckfarbe entfällt ersatzlos: Das Amtsrot war erfunden, wirkliche Bundesvordrucke führen keine. Rot und Grün bleiben allein dort, wo sie etwas bedeuten. Die Kennung wandert aus dem gerahmten Verzeichnis oben rechts in die Fußecken, links die Vordrucknummer, rechts der Ausgabestand. Die Synopse folgt demselben Gerüst. Ein weiterer Mangel ist dabei zutage getreten: Der Grund der Leitspalte hing am Block statt an der Zelle. Im Druck fällt die Fläche des Blocks weg, sodass die Leitspalte weiß herausgekommen wäre — und das Grau ist keine Zier, es sagt, welche Felder auszufüllen sind. Geprüft an allen drei Seiten und an zwei wirklichen Synopsen (UWG 19/0/6, AGG 23/1/14 als Entwurfsfassung), hell und dunkel, breit und schmal, dazu die Druckvorschau; reuse lint meldet 154/154, mvnw test dreihundertsiebenundzwanzig Testfälle ohne Fehler. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Change-Id: Ie0303f71baf5905fc8255f15ff375015a1de483e
Diffstat (limited to 'src')
-rw-r--r--src/main/java/eu/mulk/aendggner/synopse/HtmlRenderer.java430
-rw-r--r--src/main/resources/eu/mulk/aendggner/web/datenschutz.html30
-rw-r--r--src/main/resources/eu/mulk/aendggner/web/favicon.svg14
-rw-r--r--src/main/resources/eu/mulk/aendggner/web/impressum.html30
-rw-r--r--src/main/resources/eu/mulk/aendggner/web/index.html271
-rw-r--r--src/main/resources/eu/mulk/aendggner/web/style.css676
-rw-r--r--src/test/java/eu/mulk/aendggner/synopse/HtmlRendererTest.java14
7 files changed, 723 insertions, 742 deletions
diff --git a/src/main/java/eu/mulk/aendggner/synopse/HtmlRenderer.java b/src/main/java/eu/mulk/aendggner/synopse/HtmlRenderer.java
index 09a60de..6357b29 100644
--- a/src/main/java/eu/mulk/aendggner/synopse/HtmlRenderer.java
+++ b/src/main/java/eu/mulk/aendggner/synopse/HtmlRenderer.java
@@ -33,7 +33,7 @@ public final class HtmlRenderer {
.append(esc(synopse.alt().jurabk()))
.append("</title>\n<style>\n")
.append(CSS)
- .append("</style>\n</head>\n<body>\n");
+ .append("</style>\n</head>\n<body>\n<div class=\"bogen\">\n");
rendereKopf(sb, synopse, quelleBeschreibung, entwurfsfassung);
@@ -55,71 +55,76 @@ public final class HtmlRenderer {
rendereFuss(sb);
- sb.append("</body>\n</html>\n");
+ sb.append("</div>\n</body>\n</html>\n");
return sb.toString();
}
/**
- * Der Briefkopf des Vordrucks ÄG-2, im Aufbau derselbe wie auf der Aufgabeseite: links die
- * ausstellende Stelle, rechts die Kennung; darunter der Vorspann mit Herkunft und Statistik.
+ * Der Kopf des Vordrucks ÄG-2: Titel, ausstellende Stelle, darunter der Vorspann als
+ * Beschriftungsstreifen — grau, was die Stelle gedruckt hat, weiß die Eintragung daneben.
*/
private static void rendereKopf(
StringBuilder sb, Synopse synopse, String quelle, boolean entwurfsfassung) {
- sb.append("<header class=\"briefkopf\">\n<div class=\"dienststelle\">\n");
- sb.append("<p class=\"langname\">").append(LANGNAME).append("</p>\n");
- sb.append("<h1>Synopse: ").append(esc(synopse.alt().jurabk())).append("</h1>\n");
- if (synopse.alt().langue() != null) {
- sb.append("<p class=\"langue\">").append(esc(synopse.alt().langue())).append("</p>\n");
- }
- sb.append("</div>\n<dl class=\"kennung\">\n");
- sb.append("<dt>Formblatt</dt><dd>ÄG&#8209;2</dd>\n");
- sb.append("<dt>Stammgesetz</dt><dd>")
+ sb.append("<header>\n<h1>Synopse zum Stammgesetz ")
.append(esc(synopse.alt().jurabk()))
- .append("</dd>\n<dt>Erstellt</dt><dd>")
- .append(LocalDate.now())
- .append("</dd>\n");
- if (entwurfsfassung) {
- sb.append("<dt>Stand</dt><dd>Entwurfsfassung</dd>\n");
- }
- sb.append("<dt>Geltung</dt><dd>nichtamtlich</dd>\n");
- sb.append("</dl>\n</header>\n");
+ .append("</h1>\n<p class=\"stelle\">")
+ .append(LANGNAME)
+ .append("</p>\n</header>\n");
- sb.append("<div class=\"vorgang\">\n");
if (entwurfsfassung) {
sb.append(
- "<p class=\"entwurfshinweis\">Entwurfsfassung — nicht geltendes Recht. Die neue Fassung"
- + " gibt den Stand des Gesetzgebungsverfahrens wieder.</p>\n");
+ "<p class=\"entwurfshinweis\"><strong>Entwurfsfassung — nicht geltendes Recht.</strong>"
+ + " Die neue Fassung gibt den Stand des Gesetzgebungsverfahrens wieder.</p>\n");
}
- sb.append("<p class=\"quelle\">Grundlage: ").append(esc(quelle)).append("</p>\n");
+
long geaendert =
synopse.eintraege().stream()
.filter(e -> e.art() != Synopse.Aenderungsart.UNVERAENDERT)
.count();
- sb.append("<p class=\"statistik\">")
- .append(geaendert)
- .append(" geänderte Normen, ")
- .append(synopse.manuellZuPruefen().size())
- .append(" manuell zu prüfende Befehle</p>\n");
- sb.append("</div>\n");
+ sb.append("<dl class=\"vorspann\">\n");
+ vorspannZeile(sb, "Stammgesetz", synopse.alt().jurabk());
+ if (synopse.alt().langue() != null) {
+ vorspannZeile(sb, "Langbezeichnung", synopse.alt().langue());
+ }
+ vorspannZeile(sb, "Grundlage", quelle);
+ vorspannZeile(sb, "Erstellt am", LocalDate.now().toString());
+ vorspannZeile(
+ sb,
+ "Umfang",
+ geaendert
+ + " geänderte Normen, "
+ + synopse.manuellZuPruefen().size()
+ + " manuell zu prüfende Befehle");
+ vorspannZeile(sb, "Geltung", entwurfsfassung ? "nichtamtlich, Entwurfsstand" : "nichtamtlich");
+ sb.append("</dl>\n");
+ }
+
+ private static void vorspannZeile(StringBuilder sb, String bezeichnung, String wert) {
+ sb.append("<dt>")
+ .append(esc(bezeichnung))
+ .append("</dt><dd>")
+ .append(esc(wert))
+ .append("</dd>\n");
}
/**
- * Der Fußsteg. Der Vorbehalt gehört gerade hierher und nicht bloß auf die Aufgabeseite: Die
- * Synopse wird ausgedruckt und weitergereicht, das Formular nicht.
+ * Der Fußsteg trägt wie im Muster die Vordrucknummer links und den Ausgabestand rechts. Der
+ * Vorbehalt gehört gerade hierher und nicht bloß auf die Aufgabeseite: Die Synopse wird
+ * ausgedruckt und weitergereicht, das Formular nicht.
*/
private static void rendereFuss(StringBuilder sb) {
- sb.append("<footer>\n<span>Erstellt am ")
- .append(LocalDate.now())
- .append(" mit ÄndGgner</span>\n")
+ sb.append("<footer>\n<span class=\"vordrucknummer\">ÄG&#8209;2</span>\n")
.append(
- "<span class=\"nebenquelle\">Ohne Gewähr; maßgeblich ist allein die amtliche"
+ "<span>Erstellt mit ÄndGgner. Ohne Gewähr; maßgeblich ist allein die amtliche"
+ " Verkündung im jeweiligen Gesetz- oder Verordnungsblatt.</span>\n")
- .append("</footer>\n");
+ .append("<span class=\"ausgabe\">")
+ .append(LocalDate.now())
+ .append("</span>\n</footer>\n");
}
private static final String LANGNAME =
- "Nichtamtliche Zentralstelle für die maschinelle Fortschreibung von Stammgesetzen anhand"
- + " von Änderungsvorschriften des Bundes und der Länder";
+ "ÄndGgner — nichtamtliche Zentralstelle für die maschinelle Fortschreibung von Stammgesetzen"
+ + " anhand von Änderungsvorschriften des Bundes und der Länder";
private static void rendereGliederungsAenderungen(StringBuilder sb, Synopse synopse) {
if (synopse.gliederungsAenderungen().isEmpty()) {
@@ -251,45 +256,50 @@ public final class HtmlRenderer {
private static final String CSS =
"""
- /* Der Vordruck ÄG-2. Das Farbgerüst ist dasselbe wie in
- src/main/resources/eu/mulk/aendggner/web/style.css und wird hier ein zweites Mal
- geführt: Diese Datei wird aus einem blob:-Verweis geöffnet und im Befehlszeilen-
- betrieb als einzelne Datei abgelegt; sie kann kein fremdes Stilblatt einbinden.
- Wer dort etwas ändert, ändere es hier mit.
-
- Die Schrift ist geteilt: Der Vordruck — Briefkopf, Kennung, Überschriften,
- Spaltenköpfe, Kästchen, Fußsteg — steht in der Groteske, der Wortlaut der Normen
- in der Antiqua. Amtskopf und Vorschrift sind zweierlei, im Gesetzblatt wie hier.
-
- Farbe trägt allein die Änderung: rot heißt weg, grün heißt hinzu. Damit die
- Aussage auch im Schwarzweiß-Ausdruck und bei Farbfehlsichtigkeit erhalten bleibt,
- tritt zur Farbe stets die Form — durchgestrichen gegen unterstrichen — sowie die
- Spalte, in der sie steht. */
+ /* Der Vordruck ÄG-2, gesetzt nach demselben Muster wie die Aufgabeseite (siehe
+ src/main/resources/eu/mulk/aendggner/web/style.css): weißes Papier, schwarze
+ Haarlinien, grauer Raster für alles, was die Stelle gedruckt hat. Das Farbgerüst
+ wird hier ein zweites Mal geführt, weil diese Datei aus einem blob:-Verweis
+ geöffnet und im Befehlszeilenbetrieb als einzelne Datei abgelegt wird; sie kann
+ kein fremdes Stilblatt einbinden. Wer dort etwas ändert, ändere es hier mit.
+
+ Die Schrift ist geteilt: Der Vordruck steht in der Groteske, der Wortlaut der
+ Normen in der Antiqua. Amtskopf und Vorschrift sind zweierlei, im Gesetzblatt wie
+ hier.
+
+ Schmuckfarbe gibt es nicht. Farbe trägt allein die Änderung: rot heißt weg, grün
+ heißt hinzu. Damit die Aussage auch im Schwarzweiß-Ausdruck und bei
+ Farbfehlsichtigkeit erhalten bleibt, tritt zur Farbe stets die Form —
+ durchgestrichen gegen unterstrichen — sowie die Spalte, in der sie steht. */
:root {
color-scheme: light dark;
- --fg: #111;
- --bg: #fff;
- --papier: #f3f1ea;
- --muted: #595959;
- --raster: #d6d2c6;
- --kasten: #f0ede4;
- --amt: #8b0f21;
+ --fg: #000;
+ --papier: #fff;
+ --feld: #fff;
+ --grund: #d5d5d5;
+ --tint: #e4e4e4;
+ --linie: #000;
+ --muted: #444;
+ --tisch: #9a9a9a;
--del-bg: #ffd7d7;
--del-fg: #8b0000;
--ins-bg: #d7f5d7;
--ins-fg: #005f00;
- --grotesk: system-ui, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
+ --grotesk: Arial, "Helvetica Neue", Helvetica, system-ui, sans-serif;
--antiqua: Georgia, "Times New Roman", serif;
}
+ /* Im Dunkeln kehrt sich nicht die Farbe um, sondern das Verhältnis: Der Grund der
+ Stelle bleibt heller als das Feld. */
@media (prefers-color-scheme: dark) {
:root {
- --fg: #e6e6e6;
- --bg: #1c1c1c;
- --papier: #0f0f0f;
- --muted: #a0a0a0;
- --raster: #3c3c3c;
- --kasten: #242424;
- --amt: #e79aa4;
+ --fg: #e8e8e8;
+ --papier: #1a1a1a;
+ --feld: #101010;
+ --grund: #333333;
+ --tint: #242424;
+ --linie: #7a7a7a;
+ --muted: #a8a8a8;
+ --tisch: #000;
--del-bg: #5a1f1f;
--del-fg: #ffb3b3;
--ins-bg: #1f4a1f;
@@ -297,153 +307,136 @@ public final class HtmlRenderer {
}
}
* { box-sizing: border-box; }
- /* Die Unterlage endet nie, auch wenn der Bogen kürzer ist als das Fenster. */
- html { background: var(--papier); }
+ html { background: var(--tisch); }
body {
counter-reset: norm;
+ margin: 0;
+ padding: 1.5rem 1rem;
font-family: var(--grotesk);
- line-height: 1.5;
- max-width: 90rem;
- margin: 2rem auto 3rem;
- padding: 2rem 2.25rem 2.5rem;
- border: 1px solid var(--fg);
+ font-size: 0.8125rem;
+ line-height: 1.4;
color: var(--fg);
- background: var(--bg);
}
- /* 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; }
+ /* Ein Blatt Papier hat keinen Rahmen; die Kante entsteht aus dem Farbunterschied zur
+ Unterlage. Die Breite ist größer als beim Antrag, weil zwei Spalten sie brauchen. */
+ .bogen {
+ max-width: 88rem;
+ margin: 0 auto;
+ padding: 1.75rem 1.75rem 0.75rem;
+ background: var(--papier);
}
-
- /* Briefkopf und Doppellinie wie auf der Aufgabeseite: kräftig in Amtsrot, dünn in
- Rasterfarbe, wobei die zweite Linie der Oberrand des Vorspanns 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);
+ @media (max-width: 40rem) {
+ body { padding: 0; }
+ .bogen { padding: 1rem 0.75rem 0.5rem; }
}
- .langname {
- margin: 0 0 0.3rem;
- max-width: 30rem;
+
+ h1 { margin: 0 0 0.5rem; font-size: 1rem; line-height: 1.35; }
+ .stelle { margin: 0 0 0.9rem; font-size: 0.6875rem; color: var(--muted); }
+
+ .entwurfshinweis {
+ margin: 0 0 0.9rem;
+ padding: 0.45rem 0.6rem;
+ border: 1px solid var(--linie);
+ border-left: 4px solid var(--del-fg);
+ background: var(--feld);
font-size: 0.75rem;
- letter-spacing: 0.05em;
- text-transform: uppercase;
- line-height: 1.35;
- color: var(--muted);
}
- .dienststelle h1 {
- margin: 0;
- font-size: 1.9rem;
- letter-spacing: 0.06em;
- line-height: 1.1;
- }
- .langue { margin: 0.35rem 0 0; font-style: italic; color: var(--muted); }
- .kennung {
+
+ /* Der Vorspann ist der Beschriftungsstreifen des Musters: links grau die Bezeichnung,
+ rechts weiß die Eintragung, Zelle an Zelle ohne Abstand. */
+ .vorspann {
display: grid;
- grid-template-columns: auto auto;
- gap: 0 0.6rem;
+ grid-template-columns: 10rem 1fr;
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; }
- /* 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; }
+ border-top: 1px solid var(--linie);
+ border-left: 1px solid var(--linie);
+ font-size: 0.6875rem;
}
-
- .vorgang { margin-top: 3px; padding-top: 1rem; border-top: 1px solid var(--raster); }
- .quelle, .statistik, .gliederung, .ursachen {
- color: var(--muted);
- font-size: 0.85rem;
- margin: 0.2rem 0;
+ .vorspann dt {
+ padding: 0.2rem 0.5rem;
+ border-right: 1px solid var(--linie);
+ border-bottom: 1px solid var(--linie);
+ background: var(--grund);
+ font-weight: bold;
}
- .entwurfshinweis {
- margin: 0 0 0.9rem;
- padding: 0.9rem 1.1rem;
- border: 1px solid var(--raster);
- border-left: 4px solid var(--del-fg);
- background: var(--kasten);
- font-size: 0.9rem;
+ .vorspann dd {
+ margin: 0;
+ padding: 0.2rem 0.5rem;
+ border-right: 1px solid var(--linie);
+ border-bottom: 1px solid var(--linie);
+ background: var(--feld);
+ overflow-wrap: anywhere;
}
- /* Der Spaltenkopf steht mit der Gegenüberstellung in einem Block und nicht mehr im
- Kopfblock: Nur so reicht sein Klebebereich über alle Normen und nicht bloß über den
- Vorspann. Seine beiden Felder tragen die Form der Legende des Antragsvordrucks. */
+ /* Der Spaltenkopf steht mit der Gegenüberstellung in einem Block: Sein Klebebereich
+ reicht damit über alle Normen und endet vor dem Abschnitt „Manuell prüfen“. Seine
+ beiden Felder sind Beschriftungsstreifen wie im Vordruck, also grau. */
.spaltenkopf {
display: grid;
grid-template-columns: 1fr 1fr;
- gap: 1rem;
+ gap: 0.75rem;
position: sticky;
top: 0;
z-index: 1;
margin-top: 1.25rem;
- padding: 0.6rem 0 0.6rem 3rem;
- background: var(--bg);
+ padding: 0.5rem 0 0.5rem 2.5rem;
+ background: var(--papier);
}
.spaltenkopf div {
- padding: 0.3rem 0.8rem;
- background: var(--fg);
- color: var(--bg);
- font-size: 0.8rem;
+ padding: 0.25rem 0.5rem;
+ border: 1px solid var(--linie);
+ background: var(--grund);
+ font-size: 0.6875rem;
font-weight: bold;
- letter-spacing: 0.08em;
- text-transform: uppercase;
}
- /* Der Steg links trägt die Randziffer, wie im Vordruck die Feldziffer; sie macht die
- Abschnitte überdies zitierbar. */
- section { position: relative; padding-left: 3rem; }
+ /* Der Steg links trägt die Randziffer in einem Kästchen, wie der Antrag das
+ Ankreuzfeld; sie macht die Abschnitte überdies zitierbar. */
+ section { position: relative; padding-left: 2.5rem; }
section.norm {
counter-increment: norm;
- padding-top: 1rem;
- padding-bottom: 1rem;
- border-bottom: 1px solid var(--raster);
+ padding-top: 0.9rem;
+ padding-bottom: 0.9rem;
+ border-bottom: 1px solid var(--linie);
}
section.norm::before {
content: counter(norm);
position: absolute;
- top: 1.15rem;
+ top: 1rem;
left: 0;
width: 1.5rem;
- height: 1.5rem;
- border: 1px solid var(--amt);
- color: var(--amt);
- font-size: 0.8rem;
+ height: 1.2rem;
+ border: 1px solid var(--linie);
+ background: var(--grund);
+ font-size: 0.6875rem;
font-weight: bold;
- line-height: 1.4rem;
+ line-height: 1.1rem;
text-align: center;
}
- section.norm h2 { font-size: 1.05rem; margin: 0 0 0.5rem; letter-spacing: 0.02em; }
+ section.norm h2 { font-size: 0.8125rem; margin: 0 0 0.15rem; }
+ .gliederung, .ursachen { color: var(--muted); font-size: 0.6875rem; margin: 0.1rem 0; }
.vergleich {
display: grid;
grid-template-columns: 1fr 1fr;
- gap: 1rem;
+ gap: 0.75rem;
align-items: start;
+ margin-top: 0.5rem;
}
- /* Die alte Fassung liegt auf dem Kastenton wie ein Durchschlag, die neue auf
- Bogenweiß; beim Springen zwischen den Spalten ist damit ohne Hinsehen klar, wo man
+ /* Die alte Fassung liegt auf dem hellen Raster wie ein Durchschlag, die neue auf dem
+ weißen Feld; beim Springen zwischen den Spalten ist damit ohne Hinsehen klar, wo man
steht. Die Hinterlegungen der Änderungen heben sich von beiden Gründen ab. */
.vergleich > div {
- padding: 0.75rem 0.9rem;
- border: 1px solid var(--raster);
+ padding: 0.5rem 0.6rem;
+ border: 1px solid var(--linie);
white-space: pre-wrap;
overflow-wrap: anywhere;
font-family: var(--antiqua);
- font-size: 0.95rem;
+ font-size: 0.875rem;
line-height: 1.45;
}
- .vergleich > .alt { background: var(--kasten); }
- .vergleich > .neu { background: var(--bg); }
+ .vergleich > .alt { background: var(--tint); }
+ .vergleich > .neu { background: var(--feld); }
del, .alt del {
background: var(--del-bg);
@@ -455,111 +448,104 @@ public final class HtmlRenderer {
color: var(--ins-fg);
text-decoration: underline;
}
- .leer { color: var(--muted); font-style: italic; }
+ .leer { font-family: var(--grotesk); font-size: 0.75rem; color: var(--muted); }
- /* Kästchen in Versalien; die Farbe folgt derselben Regel wie im Diff. Beschriftet
- sind sie ohnehin, sodass die Farbe hier nur bestätigt, was dasteht. Der Rahmen
- steht auch dort, wo die Hinterlegung schwach wirkt. */
+ /* Kästchen wie die Ankreuzfelder des Antrags: eckig, haarfein umrandet. Beschriftet
+ sind sie ohnehin, sodass die Farbe nur bestätigt, was dasteht. */
.badge {
font-family: var(--grotesk);
- font-size: 0.7rem;
+ font-size: 0.625rem;
font-weight: normal;
text-transform: uppercase;
- letter-spacing: 0.06em;
- border: 1px solid var(--raster);
- padding: 0.1rem 0.55rem;
+ border: 1px solid var(--linie);
+ padding: 0 0.4rem;
vertical-align: middle;
white-space: nowrap;
}
- .neu-badge { background: var(--ins-bg); color: var(--ins-fg); border-color: var(--ins-fg); }
- .aufgehoben-badge {
- background: var(--del-bg);
- color: var(--del-fg);
- border-color: var(--del-fg);
- }
- .geaendert-badge { border-color: var(--raster); color: var(--muted); }
+ .neu-badge { background: var(--ins-bg); color: var(--ins-fg); }
+ .aufgehoben-badge { background: var(--del-bg); color: var(--del-fg); }
+ .geaendert-badge { background: var(--grund); color: var(--fg); }
- /* Die Abschnittsüberschriften treten als Balken auf wie die Legende des Feldblocks. */
+ /* Die Abschnittsüberschriften sind Beschriftungsstreifen über die volle Breite, wie im
+ Muster die Zeile „Verfügung des Finanzamts“. */
section.gliederung-aenderungen > h2, section.manuell > h2 {
- display: inline-block;
- margin: 0 0 0.9rem;
- 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;
+ margin: 0 0 0.6rem;
+ padding: 0.25rem 0.5rem;
+ border: 1px solid var(--linie);
+ background: var(--grund);
+ font-size: 0.75rem;
+ text-align: center;
}
section.gliederung-aenderungen { padding-top: 1.25rem; }
- section.manuell { margin-top: 2rem; padding-top: 1.5rem; border-top: 3px solid var(--amt); }
- section.manuell h3 {
- margin: 1.25rem 0 0.5rem;
- font-size: 0.8rem;
- letter-spacing: 0.06em;
- text-transform: uppercase;
- }
- section.manuell li { margin-bottom: 0.7rem; }
- .originaltext { font-family: var(--antiqua); color: var(--muted); font-size: 0.85rem; }
+ section.manuell { margin-top: 1.5rem; padding-top: 1.25rem; }
+ section.manuell h3 { margin: 1rem 0 0.4rem; font-size: 0.6875rem; }
+ section.manuell li { margin-bottom: 0.6rem; font-size: 0.75rem; }
+ .originaltext { font-family: var(--antiqua); color: var(--muted); font-size: 0.8125rem; }
+ /* Vordrucknummer links, Ausgabestand rechts, beide winzig und ohne Zierrat. */
footer {
display: flex;
flex-wrap: wrap;
+ align-items: baseline;
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;
+ gap: 0.4rem 1rem;
+ margin-top: 1.5rem;
+ padding: 0.4rem 0 0.6rem;
+ font-size: 0.625rem;
color: var(--muted);
}
+ .vordrucknummer, .ausgabe { white-space: nowrap; }
/* Zwei Spalten Gesetzestext nebeneinander sind auf dem Telefon nicht zu lesen. Gestapelt
trägt der Spaltenkopf nichts mehr; deshalb beschriftet sich dort jede Spalte selbst. */
@media (max-width: 60rem) {
.spaltenkopf { display: none; }
.vergleich { grid-template-columns: 1fr; }
- section { padding-left: 2.25rem; }
+ .vorspann { grid-template-columns: 7rem 1fr; }
+ section { padding-left: 2rem; }
.vergleich > div::before {
display: block;
- margin-bottom: 0.4rem;
+ margin: -0.5rem -0.6rem 0.4rem;
+ padding: 0.15rem 0.6rem;
+ border-bottom: 1px solid var(--linie);
+ background: var(--grund);
font-family: var(--grotesk);
- font-size: 0.7rem;
+ font-size: 0.625rem;
font-weight: bold;
- letter-spacing: 0.08em;
- text-transform: uppercase;
- color: var(--muted);
}
.vergleich > .alt::before { content: "Alte Fassung"; }
.vergleich > .neu::before { content: "Neue Fassung"; }
}
/* Gedruckt wird stets auf weißes Papier, auch aus einem dunkel eingestellten Browser
- heraus: prefers-color-scheme gilt im Druck fort. Deshalb ist hier das ganze
- Farbgerüst zurückzusetzen und nicht nur ein Teil davon — sonst käme die alte Spalte
- als schwarzer Block aus dem Drucker. */
+ heraus: prefers-color-scheme gilt im Druck fort. Deshalb ist das ganze Farbgerüst
+ zurückzusetzen und nicht nur ein Teil davon — sonst käme die alte Spalte als
+ schwarzer Block aus dem Drucker. */
@media print {
:root {
--fg: #000;
- --bg: #fff;
--papier: #fff;
+ --feld: #fff;
+ --grund: #d5d5d5;
+ --tint: #e4e4e4;
+ --linie: #000;
--muted: #333;
- --raster: #999;
- --kasten: #f2f0ea;
- --amt: #000;
+ --tisch: #fff;
--del-bg: #ffd7d7;
--del-fg: #8b0000;
--ins-bg: #d7f5d7;
--ins-fg: #005f00;
}
- body { margin: 0; padding: 0; max-width: none; border: none; font-size: 10pt; }
+ body { padding: 0; font-size: 9pt; }
+ .bogen { max-width: none; padding: 0; }
.spaltenkopf { position: static; }
.vergleich, section.norm { break-inside: avoid; }
- /* Ohne diese Festlegung wirft der Druck die Hinterlegung weg. Durchstreichung
- und Unterstreichung überstehen ihn ohnehin und tragen die Aussage auch dort,
- wo schwarzweiß gedruckt wird; der Spaltenbalken und der Durchschlagston der
- alten Fassung aber haben keine solche zweite Gestalt. */
+ /* Ohne diese Festlegung wirft der Druck die Hinterlegung weg. Durchstreichung und
+ Unterstreichung überstehen ihn ohnehin und tragen die Aussage auch dort, wo
+ schwarzweiß gedruckt wird; der Raster der Stelle aber hat keine solche zweite
+ Gestalt — er sagt, was gedruckt und was eingetragen ist. */
del, ins, .badge, .entwurfshinweis, .spaltenkopf div, .vergleich > .alt,
+ .vorspann dt, section.norm::before,
section.gliederung-aenderungen > h2, section.manuell > h2 {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
diff --git a/src/main/resources/eu/mulk/aendggner/web/datenschutz.html b/src/main/resources/eu/mulk/aendggner/web/datenschutz.html
index b217b89..e88a699 100644
--- a/src/main/resources/eu/mulk/aendggner/web/datenschutz.html
+++ b/src/main/resources/eu/mulk/aendggner/web/datenschutz.html
@@ -10,20 +10,13 @@
<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>
+<div class="bogen">
- <dl class="kennung">
- <dt>Formblatt</dt><dd>ÄG&#8209;1/B</dd>
- <dt>Anlage</dt><dd>Datenschutz</dd>
- <dt>Geltung</dt><dd>nichtamtlich</dd>
- </dl>
+ <header>
+ <p class="stelle">
+ ÄndGgner — nichtamtliche Zentralstelle für die maschinelle Fortschreibung von Stammgesetzen
+ anhand von Änderungsvorschriften des Bundes und der Länder
+ </p>
</header>
<main>
@@ -126,8 +119,13 @@
<p>Stand: 22. August 2026.</p>
</main>
<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>
+ <span class="vordrucknummer">ÄG&#8209;1/B</span>
+ <nav>
+ <a href="index.html">Zurück zum Vordruck</a> ·
+ <a href="impressum.html">Impressum</a>
+ </nav>
+ <span class="ausgabe">08.26</span>
</footer>
+
+</div>
</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 2f54d8f..b619c30 100644
--- a/src/main/resources/eu/mulk/aendggner/web/favicon.svg
+++ b/src/main/resources/eu/mulk/aendggner/web/favicon.svg
@@ -1,13 +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, Amtsrot als Rahmen des Vordrucks, schwarzes
- Zeichen. Ein Favicon erbt keine CSS-Variablen, deshalb stehen die Werte hier
+ <!-- Farben wie in style.css: Vordruckgrau als Grund, ein weißes Feld, schwarze Haarlinie,
+ schwarzes Zeichen. Ein Favicon erbt keine CSS-Variablen, deshalb stehen die Werte hier
ausgeschrieben. -->
- <rect width="32" height="32" fill="#fff"/>
- <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"
+ <rect width="32" height="32" fill="#d5d5d5"/>
+ <rect x="0.5" y="0.5" width="31" height="31" fill="none" stroke="#000"/>
+ <rect x="4.5" y="8.5" width="23" height="19" fill="#fff" stroke="#000"/>
+ <text x="16" y="19" fill="#000" font-family="Arial, Helvetica, sans-serif"
+ font-size="17" 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 cce8797..03f4063 100644
--- a/src/main/resources/eu/mulk/aendggner/web/impressum.html
+++ b/src/main/resources/eu/mulk/aendggner/web/impressum.html
@@ -10,20 +10,13 @@
<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>
+<div class="bogen">
- <dl class="kennung">
- <dt>Formblatt</dt><dd>ÄG&#8209;1/A</dd>
- <dt>Anlage</dt><dd>Impressum</dd>
- <dt>Geltung</dt><dd>nichtamtlich</dd>
- </dl>
+ <header>
+ <p class="stelle">
+ ÄndGgner — nichtamtliche Zentralstelle für die maschinelle Fortschreibung von Stammgesetzen
+ anhand von Änderungsvorschriften des Bundes und der Länder
+ </p>
</header>
<main>
@@ -72,8 +65,13 @@
</p>
</main>
<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>
+ <span class="vordrucknummer">ÄG&#8209;1/A</span>
+ <nav>
+ <a href="index.html">Zurück zum Vordruck</a> ·
+ <a href="datenschutz.html">Datenschutz</a>
+ </nav>
+ <span class="ausgabe">08.26</span>
</footer>
+
+</div>
</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 26ff522..4a0bbdd 100644
--- a/src/main/resources/eu/mulk/aendggner/web/index.html
+++ b/src/main/resources/eu/mulk/aendggner/web/index.html
@@ -15,152 +15,165 @@
<script src="app.js" defer></script>
</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>
- <h1>ÄndGgner</h1>
- </div>
-
- <dl class="kennung">
- <dt>Formblatt</dt><dd>ÄG&#8209;1</dd>
- <dt>Vorgang</dt><dd>Synopse</dd>
- <dt>Geltung</dt><dd>nichtamtlich</dd>
- </dl>
+<div class="bogen">
+
+ <header>
+ <h1>Antrag auf Erstellung einer Synopse<br>
+ zu einem Stammgesetz nach Maßgabe eines oder mehrerer Änderungsdokumente</h1>
+ <p class="stelle">
+ ÄndGgner — nichtamtliche Zentralstelle für die maschinelle Fortschreibung von Stammgesetzen
+ anhand von Änderungsvorschriften des Bundes und der Länder
+ </p>
</header>
- <main>
- <p class="betreff">
- Änderungsgesetze automatisch auf ein Stammgesetz anwenden und als Synopse darstellen.
+ <section class="beachtung">
+ <h2>Zur Beachtung:</h2>
+ <p>
+ Dieser Vordruck wendet ein oder mehrere Änderungsdokumente — verkündete Änderungsgesetze,
+ Gesetzentwürfe, Änderungsanträge und Beschlussempfehlungen — selbsttätig auf ein Stammgesetz
+ an und stellt das Ergebnis als zweispaltige Synopse gegenüber. Die Dokumentart wird aus dem
+ Text erkannt; eine Angabe darüber ist nicht zu machen.
+ </p>
+ <p>
+ Die gewählten Dateien <strong>verlassen Ihren Rechner nicht</strong>. Die gesamte Auswertung
+ läuft als WebAssembly-Programm in Ihrem Browser; es wird nichts hochgeladen und nichts
+ gespeichert.
+ </p>
+ <p>
+ Die Synopse wird automatisch erstellt und ist <strong>ohne Gewähr</strong> für Vollständigkeit
+ und Richtigkeit; sie ersetzt keine Rechtsberatung. Maßgeblich ist allein die amtliche
+ Verkündung im jeweiligen Gesetz- oder Verordnungsblatt. Uneindeutige Änderungsbefehle werden
+ zur manuellen Prüfung markiert statt stillschweigend verworfen.
</p>
-
<noscript>
- <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">
- <summary>Noch keine Dateien? Zwei Beispiele zum Ausprobieren</summary>
-
- <p>
- Das Werkzeug braucht zweierlei: das <strong>Stammgesetz</strong> in seiner geltenden
- Fassung und das <strong>Änderungsdokument</strong>, das es ändert. Beides liegt bei den
- amtlichen Stellen bereit.
+ <p class="fehlt">
+ Dieser Vordruck rechnet im Browser statt auf dem Server und braucht dafür JavaScript und
+ WebAssembly. Ohne sie bleibt er 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>
-
- <ol>
- <li>Die beiden Dateien eines Beispiels herunterladen.</li>
- <li>Sie in die Felder darunter eintragen — das xml.zip so, wie es kommt, ohne Entpacken.</li>
- <li>„Synopse erzeugen“ drücken.</li>
- </ol>
-
- <dl class="beispiele">
- <dt>Verkündetes Änderungsgesetz — Gesetz gegen den unlauteren Wettbewerb</dt>
- <dd>
- Stammgesetz:
- <a href="https://www.gesetze-im-internet.de/uwg_2004/xml.zip"
- target="_blank" rel="noopener noreferrer">UWG (xml.zip, 22 KB)</a><br>
- Änderung:
- <a href="https://www.recht.bund.de/bgbl/1/2026/43/regelungstext.pdf?__blob=publicationFile&amp;v=1"
- target="_blank" rel="noopener noreferrer">Drittes Gesetz zur Änderung des UWG,
- BGBl. 2026 I Nr. 43 (PDF, 0,3 MB)</a><br>
- <span class="hint">19 Befehle an 6 Normen, nichts manuell zu prüfen.</span>
- </dd>
-
- <dt>Gesetzentwurf — Allgemeines Gleichbehandlungsgesetz</dt>
- <dd>
- Stammgesetz:
- <a href="https://www.gesetze-im-internet.de/agg/xml.zip"
- target="_blank" rel="noopener noreferrer">AGG (xml.zip, 14 KB)</a><br>
- Änderung:
- <a href="https://dserver.bundestag.de/btd/21/061/2106178.pdf"
- target="_blank" rel="noopener noreferrer">Zweites Gesetz zur Änderung des AGG,
- BT-Drs. 21/6178 (PDF, 0,5 MB)</a><br>
- <span class="hint">
- 23 Befehle an 14 Normen, einer zur manuellen Prüfung markiert. Zeigt zugleich, was
- gälte, wenn der Entwurf so beschlossen würde — der Begründungsteil dahinter erzeugt
- keine Befehle.
- </span>
- </dd>
- </dl>
-
- <p class="hint">
- Die Verweise führen zu gesetze-im-internet.de, recht.bund.de und dserver.bundestag.de. Das
- Werkzeug ruft dort nichts von sich aus ab: Es sieht nur die Dateien, die Sie ihm im Formular
- übergeben.
- </p>
- </details>
-
- <form id="synopse-formular">
- <fieldset>
- <legend>Antrag auf Erstellung einer Synopse</legend>
-
- <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>
+ </noscript>
+ </section>
+
+ <p class="ausfuellhinweis">
+ Weiße Felder bitte ausfüllen oder <span class="kreuz">X</span> ankreuzen
+ </p>
+
+ <form id="synopse-formular">
+ <div class="vordruck">
+
+ <div class="block">
+ <div class="leitspalte">Angaben zum Stammgesetz</div>
+ <div class="felder">
+ <div class="feld">
+ <label for="stamm">Stammgesetz in der geltenden Fassung
+ <span class="erl">(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 als PDF oder Klartext)</span></label>
+ <input type="file" id="stamm" name="stamm" required>
+ </div>
</div>
+ </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 class="block">
+ <div class="leitspalte">Angaben zu den Änderungen</div>
+ <div class="felder">
+ <div class="feld">
+ <label for="aenderung">Änderungsdokument(e)
+ <span class="erl">(ein oder mehrere PDFs oder Klartextdateien: Änderungsgesetze aus
+ BGBl und GVBl, Gesetzentwürfe, Drucksachen sowie Änderungsanträge — letztere
+ zusammen mit dem Entwurf, den sie ändern. Bei Mehrfachauswahl wird in der
+ gewählten Reihenfolge nacheinander angewendet)</span></label>
+ <input type="file" id="aenderung" name="aenderung" multiple required>
+ </div>
+ <div class="feld ankreuzfeld">
+ <label>
+ <input type="checkbox" id="vollstaendig" name="vollstaendig">
+ Unveränderte Vorschriften mit in die Synopse aufnehmen
+ </label>
+ </div>
</div>
+ </div>
- <div class="field checkbox">
- <label>
- <input type="checkbox" id="vollstaendig" name="vollstaendig">
- Unveränderte Vorschriften mit in die Synopse aufnehmen
- </label>
+ <div class="block">
+ <div class="leitspalte">Antragstellung</div>
+ <div class="felder">
+ <div class="feld absenden">
+ <button type="submit">Synopse erstellen</button>
+ <span class="erl">Die Auswertung läuft in diesem Browser; je nach Umfang der
+ Dokumente dauert sie einige Sekunden.</span>
+ </div>
</div>
- </fieldset>
-
- <div class="absenden">
- <button type="submit">Synopse erzeugen</button>
</div>
- </form>
-
- <p id="meldung" class="meldung" hidden aria-live="polite" aria-atomic="true"></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>
+
+ </div>
+ </form>
+
+ <section class="verfuegung">
+ <h2>Verfügung der Zentralstelle</h2>
+ <div class="verfuegungsfeld">
+ <p id="meldung" class="meldung" hidden aria-live="polite" aria-atomic="true"></p>
+ <p class="platzhalter">Wird nach Absenden des Antrags ausgefüllt.</p>
+ </div>
+ </section>
+
+ <details class="ausfuellhilfe">
+ <summary>Ausfüllhilfe — zwei Beispiele zum Ausprobieren</summary>
+
+ <p>
+ Der Vordruck braucht zweierlei: das <strong>Stammgesetz</strong> in seiner geltenden Fassung
+ und das <strong>Änderungsdokument</strong>, das es ändert. Beides liegt bei den amtlichen
+ Stellen bereit. Die beiden Dateien eines Beispiels herunterladen, in die Felder oben
+ eintragen — das xml.zip so, wie es kommt, ohne Entpacken — und „Synopse erstellen“ drücken.
+ </p>
+
+ <dl class="beispiele">
+ <dt>Verkündetes Änderungsgesetz — Gesetz gegen den unlauteren Wettbewerb</dt>
+ <dd>
+ Stammgesetz:
+ <a href="https://www.gesetze-im-internet.de/uwg_2004/xml.zip"
+ target="_blank" rel="noopener noreferrer">UWG (xml.zip, 22 KB)</a><br>
+ Änderung:
+ <a href="https://www.recht.bund.de/bgbl/1/2026/43/regelungstext.pdf?__blob=publicationFile&amp;v=1"
+ target="_blank" rel="noopener noreferrer">Drittes Gesetz zur Änderung des UWG,
+ BGBl. 2026 I Nr. 43 (PDF, 0,3 MB)</a><br>
+ <span class="erl">19 Befehle an 6 Normen, nichts manuell zu prüfen.</span>
+ </dd>
+
+ <dt>Gesetzentwurf — Allgemeines Gleichbehandlungsgesetz</dt>
+ <dd>
+ Stammgesetz:
+ <a href="https://www.gesetze-im-internet.de/agg/xml.zip"
+ target="_blank" rel="noopener noreferrer">AGG (xml.zip, 14 KB)</a><br>
+ Änderung:
+ <a href="https://dserver.bundestag.de/btd/21/061/2106178.pdf"
+ target="_blank" rel="noopener noreferrer">Zweites Gesetz zur Änderung des AGG,
+ BT-Drs. 21/6178 (PDF, 0,5 MB)</a><br>
+ <span class="erl">
+ 23 Befehle an 14 Normen, einer zur manuellen Prüfung markiert. Zeigt zugleich, was gälte,
+ wenn der Entwurf so beschlossen würde — der Begründungsteil dahinter erzeugt keine
+ Befehle.
+ </span>
+ </dd>
+ </dl>
+
+ <p class="erl">
+ Die Verweise führen zu gesetze-im-internet.de, recht.bund.de und dserver.bundestag.de. Der
+ Vordruck ruft dort nichts von sich aus ab: Er sieht nur die Dateien, die Sie ihm übergeben.
+ </p>
+ </details>
<footer>
+ <span class="vordrucknummer">ÄG&#8209;1</span>
<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>
+ <a href="aendggner-quelltext.tar.gz">Quelltext dieser Fassung (AGPLv3 oder später)</a> ·
+ <a href="https://gerrit.benkard.de/plugins/gitiles/aendggner">Git</a>
</nav>
- <span class="nebenquelle">(<a href="https://gerrit.benkard.de/plugins/gitiles/aendggner">Git</a>)</span>
+ <span class="ausgabe">08.26</span>
</footer>
+
+</div>
</body>
</html>
diff --git a/src/main/resources/eu/mulk/aendggner/web/style.css b/src/main/resources/eu/mulk/aendggner/web/style.css
index 81c16d7..36c2198 100644
--- a/src/main/resources/eu/mulk/aendggner/web/style.css
+++ b/src/main/resources/eu/mulk/aendggner/web/style.css
@@ -1,35 +1,43 @@
/* SPDX-FileCopyrightText: 2020 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
SPDX-License-Identifier: AGPL-3.0-or-later */
-/* 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. */
+/* Ein Vordruck nach dem Vorbild der amtlichen Steuerformulare. Dort gilt eine einzige,
+ durchgehaltene Regel, und sie steht sogar im Formular selbst: „Weiße Felder bitte
+ ausfüllen“. Grau ist, was die Stelle gedruckt hat — Beschriftungen, Leitspalten,
+ Abschnittsköpfe, die Verfügung am Ende. Weiß ist, was der Antragsteller beiträgt.
+ Diese Regel trägt hier die gesamte Gestaltung.
+
+ Alles andere folgt daraus: schwarze Haarlinien, aneinanderstoßende Zellen ohne Abstand
+ und ohne Rundung, kleine enge Groteske, Beschriftung innen oben links im Feld,
+ Erläuterungen in noch kleinerer Schrift dahinter, die Vordrucknummer winzig in den
+ Fußecken. Schmuckfarbe gibt es nicht: Rot und Grün treten allein dort auf, wo sie etwas
+ bedeuten — Fehler und Bestätigung —, und nie als einziger Träger der Aussage. */
:root {
color-scheme: light dark;
- --fg: #111;
- --bg: #fff;
- --papier: #f3f1ea;
- --muted: #595959;
- --border: #bbb;
- --raster: #d6d2c6;
- --kasten: #f0ede4;
- --amt: #8b0f21;
+ --fg: #000;
+ --papier: #fff;
+ --feld: #fff;
+ --grund: #d5d5d5;
+ --tint: #e4e4e4;
+ --linie: #000;
+ --muted: #444;
+ --tisch: #9a9a9a;
--warnung: #8b0000;
--bestaetigung: #005f00;
}
+/* Im Dunkeln kehrt sich nicht die Farbe um, sondern das Verhältnis: Der Grund der Stelle
+ bleibt heller als das Feld, das auszufüllen ist. */
@media (prefers-color-scheme: dark) {
:root {
- --fg: #e6e6e6;
- --bg: #1c1c1c;
- --papier: #0f0f0f;
- --muted: #a0a0a0;
- --border: #4a4a4a;
- --raster: #3c3c3c;
- --kasten: #242424;
- --amt: #e79aa4;
+ --fg: #e8e8e8;
+ --papier: #1a1a1a;
+ --feld: #101010;
+ --grund: #333333;
+ --tint: #242424;
+ --linie: #7a7a7a;
+ --muted: #a8a8a8;
+ --tisch: #000;
--warnung: #ffb3b3;
--bestaetigung: #b3ffb3;
}
@@ -39,286 +47,247 @@
box-sizing: border-box;
}
-/* Die Unterlage endet nie, auch wenn der Bogen kürzer ist als das Fenster. */
html {
- background: var(--papier);
+ background: var(--tisch);
}
body {
- 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;
+ margin: 0;
+ padding: 1.5rem 1rem;
+ font-family: Arial, "Helvetica Neue", Helvetica, system-ui, sans-serif;
+ font-size: 0.8125rem;
+ line-height: 1.4;
color: var(--fg);
- background: var(--bg);
- line-height: 1.55;
-}
-
-/* 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;
- }
-}
-
-/* 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;
+/* Der Bogen. Kein Rahmen: Ein Blatt Papier hat keinen, die Kante entsteht aus dem
+ Farbunterschied zur Unterlage. */
+.bogen {
+ max-width: 52rem;
+ margin: 0 auto;
+ padding: 1.75rem 1.75rem 0.75rem;
+ background: var(--papier);
}
-.wortmarke a {
- text-decoration: none;
+@media (max-width: 40rem) {
+ body { padding: 0; }
+ .bogen { padding: 1rem 0.75rem 0.5rem; }
}
-.langname {
- margin: 0 0 0.3rem;
- max-width: 26rem;
- font-size: 0.75rem;
- letter-spacing: 0.05em;
- text-transform: uppercase;
+h1 {
+ margin: 0 0 0.5rem;
+ font-size: 1rem;
line-height: 1.35;
- color: var(--muted);
}
-/* 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;
+.stelle {
+ margin: 0 0 0.9rem;
+ font-size: 0.6875rem;
+ color: var(--muted);
}
-.kennung dt {
- letter-spacing: 0.06em;
- text-transform: uppercase;
- color: var(--muted);
+/* Ohne Schmuckfarbe trägt allein die Unterstreichung das Klick-Signal. */
+a {
+ color: inherit;
+ text-decoration: underline;
}
-.kennung dd {
- margin: 0;
- font-weight: bold;
- color: var(--amt);
- white-space: nowrap;
+/* Der Vorgabe-Umriss ist auf dem grauen Raster kaum auszumachen. */
+:focus-visible {
+ outline: 2px solid var(--fg);
+ outline-offset: 1px;
}
-main {
- margin-top: 3px;
- padding-top: 1.5rem;
- border-top: 1px solid var(--raster);
+/* „Zur Beachtung“ steht im Muster als weißer Kasten mit fetter Anrede und dichtem
+ Fließtext; die Überschrift bleibt in der Zeile des ersten Absatzes. */
+.beachtung {
+ padding: 0.6rem 0.7rem;
+ border: 1px solid var(--linie);
+ background: var(--feld);
+ font-size: 0.75rem;
}
-.betreff {
- margin: 0 0 1.75rem;
- font-size: 1.05rem;
+.beachtung h2 {
+ margin: 0 0 0.35rem;
+ font-size: 0.75rem;
}
-/* Impressum und Datenschutz. */
-main > h1 {
- margin-bottom: 1.25rem;
- font-size: 1.4rem;
+.beachtung p {
+ margin: 0 0 0.5rem;
}
-h2 {
- margin: 1.75rem 0 0.5rem;
- font-size: 0.9rem;
- letter-spacing: 0.06em;
- text-transform: uppercase;
+.beachtung p:last-child {
+ margin-bottom: 0;
}
-address {
- font-style: normal;
- margin: 0.5rem 0;
+.fehlt {
+ padding-left: 0.6rem;
+ border-left: 3px solid var(--warnung);
+ font-weight: bold;
}
-code {
- font-size: 0.9375em;
+/* Der Ausfüllhinweis ist im Muster ein eigener Streifen über dem Feldblock — er erklärt
+ genau die Regel, nach der dieses Blatt gesetzt ist. */
+.ausfuellhinweis {
+ margin: 0.9rem 0 0;
+ padding: 0.3rem 0.5rem;
+ border: 1px solid var(--linie);
+ border-bottom: none;
+ background: var(--grund);
+ font-size: 0.75rem;
+ font-weight: bold;
}
-/* Ohne Schmuckfarbe trägt allein die Unterstreichung das Klick-Signal. */
-a {
- color: var(--fg);
- text-decoration: underline;
+.kreuz {
+ display: inline-block;
+ width: 1.1em;
+ border: 1px solid var(--linie);
+ background: var(--feld);
+ font-weight: bold;
+ text-align: center;
}
-/* 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 Rahmen sind halbiert — außen oben und links, an den Zellen unten und
+ rechts —, damit zwischen zwei Zellen nur eine einzige Haarlinie steht und nicht zwei. */
+.vordruck {
+ border-top: 1px solid var(--linie);
+ border-left: 1px solid var(--linie);
+ background: var(--grund);
}
-/* 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);
+.block {
+ display: grid;
+ grid-template-columns: 8.5rem 1fr;
}
-legend {
- margin-left: -0.25rem;
- padding: 0.3rem 0.8rem;
- background: var(--fg);
- color: var(--bg);
- font-size: 0.8rem;
+/* Der Grund steht ausdrücklich an der Zelle und nicht nur am Block: Im Druck fällt sonst
+ die Fläche des Blocks weg und die Leitspalte käme weiß heraus. */
+.leitspalte {
+ padding: 0.4rem 0.5rem;
+ border-right: 1px solid var(--linie);
+ border-bottom: 1px solid var(--linie);
+ background: var(--grund);
+ font-size: 0.6875rem;
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;
+/* Auf dem Telefon nähme die Leitspalte die halbe Zeile. Sie tritt dann über ihre Felder,
+ als voller Beschriftungsstreifen — eine Form, die das Muster ebenfalls kennt. */
+@media (max-width: 34rem) {
+ .block {
+ grid-template-columns: 1fr;
+ }
+
+ .leitspalte {
+ border-right: none;
+ }
}
-.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;
+.feld {
+ padding: 0.25rem 0.5rem 0.4rem;
+ border-right: 1px solid var(--linie);
+ border-bottom: 1px solid var(--linie);
+ background: var(--feld);
}
+/* Die Beschriftung steht klein im Feld oben links, die Erläuterung noch kleiner dahinter;
+ darunter bleibt der Platz für die Eintragung. */
label {
display: block;
+ font-size: 0.6875rem;
font-weight: bold;
- letter-spacing: 0.04em;
- margin-bottom: 0.4rem;
}
-.field.checkbox label {
+.erl {
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.4rem 0 0;
- font-size: 0.8125rem;
+ font-size: 0.6875rem;
color: var(--muted);
}
input[type="file"] {
width: 100%;
- padding: 0.35rem;
- border: 1px solid var(--border);
+ margin-top: 0.35rem;
+ padding: 0;
+ border: none;
background: transparent;
color: inherit;
font: inherit;
- font-size: 0.875rem;
+ font-size: 0.75rem;
}
-/* 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. */
+/* Der Dateiwähler ist der einzige Knopf im Feld und trägt deshalb die Form der übrigen
+ Eintragungsfelder: eckig, haarfein umrandet, weiß. */
input[type="file"]::file-selector-button {
- margin-right: 0.75rem;
- padding: 0.3rem 0.9rem;
- border: 1px solid var(--fg);
- background: var(--bg);
+ margin-right: 0.6rem;
+ padding: 0.15rem 0.7rem;
+ border: 1px solid var(--linie);
+ background: var(--feld);
color: var(--fg);
font: inherit;
- font-size: 0.8125rem;
- font-weight: bold;
- letter-spacing: 0.04em;
+ font-size: 0.6875rem;
cursor: pointer;
}
input[type="file"]::file-selector-button:hover {
- background: var(--fg);
- color: var(--bg);
+ background: var(--grund);
+}
+
+/* Das Ankreuzfeld steht vor dem Text und wird angekreuzt, nicht angehakt. */
+.ankreuzfeld label {
+ display: flex;
+ align-items: baseline;
+ gap: 0.5rem;
+ font-weight: normal;
+ font-size: 0.75rem;
+}
+
+.ankreuzfeld input {
+ appearance: none;
+ -webkit-appearance: none;
+ flex: none;
+ position: relative;
+ width: 0.95rem;
+ height: 0.95rem;
+ margin: 0;
+ border: 1px solid var(--linie);
+ background: var(--feld);
+ cursor: pointer;
+}
+
+.ankreuzfeld input:checked::before {
+ content: "\00D7";
+ position: absolute;
+ inset: 0;
+ font-size: 0.9rem;
+ font-weight: bold;
+ line-height: 0.85rem;
+ text-align: center;
+ color: var(--fg);
}
.absenden {
- margin-bottom: 0.5rem;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 0.5rem 0.9rem;
+ padding-top: 0.5rem;
}
button {
font: inherit;
+ font-size: 0.8125rem;
font-weight: bold;
- 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);
+ padding: 0.4rem 1.1rem;
+ border: 2px solid var(--linie);
+ background: var(--feld);
+ color: var(--fg);
cursor: pointer;
}
-/* Umkehr statt brightness(): Ein schwarzer Knopf wird davon nicht heller. */
+/* Umkehr statt brightness(): An einem weißen Knopf richtet die nichts aus. */
button:hover {
- background: var(--bg);
- color: var(--fg);
-}
-
-/* Gedrückt fährt der Knopf in seinen eigenen Schatten. */
-button:active {
- transform: translate(3px, 3px);
- box-shadow: none;
+ background: var(--fg);
+ color: var(--papier);
}
/* grayscale() ist an einem grauen Knopf wirkungslos. */
@@ -327,100 +296,52 @@ button[disabled] {
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);
+button[disabled]:hover {
+ background: var(--feld);
+ color: var(--fg);
}
-.kasten h2 {
- margin: 0 0 0.5rem;
- font-size: 0.75rem;
+/* Die Verfügung ist im Muster der Abschnitt, den die Stelle ausfüllt: grau umrandet,
+ mit zentrierter fetter Überschrift. Er steht auch dann schon da, wenn er noch leer ist —
+ ein Vordruck zeigt seine Abschnitte, bevor sie ausgefüllt sind. */
+.verfuegung {
+ margin-top: 1.25rem;
+ border: 1px solid var(--linie);
+ background: var(--grund);
}
-.kasten p {
+.verfuegung h2 {
margin: 0;
+ padding: 0.3rem 0.5rem;
+ border-bottom: 1px solid var(--linie);
+ font-size: 0.75rem;
+ text-align: center;
}
-/* Zugeklappt eine Zeile, damit das Formular oben bleibt; aufgeklappt im Zuschnitt der
- ü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;
+.verfuegungsfeld {
+ padding: 0.5rem;
}
-.einfuehrung summary {
- font-weight: bold;
- letter-spacing: 0.04em;
- cursor: pointer;
- list-style: none;
+.platzhalter {
+ margin: 0;
+ font-size: 0.75rem;
+ color: var(--muted);
}
-.einfuehrung summary::-webkit-details-marker {
+/* Steht eine Meldung, so tritt der Platzhalter zurück. */
+#meldung:not([hidden]) + .platzhalter {
display: none;
}
-.einfuehrung summary::before {
- content: "\25B8";
- display: inline-block;
- width: 1em;
- color: var(--amt);
-}
-
-.einfuehrung[open] summary::before {
- content: "\25BE";
-}
-
-.einfuehrung > :not(summary) {
- margin: 0.75rem 0 0;
-}
-
-.einfuehrung ol {
- padding-left: 1.25rem;
-}
-
-.einfuehrung dt {
- font-weight: bold;
- margin-top: 0.9rem;
- padding-top: 0.5rem;
- border-top: 1px solid var(--raster);
-}
-
-.einfuehrung dd {
- margin: 0.25rem 0 0;
-}
-
-/* Der Erläuterungssatz unter einem Beispiel steht als span in der dd und braucht deshalb
- eigene Absatzbildung. */
-.einfuehrung .hint {
- display: block;
-}
-
-.disclaimer {
- margin-top: 2rem;
- 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. */
+/* Die Meldung ist die Eintragung der Stelle und deshalb weiß. Ihr Zeichen im Steg — ✓ oder
+ ! — trägt den Zustand auch dort, wo die Farbe nicht ankommt. Während der Arbeit steht
+ weder Zeichen noch Farbe, weil noch nichts feststeht. */
.meldung {
- margin: 1.5rem 0 0;
- font-size: 0.9375rem;
+ margin: 0;
+ padding: 0.45rem 0.6rem;
+ border: 1px solid var(--linie);
+ background: var(--feld);
+ font-size: 0.8125rem;
}
.meldung.arbeit {
@@ -430,13 +351,14 @@ button[disabled] {
.meldung.fertig,
.meldung.fehler {
position: relative;
- padding-left: 2.5rem;
+ padding-left: 2rem;
+ border-left-width: 4px;
}
.meldung.fertig::before,
.meldung.fehler::before {
position: absolute;
- left: 1.1rem;
+ left: 0.7rem;
font-weight: bold;
}
@@ -459,72 +381,134 @@ button[disabled] {
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. */
+/* Die Ausfüllhilfe ist ein Merkblatt und liegt dem Vordruck bei, statt in ihm zu stehen. */
+.ausfuellhilfe {
+ margin-top: 1.25rem;
+ padding: 0.5rem 0.7rem;
+ border: 1px solid var(--linie);
+ background: var(--tint);
+ font-size: 0.75rem;
+}
+
+.ausfuellhilfe summary {
+ font-weight: bold;
+ cursor: pointer;
+ list-style: none;
+}
+
+.ausfuellhilfe summary::-webkit-details-marker {
+ display: none;
+}
+
+.ausfuellhilfe summary::before {
+ content: "\25B8\00A0";
+}
+
+.ausfuellhilfe[open] summary::before {
+ content: "\25BE\00A0";
+}
+
+.ausfuellhilfe > :not(summary) {
+ margin: 0.6rem 0 0;
+}
+
+.ausfuellhilfe dt {
+ margin-top: 0.7rem;
+ padding-top: 0.5rem;
+ border-top: 1px solid var(--linie);
+ font-weight: bold;
+}
+
+.ausfuellhilfe dd {
+ margin: 0.2rem 0 0;
+}
+
+.ausfuellhilfe .erl {
+ display: block;
+}
+
+/* Im Muster steht unten links die Vordrucknummer und unten rechts der Ausgabestand, beide
+ winzig und ohne Zierrat. Die Pflichtangaben stehen dazwischen. */
footer {
display: flex;
flex-wrap: wrap;
+ align-items: baseline;
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 {
+ gap: 0.4rem 1rem;
+ margin-top: 1.5rem;
+ padding: 0.4rem 0 0.6rem;
+ font-size: 0.625rem;
color: var(--muted);
}
footer nav {
- max-width: 32rem;
+ font-size: 0.6875rem;
}
-.nebenquelle {
+.vordrucknummer,
+.ausgabe {
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. Gedruckt wird stets auf weißes Papier, auch aus einem dunkel
- eingestellten Browser heraus — prefers-color-scheme gilt im Druck fort. Deshalb ist
- das ganze Farbgerüst zurückzusetzen und nicht nur ein Teil davon. */
+/* Impressum und Datenschutz: dieselbe Anmutung, aber Fließtext statt Feldblock. */
+.bogen > main {
+ padding-bottom: 0.5rem;
+ font-size: 0.8125rem;
+}
+
+main h1 {
+ font-size: 1rem;
+}
+
+main h2 {
+ margin: 1.1rem 0 0.3rem;
+ padding: 0.2rem 0.4rem;
+ border: 1px solid var(--linie);
+ background: var(--grund);
+ font-size: 0.6875rem;
+}
+
+main p,
+main address {
+ margin: 0.4rem 0;
+ max-width: 42rem;
+}
+
+address {
+ font-style: normal;
+}
+
+code {
+ font-size: 0.9375em;
+}
+
+/* Ein Vordruck gehört ausgedruckt: ohne Unterlage, ohne Ränder. Gedruckt wird stets auf
+ weißes Papier, auch aus einem dunkel eingestellten Browser heraus — prefers-color-scheme
+ gilt im Druck fort. Deshalb ist das ganze Farbgerüst zurückzusetzen und nicht nur ein
+ Teil davon. Das Grau selbst muss mitgedruckt werden: Es sagt, welche Felder auszufüllen
+ sind, und ist damit keine Zier. */
@media print {
:root {
--fg: #000;
- --bg: #fff;
--papier: #fff;
+ --feld: #fff;
+ --grund: #d5d5d5;
+ --tint: #e4e4e4;
+ --linie: #000;
--muted: #333;
- --border: #666;
- --raster: #999;
- --kasten: #fff;
- --amt: #000;
+ --tisch: #fff;
--warnung: #8b0000;
--bestaetigung: #005f00;
}
- body {
- margin: 0;
- padding: 0;
- max-width: none;
- border: none;
- font-size: 10pt;
- }
-
- .einfuehrung,
- .absenden,
- .meldung[hidden] {
- display: none;
- }
-
- a {
- text-decoration: none;
- }
+ body { padding: 0; font-size: 9pt; }
+ .bogen { max-width: none; padding: 0; }
+ .ausfuellhilfe { display: none; }
+ a { text-decoration: none; }
+ .block, .beachtung, .verfuegung { break-inside: avoid; }
- fieldset,
- .field,
- .kasten {
- break-inside: avoid;
+ .leitspalte, .ausfuellhinweis, .verfuegung, .verfuegung h2, .kreuz, .ausfuellhilfe {
+ -webkit-print-color-adjust: exact;
+ print-color-adjust: exact;
}
}
diff --git a/src/test/java/eu/mulk/aendggner/synopse/HtmlRendererTest.java b/src/test/java/eu/mulk/aendggner/synopse/HtmlRendererTest.java
index 09a5b7c..b80fc88 100644
--- a/src/test/java/eu/mulk/aendggner/synopse/HtmlRendererTest.java
+++ b/src/test/java/eu/mulk/aendggner/synopse/HtmlRendererTest.java
@@ -108,20 +108,22 @@ class HtmlRendererTest {
}
@Test
- void traegtKennungUndFusssteg() {
+ void traegtVorspannUndFusssteg() {
var html = HtmlRenderer.rendere(synopse(), "test.xml + test.pdf");
- assertThat(html).contains("&#8209;2").contains("Stammgesetz").contains("nichtamtlich");
- assertThat(html).contains("Grundlage: test.xml + test.pdf");
+ assertThat(html).contains("<dt>Stammgesetz</dt><dd>TestG</dd>");
+ assertThat(html).contains("<dt>Grundlage</dt><dd>test.xml + test.pdf</dd>");
+ assertThat(html).contains("<dt>Geltung</dt><dd>nichtamtlich</dd>");
+ assertThat(html).contains("class=\"vordrucknummer\">ÄG&#8209;2<");
assertThat(html).contains("maßgeblich ist allein die amtliche Verkündung");
- assertThat(html).doesNotContain("Entwurfsfassung");
+ assertThat(html).doesNotContain("Entwurfsstand");
}
@Test
- void weistDieEntwurfsfassungInDerKennungAus() {
+ void weistDenEntwurfsstandImVorspannAus() {
var html = HtmlRenderer.rendere(synopse(), "quelle", true);
- assertThat(html).contains("<dt>Stand</dt><dd>Entwurfsfassung</dd>");
+ assertThat(html).contains("<dt>Geltung</dt><dd>nichtamtlich, Entwurfsstand</dd>");
assertThat(html).contains("nicht geltendes Recht");
}