/*
Theme Name: baupvo.io
Theme URI: https://baupvo.io/
Author: Zurynski, Oezdogan & Co GmbH
Author URI: https://baupvo.io/impressum/
Description: Klassisches WordPress-Theme für die maschinenlesbare Seite der Bauproduktenverordnung. Dokumentationsraster mit Spezifikationsbaum, Feldtabellen aus zusammenfallenden 2-px-Panelkanten, Feldkarten-Panel, Schema-Ansichten (JSON/XML/Tabelle/Etikettendaten), Prüfer und Identifikator-Zerleger. Dunkelmodus ist Auslieferungszustand. Selbst gehostete Schriften, keine externen Requests, kein Build-Schritt.
Version: 1.0.0
Requires at least: 6.0
Tested up to: 6.6
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: baupvo-io
Tags: klassisches-theme, dokumentation, datenmodell, barrierefrei, dunkelmodus
*/

/* ============================================================
   INHALT
   ------------------------------------------------------------
    1  Token
    2  Schriften (selbst gehostet)
    3  Grundsatz und Deutschsatz
    4  Fokus
    5  Kopfleiste
    6  Raster
    7  Panel und Überschriften
    8  Kopfband
    9  Spezifikationsbaum
   10  Feldtabelle
   11  Feldkarten-Panel
   12  Schema-Panel
   13  Rechtsanker-Zeile
   14  Prüfer
   15  Identifikator-Zerleger
   16  Geltungsraster
   17  Chips, Marker, Statuswörter
   18  Grafiken
   19  Formulare und Schaltflächen
   20  Beitrag, Archiv, Blätterleiste, 404
   21  Fuß
   22  Anzeige (eigener Namensraum)
   23  Bewegung
   24  Druck
   ============================================================ */


/* ============================================================
   1  TOKEN
   ------------------------------------------------------------
   Die vier Grundtoken je Modus (Grund, Lesetext, Sekundaer, Akzent)
   sind netzweit zentral vergeben und duerfen NICHT geaendert
   werden. Alles Uebrige ist daraus abgeleitet und GEGEN SIE
   nachgerechnet — der Entwurf von baupvo-io-v2.json nannte noch
   die alte Palette (#0F151A / #EAF0F5 / #5CD0E6 …); jene Werte
   sind hier ueberall ersetzt, die Kontrastregeln des Entwurfs
   aber eingehalten. Die Kontrastzahl steht bei dem Token, fuer
   das sie gilt, damit eine Aenderung sofort zeigt, was sie kostet.

   Warum ueberhaupt abgeleitete Flaechen noetig sind: die Seite
   trennt ausschliesslich ueber Kanten. Eine Kante braucht eine
   Flaeche, auf der sie liegt, und ein vertieftes Codefeld braucht
   einen eigenen Grund — sonst waere jeder Codeblock nur ein
   Absatz mit Monoschrift.
   ============================================================ */

:root {
	/* --- Dunkel ist der ausgelieferte Standard. ---
	   Die :root-Werte SIND die Dunkelwerte; der Hellmodus schaltet
	   sie um. So kommt die Seite auch dann dunkel an, wenn das
	   Umschalt-Skript ausfaellt — der Auslieferungszustand haengt
	   nicht an JavaScript. */

	/* Vorgegeben, netzweit vergeben. */
	--io-grund:   #0C1014;
	--io-text:    #8EA0A2;  /* 6,94:1 auf Grund · 6,38:1 auf Panel · 7,20:1 auf Codeflaeche */
	--io-meta:    #6C8B8E;  /* 5,21:1 auf Grund · 4,79:1 auf Panel */
	--io-akzent:  #3D8E95;  /* 5,01:1 auf Grund · 4,61:1 auf Panel · 5,20:1 auf Codeflaeche */

	/* Abgeleitet — Flaechen. Der Unterschied zum Grund ist
	   AUSDRUECKLICH DEKORATIV (1,09:1 Panel, 1,04:1 Code,
	   1,09:1 Chip) und wird nirgends als Signal behauptet.
	   Getragen wird jede Trennung von der Kante. */
	--io-panel:   #141A20;
	--io-code:    #070A0D;
	--io-chip:    #1A2228;
	--io-hover:   #1B2329;  /* dekorativ, nie allein tragend */
	--io-tint:    #10262B;  /* Zeilenauswahl, dekorativ, nie allein tragend */

	/* Abgeleitet — Kante. Tragendes Trennmittel, deshalb bewusst
	   ueber 3:1 gegen JEDE Flaeche der Seite:
	   3,87:1 Grund · 3,56:1 Panel · 4,02:1 Code · 3,26:1 Chip. */
	--io-kante:   #5E7383;

	/* Abgeleitet — Zustandsflaechen. */
	--io-aktiv:        #2E757D; /* 3,60:1 gegen Grund, 3,31:1 gegen Panel (SC 1.4.11) */
	--io-auf-aktiv:    #FFFFFF; /* 5,31:1 auf der aktiven Flaeche */
	--io-primaer:      #3D8E95; /* = Akzent */
	--io-auf-primaer:  #0C1014; /* 5,01:1 auf dem Primaerknopf */

	/* Status. In Graustufen sind diese Toene nahezu identisch
	   (SC 1.4.1), deshalb traegt jeder Status zusaetzlich ein
	   Wortlabel in Versalien, einen Formmarker und eine eigene
	   Textspalte in der Feldtabelle. */
	--io-status-ohne:      #5FD08A; /* 9,13:1 auf Panel */
	--io-status-abw:       #FF8B7E; /* 7,74:1 auf Panel */
	--io-status-ausleg:    #F2B441; /* 9,53:1 auf Panel */
	--io-status-entfallen: #8A98A4; /* 6,01:1 auf Panel */

	/* Fokus — eigener Token, kommt in KEINER anderen Rolle vor.
	   Ein Akzentring auf dem akzentgefuellten Primaerknopf waere
	   1,00:1 genau dort, wo der Fokus gebraucht wird. Die beiden
	   Ringfarben stehen zueinander bei 19,03:1; gegen jeden
	   Zustand der Seite traegt mindestens eine von beiden >= 3:1
	   (Grund dunkel 19,11 · Panel 17,58 · Code 19,84 · Chip 16,11 ·
	   aktive Flaeche 5,31 · Primaerknopf 4,99 · Grund hell 9,06 ·
	   Panel hell 11,00 · Code hell 8,14 · Chip hell 10,09 ·
	   Akzentflaeche hell 11,46). */
	--io-fokus-innen: #FFFFFF;
	--io-fokus-aussen: #08121A;

	/* Raster. Vertikale Einheit 4 px — jeder Abstand der Seite ist
	   ein Vielfaches davon, damit die Monozeilen der Ueberschriften
	   ueber Abschnittsgrenzen hinweg auf derselben Linie sitzen. */
	--io-e: 4px;
	--io-kopfleiste: 56px;
	--io-prosa: 34rem;      /* ca. 68 Zeichen */
	--io-container: 1584px;
	--io-schiene-links: 264px;
	--io-schiene-rechts: 304px;
	--io-rinne: 40px;

	color-scheme: dark;
}

/* Hellmodus. Getrennt gerechnet, nicht invertiert: jede
   Zustandsflaeche und jede Textfarbe auf Akzent hat einen eigenen
   Wert. Der Hellgrund #F2F5F8 ist deutlich dunkler als das Weiss
   des Entwurfs — alle abgeleiteten Werte sind deshalb neu
   bestimmt, insbesondere die Statusfarben (die hellen Werte des
   Entwurfs, etwa #14653A, lagen auf diesem Grund unter 4,5:1). */
:root[data-theme="hell"] {
	--io-grund:   #F2F5F8;
	--io-text:    #18282E;  /* 7,22:1 auf Grund · 8,77:1 auf Panel · 6,49:1 auf Codeflaeche */
	--io-meta:    #353A3B;  /* 5,46:1 auf Grund · 6,63:1 auf Panel */
	--io-akzent:  #084045;  /* 5,46:1 auf Grund · 6,63:1 auf Panel · 4,90:1 auf Codeflaeche */

	--io-panel:   #BCC7CD;  /* dekorativ 1,21:1 gegen Grund */
	--io-code:    #9DACB6;  /* dekorativ 1,35:1 gegen Panel */
	--io-chip:    #B2BEC5;  /* dekorativ 1,11:1 gegen Panel */
	--io-hover:   #B0BCC3;
	--io-tint:    #9FB4BB;

	--io-kante:   #46545F;  /* 3,71:1 Grund · 4,50:1 Panel · 3,33:1 Code · 4,13:1 Chip */

	--io-aktiv:       #084045; /* = Akzent, 5,46:1 gegen Grund */
	--io-auf-aktiv:   #FFFFFF; /* 11,46:1 */
	--io-primaer:     #084045;
	--io-auf-primaer: #FFFFFF; /* 11,46:1 */

	--io-status-ohne:      #0B4526; /* 6,15:1 Panel · 5,21:1 Grund */
	--io-status-abw:       #7A1710; /* 6,05:1 Panel · 5,12:1 Grund */
	--io-status-ausleg:    #5A3A00; /* 5,78:1 Panel · 4,89:1 Grund */
	--io-status-entfallen: #3B464E; /* 5,46:1 Panel · 4,62:1 Grund */

	color-scheme: light;
}

/* Systemwahl. Greift NUR, wenn der Umschalter auf "System" steht
   (data-theme="system"), damit eine ausdrueckliche Wahl die
   Systemeinstellung in BEIDE Richtungen ueberschreibt: wer dunkel
   waehlt, bekommt dunkel auch auf einem hell eingestellten
   Betriebssystem, und umgekehrt. */
@media (prefers-color-scheme: light) {
	:root[data-theme="system"] {
		--io-grund:   #F2F5F8;
		--io-text:    #18282E;
		--io-meta:    #353A3B;
		--io-akzent:  #084045;
		--io-panel:   #BCC7CD;
		--io-code:    #9DACB6;
		--io-chip:    #B2BEC5;
		--io-hover:   #B0BCC3;
		--io-tint:    #9FB4BB;
		--io-kante:   #46545F;
		--io-aktiv:       #084045;
		--io-auf-aktiv:   #FFFFFF;
		--io-primaer:     #084045;
		--io-auf-primaer: #FFFFFF;
		--io-status-ohne:      #0B4526;
		--io-status-abw:       #7A1710;
		--io-status-ausleg:    #5A3A00;
		--io-status-entfallen: #3B464E;
		color-scheme: light;
	}
}


/* ============================================================
   2  SCHRIFTEN — selbst gehostet, kein Fremdrequest
   ------------------------------------------------------------
   Kein Google-Fonts-CDN: eine Einbindung von fonts.gstatic.com
   uebertraegt die IP jedes Besuchers an einen Dritten und ist in
   Deutschland gerichtlich beanstandet worden. Die Dateien liegen
   unter /assets/fonts/ im Theme; welche noch zu beschaffen sind,
   steht in README.md.

   ROLLENVERTEILUNG (bewusste Umkehrung der Konvention):
   Ueberschriften und Tabellenkoepfe stehen in JetBrains Mono,
   der Fliesstext in Recursive Sans Linear. Dadurch stehen
   Abschnittsnummern ueber die ganze Seite exakt untereinander,
   und die Monoschrift traegt auf dieser Seite durchgehend
   Datenbedeutung: Feldpfade, Werte, Einheiten, Identifikatoren.
   Genau deshalb ist Mono im Anzeigenblock ausgeschlossen.

   font-display: swap — der Text ist ab dem ersten Frame lesbar;
   bei einer Nachschlageseite am zweiten Monitor waere ein
   unsichtbarer Textblock der schlechtere Tausch.
   ============================================================ */

/* --- Recursive Sans Linear (SIL OFL 1.1) — Fliesstext --- */
@font-face {
	font-family: "Recursive Sans Linear";
	src: url("assets/fonts/recursive-sans-linear-400-latin.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "Recursive Sans Linear";
	src: url("assets/fonts/recursive-sans-linear-400-latin-ext.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: "Recursive Sans Linear";
	src: url("assets/fonts/recursive-sans-linear-500-latin.woff2") format("woff2");
	font-weight: 500;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "Recursive Sans Linear";
	src: url("assets/fonts/recursive-sans-linear-500-latin-ext.woff2") format("woff2");
	font-weight: 500;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: "Recursive Sans Linear";
	src: url("assets/fonts/recursive-sans-linear-600-latin.woff2") format("woff2");
	font-weight: 600;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "Recursive Sans Linear";
	src: url("assets/fonts/recursive-sans-linear-600-latin-ext.woff2") format("woff2");
	font-weight: 600;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- JetBrains Mono 2.304 (SIL OFL 1.1) — Ueberschriften, Daten ---
   Die Lizenz ist versionsabhaengig: v1.x stand unter Apache 2.0.
   Ausgeliefert wird 2.304 unter OFL 1.1; die unveraenderte
   OFL.txt liegt neben den Dateien und ist im Impressum verlinkt.
   Der Zeichenvorrat enthaelt zusaetzlich U+00B5, U+00B0, U+202F
   und U+2032-2033, damit Einheiten, Grad- und Winkelzeichen
   nicht auf eine Systemschrift zurueckfallen — bei Messwerten
   waere ein Schriftwechsel mitten in der Einheit ein Lesefehler. */
@font-face {
	font-family: "JetBrains Mono";
	src: url("assets/fonts/jetbrains-mono-400-latin.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+00B0, U+00B5, U+0131, U+0152-0153, U+2000-206F, U+202F, U+2032-2033, U+20AC, U+2122, U+2190-2193, U+2212, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "JetBrains Mono";
	src: url("assets/fonts/jetbrains-mono-400-latin-ext.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-024F, U+1E00-1EFF, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: "JetBrains Mono";
	src: url("assets/fonts/jetbrains-mono-700-latin.woff2") format("woff2");
	font-weight: 700;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+00B0, U+00B5, U+0131, U+0152-0153, U+2000-206F, U+202F, U+2032-2033, U+20AC, U+2122, U+2190-2193, U+2212, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "JetBrains Mono";
	src: url("assets/fonts/jetbrains-mono-700-latin-ext.woff2") format("woff2");
	font-weight: 700;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-024F, U+1E00-1EFF, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: "JetBrains Mono";
	src: url("assets/fonts/jetbrains-mono-800-latin.woff2") format("woff2");
	font-weight: 800;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+00B0, U+00B5, U+0131, U+0152-0153, U+2000-206F, U+202F, U+2032-2033, U+20AC, U+2122, U+2190-2193, U+2212, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "JetBrains Mono";
	src: url("assets/fonts/jetbrains-mono-800-latin-ext.woff2") format("woff2");
	font-weight: 800;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-024F, U+1E00-1EFF, U+2C60-2C7F, U+A720-A7FF;
}

:root {
	--io-sans: "Recursive Sans Linear", "Segoe UI", Roboto, sans-serif;
	--io-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
}


/* ============================================================
   3  GRUNDSATZ UND DEUTSCHSATZ
   ------------------------------------------------------------
   Die Regeln dieses Blocks sind keine Kosmetik. Ein Feldpfad wie
   "dop.declaredPerformance[].essentialCharacteristic" muss
   umbrechen duerfen, eine Fundstelle wie "Art. 15 Abs. 2
   Buchst. c" darf es nicht — bricht sie um, entsteht eine
   Zeile, die auf eine andere Vorschrift zu zeigen scheint.
   ============================================================ */

*,
*::before,
*::after { box-sizing: border-box; }

html {
	font-size: 100%;              /* Basis 16 px, nie in px festgenagelt */
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body {
	margin: 0;
	background: var(--io-grund);
	color: var(--io-text);
	font-family: var(--io-sans);
	font-size: 1rem;              /* 16 px, auch auf dem Desktop — der
	                                 Desktopsatz ist nirgends kleiner als
	                                 der mobile */
	line-height: 1.625;           /* 26 px */
	font-weight: 400;
	/* Deutschsatz: lange Komposita wie
	   "Leistungsbestaendigkeitsbewertung" muessen trennen duerfen,
	   sonst reisst der 34-rem-Prosablock auf. */
	hyphens: auto;
	-webkit-hyphens: auto;
	hyphenate-limit-chars: 6 3 3;
	overflow-wrap: break-word;
	/* Zahlen in Tabellen, Statuszeilen UND im Fliesstext stehen
	   untereinander — eine Versionsnummer 1.3.2 neben 1.4.0 wird
	   sonst optisch unterschiedlich breit. */
	font-variant-numeric: tabular-nums lining-nums;
	text-underline-offset: 0.18em;
}

/* Der Seitenkoerper scrollt NIE horizontal. Breite Tabellen
   scrollen in ihrem eigenen Container (Abschnitt 10). */
html,
body { overflow-x: clip; max-width: 100%; }

img, svg, video { max-width: 100%; height: auto; }

a {
	color: var(--io-akzent);
	text-decoration: underline;
	text-decoration-thickness: 1px;
}
a:hover { text-decoration-thickness: 2px; }

h1, h2, h3, h4, h5, h6 {
	font-family: var(--io-mono);
	color: var(--io-text);
	margin: 0;
	hyphens: none;   /* Ueberschriften trennen nicht — die Monozeile
	                    soll ihre Zeichenzahl behalten */
}

h1 {
	font-size: 2rem;       /* 32/40 */
	line-height: 1.25;
	font-weight: 800;
	letter-spacing: -0.02em;
}

h2 {
	font-size: 1.375rem;   /* 22/30 */
	line-height: 1.3636;
	font-weight: 700;
	/* Die 2-px-Oberlinie ist die Panelkante, die den Abschnitt
	   traegt — kein Zierstrich. Sie ist der Grund, warum es auf
	   dieser Seite keine Balken und keine Haarlinien gibt. */
	border-top: 2px solid var(--io-kante);
	padding-top: calc(var(--io-e) * 3);
	margin-top: calc(var(--io-e) * 10);
	margin-bottom: calc(var(--io-e) * 4);
}

h3 {
	font-size: 1.125rem;   /* 18/26 */
	line-height: 1.4444;
	font-weight: 700;
	margin-top: calc(var(--io-e) * 7);
	margin-bottom: calc(var(--io-e) * 2);
}

h4 {
	font-size: 0.875rem;   /* 14/20 — Feldgruppen-Label */
	line-height: 1.4286;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--io-meta);
	margin-top: calc(var(--io-e) * 6);
	margin-bottom: calc(var(--io-e) * 2);
}

p { margin: 0 0 calc(var(--io-e) * 4); }

/* Prosa laeuft in JEDEM Band auf 34 rem — auch in den
   einspaltigen. Ohne diese Deckelung lief der Text in den
   Baendern 640-1279 px auf 124 bis 130 Zeichen aus. */
.io-prosa,
.io-prosa p,
.io-prosa ul,
.io-prosa ol,
.io-prosa dl { max-width: var(--io-prosa); }

.io-lead {
	font-size: 1.125rem;   /* 18/30 */
	line-height: 1.6667;
	max-width: var(--io-prosa);
}

.io-meta,
.io-fussnote {
	font-size: 0.875rem;   /* 14/22 */
	line-height: 1.5714;
	color: var(--io-meta);
}
.io-fussnote { font-size: 0.8125rem; line-height: 1.5385; } /* 13/20 */

/* Feldpfade, Werte, Einheiten, IDs, Datumsangaben.
   overflow-wrap ist hier ausdruecklich erlaubt: ein 60 Zeichen
   langer Pfad muss brechen duerfen, sonst sprengt er die Zelle. */
.io-pfad,
code, kbd, samp, pre {
	font-family: var(--io-mono);
	font-variant-ligatures: none;   /* -> und != duerfen in Daten
	                                   nicht zu einem Zeichen
	                                   verschmelzen */
}
.io-pfad {
	font-size: 0.875rem;
	overflow-wrap: anywhere;
	word-break: break-word;
	hyphens: none;
}
code { font-size: 0.94em; }

/* Fundstellen, Normbezeichnungen, Leistungsklassen. Diese Chips
   duerfen NICHT umbrechen: "EN 13501-1" in zwei Zeilen liest sich
   wie zwei Angaben, "A2-s1,d0" waere in zwei Zeilen falsch. */
.io-fundstelle,
.io-norm {
	white-space: nowrap;
	hyphens: none;
	font-variant-numeric: tabular-nums lining-nums;
}

/* Sprungmarke: erstes fokussierbares Element des Dokuments.
   Sie ist nicht versteckt, sondern nur aus dem Sichtfeld
   geschoben — Vorlesesoftware und Tastatur erreichen sie. */
.io-sprungmarke {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100;
	background: var(--io-panel);
	color: var(--io-text);
	border: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 4);
	font-family: var(--io-mono);
	font-size: 0.875rem;
	text-decoration: none;
}
.io-sprungmarke:focus {
	left: calc(var(--io-e) * 4);
	top: calc(var(--io-e) * 4);
}

/* Nur fuer Vorlesesoftware. */
.io-nur-sr {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Jedes Sprungziel muss unter der 56-px-Kopfleiste hervorkommen.
   72 px = 56 Kopfleiste + 16 Luft. */
:target,
[id] { scroll-margin-top: 72px; }


/* ============================================================
   4  FOKUS
   ------------------------------------------------------------
   Zweifarbiger Ring als box-shadow — als outline waere er zwar
   auch moeglich, aber box-shadow erlaubt zwei Ringe ohne einen
   zweiten Umriss und ohne Layoutsprung. 2 px Versatz laesst die
   Grundflaeche zwischen Element und Ring durchscheinen; damit
   bleibt der Ring auch auf einer akzentgefuellten Flaeche als
   Ring erkennbar.

   Der Fokus ist zusaetzlich formsichtbar: das fokussierte Panel
   schaltet seine Kante auf Akzent. Fokus ist damit nicht allein
   farbcodiert.
   ============================================================ */

:focus { outline: none; }

:focus-visible {
	outline: none;
	box-shadow:
		0 0 0 2px var(--io-grund),
		0 0 0 4px var(--io-fokus-innen),
		0 0 0 6px var(--io-fokus-aussen);
	border-radius: 0;   /* Radius 0 auf der ganzen Seite */
	position: relative;
	z-index: 3;
}

/* Auf Flaechen, die nicht der Seitengrund sind, muss der Versatz
   die jeweilige Flaeche zeigen, sonst entsteht ein Farbsprung. */
.io-panel :focus-visible,
.io-feldtabelle :focus-visible {
	box-shadow:
		0 0 0 2px var(--io-panel),
		0 0 0 4px var(--io-fokus-innen),
		0 0 0 6px var(--io-fokus-aussen);
}
.io-code :focus-visible,
.io-schema__flaeche :focus-visible {
	box-shadow:
		0 0 0 2px var(--io-code),
		0 0 0 4px var(--io-fokus-innen),
		0 0 0 6px var(--io-fokus-aussen);
}

.io-panel:focus-within { border-color: var(--io-akzent); }


/* ============================================================
   5  KOPFLEISTE
   ------------------------------------------------------------
   56 px hoch, sticky, mit Wortmarke, Navigation, Suchfeld,
   Versions-Badge und dem Modusumschalter. Sie ist der Grund fuer
   scroll-margin-top: 72px auf allen Ankern.
   ============================================================ */

.io-kopfleiste {
	position: sticky;
	top: 0;
	z-index: 20;
	min-height: var(--io-kopfleiste);
	background: var(--io-grund);
	border-bottom: 2px solid var(--io-kante);
}

.io-kopfleiste__innen {
	max-width: var(--io-container);
	margin: 0 auto;
	padding: 0 calc(var(--io-e) * 8);
	min-height: var(--io-kopfleiste);
	display: flex;
	align-items: center;
	gap: calc(var(--io-e) * 4);
	flex-wrap: wrap;
}

/* Wortmarke: durchgehend klein, JetBrains Mono ExtraBold,
   die TLD in Akzentfarbe. Kein Bild — eine Wortmarke als Grafik
   waere bei 400 % Zoom unscharf und bei abgeschalteten Bildern
   weg. */
.io-marke {
	font-family: var(--io-mono);
	font-weight: 800;
	font-size: 1rem;
	letter-spacing: -0.02em;
	text-transform: lowercase;
	text-decoration: none;
	color: var(--io-text);
	white-space: nowrap;
	padding: calc(var(--io-e) * 2) 0;
}
.io-marke__tld { color: var(--io-akzent); }
.io-marke:hover { text-decoration: underline; }

.io-hauptnav ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	gap: calc(var(--io-e) * 1);
	flex-wrap: wrap;
}
.io-hauptnav a {
	display: block;
	min-height: 44px;
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 3);
	font-family: var(--io-mono);
	font-size: 0.875rem;
	text-decoration: none;
	color: var(--io-text);
	border: 2px solid transparent;
}
.io-hauptnav a:hover {
	background: var(--io-hover);
	text-decoration: underline;
}
/* Die aktuelle Seite traegt aria-current="page". Sie wird NICHT
   allein durch die Flaeche kenntlich gemacht — die Flaeche liegt
   zwar bei 3,60:1 gegen den Grund und ist damit als Flaeche
   erkennbar (SC 1.4.11), traegt aber keine Bedeutung fuer
   jemanden mit Farbsinnstoerung. Deshalb zusaetzlich der
   gefuellte Marker davor. */
.io-hauptnav a[aria-current="page"] {
	background: var(--io-aktiv);
	color: var(--io-auf-aktiv);
	border-color: var(--io-kante);
}
.io-hauptnav a[aria-current="page"]::before {
	content: "\25A0\00A0";   /* gefuelltes Quadrat + geschuetztes Leerzeichen */
}

.io-kopfleiste__werkzeuge {
	margin-left: auto;
	display: flex;
	align-items: center;
	gap: calc(var(--io-e) * 2);
	flex-wrap: wrap;
}

.io-version-badge {
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	background: var(--io-chip);
	color: var(--io-text);
	border: 1px solid var(--io-kante);
	padding: calc(var(--io-e) * 1) calc(var(--io-e) * 2);
	white-space: nowrap;
}

/* Modusumschalter: drei Zustaende. Die Wahl liegt in
   localStorage und ueberschreibt prefers-color-scheme in beide
   Richtungen — deshalb drei Knoepfe und kein Zweiwegschalter:
   "System" muss ausdruecklich waehlbar bleiben. */
.io-modus {
	display: flex;
	border: 2px solid var(--io-kante);
}
.io-modus__knopf {
	min-width: 44px;
	min-height: 32px;
	padding: calc(var(--io-e) * 1) calc(var(--io-e) * 2);
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	background: transparent;
	color: var(--io-text);
	border: 0;
	border-left: 2px solid var(--io-kante);
	cursor: pointer;
}
.io-modus__knopf:first-child { border-left: 0; }
.io-modus__knopf[aria-pressed="true"] {
	background: var(--io-aktiv);
	color: var(--io-auf-aktiv);
}
/* Formsignal zusaetzlich zur Flaeche. */
.io-modus__knopf[aria-pressed="true"]::before { content: "\25A0\00A0"; }

/* Schalter fuer den Spezifikationsbaum, nur unter 1024 px sichtbar. */
.io-baumschalter {
	display: none;
	min-height: 32px;
	min-width: 44px;
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	background: var(--io-chip);
	color: var(--io-text);
	border: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 1) calc(var(--io-e) * 2);
	cursor: pointer;
}


/* ============================================================
   6  RASTER
   ------------------------------------------------------------
   Dreiteiliges Dokumentationsraster. Kein Hero, kein Bild ueber
   der Falz: die Seite beginnt mit einer Kante (dem Kopfband),
   nicht mit einer Textzeile.
   ============================================================ */

.io-huelle {
	max-width: var(--io-container);
	margin: 0 auto;
	padding: 0 calc(var(--io-e) * 8) calc(var(--io-e) * 16);
}

.io-raster {
	display: grid;
	grid-template-columns: var(--io-schiene-links) minmax(0, 1fr) var(--io-schiene-rechts);
	gap: var(--io-rinne);
	align-items: start;
	padding-top: calc(var(--io-e) * 6);
}

.io-inhalt { min-width: 0; }   /* ohne min-width:0 sprengt eine
                                  breite Tabelle die Rasterspalte,
                                  statt in ihrem Container zu
                                  scrollen */

.io-schiene {
	position: sticky;
	top: calc(var(--io-kopfleiste) + var(--io-e) * 4);
	max-height: calc(100vh - var(--io-kopfleiste) - var(--io-e) * 8);
	overflow-y: auto;
	/* Verhindert, dass der Seitenkoerper weiterscrollt, wenn die
	   Schiene am Ende ist — bei einer Nachschlagesitzung ist das
	   Wegrutschen des Baums der haeufigste Fehlgriff. */
	overscroll-behavior: contain;
	min-width: 0;
}

/* 1280-1599 px: Schienen schmaler, Inhalt fluid. */
@media (max-width: 1599px) {
	:root {
		--io-schiene-links: 248px;
		--io-schiene-rechts: 288px;
	}
}

/* 1024-1279 px: rechte Schiene entfaellt, das Feldkarten-Panel
   wandert als aufklappbares Panel unter die Tabelle. */
@media (max-width: 1279px) {
	.io-raster { grid-template-columns: var(--io-schiene-links) minmax(0, 1fr); }
	.io-schiene--rechts { display: none; }
	.io-feldkarte--unten { display: block; }
}

/* 640-1023 px: linke Schiene wird zur Schublade hinter dem
   Schalter in der Kopfleiste. */
@media (max-width: 1023px) {
	.io-raster { grid-template-columns: minmax(0, 1fr); }
	.io-baumschalter { display: inline-block; }
	.io-schiene--links {
		position: static;
		max-height: none;
		overflow: visible;
		display: none;
		margin-bottom: calc(var(--io-e) * 6);
	}
	.io-schiene--links[data-offen="ja"] { display: block; }
}

@media (max-width: 639px) {
	.io-huelle,
	.io-kopfleiste__innen { padding-left: calc(var(--io-e) * 4); padding-right: calc(var(--io-e) * 4); }
	h1 { font-size: 1.75rem; }
}


/* ============================================================
   7  PANEL UND UEBERSCHRIFTEN
   ------------------------------------------------------------
   Jeder redaktionelle Block ist ein GESCHLOSSENES Panel mit
   umlaufender 2-px-Kante und Radius 0. Diese Geometrie ist der
   Unterschied zum Anzeigenband, das nur oben und unten eine
   Kante hat — und sie bleibt in Graustufen und im Ausdruck
   erhalten.
   ============================================================ */

.io-panel {
	background: var(--io-panel);
	border: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 6);
	margin-bottom: calc(var(--io-e) * 6);
}
.io-panel > :last-child { margin-bottom: 0; }
.io-panel h2:first-child { margin-top: 0; border-top: 0; padding-top: 0; }

.io-panel--vertieft {
	background: var(--io-code);
}

.io-panel__kopf {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: calc(var(--io-e) * 3);
	flex-wrap: wrap;
	margin-bottom: calc(var(--io-e) * 4);
}

/* Ankersymbol je Ueberschrift: 32 x 32 px Zielflaeche. */
.io-anker {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	color: var(--io-akzent);
	text-decoration: none;
	vertical-align: middle;
}
.io-anker svg { width: 20px; height: 20px; }


/* ============================================================
   8  KOPFBAND
   ------------------------------------------------------------
   Liegendes Panel aus vier bis fuenf durch 2-px-Kanten
   getrennten Zellen, ueber der H1. Die Seite beginnt damit mit
   einer Kante statt mit einer Textzeile — und die Statusangabe
   steht bewusst NICHT als Zeile unter der H1.
   ============================================================ */

.io-kopfband {
	border: 2px solid var(--io-kante);
	background: var(--io-panel);
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	margin-bottom: calc(var(--io-e) * 6);
}

.io-kopfband__zelle {
	border-left: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 4);
	min-height: 56px;
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: calc(var(--io-e) * 1);
}
.io-kopfband__zelle:first-child { border-left: 0; }

.io-kopfband__label {
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--io-meta);
}
.io-kopfband__wert {
	font-family: var(--io-mono);
	font-size: 0.875rem;
	color: var(--io-text);
}

/* Der Betreiberhinweis laeuft ueber die volle Breite unter den
   Zellen — er ist kein Datum unter vielen, sondern die
   Einschraenkung, unter der alles darueber steht. */
.io-kopfband__hinweis {
	grid-column: 1 / -1;
	border-top: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 4);
	font-size: 0.8125rem;
	line-height: 1.5385;
	color: var(--io-meta);
	max-width: none;
}

@media (max-width: 639px) {
	.io-kopfband { grid-template-columns: 1fr; }
	.io-kopfband__zelle { border-left: 0; border-top: 2px solid var(--io-kante); }
	.io-kopfband__zelle:first-child { border-top: 0; }
}


/* ============================================================
   9  SPEZIFIKATIONSBAUM (linke Schiene)
   ------------------------------------------------------------
   Dreistufig: Kapitel -> Feldgruppe -> Feld. Panelstapel mit
   Trefferzaehler und Statuswort.
   ============================================================ */

.io-baum {
	border: 2px solid var(--io-kante);
	background: var(--io-panel);
}
.io-baum__kopf {
	border-bottom: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 4);
}
.io-baum__titel {
	font-family: var(--io-mono);
	font-size: 0.875rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--io-meta);
	margin: 0 0 calc(var(--io-e) * 2);
}

.io-baum__gruppe { border-top: 2px solid var(--io-kante); }
.io-baum__gruppe:first-of-type { border-top: 0; }

.io-baum__kapitel {
	font-family: var(--io-mono);
	font-size: 0.875rem;
	font-weight: 700;
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 4);
	margin: 0;
	display: flex;
	justify-content: space-between;
	gap: calc(var(--io-e) * 2);
	color: var(--io-text);
	text-transform: none;
	letter-spacing: 0;
	border-bottom: 2px solid var(--io-kante);
}
.io-baum__zaehler {
	font-size: 0.8125rem;
	color: var(--io-meta);
	font-weight: 400;
}

.io-baum ul { list-style: none; margin: 0; padding: 0; }

.io-baum a {
	display: block;
	min-height: 44px;
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 4);
	font-size: 0.875rem;
	line-height: 1.4286;
	color: var(--io-text);
	text-decoration: none;
	border-bottom: 2px solid var(--io-kante);
}
.io-baum li:last-child > a { border-bottom: 0; }
.io-baum a:hover { background: var(--io-hover); text-decoration: underline; }

.io-baum a[aria-current="true"] {
	background: var(--io-aktiv);
	color: var(--io-auf-aktiv);
}
.io-baum a[aria-current="true"]::before { content: "\25A0\00A0"; }

.io-baum__feld {
	padding-left: calc(var(--io-e) * 8);
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	overflow-wrap: anywhere;
}

/* Volltextsuche des Baums. Feldpfade werden hoeher gewichtet;
   die Gewichtung selbst steckt in assets/js/baum.js. */
.io-baum__suche { padding: calc(var(--io-e) * 3) calc(var(--io-e) * 4); }
.io-baum__treffer {
	font-size: 0.8125rem;
	color: var(--io-meta);
	padding: 0 calc(var(--io-e) * 4) calc(var(--io-e) * 3);
}


/* ============================================================
   10  FELDTABELLE — der Kernbaustein
   ------------------------------------------------------------
   Ein Gitter aus ZUSAMMENFALLENDEN 2-px-Kanten (border-collapse).
   Kein Zebra, keine Haarlinien, keine vertikalen Zierlinien.
   Die Dichte entsteht aus der 44-px-Zeile und dem Kantengitter,
   nicht aus einem kleinen Schriftgrad.

   WARUM DER SCROLLCONTAINER IN JEDEM BAND STEHT UND NICHT ERST
   AUF DEM TELEFON: Sieben Spalten brauchen bei 14-px-Satz
   rechnerisch mehr als die 936 px des Inhaltsbereichs. Ohne
   eigenen Scrollcontainer wuerde der Seitenkoerper horizontal
   scrollen — das ist der Fehler, den die Seite nie machen darf.
   Der Container ist tabindex="0" und role="region" mit Namen,
   damit er per Tastatur erreichbar und scrollbar ist.
   ============================================================ */

.io-tabellenrahmen {
	position: relative;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	border: 2px solid var(--io-kante);
	background: var(--io-panel);
	margin-bottom: calc(var(--io-e) * 2);
	/* Schattenkante: zeigt an, dass rechts noch etwas liegt.
	   Sie ist Beiwerk — die Scrollbarkeit selbst steht als Text
	   in der Legende darunter, nicht nur in diesem Schatten. */
	background-image:
		linear-gradient(to right, var(--io-panel), rgba(0, 0, 0, 0) 24px),
		linear-gradient(to left, var(--io-panel), rgba(0, 0, 0, 0) 24px),
		linear-gradient(to right, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0)),
		linear-gradient(to left, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0));
	background-position: 0 0, 100% 0, 0 0, 100% 0;
	background-repeat: no-repeat;
	background-size: 32px 100%, 32px 100%, 12px 100%, 12px 100%;
	background-attachment: local, local, scroll, scroll;
}

.io-feldtabelle {
	border-collapse: collapse;
	width: 100%;
	min-width: 1040px;      /* die rechnerische Mindestbreite der
	                           sieben Spalten bei 14 px */
	font-size: 0.875rem;
	line-height: 1.4286;
	font-variant-numeric: tabular-nums lining-nums;
}

.io-feldtabelle caption {
	text-align: left;
	font-size: 0.8125rem;
	color: var(--io-meta);
	padding: calc(var(--io-e) * 2) calc(var(--io-e) * 3);
	border-bottom: 2px solid var(--io-kante);
	position: sticky;
	left: 0;
}

.io-feldtabelle th,
.io-feldtabelle td {
	border: 2px solid var(--io-kante);
	padding: 10px 12px;
	text-align: left;
	vertical-align: top;
}

/* DIE EINE AUSNAHME VON DER REGEL "min-height, nie height":
   Auf einer Tabellenzeile wirkt `height` nach CSS-Tabellenmodell
   als MINDESTHOEHE — die Zeile waechst, sobald der Inhalt mehr
   braucht. `min-height` dagegen wird auf table-row schlicht
   ignoriert. Hier ist `height` also die einzige Schreibweise, die
   das Gewuenschte tut: 44 px Grundzeile, und "Werkseigene
   Produktionskontrolle" darf trotzdem zweizeilig umbrechen, ohne
   das Raster zu sprengen. */
.io-feldtabelle tr { height: 44px; }

.io-feldtabelle thead th {
	font-family: var(--io-mono);
	font-size: 0.875rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--io-text);
	background: var(--io-chip);
	position: sticky;
	top: 0;
	z-index: 2;
	white-space: nowrap;
}

/* Sticky erste Spalte: der Feldpfad ist der Schluessel jeder
   Zeile. Scrollt er weg, weiss niemand mehr, wozu die Werte
   rechts gehoeren. */
.io-feldtabelle .io-sp-pfad {
	position: sticky;
	left: 0;
	z-index: 1;
	background: var(--io-panel);
	min-width: 260px;
	max-width: 320px;
}
.io-feldtabelle thead .io-sp-pfad {
	z-index: 3;
	background: var(--io-chip);
}

.io-feldtabelle tbody tr:hover td { background: var(--io-hover); }
.io-feldtabelle tbody tr:hover .io-sp-pfad { background: var(--io-hover); }

/* Zeilenauswahl: der Tint allein traegt nichts (1,17:1). Deshalb
   IMMER zusaetzlich die Akzentkante links und der gefuellte
   Marker in der Pfadzelle. */
.io-feldtabelle tbody tr[data-gewaehlt="ja"] td { background: var(--io-tint); }
.io-feldtabelle tbody tr[data-gewaehlt="ja"] .io-sp-pfad {
	background: var(--io-tint);
	box-shadow: inset 4px 0 0 0 var(--io-akzent);
}
.io-feldtabelle tbody tr[data-gewaehlt="ja"] .io-sp-pfad .io-pfad::before {
	content: "\25A0\00A0";
	color: var(--io-akzent);
}

.io-sp-typ,
.io-sp-kard { font-family: var(--io-mono); white-space: nowrap; }
.io-sp-kard { text-align: right; }
.io-sp-pflicht { font-family: var(--io-mono); white-space: nowrap; }

.io-sp-anker {
	width: 44px;
	text-align: center;
	padding: calc(var(--io-e) * 1);
}

/* Versionsvermerk in derselben Zeile, aufklappbar — statt einer
   zweispaltigen Synopse. Die Synopse gehoert der Schwesterseite
   bauproduktenverordnung.io; hier steht die Aenderung als Text
   in der Statusspalte. */
.io-aenderung {
	display: block;
	margin-top: calc(var(--io-e) * 1);
	font-size: 0.8125rem;
	color: var(--io-meta);
}
.io-aenderung > summary {
	cursor: pointer;
	font-family: var(--io-mono);
	white-space: nowrap;
}
.io-aenderung__paar {
	margin: calc(var(--io-e) * 2) 0 0;
	display: grid;
	gap: calc(var(--io-e) * 1);
	font-family: var(--io-mono);
	font-size: 0.8125rem;
}
.io-aenderung__paar dt {
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--io-meta);
}
.io-aenderung__paar dd { margin: 0 0 calc(var(--io-e) * 2); overflow-wrap: anywhere; }

/* Umschalter Tabelle <-> Panelansicht. Unter 640 px ist die
   Panelansicht die brauchbarere Darstellung; der Umschalter
   steht aber in jedem Band, weil auch am zweiten Monitor
   jemand lieber ein Feld je Panel liest. */
.io-tabellenwerkzeuge {
	display: flex;
	gap: calc(var(--io-e) * 2);
	align-items: center;
	flex-wrap: wrap;
	margin-bottom: calc(var(--io-e) * 3);
}

.io-feldpanels { display: none; }
.io-feldtabellenblock[data-ansicht="panels"] .io-feldpanels { display: block; }
.io-feldtabellenblock[data-ansicht="panels"] .io-tabellenrahmen { display: none; }

.io-feldpanel {
	border: 2px solid var(--io-kante);
	background: var(--io-panel);
	margin-bottom: calc(var(--io-e) * 3);
}
.io-feldpanel__kopf {
	border-bottom: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 3);
	font-family: var(--io-mono);
	font-size: 0.875rem;
	overflow-wrap: anywhere;
}
.io-feldpanel dl {
	margin: 0;
	display: grid;
	grid-template-columns: minmax(120px, 40%) 1fr;
}
.io-feldpanel dt,
.io-feldpanel dd {
	margin: 0;
	padding: 10px 12px;
	border-top: 2px solid var(--io-kante);
	font-size: 0.875rem;
	min-height: 44px;
}
.io-feldpanel dt {
	font-family: var(--io-mono);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	font-size: 0.8125rem;
	color: var(--io-meta);
	border-right: 2px solid var(--io-kante);
}


/* ============================================================
   11  FELDKARTEN-PANEL (rechte Schiene)
   ------------------------------------------------------------
   Ersetzt "Auf dieser Seite". Zeigt dauerhaft das gerade
   angesteuerte Feld vollstaendig und folgt der Tastaturnavigation
   in der Tabelle; die Ankuendigung laeuft ueber aria-live.
   ============================================================ */

.io-feldkarte {
	border: 2px solid var(--io-kante);
	background: var(--io-panel);
}
.io-feldkarte__kopf {
	border-bottom: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 4);
	font-family: var(--io-mono);
	font-size: 0.875rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--io-meta);
}
.io-feldkarte__leer,
.io-feldkarte__koerper { padding: calc(var(--io-e) * 4); }
.io-feldkarte__leer { font-size: 0.875rem; color: var(--io-meta); }

.io-feldkarte dl { margin: 0; }
.io-feldkarte dt {
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--io-meta);
	margin-top: calc(var(--io-e) * 3);
}
.io-feldkarte dt:first-child { margin-top: 0; }
.io-feldkarte dd {
	margin: calc(var(--io-e) * 1) 0 0;
	font-size: 0.875rem;
	line-height: 1.5;
	overflow-wrap: anywhere;
}

.io-feldkarte__pfad {
	display: block;
	font-family: var(--io-mono);
	font-size: 0.875rem;
	background: var(--io-code);
	border: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 2) calc(var(--io-e) * 3);
	overflow-wrap: anywhere;
}

.io-feldkarte--unten { display: none; margin-top: calc(var(--io-e) * 6); }
@media (max-width: 1279px) {
	.io-feldkarte--unten { display: block; }
}

/* Die RECHTE Schiene ist selbst NICHT sticky — nur die Feldkarte darin.
   Grund: unter der Karte liegt der Anzeigenplatz A, und eine Anzeige
   darf nie mitscrollen. Waere die ganze Schiene sticky, klebte sie mit.
   So bleibt die Karte am Fokus und das Anzeigenband bleibt, wo es im
   Dokument steht. */
.io-schiene--rechts {
	position: static;
	max-height: none;
	overflow: visible;
}
.io-schiene--rechts .io-feldkarte {
	position: sticky;
	top: calc(var(--io-kopfleiste) + var(--io-e) * 4);
	max-height: calc(100vh - var(--io-kopfleiste) - var(--io-e) * 8);
	overflow-y: auto;
	overscroll-behavior: contain;
}


/* ============================================================
   12  SCHEMA-PANEL
   ------------------------------------------------------------
   Derselbe Datensatz in vier Ansichten. Die Ansichtswahl bleibt
   seitenuebergreifend erhalten (localStorage) — wer in JSON
   arbeitet, will nicht auf jeder Seite neu umschalten.
   ============================================================ */

.io-schema { border: 2px solid var(--io-kante); background: var(--io-panel); margin-bottom: calc(var(--io-e) * 6); }

.io-schema__leiste {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: calc(var(--io-e) * 2);
	padding: calc(var(--io-e) * 3);
	border-bottom: 2px solid var(--io-kante);
}

.io-schema__reiter { display: flex; border: 2px solid var(--io-kante); }
.io-schema__reiter button {
	min-height: 32px;
	min-width: 44px;
	padding: calc(var(--io-e) * 1) calc(var(--io-e) * 3);
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	background: transparent;
	color: var(--io-text);
	border: 0;
	border-left: 2px solid var(--io-kante);
	cursor: pointer;
}
.io-schema__reiter button:first-child { border-left: 0; }
.io-schema__reiter button[aria-selected="true"] {
	background: var(--io-aktiv);
	color: var(--io-auf-aktiv);
}
.io-schema__reiter button[aria-selected="true"]::before { content: "\25A0\00A0"; }

.io-schema__flaeche { background: var(--io-code); }
.io-schema__flaeche[hidden] { display: none; }

/* Codeblock mit Zeilennummern. Die Nummern stehen als eigene
   Spalte statt als ::before-Inhalt, damit sie beim Kopieren
   NICHT mitgehen — ein Schema mit Zeilennummern im Editor ist
   unbrauchbar. */
.io-code {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	background: var(--io-code);
	overflow-x: auto;
	max-height: 32rem;
	overscroll-behavior: contain;
}
.io-code__nummern {
	margin: 0;
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 2);
	border-right: 2px solid var(--io-kante);
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	line-height: 1.5714;
	color: var(--io-meta);
	text-align: right;
	white-space: pre;
	user-select: none;
	font-variant-numeric: tabular-nums lining-nums;
}
.io-code__text {
	margin: 0;
	padding: calc(var(--io-e) * 3);
	font-family: var(--io-mono);
	font-size: 0.875rem;
	line-height: 1.5714;
	color: var(--io-text);
	white-space: pre;
	tab-size: 2;
}

.io-schema__fuss {
	border-top: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 3);
	font-size: 0.8125rem;
	color: var(--io-meta);
	display: flex;
	flex-wrap: wrap;
	gap: calc(var(--io-e) * 3);
	align-items: center;
}
.io-schema__pruefsumme { font-family: var(--io-mono); overflow-wrap: anywhere; }


/* ============================================================
   13  RECHTSANKER-ZEILE
   ------------------------------------------------------------
   Einzeilige Herkunftsangabe unter jeder Feldgruppe. Sie ist der
   einzige Ort, an dem diese Seite auf den Verordnungstext zeigt
   — erklaert wird er hier nie, dafuer gibt es
   bauproduktenverordnung.io.
   ============================================================ */

.io-rechtsanker {
	border: 2px solid var(--io-kante);
	background: var(--io-panel);
	padding: calc(var(--io-e) * 3) calc(var(--io-e) * 4);
	font-size: 0.875rem;
	line-height: 1.5714;
	margin-bottom: calc(var(--io-e) * 6);
	display: flex;
	flex-wrap: wrap;
	gap: calc(var(--io-e) * 2) calc(var(--io-e) * 4);
	align-items: baseline;
}
.io-rechtsanker__label {
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--io-meta);
	white-space: nowrap;
}
.io-rechtsanker__vorgaenger { color: var(--io-meta); }

/* Der Vermerk fuer Aussagen OHNE Rechtsanker. Er ist bewusst
   auffaellig gesetzt: eine Festlegung des Betreibers darf nicht
   wie eine Rechtspflicht aussehen. */
.io-ausleg-vermerk {
	display: inline-block;
	font-family: var(--io-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--io-status-ausleg);
	border: 1px solid var(--io-kante);
	background: var(--io-chip);
	padding: 2px calc(var(--io-e) * 2);
	white-space: nowrap;
}


/* ============================================================
   14  PRUEFER
   ------------------------------------------------------------
   Ergebnis ist eine BEFUNDLISTE, kein Konformitaetsurteil. Die
   Drop-Zone ist der EINZIGE Ort der Seite mit gestrichelter
   Umrandung — gestrichelt ist damit exklusiv als Ablage-Idiom
   belegt und fuer Anzeigen gesperrt.
   ============================================================ */

.io-pruefer { border: 2px solid var(--io-kante); background: var(--io-panel); margin-bottom: calc(var(--io-e) * 6); }
.io-pruefer__kopf { border-bottom: 2px solid var(--io-kante); padding: calc(var(--io-e) * 4); }
.io-pruefer__koerper { padding: calc(var(--io-e) * 4); }

.io-ablage {
	border: 2px dashed var(--io-kante);
	background: var(--io-code);
	padding: calc(var(--io-e) * 6);
	text-align: center;
	min-height: 120px;
}
.io-ablage[data-ueber="ja"] { border-color: var(--io-akzent); background: var(--io-tint); }

.io-pruefer textarea {
	width: 100%;
	min-height: 12rem;
	font-family: var(--io-mono);
	font-size: 0.875rem;
	line-height: 1.5714;
	background: var(--io-code);
	color: var(--io-text);
	border: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 3);
	resize: vertical;
}

.io-befund { border-collapse: collapse; width: 100%; font-size: 0.875rem; margin-top: calc(var(--io-e) * 4); }
.io-befund th,
.io-befund td { border: 2px solid var(--io-kante); padding: 10px 12px; text-align: left; vertical-align: top; }
.io-befund thead th {
	font-family: var(--io-mono);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	background: var(--io-chip);
}

.io-pruefergebnis {
	font-family: var(--io-mono);
	font-size: 0.875rem;
	border: 2px solid var(--io-kante);
	background: var(--io-chip);
	padding: calc(var(--io-e) * 3);
	margin-top: calc(var(--io-e) * 4);
}


/* ============================================================
   15  IDENTIFIKATOR-ZERLEGER
   ============================================================ */

.io-zerleger { border: 2px solid var(--io-kante); background: var(--io-panel); margin-bottom: calc(var(--io-e) * 6); }
.io-zerleger__koerper { padding: calc(var(--io-e) * 4); }

.io-segmente { display: flex; flex-wrap: wrap; gap: 0; margin: calc(var(--io-e) * 4) 0 0; padding: 0; list-style: none; }
.io-segment {
	border: 2px solid var(--io-kante);
	margin: 0 -2px -2px 0;   /* Kanten fallen zusammen, wie in der
	                            Feldtabelle */
	padding: calc(var(--io-e) * 2) calc(var(--io-e) * 3);
	min-width: 120px;
	background: var(--io-panel);
}
.io-segment__wert {
	display: block;
	font-family: var(--io-mono);
	font-size: 0.875rem;
	overflow-wrap: anywhere;
}
.io-segment__label {
	display: block;
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--io-meta);
	margin-bottom: calc(var(--io-e) * 1);
}

/* Traegerdarstellung: schwarz auf weiss AUCH im Dunkelmodus.
   Scanbarkeit haengt am Kontrast; ein invertierter Datenmatrix-
   Code waere fuer viele Lesegeraete unlesbar und als Muster
   irrefuehrend. Deshalb feste Farben und 8 px Innenabstand. */
.io-traeger {
	background: #FFFFFF;
	padding: 8px;
	border: 2px solid var(--io-kante);
	display: inline-block;
	margin-top: calc(var(--io-e) * 4);
}
.io-traeger svg { display: block; color: #000000; }


/* ============================================================
   16  GELTUNGSRASTER
   ------------------------------------------------------------
   Datumsmatrix statt erzaehlender Zeitleiste. JEDE Zelle nennt
   ihr Datum als Text; keine Zelle wird allein durch Einfaerbung
   unterschieden.
   ============================================================ */

.io-geltung { border-collapse: collapse; width: 100%; font-size: 0.875rem; }
.io-geltung caption {
	text-align: left;
	font-size: 0.8125rem;
	color: var(--io-meta);
	padding: calc(var(--io-e) * 2) calc(var(--io-e) * 3);
}
.io-geltung th,
.io-geltung td {
	border: 2px solid var(--io-kante);
	padding: 10px 12px;
	text-align: left;
	vertical-align: top;
	min-height: 44px;
}
.io-geltung thead th,
.io-geltung tbody th {
	font-family: var(--io-mono);
	font-weight: 700;
	background: var(--io-chip);
}
.io-geltung thead th { text-transform: uppercase; letter-spacing: 0.06em; }
.io-geltung td { font-family: var(--io-mono); white-space: nowrap; }


/* ============================================================
   17  CHIPS, MARKER, STATUSWOERTER
   ------------------------------------------------------------
   SC 1.4.1: Die Statustoene sind in Graustufen praktisch
   identisch (1,18:1 dunkel). Jeder Status traegt deshalb
   ZWINGEND drei Traeger: Wortlabel in Versalien, Formmarker und
   eine eigene Textspalte in der Feldtabelle. Die Farbe ist der
   vierte, nicht der erste Traeger.
   ============================================================ */

.io-chip {
	display: inline-block;
	background: var(--io-chip);
	border: 1px solid var(--io-kante);
	padding: 2px calc(var(--io-e) * 2);
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	white-space: nowrap;
}

.io-status {
	display: inline-flex;
	align-items: baseline;
	gap: calc(var(--io-e) * 2);
	font-family: var(--io-sans);
	font-weight: 600;
	font-size: 0.8125rem;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	white-space: nowrap;
}
.io-status__marker {
	display: inline-block;
	width: 10px;
	height: 10px;
	border: 2px solid currentColor;
	flex: none;
}

/* Vier unterscheidbare FORMEN, nicht vier Farben:
   gefuellt / halbgefuellt / offen / durchgestrichen. */
.io-status--pflicht     { color: var(--io-status-ohne); }
.io-status--pflicht .io-status__marker { background: currentColor; }

.io-status--optional    { color: var(--io-status-entfallen); }
.io-status--optional .io-status__marker {
	background: linear-gradient(135deg, currentColor 0 50%, transparent 50% 100%);
}

.io-status--ausleg      { color: var(--io-status-ausleg); }
.io-status--ausleg .io-status__marker { background: transparent; }

.io-status--abweichung  { color: var(--io-status-abw); }
.io-status--abweichung .io-status__marker {
	background: linear-gradient(to bottom right,
		transparent calc(50% - 1px), currentColor calc(50% - 1px),
		currentColor calc(50% + 1px), transparent calc(50% + 1px));
}

.io-status--entfallen   { color: var(--io-status-entfallen); text-decoration: line-through; }
.io-status--entfallen .io-status__marker {
	background: linear-gradient(to bottom right,
		transparent calc(50% - 1px), currentColor calc(50% - 1px),
		currentColor calc(50% + 1px), transparent calc(50% + 1px));
}


/* ============================================================
   18  GRAFIKEN
   ------------------------------------------------------------
   Alle Zeichnungen sind Inline-SVG mit <title> und <desc>,
   themefaehig ueber currentColor. Keine Fotografie, keine
   Verlaeufe, keine Schatten, keine Flaechen. Icons sind
   ausschliesslich funktional.
   ============================================================ */

.io-abbildung {
	border: 2px solid var(--io-kante);
	background: var(--io-panel);
	padding: calc(var(--io-e) * 4);
	margin: 0 0 calc(var(--io-e) * 6);
}
.io-abbildung svg {
	display: block;
	width: 100%;
	height: auto;
	color: var(--io-text);
}
.io-abbildung figcaption {
	font-size: 0.8125rem;
	line-height: 1.5385;
	color: var(--io-meta);
	margin-top: calc(var(--io-e) * 3);
	border-top: 2px solid var(--io-kante);
	padding-top: calc(var(--io-e) * 3);
}
.io-abbildung__nummer {
	font-family: var(--io-mono);
	font-weight: 700;
	color: var(--io-text);
}

/* Die Tabellenfassung unter einem komplexen Diagramm. Sie ist
   keine Zugabe, sondern die Textalternative fuer alles, was eine
   Zeichnung an Beziehungen zeigt und ein alt-Text nicht traegt. */
.io-abbildung__tabelle { margin-top: calc(var(--io-e) * 4); }
.io-abbildung__tabelle > summary {
	font-family: var(--io-mono);
	font-size: 0.875rem;
	cursor: pointer;
	min-height: 44px;
	display: flex;
	align-items: center;
}

.io-icon { width: 20px; height: 20px; stroke-width: 1.5; fill: none; stroke: currentColor; }


/* ============================================================
   19  FORMULARE UND SCHALTFLAECHEN
   ============================================================ */

input, select, textarea, button { font: inherit; color: inherit; }

.io-feld {
	background: var(--io-code);
	color: var(--io-text);
	border: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 2) calc(var(--io-e) * 3);
	min-height: 44px;
	width: 100%;
	font-family: var(--io-mono);
	font-size: 0.875rem;
}
.io-feld::placeholder { color: var(--io-meta); opacity: 1; }

.io-label {
	display: block;
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--io-meta);
	margin-bottom: calc(var(--io-e) * 1);
}

.io-knopf {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: calc(var(--io-e) * 2);
	min-height: 44px;
	min-width: 44px;
	padding: calc(var(--io-e) * 2) calc(var(--io-e) * 4);
	font-family: var(--io-mono);
	font-size: 0.875rem;
	background: var(--io-chip);
	color: var(--io-text);
	border: 2px solid var(--io-kante);
	cursor: pointer;
	text-decoration: none;
}
.io-knopf:hover { background: var(--io-hover); }
.io-knopf--primaer {
	background: var(--io-primaer);
	color: var(--io-auf-primaer);
	border-color: var(--io-kante);
}
.io-knopf--primaer:hover { background: var(--io-primaer); text-decoration: underline; }

/* Kopierschaltflaeche: 24 x 24 px ist die Untergrenze, hier
   32 x 32, weil sie in der Tabellenzeile neben dem Anker steht. */
.io-kopieren {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	background: transparent;
	border: 2px solid transparent;
	color: var(--io-akzent);
	cursor: pointer;
}
.io-kopieren:hover { border-color: var(--io-kante); background: var(--io-hover); }

.io-suchformular { display: flex; gap: 0; }
.io-suchformular .io-feld { border-right-width: 0; }
.io-suchformular .io-knopf { flex: none; }

/* In der Kopfleiste darf das Suchfeld nicht die Navigation
   verdraengen: es bekommt eine Obergrenze und darf schrumpfen.
   Ohne die Obergrenze zieht ein flex-Kind mit width:100% die
   gesamte Restbreite an sich. */
.io-suchfeld { flex: 0 1 auto; min-width: 0; }
.io-suchfeld .io-feld { width: 100%; max-width: 22ch; min-width: 8ch; }


/* ============================================================
   20  BEITRAG, ARCHIV, BLAETTERLEISTE, 404
   ============================================================ */

.io-eintrag {
	border: 2px solid var(--io-kante);
	background: var(--io-panel);
	padding: calc(var(--io-e) * 5);
	margin-bottom: calc(var(--io-e) * 4);
}
.io-eintrag h2 { border-top: 0; padding-top: 0; margin-top: 0; font-size: 1.125rem; }
.io-eintrag h2 a { text-decoration: none; }
.io-eintrag h2 a:hover { text-decoration: underline; }
.io-eintrag__meta {
	font-family: var(--io-mono);
	font-size: 0.8125rem;
	color: var(--io-meta);
	margin: calc(var(--io-e) * 2) 0 calc(var(--io-e) * 3);
	display: flex;
	flex-wrap: wrap;
	gap: calc(var(--io-e) * 3);
}

.io-blaetter { margin-top: calc(var(--io-e) * 6); }
.io-blaetter .nav-links,
.io-blaetter .page-numbers {
	font-family: var(--io-mono);
	font-size: 0.875rem;
}
.io-blaetter .nav-links { display: flex; flex-wrap: wrap; gap: calc(var(--io-e) * 2); }
.io-blaetter a.page-numbers,
.io-blaetter span.page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 0 calc(var(--io-e) * 2);
	border: 2px solid var(--io-kante);
	text-decoration: none;
	background: var(--io-panel);
}
.io-blaetter span.page-numbers.current {
	background: var(--io-aktiv);
	color: var(--io-auf-aktiv);
}
.io-blaetter span.page-numbers.current::before { content: "\25A0\00A0"; }

.io-inhalt ul,
.io-inhalt ol { padding-left: calc(var(--io-e) * 6); }
.io-inhalt li { margin-bottom: calc(var(--io-e) * 2); }

.io-inhalt blockquote {
	border-left: 2px solid var(--io-kante);
	margin: 0 0 calc(var(--io-e) * 4);
	padding-left: calc(var(--io-e) * 4);
	max-width: var(--io-prosa);
}

.io-inhalt table {
	border-collapse: collapse;
	width: 100%;
	font-size: 0.875rem;
	font-variant-numeric: tabular-nums lining-nums;
}
.io-inhalt th,
.io-inhalt td {
	border: 2px solid var(--io-kante);
	padding: 10px 12px;
	text-align: left;
	vertical-align: top;
}
.io-inhalt thead th {
	font-family: var(--io-mono);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	background: var(--io-chip);
}

.io-inhalt pre {
	background: var(--io-code);
	border: 2px solid var(--io-kante);
	padding: calc(var(--io-e) * 4);
	overflow-x: auto;
	font-size: 0.875rem;
	line-height: 1.5714;
}


/* ============================================================
   21  FUSS
   ------------------------------------------------------------
   Die Impressumszeile steht UNGEKUERZT auf jeder Seite. Sie ist
   kein Kleingedrucktes: die Betreiberangabe und die nach
   § 18 Abs. 2 MStV verantwortliche Person stehen im selben
   Schriftgrad wie jede andere Fussnote der Seite (13 px, der
   kleinste Grad der ganzen Seite) und in Lesetextfarbe, nicht
   ausgegraut.
   ============================================================ */

.io-fuss {
	border-top: 2px solid var(--io-kante);
	background: var(--io-grund);
	margin-top: calc(var(--io-e) * 12);
}
.io-fuss__innen {
	max-width: var(--io-container);
	margin: 0 auto;
	padding: calc(var(--io-e) * 8);
}

.io-fuss__raster {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: calc(var(--io-e) * 6);
	margin-bottom: calc(var(--io-e) * 6);
}
.io-fuss h2 {
	font-size: 0.875rem;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--io-meta);
	border-top: 0;
	padding-top: 0;
	margin: 0 0 calc(var(--io-e) * 3);
}
.io-fuss ul { list-style: none; margin: 0; padding: 0; }
.io-fuss li { margin-bottom: calc(var(--io-e) * 2); }
.io-fuss a { color: var(--io-akzent); }

.io-impressumszeile {
	border-top: 2px solid var(--io-kante);
	padding-top: calc(var(--io-e) * 4);
	font-size: 0.8125rem;
	line-height: 1.5385;
	color: var(--io-text);
}
.io-impressumszeile p { margin: 0 0 calc(var(--io-e) * 2); max-width: 60rem; }
.io-impressumszeile p:last-child { margin-bottom: 0; }
.io-impressumszeile__hinweis { color: var(--io-meta); }


/* ============================================================
   22  ANZEIGE — eigener Namensraum, kein Panel
   ------------------------------------------------------------
   WAS DIE TRENNUNG TRAEGT, EHRLICH BEZIFFERT:
   (1) GEOMETRIE. Jeder redaktionelle Block ist ein geschlossenes
       Panel mit umlaufender 2-px-Kante. Die Anzeige ist ein
       OFFENES BAND: 2-px-Kante nur oben und unten, KEINE
       Seitenkanten. Diese Unterscheidung bleibt in Graustufen
       und im Ausdruck erhalten.
   (2) DIE KANTEN SELBST. Durchgezogen 2 px, 3,71:1 hell bzw.
       3,87:1 dunkel gegen den Grund. Gestrichelt ist
       ausgeschlossen: gestrichelt gehoert der Drop-Zone des
       Pruefers.
   (3) TEXTLABEL "ANZEIGE" als erstes Element INNERHALB des
       Bandes, ueber die volle Bandbreite, mit eigener 2-px-Kante
       darunter. Ausdruecklich NICHT in JetBrains Mono — Mono
       traegt auf dieser Seite Datenbedeutung.
   (4) SCHLUSSZEILE unter dem Motiv, netzweit wortgleich.

   AUSDRUECKLICH NICHT BEHAUPTET: dass der FLAECHENTON trennt.
   Panel gegen Grund liegt bei 1,21:1 hell und 1,09:1 dunkel;
   dieser Unterschied ist messbar wirkungslos und wird deshalb
   nicht als Signal gefuehrt. Die Anzeige liegt auf dem Grund —
   das ist Beiwerk, nicht Kennzeichnung.

   AUSGESCHLOSSEN IM BLOCK: Akzentfarbe, Statusfarben, Chips,
   Badges, Kopier- und Ankersymbole, Mono, Feldpfad-Optik,
   Abbildungsnummern, Quellenzeilen.
   ============================================================ */

.anzeige {
	border-top: 2px solid var(--io-kante);
	border-bottom: 2px solid var(--io-kante);
	border-left: 0;
	border-right: 0;
	background: transparent;   /* liegt auf dem Grund, ohne eigene Flaeche */
	padding: 0;
}

.anzeige--platz-a { margin-top: 48px; }

.anzeige--platz-b {
	margin-top: 40px;
	margin-bottom: 40px;
	min-height: 120px;
}

.anzeige__label {
	display: block;
	border-bottom: 2px solid var(--io-kante);
	padding: 6px 0;
	font-family: var(--io-sans);
	font-weight: 700;
	font-size: 0.8125rem;    /* 13 px, kleinster Grad der Seite */
	line-height: 1.5385;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--io-meta);   /* 5,21:1 dunkel / 5,46:1 hell gegen Grund */
}

.anzeige__motiv {
	display: block;
	padding: 12px 0;
	min-height: 100px;
}
.anzeige__motiv img {
	display: block;
	max-width: 100%;
	height: auto;
}
.anzeige__motiv a {
	color: var(--io-text);   /* NICHT Akzentfarbe: der Akzent gehoert
	                            dem redaktionellen Teil */
	text-decoration: underline;
}

.anzeige__text {
	font-family: var(--io-sans);
	font-size: 0.875rem;
	line-height: 1.5714;
	color: var(--io-text);
	margin: 0 0 8px;
	max-width: var(--io-prosa);
}

.anzeige__schluss {
	margin: 0;
	padding: 6px 0 8px;
	font-family: var(--io-sans);
	font-size: 0.8125rem;
	line-height: 1.5385;
	color: var(--io-meta);
}


/* ============================================================
   23  BEWEGUNG
   ------------------------------------------------------------
   Die Seite animiert von sich aus nichts. Die einzigen
   Bewegungen sind das weiche Scrollen zu einem Anker und die
   Aufklapp-Uebergaenge des Browsers. Beide werden abgeschaltet,
   wenn das System reduzierte Bewegung meldet.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
}


/* ============================================================
   24  DRUCK
   ------------------------------------------------------------
   Ein ausgedrucktes Feldmapping geht in die Projektakte. Dort
   haben Werbung, Schienen und Umschalter nichts zu suchen, und
   ein Feldpfad ohne seinen Permalink ist nicht nachvollziehbar
   — deshalb wird der Verweis hinter dem Pfad ausgedruckt.
   ============================================================ */

@media print {
	@page { margin: 16mm; }

	/* Der Ausdruck ist immer hell. Ein Dunkelmodus-Ausdruck
	   verbraucht eine Tonerkassette und ist schlechter lesbar. */
	:root {
		--io-grund: #FFFFFF;
		--io-panel: #FFFFFF;
		--io-code: #FFFFFF;
		--io-chip: #FFFFFF;
		--io-hover: #FFFFFF;
		--io-tint: #FFFFFF;
		--io-text: #000000;
		--io-meta: #333333;
		--io-kante: #000000;
		--io-akzent: #000000;
	}

	body { background: #FFFFFF; color: #000000; font-size: 10pt; }

	.anzeige,
	.io-schiene,
	.io-baum,
	.io-baumschalter,
	.io-modus,
	.io-kopfleiste__werkzeuge,
	.io-sprungmarke,
	.io-tabellenwerkzeuge,
	.io-kopieren,
	.io-suchformular,
	.io-blaetter,
	.io-pruefer__koerper form { display: none !important; }

	.io-kopfleiste { position: static; border-bottom: 1pt solid #000; }
	.io-raster { display: block; }

	.io-panel,
	.io-kopfband,
	.io-feldkarte,
	.io-schema,
	.io-rechtsanker,
	.io-abbildung { border: 1pt solid #000; break-inside: avoid; }

	/* Feldtabellen brechen um und wiederholen ihren Kopf. Ohne
	   thead-Wiederholung ist Seite 2 eines Feldmappings
	   unlesbar. */
	.io-tabellenrahmen { overflow: visible; border: 0; background: none; }
	.io-feldtabelle { min-width: 0; font-size: 8.5pt; }
	.io-feldtabelle thead { display: table-header-group; }
	.io-feldtabelle tr { break-inside: avoid; }
	.io-feldtabelle th,
	.io-feldtabelle td { border: 0.5pt solid #000; }
	.io-feldtabelle .io-sp-pfad,
	.io-feldtabelle thead th { position: static; }

	/* Der Permalink hinter jedem Feldpfad. */
	.io-sp-pfad .io-anker::after,
	.io-feldkarte__pfad::after {
		content: " " attr(href);
		font-size: 7.5pt;
		word-break: break-all;
	}

	.io-code { max-height: none; overflow: visible; }
	.io-code__text { white-space: pre-wrap; }

	details { display: block; }
	details > summary { display: none; }

	a { text-decoration: underline; }
	.io-inhalt a[href^="http"]::after {
		content: " (" attr(href) ")";
		font-size: 8pt;
		word-break: break-all;
	}

	.io-druckfuss { display: block !important; border-top: 1pt solid #000; padding-top: 4mm; margin-top: 6mm; font-size: 8pt; }
}

/* Die Druckfusszeile mit Betreiber, verantwortlicher Person,
   Modellversion und Abrufdatum steht im Markup, ist aber am
   Bildschirm ohne Funktion — dort traegt der Fuss dieselben
   Angaben in voller Groesse. */
.io-druckfuss { display: none; }


/* ============================================================
   BESCHRIFTUNGEN BRECHEN NICHT MEHR MITTEN IM WORT
   ============================================================
   Gesperrte Versalbeschriftungen in schmalen Zellen brachen zeichenweise
   um — aus "ORDNUNGSZAHLBEREICH" wurde "ORDNUNGSZAHLBEREIC / H". Ursache
   ist die Kombination aus letter-spacing und fehlender Silbentrennung:
   Der Browser bricht dann am letzten passenden Zeichen statt an einer
   Silbengrenze. Deutsche Fachkomposita treffen das zwangslaeufig. */

[class*="eyebrow"], [class*="ueberzeile"], [class*="__label"],
[class*="-label"], [class*="__marke"], [class*="kicker"],
[class*="__rubrik"], [class*="__feldname"], [class*="schriftfeld"] dt,
[class*="schriftfeld"] .bpo-feld__name {
  hyphens: auto;
  -webkit-hyphens: auto;
  overflow-wrap: break-word;
  word-break: normal;
  hyphenate-limit-chars: 8 4 4;
}
