/* ===================================================================
   DASHBOARD-CSS — KONSOLIDIERTE FASSUNG v34, 18.08.2026
   Ersetzt den GESAMTEN Inhalt des Oxygen-Elements `CSS Code` (Seite 11).

   Was das ist: der geflattete Endzustand der bisherigen Schichten
   dieses Elements (Basis + Haertung + Nutzer-Gestaltung, Glas v2,
   LifeOS-Monochrom v31, Innenpolster v32, Rot/Gruen v33). Jede Regel
   und jedes Token steht nur noch EINMAL — es gibt keine Overrides
   mehr. Maschinell erzeugt und verifiziert (Property-Karten-Diff
   Schicht- vs. Endfassung: 0 Abweichungen) -> konsolidierung.md.

   NICHT HIER: Die Sprungnavigation (Abschnitt 24 v30) liegt im
   EIGENEN Element `Menu CSS` und bleibt unveraendert. Lokales
   Spiegelbild: dashboard-css-navigation-zusatz.css.

   Gewollte Aenderungen gegenueber dem Live-Stand vor v34:
     - --viz-gut:      #006300 -> #04b404   (User-Entscheid 18.08.)
     - --viz-kritisch: #d03b3b -> #f84444
     - --viz-div-*-Rampen aus den neuen Endfarben abgeleitet
       (OKLab-Mischung von --viz-div-neutral zur Endfarbe).
   Entfernt ohne Wirkungsaenderung: alle @supports-Glasbloecke (Token
   --viz-surface-glas/#fff und --viz-blur/none machten sie inert; die
   Token selbst bleiben definiert, Abschnitt 1).

   PFLEGE AB JETZT: Aenderungen direkt an der jeweiligen Stelle
   vornehmen, nicht mehr anhaengen — die Historie liegt in Git
   (dashboards-Repo) und in backup-design-2026-08-18/.
   =================================================================== */
@font-face{
  font-family: "Figtree";
  font-style: normal;
  font-weight: 300 900;
  font-display: optional;
  src: url("https://tvhp6g7shv-art.github.io/arbeitsmarkt-at/fonts/figtree-latin-wght-normal.woff2")
       format("woff2");
  unicode-range:
    U+0-FF, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC,
    U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family: "Figtree";
  font-style: normal;
  font-weight: 300 900;
  font-display: optional;
  src: url("https://tvhp6g7shv-art.github.io/arbeitsmarkt-at/fonts/figtree-latin-ext-wght-normal.woff2")
       format("woff2");
  unicode-range:
    U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* -------------------------------------------------------------------
   1. Design-Token — EINZIGE Definitionsstelle
   kern.js liest alle Farben/Schriften beim Laden per getComputedStyle;
   Aenderungen hier wirken daher auch auf alle ECharts-Grafiken.
   Ausnahmen per JS-Nachfaerbung (Element `JavaScript Code`):
   Fluss rot/gruen, Zeitreihe Maenner blau / Frauen rosa.
   ------------------------------------------------------------------- */

.viz-root,
#dashboard {
  color-scheme: light;
  --viz-surface-glas-blur: 12px;
  --viz-surface-glas-border: rgb(255 255 255 / .35);
  --viz-fs-achse: 11px;
  --viz-fs-label: 11.5px;
  --viz-fs-serie: 12px;
  --viz-fs-tooltip: 12.5px;
  --viz-fs-eng: 10.5px;
  --viz-fw-normal: 400;
  --viz-fw-mittel: 500;
  --viz-fw-kraeftig: 600;
  --viz-fw-kpi: 650;
  --viz-gap: var(--m, 1.25rem);
  color: var(--viz-text);
  font-family: var(--viz-font);
  --viz-surface: #ffffff;
  --viz-plane: #fafafa;
  --viz-surface-glas: #ffffff;
  --viz-blur: none;
  --viz-text: #0a0a0a;
  --viz-text-2: #0a0a0a;
  --viz-muted: #767676;
  --viz-grid: #ececec;
  --viz-axis: #d9d9d9;
  --viz-border: #e5e5e5;
  --viz-series-1: #0a0a0a;
  --viz-series-2: #9a9a9a;
  --viz-series-3: #c9c9c9;
  --viz-series-4: #4d4d4d;
  --viz-series-5: #e0e0e0;
  --viz-series-6: #737373;
  --viz-seq-1: #f2f2f2;
  --viz-seq-2: #d9d9d9;
  --viz-seq-3: #b3b3b3;
  --viz-seq-4: #8c8c8c;
  --viz-seq-5: #595959;
  --viz-seq-6: #262626;
  --viz-font: ui-monospace, "SF Mono", "SFMono-Regular", Menlo,
              Consolas, "Liberation Mono", monospace;
  --viz-font-display: var(--viz-font);
  /* v41: Figtree bleibt fuer Titel und Fliesstext-Beiwerk (h1, h2,
     .viz-unterzeile, .viz-fuss). Diagrammtext, KPI und Etiketten
     bleiben monospace. @font-face steht in Abschnitt 1. */
  --viz-font-titel: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
  --viz-radius: 8px;
  --viz-radius-s: 6px;
  --viz-glas-fill: #ffffff;
  --viz-glas-blur: 0px;
  --viz-glas-rim: transparent;
  --viz-glas-edge: var(--viz-border);
  --viz-glas-radius: 8px;
  --viz-gut: #04b404;
  --viz-kritisch: #f84444;
  --viz-div-neutral: #f0efec;
  --viz-div-gut-1: #d4e7ce;
  --viz-div-gut-2: #a5d89e;
  --viz-div-gut-3: #77ca6f;
  --viz-div-gut-4: #3cbb36;
  --viz-div-schlecht-1: #f7d7d1;
  --viz-div-schlecht-2: #fcafa6;
  --viz-div-schlecht-3: #fd887e;
  --viz-div-schlecht-4: #fa5b56;
}
/* -------------------------------------------------------------------
   2. Typografie
   H1 humanistisch-serifenlos, H2/Etiketten Versalien-Monospace.
   ------------------------------------------------------------------- */

.viz-root h1 {
  margin: 0 0 var(--xxs, 0.4rem);
  font-size: var(--l, 1.56rem);
  font-family: var(--viz-font-titel);   /* v41: Figtree zurueck */
  font-weight: 600;
  letter-spacing: -0.02em;
}
.viz-root h2 {
  margin: 0;
  font-size: var(--xs, 0.8rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.viz-lead {
  font-size: var(--xs);
  color: var(--viz-muted);
}

.h2 {
    font-family: var(--viz-font-titel);   /* v41: Figtree zurueck */
}
/* -------------------------------------------------------------------
   3. Karten und KPI-Kacheln
   Weisse Flaeche, 1 px Linie, 8 px Radius (LifeOS).
   ------------------------------------------------------------------- */

.viz-karte {
  margin-bottom: var(--viz-gap);
  padding: var(--xxxxl, 1.25rem);
  background: #ffffff;
  border: 1px solid var(--viz-border);
  border-radius: var(--viz-radius);
}
.viz-kopfzeile {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: var(--s, 0.8rem);
}
.viz-unterzeile {
  margin: 0;
  font-family: var(--viz-font-titel);   /* v41: Figtree zurueck */
  font-size: var(--xs, 0.8rem);
  color: var(--viz-muted);
}
.viz-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));   /* v35: immer 4 oder 2, nie ungerade */
  gap: var(--viz-gap);
  margin-bottom: var(--viz-gap);
}
.viz-kpi {
  padding: var(--r, 1rem) var(--m, 1.25rem);
  position: relative;
  container-type: inline-size;   /* v39: cqw-Bezug fuer den Wert */
  color: var(--viz-text);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background: #ffffff;
  border: 1px solid var(--viz-border);
  border-radius: var(--viz-radius);
}
.viz-kpi-titel {
  margin: 0 0 var(--xxs, 0.4rem);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--viz-text);
}
.viz-kpi-wert {
  font-family: var(--viz-font-display);
  white-space: nowrap;                             /* v39: Zahlen brechen nie um */
  font-size: var(--xl, 1.9rem);                    /* Rueckfall ohne cq-Support */
  font-size: min(var(--xl, 1.9rem), 11.5cqw);      /* v39: schrumpft statt umzubrechen */
  font-weight: var(--viz-fw-kpi);
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.viz-kpi-delta {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: var(--xxs, 0.4rem);
  font-size: var(--xs, 0.8rem);
  font-variant-numeric: tabular-nums;
  color: var(--viz-muted);
}
.viz-delta-hoch {
  color: var(--viz-kritisch);
}
.viz-delta-runter {
  color: var(--viz-gut);
}
/* -------------------------------------------------------------------
   4. Diagrammflaechen
   ------------------------------------------------------------------- */

.viz-chart {
  width: 100%;
  height: 340px;
}
.viz-chart-hoch {
  height: 420px;
}
.viz-chart-karte {
  height: 560px;
}
.viz-chart-karte-eu {
  height: 700px;
}
/* -------------------------------------------------------------------
   5. Schalter und Knoepfe
   Aktiver Modus als schwarze Pille mit weisser Schrift.
   ------------------------------------------------------------------- */

.viz-knopfreihe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--xxs, 0.4rem);
}
.viz-tabelle-schalter,
.viz-einbetten {
  padding: var(--xxs, 0.4rem) var(--s, 0.8rem);
  font: inherit;
  color: var(--viz-text-2);
  background: none;
  border: 1px solid var(--viz-border);
  cursor: pointer;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border-radius: var(--viz-radius-s);
}
.viz-tabelle-schalter:hover,
.viz-einbetten:hover {
  color: var(--viz-text);
}
.viz-modus {
  display: inline-flex;
  overflow: hidden;
  border: 1px solid var(--viz-border);
  border-radius: var(--viz-radius-s);
}
.viz-modus button {
  padding: var(--xxs, 0.4rem) var(--s, 0.8rem);
  font: inherit;
  color: var(--viz-text-2);
  background: none;
  border: 0;
  cursor: pointer;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.viz-modus button[aria-pressed="true"] {
  font-weight: var(--viz-fw-kraeftig);
  color: #ffffff;
  background: #0a0a0a;
}
.viz-tabelle-schalter:focus-visible,
.viz-modus button:focus-visible,
.viz-einbetten:focus-visible,
dialog.viz-dialog button:focus-visible {
  outline: 2px solid var(--viz-series-1);
  outline-offset: 2px;
}
.viz-verborgen,
.viz-tabelle-schalter:not([data-ziel="t-bezirke"]) {
  display: none;
}
/* -------------------------------------------------------------------
   6. Tabellen
   ------------------------------------------------------------------- */

table.viz-tabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--xs, 0.8rem);
  font-variant-numeric: tabular-nums;
}
table.viz-tabelle th {
  padding: var(--xxs, 0.4rem) var(--xs, 0.8rem);
  text-align: left;
  font-weight: var(--viz-fw-kraeftig);
  color: var(--viz-text-2);
  border-bottom: 1px solid var(--viz-axis);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
table.viz-tabelle td {
  padding: var(--xxs, 0.4rem) var(--xs, 0.8rem);
  color: var(--viz-text);
  border-bottom: 1px solid var(--viz-grid);
}
table.viz-tabelle th.num,
table.viz-tabelle td.num {
  text-align: right;
}
.viz-spark-zelle {
  width: 130px;
}
/* -------------------------------------------------------------------
   7. Hinweiskasten und Fusszeile
   ------------------------------------------------------------------- */

.viz-hinweis {
  margin-bottom: var(--viz-gap);
  padding: var(--s, 0.8rem) var(--r, 1rem);
  font-size: var(--xs, 0.8rem);
  color: var(--viz-text-2);
  background: var(--viz-surface);
  border: 1px solid var(--viz-border);
  border-left: 3px solid var(--viz-series-2);
  border-radius: var(--viz-radius);
  border-left-width: 3px;
}
.viz-fuss {
  font-family: var(--viz-font-titel);   /* v41: Figtree zurueck */
  font-size: var(--xs, 0.8rem);
  line-height: 1.6;
  color: var(--viz-muted);
}
.viz-fuss a {
  color: inherit;
}
/* -------------------------------------------------------------------
   8. Kopfzeilen-Varianten der Sektionen
   ------------------------------------------------------------------- */

#s-verlauf .viz-kopfzeile,
.viz-karte[data-chart="zeitreihe"] .viz-kopfzeile,
.viz-karte[data-chart="ausbildung"] .viz-kopfzeile {
  grid-column: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  margin-bottom: 0;
  padding-top: 0;
  gap: var(--r, 1rem);
}
#s-verlauf .viz-knopfreihe {
  width: 100%;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s, 0.8rem);
}
#s-verlauf .viz-tabelle-schalter {
  margin-left: auto;
}
/* -------------------------------------------------------------------
   9. Einbetten-Dialog
   ------------------------------------------------------------------- */

dialog.viz-dialog {
  width: calc(100% - 40px);
  max-width: var(--container-s, 640px);
  padding: var(--m, 1.4rem);
  font-family: var(--viz-font);
  color: var(--viz-text);
  background: var(--viz-surface);
  border: 1px solid var(--viz-border);
  border-radius: var(--viz-radius);
}
dialog.viz-dialog::backdrop {
  background: rgb(0 0 0 / 0.35);
}
dialog.viz-dialog h3 {
  margin: 0 0 var(--xxs, 0.4rem);
  font-family: var(--viz-font-display);
  font-size: var(--s, 1rem);
  font-weight: var(--viz-fw-kraeftig);
}
dialog.viz-dialog p {
  margin: 0 0 var(--s, 0.8rem);
  font-size: var(--xs, 0.8rem);
  line-height: 1.55;
  color: var(--viz-text-2);
}
dialog.viz-dialog textarea {
  width: 100%;
  height: 128px;
  padding: var(--xs, 0.8rem);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--xs, 0.8rem);
  line-height: 1.5;
  color: var(--viz-text);
  background: var(--viz-plane);
  border: 1px solid var(--viz-border);
  border-radius: var(--viz-radius);
  resize: vertical;
}
dialog.viz-dialog .viz-dialog-fuss {
  display: flex;
  gap: var(--xxs, 0.4rem);
  justify-content: flex-end;
  margin-top: var(--s, 0.8rem);
}
dialog.viz-dialog button {
  padding: var(--xxs, 0.4rem) var(--s, 0.8rem);
  font: inherit;
  font-size: var(--xs, 0.8rem);
  border-radius: var(--viz-radius);
  cursor: pointer;
}
dialog.viz-dialog button.primaer {
  color: #fff;
  background: var(--viz-series-1);
  border: 0;
}
dialog.viz-dialog button.sekundaer {
  color: var(--viz-text-2);
  background: none;
  border: 1px solid var(--viz-border);
}
/* -------------------------------------------------------------------
   10. Sektionsgeometrie — zweispaltige Karten
   Sektion traegt das Polster, Innenkacheln stehen auf 0
   (einheitlich 83 px sichtbarer Innenabstand, messend abgenommen).
   ------------------------------------------------------------------- */

.viz-karte[data-chart="zeitreihe"],
#s-verlauf,
#s-generationen,
.viz-karte[data-chart="ausbildung"],
#s-laender,
#s-fluss,
#s-dauer,
#s-stellen,
#s-schulung,
#s-branche,
#s-eurang,
#s-eukarte {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: var(--viz-gap);
  align-items: start;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  padding: var(--xxxxl, 1.25rem);
  background: #ffffff;
}
.viz-karte[data-chart="zeitreihe"] .viz-chart {
  grid-column: 2 / -1;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 340px;
}
.viz-karte[data-chart="zeitreihe"] #t-zeitreihe,
#s-verlauf #t-verlauf,
#s-generationen #t-generationen,
.viz-karte[data-chart="ausbildung"] #t-ausbildung,
#s-fluss #t-fluss,
#s-dauer #t-dauer,
#s-stellen #t-stellen,
#s-schulung #t-schulung,
#s-branche #t-branche,
#s-eurang #t-eurang,
#s-eukarte #t-eukarte {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}
#s-verlauf .viz-einbetten {
  margin-left: 0;
}
#s-verlauf .viz-chart,
.viz-karte[data-chart="ausbildung"] .viz-chart {
  grid-column: 2 / -1;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 420px;
}
#s-generationen .viz-chart,
#s-fluss .viz-chart {
  grid-column: 1 / 4;
  grid-row: 1 / span 2;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 340px;
}
#s-generationen .viz-kopfzeile {
  grid-column: 4;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  margin-bottom: 0;
  padding-top: 0;
  gap: var(--r, 1rem);
}
#s-generationen #h-generationen,
#s-fluss #h-fluss {
  grid-column: 4;
  grid-row: 2;
  align-self: center;
}
.viz-kopfzeile > div:not(.viz-knopfreihe) {
  display: flex;
  flex-direction: column;
  gap: var(--xxs, 0.4rem);
}
.viz-karte[data-chart="karte"] {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  padding: var(--xxxxl, 1.25rem);
  background: #ffffff;
}
#s-laender .viz-kopfzeile {
  grid-column: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
#s-laender #t-laender {
  grid-column: 2 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
}
#s-fluss .viz-kopfzeile {
  grid-column: 4;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
#s-dauer .viz-chart,
#s-stellen .viz-chart,
#s-eurang .viz-chart {
  grid-row: 1 / span 2;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  grid-column: 2 / -1;
  padding: 0;
  min-height: 340px;
}
#s-schulung .viz-chart {
  grid-row: 1 / span 2;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  grid-column: 1 / 4;
  padding: 0;
  min-height: 340px;
}
#s-branche .viz-chart {
  grid-row: 1 / span 2;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  grid-column: 1 / 4;
  padding: 0;
  min-height: 420px;
}
#s-dauer .viz-kopfzeile,
#s-stellen .viz-kopfzeile,
#s-eurang .viz-kopfzeile {
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
  grid-column: 1;
}
#s-schulung .viz-kopfzeile,
#s-branche .viz-kopfzeile,
#s-eukarte .viz-kopfzeile {
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
  grid-column: 4;
}
#s-dauer #h-dauer,
#s-stellen #h-stellen,
#s-eurang #h-eurang {
  grid-row: 2;
  align-self: center;
  grid-column: 1;
}
#s-schulung #h-schulung,
#s-branche #h-branche,
#s-eukarte #h-eukarte {
  grid-row: 2;
  align-self: center;
  grid-column: 4;
}
#s-eukarte .viz-chart {
  grid-row: 1 / span 2;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 700px;
  grid-column: 1 / 4;
}
/* -------------------------------------------------------------------
   11. Glas-Utility — stillgelegt
   Bleibt fuer evtl. Markup-Nutzung erhalten; Token sind neutral
   (weiss/0), sichtbar ist nur noch eine weisse Flaeche mit Linie.
   ------------------------------------------------------------------- */

.glas {
  position: relative;
  border-radius: var(--viz-glas-radius);
  color: var(--viz-text);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background: #ffffff;
}
.glas::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid var(--viz-glas-edge);
  pointer-events: none;
}
/* -------------------------------------------------------------------
   12. Schmale Fenster: 768 px, 480 px, 960 px
   Die Nav-Media-Queries (960/961) liegen im Element `Menu CSS`.
   ------------------------------------------------------------------- */

@media (max-width: 768px) {
  .viz-karte {
    padding: var(--s, 0.8rem);
    min-height: calc(260px + 2 * var(--s, 0.8rem));
  }
  .viz-kopfzeile {
    flex-wrap: wrap;
    gap: var(--xxs, 0.4rem);
  }
  .viz-chart-karte {
    height: 300px;
  }
  .viz-chart-karte-eu {
    height: 480px;
  }
  .viz-chart {
    height: 260px;
  }
  table.viz-tabelle {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
  table.viz-tabelle th,
  table.viz-tabelle td {
    padding: var(--xxs, 0.4rem) var(--xxs, 0.4rem);
  }
  .viz-spark-zelle {
    width: 90px;
  }
}
@media (max-width: 480px) {
  .viz-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));   /* v35: nie ungerade */
  }
  .viz-chart-karte {
    height: 240px;
  }
  .viz-chart-karte-eu {
    height: 380px;
  }
  .viz-chart {
    height: 230px;
  }
  .viz-kopfzeile .viz-knopfreihe {
    width: 100%;
  }
}
@media (max-width: 960px) {
  .viz-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));   /* v35: 4 -> 2 Spalten */
  }
  .viz-karte[data-chart="zeitreihe"],
  #s-verlauf,
  #s-generationen,
  .viz-karte[data-chart="ausbildung"],
  #s-laender,
  #s-fluss,
  #s-dauer,
  #s-stellen,
  #s-schulung,
  #s-branche,
  #s-eurang,
  #s-eukarte {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
  .viz-karte[data-chart="zeitreihe"] .viz-kopfzeile {
    grid-column: 1;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    padding-top: 0;
    margin-bottom: var(--s, 0.8rem);
  }
  .viz-karte[data-chart="zeitreihe"] .viz-chart,
  #s-verlauf .viz-chart,
  .viz-karte[data-chart="ausbildung"] .viz-chart {
    grid-column: 1;
    padding: 0;
    min-height: 260px;
  }
  #s-verlauf .viz-kopfzeile {
    grid-column: 1;
    padding-top: 0;
    margin-bottom: var(--s, 0.8rem);
  }
  #s-verlauf .viz-knopfreihe {
    flex-direction: row;
    align-items: center;
  }
  #s-verlauf .viz-einbetten {
    margin-left: auto;
  }
  #s-generationen .viz-chart,
  #s-fluss .viz-chart,
  #s-dauer .viz-chart,
  #s-stellen .viz-chart,
  #s-schulung .viz-chart,
  #s-branche .viz-chart,
  #s-eurang .viz-chart {
    grid-column: 1;
    grid-row: auto;
    padding: 0;
    min-height: 260px;
  }
  #s-generationen .viz-kopfzeile {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    padding-top: 0;
    margin-bottom: var(--s, 0.8rem);
  }
  #s-generationen #h-generationen,
  #s-fluss #h-fluss,
  #s-dauer #h-dauer,
  #s-stellen #h-stellen,
  #s-schulung #h-schulung,
  #s-branche #h-branche,
  #s-eurang #h-eurang,
  #s-eukarte #h-eukarte {
    grid-column: 1;
    grid-row: auto;
  }
  .viz-karte[data-chart="ausbildung"] .viz-kopfzeile,
  #s-laender .viz-kopfzeile {
    grid-column: 1;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--s, 0.8rem);
  }
  #s-laender #t-laender {
    grid-column: 1;
    padding: 0;
  }
  #s-fluss .viz-kopfzeile,
  #s-dauer .viz-kopfzeile,
  #s-stellen .viz-kopfzeile,
  #s-schulung .viz-kopfzeile,
  #s-branche .viz-kopfzeile,
  #s-eurang .viz-kopfzeile,
  #s-eukarte .viz-kopfzeile {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--s, 0.8rem);
  }
  #s-eukarte .viz-chart {
    grid-column: 1;
    grid-row: auto;
    padding: 0;
    min-height: 480px;
  }
  .viz-karte[data-chart="karte"] {
    padding: var(--s, 0.8rem);
  }
}

/* -------------------------------------------------------------------
   13. Menuezeile ueber dem Dashboard (v35, 18.08.2026)
   Statisches Markup im ersten HTML-Code-Element. Trenner zwischen den
   Listenpunkten sind border-left (rein visuell, Screenreader-neutral).
   ------------------------------------------------------------------- */
.viz-menu {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--xxs, 0.4rem) var(--r, 1rem);
  margin-bottom: var(--m, 1.25rem);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter,
               system-ui, sans-serif;
  font-size: 0.95rem;
  color: var(--viz-text, #0a0a0a);
}
.viz-menu p {
  margin: 0;
}
.viz-menu ul {
  display: flex;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}
.viz-menu li {
  display: flex;
}
.viz-menu li + li {
  border-left: 1px solid var(--viz-text, #0a0a0a);
}
.viz-menu a {
  padding: 2px 10px;
  color: inherit;
  text-decoration: none;
}
.viz-menu p a {
  padding: 2px 0;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.viz-menu li:last-child a {
  padding-right: 0;
}
.viz-menu a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.viz-menu a:focus-visible {
  outline: 2px solid var(--viz-text, #0a0a0a);
  outline-offset: 2px;
}
/* v36: Menuezeile steht ausserhalb der weissen Flaeche (JS hebt sie vor
   den Container). Gleiche Aussenbreite wie der Container (--container-r),
   Text buendig mit dessen Kante. */
.viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu {
  box-sizing: border-box;
  width: 100%;
  max-width: var(--container-r, 96rem);
  margin: var(--m, 1.25rem) auto var(--s, 0.8rem);
  padding: 0;
}
/* v37: Menue-Knopf und Flyout der Sprungnavigation in der Kopfzeile.
   Die Leiste ist keine Rasterspalte mehr (volle Grafikbreite); das
   JS haengt .viz-nav in .viz-menu-flyout. Interner Kopf/Klappknopf
   der Leiste entfallen im Flyout. */
.viz-menu {
  position: relative;
}
.viz-menu-mit-knopf {
  justify-content: flex-start;
}
.viz-menu-mit-knopf ul {
  margin-left: auto;
}
.viz-menu-knopf {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 14px;
  font-family: var(--viz-font, ui-monospace, monospace);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--viz-text, #0a0a0a);
  background: var(--viz-surface, #ffffff);
  border: 1px solid var(--viz-border, #e5e5e5);
  border-radius: var(--viz-radius-s, 6px);
  cursor: pointer;
}
.viz-menu-knopf[aria-expanded="true"] {
  color: #ffffff;
  background: #0a0a0a;
  border-color: #0a0a0a;
}
.viz-menu-knopf:focus-visible {
  outline: 2px solid var(--viz-text, #0a0a0a);
  outline-offset: 2px;
}
.viz-menu-flyout {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 60;
  width: min(320px, calc(100vw - 32px));
}
.viz-menu-flyout .viz-nav {
  position: static;
  margin: 0;   /* v40: 960er-Regel aus Menu CSS gibt sonst margin-bottom 20px */
  max-height: min(60vh, 480px);
  box-shadow: 0 12px 32px rgb(0 0 0 / 0.12);
}
.viz-menu-flyout .viz-nav-kopf {
  display: none;
}
.viz-menu-flyout .viz-nav ol {
  display: block !important;
}
/* v38: Mittelachse und Mobile. Theme gibt p/ul margin-bottom 16px —
   Flex zentriert die Margin-Box, Texte hingen 8px zu hoch. Unter
   700px wandern Impressum/Datenschutz ins Flyout (Klon per JS),
   die Kopfzeile bleibt einzeilig. */
.viz-root .viz-menu p {
  margin: 0 !important;   /* Theme-Margins kommen mit hoeherer Spezifitaet */
}
.viz-root .viz-menu-mit-knopf > ul {
  margin: 0 0 0 auto !important;   /* rechtsbuendig; Theme-Margin weg */
}
.viz-menu p {
  min-width: 0;
}
.viz-root .viz-menu .viz-menu-flyout-links {
  display: none;   /* muss .viz-menu ul (display:flex) schlagen */
  list-style: none;
  margin: 0 !important;   /* v40: buendig an den Grafiken-Block */
  padding: 6px 0;
  background: var(--viz-surface, #ffffff);
  border: 1px solid var(--viz-border, #e5e5e5);
  border-radius: var(--viz-radius-s, 6px);
  box-shadow: 0 12px 32px rgb(0 0 0 / 0.12);
}
.viz-menu-flyout-links li {
  display: block;
}
.viz-root .viz-menu .viz-menu-flyout-links li + li {
  border-left: 0;
}
.viz-menu-flyout-links a {
  display: block;
  padding: 10px 14px;
}
@media (max-width: 700px) {
  .viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu {
    margin: 0 auto var(--s, 0.8rem);   /* v40: kein Abstand ueber der Zeile */
    padding: 0 var(--s, 0.8rem);       /* v40: seitliche Luft am Viewportrand */
  }
  .viz-menu-mit-knopf > ul {
    display: none;
  }
  .viz-root .viz-menu .viz-menu-flyout-links {
    display: block;
  }
  .viz-menu {
    flex-wrap: nowrap;
  }
}

p {
	margin-top: unset;
	margin-bottom: var(--r);
}

/* ===================================================================
   Abschnitt 24 — Sprungnavigation IM CONTAINER (NUR ANGEHAENGT)
   Version v30, 17.08.2026   (ersetzt v28/v29 dieses Abschnitts)

   ANHAENGEN, NICHT ERSETZEN. Dieser Block kommt UNTEN an das
   bestehende Oxygen-Element `CSS Code` (Live-Stand: Abschnitte 1-23,
   dashboard-css-live.css). Oberhalb wird nichts geaendert.
   Steht dort noch Abschnitt 24 in der Fassung v28/v29: nur diesen
   Abschnitt loeschen und durch den hier ersetzen.

   WAS SICH GEGENUEBER v29 GEAENDERT HAT
   Die Leiste hing am <body>, klebte an der Fensterkante und rueckte
   ueber `body { padding-left }` die ganze Seite ein — Header und Footer
   inbegriffen. Sie steht jetzt IM Container des Dashboards:

     - `.viz-nav-raster` (die Klasse setzt das Skript auf den Container,
       in den es die Leiste eingehaengt hat) wird ab 961 px zu einem
       zweispaltigen Raster: Spalte 1 = Leiste, Spalte 2 = alles andere.
     - Die Leiste ist `position: sticky` statt `fixed`. Sie laeuft mit
       dem Container, bleibt am oberen Rand stehen und endet mit ihm.
       Kein `position: fixed` mehr — damit entfaellt auch das Problem
       aus v28, dass ein Vorfahre mit transform/backdrop-filter den
       Bezugsrahmen an sich zieht. `sticky` bezieht sich auf den
       naechsten scrollenden Vorfahren, hier das Dokument.
     - Kein `padding-left` am <body> mehr: Header, Footer und der Rest
       der Seite stehen wieder wie vorher.
     - Unter 960 px kein fixierter Burger und kein Schirm mehr. Die
       Leiste bleibt im Fluss, klappt als schmale Zeile oben im
       Container zusammen und wird per Knopf in ihrer eigenen Kopfzeile
       geoeffnet.

   Preis der Umstellung: die Grafikspalte wird um Leistenbreite plus
   Luecke schmaler (bei 1267 px Fenster: 827 -> 547 px). Stellschrauben
   dafuer stehen in 24.1.

   Was hier steht:
     24.1  Masse und Signalfarbe
     24.2  Zweispaltiges Raster im Container
     24.3  Die Leiste selbst
     24.4  Eintraege und Aktivmarkierung
     24.5  Sprungziel-Abstand der Karten
     24.6  Schmale Fenster (unter 960 px)
     24.7  Druck und reduzierte Bewegung
   =================================================================== */

/* -------------------------------------------------------------------
   24.1 Masse und Signalfarbe
   Zentral an einer Stelle. `--viz-nav-w` bestimmt die Spaltenbreite,
   `--viz-nav-luecke` den Abstand zur Grafikspalte. Wer den Grafiken
   mehr Platz geben will, verkleinert beides — oder erhoeht
   `--container-r` des Themes, dann wird der Container breiter.
   ------------------------------------------------------------------- */
:root {
  --viz-nav-w: 248px;          /* Breite der Menuespalte */
  --viz-nav-luecke: 32px;      /* Abstand Leiste <-> Grafiken */
  --viz-nav-bruch: 960px;      /* darunter: eingeklappt (nur Doku,
                                  Media Queries brauchen feste Werte) */
  --viz-nav-abstand: 24px;     /* Luft ueber dem angesprungenen Titel;
                                  das Skript ueberschreibt den Wert mit
                                  gemessener Leistenhoehe + LUFT_OBEN */
  --viz-nav-boden: 24px;       /* Luft unter der Leiste am Fensterrand */
}

/* -------------------------------------------------------------------
   24.2 Zweispaltiges Raster im Container

   `.viz-nav-raster` setzt das Skript auf genau das Element, in das es
   die Leiste eingehaengt hat (`.viz-root > .container`, sonst
   `.viz-root`). Deshalb steht hier kein Oxygen-Klassenname — das
   Raster sitzt immer da, wo die Leiste wirklich haengt.

   `grid-row` der Leiste setzt das Skript auf die genaue Zahl der
   Geschwister; `span 999` hier ist nur der Rueckfall, falls das Skript
   den Wert nicht setzen kann. Leere Zeilen sind 0 px hoch.

   Zum Abstandsverhalten: Rasterelemente bilden einen eigenen
   Formatierungskontext, die 24-px-Aussenabstaende der Karten fallen
   also nicht mehr aus ihren Oxygen-Huellen heraus, sondern zaehlen zu
   deren Hoehe. Der sichtbare Abstand bleibt derselbe.
   ------------------------------------------------------------------- */
@media (min-width: 961px) {
  .viz-nav-raster {
    display: grid;
    grid-template-columns: var(--viz-nav-w) minmax(0, 1fr);
    column-gap: var(--viz-nav-luecke);
    align-items: start;
  }
  .viz-nav-raster > * {
    grid-column: 2;
    min-width: 0;   /* sonst sprengen breite ECharts-Leinwaende die Spalte */
  }
  .viz-nav-raster > .viz-nav {
    grid-column: 1;
    grid-row: 1 / span 999;
  }
}

/* ALTERNATIVE (alter Stand v29): Leiste am Fensterrand statt im
   Container. Dann in oxygen-navigation-javascript.txt das Einhaengen
   auf document.body zurueckstellen und hier ergaenzen:
     @media (min-width: 961px) { body.viz-nav-aktiv { padding-left: var(--viz-nav-w); } }
     .viz-nav { position: fixed; top: 0; left: 0; height: 100dvh; }
*/

/* -------------------------------------------------------------------
   24.3 Die Leiste selbst
   `sticky` mit `align-self: start`: die Leiste ist nur so hoch wie ihr
   Inhalt und wandert innerhalb ihrer Rasterzelle mit. `max-height`
   deckelt sie auf die Fensterhoehe, damit auch eine lange Liste
   vollstaendig erreichbar bleibt — dann scrollt sie in sich selbst.
   ------------------------------------------------------------------- */
.viz-nav {
  --viz-nav-signal: var(--viz-series-1, #2a78d6);
  position: sticky;
  top: var(--viz-nav-abstand, 24px);
  z-index: 5;
  align-self: start;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: var(--s, 0.8rem);
  max-height: calc(100dvh - var(--viz-nav-abstand, 24px) - var(--viz-nav-boden, 24px));
  padding: var(--m, 1.25rem) var(--s, 0.8rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  font-family: var(--viz-font, system-ui, -apple-system, "Segoe UI", sans-serif);
  color: var(--viz-text, #000);
  background: var(--viz-surface, #fcfcfb);
  border: 1px solid var(--viz-border, #5a5a5a);
  border-radius: var(--viz-radius-m, var(--viz-radius-s, 10px));
}
/* Milchglas nur, wo der Browser es kann — dieselbe Regel wie bei
   .viz-karte in Abschnitt 5. Als Kind von .viz-root ist das jetzt
   unbedenklich: die Leiste ist nicht mehr `fixed`, ein eigener
   Bezugsrahmen stoert sie nicht. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .viz-nav {
    background: var(--viz-surface-glas, rgb(252 252 251 / .8));
    -webkit-backdrop-filter: var(--viz-blur, blur(12px) saturate(1.4));
    backdrop-filter: var(--viz-blur, blur(12px) saturate(1.4));
  }
}

/* Kopfzeile: Titel und — nur schmal — der Klappknopf */
.viz-nav-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--xs, 0.6rem);
}
.viz-nav-titel {
  margin: 0;
  padding: 0 10px;
  font-family: var(--viz-font-display, var(--viz-font, sans-serif));
  font-size: var(--xxs, 0.72rem);
  font-weight: var(--viz-fw-kraeftig, 600);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--viz-muted, #000);
}
.viz-nav ol {
  margin: 0;
  padding: 0;
  list-style: none;
}
.viz-nav li[hidden] {
  display: none;   /* Karten, deren Daten noch nicht geladen sind */
}
.viz-nav[hidden] {
  display: none;
}

/* -------------------------------------------------------------------
   24.4 Eintraege und Aktivmarkierung
   Die Signalfarbe wirkt dreifach: Schriftfarbe, Balken links,
   getoenter Grund. Farbe allein waere zu wenig — WCAG 1.4.1.
   ------------------------------------------------------------------- */
.viz-nav a {
  display: block;
  padding: 7px 10px;
  font-size: var(--xs, 0.8rem);
  font-weight: var(--viz-fw-normal, 400);
  line-height: 1.35;
  color: var(--viz-text-2, #000);
  text-decoration: none;
  border-left: 2px solid transparent;
  transition: color .15s ease, background-color .15s ease, border-color .15s ease;
}
.viz-nav a:hover {
  background: var(--viz-plane, #f9f9f7);
}
.viz-nav a[aria-current="true"] {
  color: var(--viz-nav-signal);
  font-weight: var(--viz-fw-kraeftig, 600);
  border-left-color: var(--viz-nav-signal);
  background: var(--viz-plane, #f9f9f7);   /* Rueckfall */
  background: color-mix(in srgb, var(--viz-nav-signal) 10%, transparent);
}
.viz-nav a:focus-visible {
  outline: 2px solid var(--viz-nav-signal);
  outline-offset: -2px;
}
/* Zaehlung vor dem Titel — hilft beim Wiederfinden, wenn zwei Karten
   aehnlich heissen. Nicht anwaehlbar, damit sie nicht mitkopiert wird. */
.viz-nav ol {
  counter-reset: viz-nav;
}
.viz-nav li {
  counter-increment: viz-nav;
}
.viz-nav a::before {
  content: counter(viz-nav) "\00a0\00a0";
  font-variant-numeric: tabular-nums;
  color: var(--viz-muted, #666);
  -webkit-user-select: none;
  user-select: none;
}
.viz-nav a[aria-current="true"]::before {
  color: var(--viz-nav-signal);
}

/* -------------------------------------------------------------------
   24.5 Sprungziel-Abstand
   Ohne scroll-margin klebt der angesprungene Titel an der Fensterkante.
   Den Wert setzt das Skript aus der gemessenen Hoehe fixierter Leisten
   am oberen Rand (Adminleiste, klebriger Theme-Kopf) plus LUFT_OBEN —
   derselbe Wert, den die Leiste als `top` benutzt.
   ------------------------------------------------------------------- */
.viz-root .viz-karte,
.viz-root .viz-kpis {
  scroll-margin-top: var(--viz-nav-abstand, 24px);
}

/* -------------------------------------------------------------------
   24.6 Schmale Fenster (unter 960 px)
   Einspaltig. Die Leiste bleibt im Fluss ganz oben im Container und
   klappt auf eine Zeile zusammen; der Knopf sitzt in ihrer Kopfzeile.
   Kein fixierter Knopf, kein Schirm — alles bleibt im Container.
   ------------------------------------------------------------------- */
.viz-nav-schalter {
  display: none;   /* ab 961 px steht die Liste ohnehin offen */
}
@media (max-width: 960px) {
  .viz-nav-raster {
    display: block;
  }
  .viz-nav {
    position: sticky;
    top: var(--viz-nav-abstand, 24px);
    margin-bottom: var(--m, 1.25rem);
    max-height: min(70dvh, calc(100dvh - var(--viz-nav-abstand, 24px) - var(--viz-nav-boden, 24px)));
  }
  /* eingeklappt: nur die Kopfzeile, kein Eigenscroll */
  .viz-nav:not(.viz-nav-offen) {
    overflow: hidden;
  }
  .viz-nav:not(.viz-nav-offen) ol {
    display: none;
  }
  .viz-nav-schalter {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    box-sizing: border-box;
    min-width: 44px;   /* 44 px = Mindestgroesse fuer Fingerziele, WCAG 2.5.5 */
    min-height: 44px;
    padding: 0 12px;
    font: inherit;
    font-size: var(--xs, 0.8rem);
    color: var(--viz-text, #000);
    background: var(--viz-plane, #f9f9f7);
    border: 1px solid var(--viz-border, #5a5a5a);
    border-radius: var(--viz-radius-s, 6px);
    cursor: pointer;
  }
  .viz-nav-schalter::after {
    content: "";
    width: 8px;
    height: 8px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform .2s ease;
  }
  .viz-nav-schalter[aria-expanded="true"] {
    border-color: var(--viz-series-1, #2a78d6);
  }
  .viz-nav-schalter[aria-expanded="true"]::after {
    transform: translateY(2px) rotate(-135deg);
  }
  .viz-nav-schalter:focus-visible {
    outline: 2px solid var(--viz-series-1, #2a78d6);
    outline-offset: 2px;
  }
}

/* -------------------------------------------------------------------
   24.7 Druck und reduzierte Bewegung
   ------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .viz-nav,
  .viz-nav a,
  .viz-nav-schalter::after {
    transition: none;
  }
}
@media print {
  .viz-nav {
    display: none !important;
  }
  .viz-nav-raster {
    display: block !important;
  }
}

/* ===================================================================
   Abschnitt 25 — TABLET-UMBRUCH 1024 px (NUR ANGEHAENGT)
   Version v42, 18.08.2026

   ANHAENGEN, NICHT ERSETZEN. Dieser Block kommt UNTEN an idl.css,
   hinter Abschnitt 24 (Sprungnavigation). Oberhalb wird nichts
   geaendert. Lokales Spiegelbild: idl-css-zusatz-v42.css.

   WARUM
   Drei Umbruchpunkte lagen zu niedrig, und dazwischen entstanden
   genau die Fehler, die auf dem iPad sichtbar waren:

     960 px  Sektionsgeometrie. Bei 1024 px (iPad quer) galt noch das
             vierspaltige Raster — die Kopfzeilen standen links oder
             rechts NEBEN der Grafik statt darueber, und die
             Zeichenflaeche schrumpfte auf rund 480 px. Daher die
             abgeschnittenen Kategorienamen und Achsenzahlen.
     961 px  Sprungnavigation. Ihre Spalte (248 px + 32 px Luecke)
             blieb bei 1024 px stehen und nahm 280 px der 1024 weg —
             der eigentliche Grund fuer die enge Grafikspalte.
     700 px  Menuezeile. Bei 768 px fehlte das seitliche Polster, und
             Impressum/Datenschutz standen noch in der Kopfzeile, wo
             sie ueber den rechten Rand hinausliefen.

   Alle drei ziehen auf 1024 px bzw. 768 px nach. Die bestehenden
   Bloecke bleiben unangetastet; weil dieser Abschnitt spaeter in der
   Datei steht, gewinnt er bei gleicher Spezifitaet.

   NICHT NUR CSS: In der Sprungnavigation (Oxygen-Element
   `JavaScript Code`) steht die Konstante BRUCH_MOBIL auf 960. Die
   Zahl muss zur Media Query in 25.2 passen, sonst schliesst sich das
   Flyout zwischen 961 und 1024 px nach einem Klick nicht von selbst.
   Auf 1024 aendern.

   Was hier steht:
     25.1  Sektionsgeometrie einspaltig bis 1024 px
     25.2  Sprungnavigation eingeklappt bis 1024 px
     25.3  Menuezeile bis 768 px
   =================================================================== */

/* -------------------------------------------------------------------
   25.1 Sektionsgeometrie einspaltig bis 1024 px
   Inhaltsgleich mit dem bestehenden 960er-Block in Abschnitt 12, nur
   mit hoeherer Schwelle. Zwischen 0 und 960 px greifen beide und sagen
   dasselbe — kein Konflikt.
   ------------------------------------------------------------------- */
@media (max-width: 1024px) {
  .viz-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .viz-karte[data-chart="zeitreihe"],
  #s-verlauf,
  #s-generationen,
  .viz-karte[data-chart="ausbildung"],
  #s-laender,
  #s-fluss,
  #s-dauer,
  #s-stellen,
  #s-schulung,
  #s-branche,
  #s-eurang,
  #s-eukarte {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
  .viz-karte[data-chart="zeitreihe"] .viz-kopfzeile {
    grid-column: 1;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    padding-top: 0;
    margin-bottom: var(--s, 0.8rem);
  }
  .viz-karte[data-chart="zeitreihe"] .viz-chart,
  #s-verlauf .viz-chart,
  .viz-karte[data-chart="ausbildung"] .viz-chart {
    grid-column: 1;
    padding: 0;
    min-height: 260px;
  }
  #s-verlauf .viz-kopfzeile {
    grid-column: 1;
    padding-top: 0;
    margin-bottom: var(--s, 0.8rem);
  }
  #s-verlauf .viz-knopfreihe {
    flex-direction: row;
    align-items: center;
  }
  #s-verlauf .viz-einbetten {
    margin-left: auto;
  }
  #s-generationen .viz-chart,
  #s-fluss .viz-chart,
  #s-dauer .viz-chart,
  #s-stellen .viz-chart,
  #s-schulung .viz-chart,
  #s-branche .viz-chart,
  #s-eurang .viz-chart {
    grid-column: 1;
    grid-row: auto;
    padding: 0;
    min-height: 260px;
  }
  #s-generationen .viz-kopfzeile {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    padding-top: 0;
    margin-bottom: var(--s, 0.8rem);
  }
  #s-generationen #h-generationen,
  #s-fluss #h-fluss,
  #s-dauer #h-dauer,
  #s-stellen #h-stellen,
  #s-schulung #h-schulung,
  #s-branche #h-branche,
  #s-eurang #h-eurang,
  #s-eukarte #h-eukarte {
    grid-column: 1;
    grid-row: auto;
  }
  .viz-karte[data-chart="ausbildung"] .viz-kopfzeile,
  #s-laender .viz-kopfzeile {
    grid-column: 1;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--s, 0.8rem);
  }
  #s-laender #t-laender {
    grid-column: 1;
    padding: 0;
  }
  #s-fluss .viz-kopfzeile,
  #s-dauer .viz-kopfzeile,
  #s-stellen .viz-kopfzeile,
  #s-schulung .viz-kopfzeile,
  #s-branche .viz-kopfzeile,
  #s-eurang .viz-kopfzeile,
  #s-eukarte .viz-kopfzeile {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--s, 0.8rem);
  }
  #s-eukarte .viz-chart {
    grid-column: 1;
    grid-row: auto;
    padding: 0;
    min-height: 480px;
  }
  .viz-karte[data-chart="karte"] {
    padding: var(--s, 0.8rem);
  }
}

/* -------------------------------------------------------------------
   25.2 Sprungnavigation eingeklappt bis 1024 px
   Inhaltsgleich mit 24.6, nur mit hoeherer Schwelle. `display: block`
   schaltet das zweispaltige Raster aus 24.2 ab; die dortigen
   grid-column/grid-row-Angaben (auch die, die das Skript inline setzt)
   sind in einem Block-Container wirkungslos.
   ------------------------------------------------------------------- */
:root {
  --viz-nav-bruch: 1024px;   /* nur Doku, siehe 24.1 */
}
@media (max-width: 1024px) {
  .viz-nav-raster {
    display: block;
  }
  .viz-nav {
    position: sticky;
    top: var(--viz-nav-abstand, 24px);
    margin-bottom: var(--m, 1.25rem);
    max-height: min(70dvh, calc(100dvh - var(--viz-nav-abstand, 24px) - var(--viz-nav-boden, 24px)));
  }
  .viz-nav:not(.viz-nav-offen) {
    overflow: hidden;
  }
  .viz-nav:not(.viz-nav-offen) ol {
    display: none;
  }
  .viz-nav-schalter {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    box-sizing: border-box;
    min-width: 44px;
    min-height: 44px;
    padding: 0 12px;
    font: inherit;
    font-size: var(--xs, 0.8rem);
    color: var(--viz-text, #000);
    background: var(--viz-plane, #f9f9f7);
    border: 1px solid var(--viz-border, #5a5a5a);
    border-radius: var(--viz-radius-s, 6px);
    cursor: pointer;
  }
  .viz-nav-schalter::after {
    content: "";
    width: 8px;
    height: 8px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform .2s ease;
  }
  .viz-nav-schalter[aria-expanded="true"] {
    border-color: var(--viz-series-1, #2a78d6);
  }
  .viz-nav-schalter[aria-expanded="true"]::after {
    transform: translateY(2px) rotate(-135deg);
  }
  .viz-nav-schalter:focus-visible {
    outline: 2px solid var(--viz-series-1, #2a78d6);
    outline-offset: 2px;
  }
}

/* -------------------------------------------------------------------
   25.3 Menuezeile bis 768 px
   Inhaltsgleich mit dem 700er-Block am Ende von Abschnitt 13. 768 px
   ist die Hochkantbreite des iPad — dort fehlte bisher das seitliche
   Polster, und Impressum/Datenschutz liefen aus der Zeile heraus.
   ------------------------------------------------------------------- */
@media (max-width: 768px) {
  .viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu {
    margin: 0 auto var(--s, 0.8rem);
    padding: 0 var(--s, 0.8rem);
  }
  .viz-menu-mit-knopf > ul {
    display: none;
  }
  .viz-root .viz-menu .viz-menu-flyout-links {
    display: block;
  }
  .viz-menu {
    flex-wrap: nowrap;
  }
}


/* ===================================================================
   Abschnitt 26 — MENUEZEILE BUENDIG ZUM CONTAINER (NUR ANGEHAENGT)
   Version v43, 18.08.2026

   Das Problem: die Menuezeile klebte auf Tablet und Handy an den
   Fensterkanten, waehrend die Karten eingerueckt standen.

   Ursache: Das Skript hebt die Zeile aus dem Container heraus, damit
   sie ausserhalb der weissen Flaeche steht (v36). Damit verliert sie
   aber auch dessen seitliches Polster. `.viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu` stand
   deshalb auf `padding: 0` — die Zeile lief bis an den Rand, die
   Karten begannen erst bei 96 px (1024) bzw. 38 px (768).

   Der 700er-Block in Abschnitt 13 und 25.3 setzten zwar ein Polster,
   aber ein eigenes (`var(--s)`, rund 14 px) — zu wenig, und es passte
   zu nichts. Beide werden hier ueberschrieben.

   Gemessen wird gegen `.container`, das Oxygen so polstert:
     ueber 1023 px   var(--xxxxxl)   96 px
     bis  1023 px    2.4rem          38,4 px
     bis   767 px    1.56rem         24,96 px
   Dieselben Schwellen und Werte stehen unten. WENN SICH DAS POLSTER
   DES THEMES AENDERT, MUSS DIESER BLOCK MIT — die Werte lassen sich
   nicht aus einem gemeinsamen Token ableiten, weil Oxygen unterhalb
   von 1023 px eigene Zahlen setzt statt `--xxxxxl` zu skalieren.

   Nachgemessen im iframe gegen die Live-Seite bei 1400/1119/1024/834/
   768/600/480 px: Versatz zwischen Menuetext und Kartenkante 0 px auf
   allen sieben Breiten, kein Ueberlauf.
   =================================================================== */

.viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu {
  padding-left: var(--xxxxxl);
  padding-right: var(--xxxxxl);
}
@media (max-width: 1023px) {
  .viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu {
    padding-left: var(--s);
    padding-right: var(--s);
  }
}
@media (max-width: 767px) {
  .viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu {
    padding-left: var(--s);
    padding-right: var(--s);
  }
}


/* ===================================================================
   Abschnitt 27 — LAYOUT-SPRUENGE (CLS), NUR ANGEHAENGT
   Version v44, 18.08.2026

   Messung 18.08.: CLS 0,45 auf der Startseite. Core Web Vitals werten
   ab 0,1 als "gut", ab 0,25 als "schlecht". Es war EIN grosser Sprung
   bei rund 1,2-1,9 s, nicht viele kleine — genau dann, wenn die Daten
   ankommen. Zwei Ursachen, beide muessen weg; einzeln bringt keine den
   Wert unter 0,25:

   1. NEUN VON VIERZEHN KARTEN stehen im Markup auf `display: none` und
      werden eingeblendet, sobald ihre Daten da sind. Die Seite waechst
      dabei auf einen Schlag um mehrere Bildschirmhoehen.
      -> Karten von Anfang an anzeigen. Ihr `.viz-chart`-Feld hat schon
         eine feste Hoehe, der Platz stimmt also im Wesentlichen; es
         fuellt sich nur der Rahmen, statt dass er entsteht.
      Gemessen allein: 0,447 -> 0,161.

   2. DIE MENUEZEILE waechst von 25 auf 40 px, sobald das
      Navigationsskript den MENUE-Knopf einhaengt (`min-height: 40px`
      am Knopf). Das schiebt den gesamten Container nach unten.
      -> Zeile von vornherein auf Knopfhoehe stellen. 40 px stimmen auf
         allen gemessenen Breiten (1200/1024/768/600/480/390).
      Gemessen allein: 0,447 -> 0,273.

   Zusammen gemessen: 0,10 bis 0,13 bei 1024-1200 px. Auf schmalen
   Fenstern bleibt mehr uebrig (768 px: 0,27; 480 px: 0,41) — dort
   fliesst der Text der Hinweiszeilen ueber mehr Zeilen um, sobald er
   ankommt. Das ist noch offen.

   NEBENWIRKUNG, BEWUSST IN KAUF GENOMMEN (User-Entscheid 18.08.):
   Eine Karte, deren Daten ausfallen, bleibt jetzt als leerer Rahmen
   mit Ueberschrift stehen, statt zu verschwinden. Vorher verbarg
   `display: none` den Ausfall — was ihn auch vor uns verbarg.

   `!important` ist noetig, weil `display: none` als Attribut am
   Element steht (Inline-Stil schlaegt jede Regel ohne `!important`).
   =================================================================== */

/* 27.1 Karten belegen ihren Platz von Anfang an.
   Zwei Zeilen, weil die Karten zwei verschiedene Anzeigearten haben:
   die schlichten sind Bloecke, die zweispaltigen aus Abschnitt 10 sind
   Raster. Die Liste unten ist dieselbe wie dort. */
.viz-root .viz-karte {
  display: block !important;
}
.viz-root .viz-karte[data-chart="zeitreihe"],
.viz-root #s-verlauf,
.viz-root #s-generationen,
.viz-root .viz-karte[data-chart="ausbildung"],
.viz-root #s-laender,
.viz-root #s-fluss,
.viz-root #s-dauer,
.viz-root #s-stellen,
.viz-root #s-schulung,
.viz-root #s-branche,
.viz-root #s-eurang,
.viz-root #s-eukarte {
  display: grid !important;
}

/* 27.2 Menuezeile auf Knopfhoehe, bevor der Knopf da ist. */
.viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu {
  min-height: 40px;
}


/* ===================================================================
   Abschnitt 28 — PLATZ FUER SPAETER GEFUELLTE BLOECKE (NUR ANGEHAENGT)
   Version v45, 18.08.2026

   Lighthouse (gedrosselt, 1024 px) meldete CLS 0,492 — also deutlich
   mehr als die 0,133, die ohne Drosselung messbar waren. Der Grund:
   gedrosselt kommen die Daten spaeter, die Spruenge fallen groesser
   aus. Lighthouse benannte als Verursacher `oxy-html-code-11-116`
   (die erste Karte) und den Container darueber — nicht die Karten
   selbst, sondern was UEBER ihnen waechst.

   Nachgemessen mit previousRect/currentRect waren es drei Bloecke,
   die im HTML leer stehen und erst per JavaScript gefuellt werden.
   Jeder schiebt alles unter sich nach unten:

     .viz-kpis   die vier Kennzahlkacheln   0 -> 150 bis 299 px
     #fuss       der Quellenblock unter dem
                 Titel ("Datenquellen: ...") 0 -> 102 bis 184 px
     .viz-menu   Liste + Absatz brechen vor
                 dem Skript ueber mehrere
                 Zeilen um, danach eine Zeile 150 -> 40 px (Ruck NACH OBEN)

   Die Hoehen wurden je Breite im Browser gemessen (1400/1200/1024/
   768/600/480/390 px) und auf die naechstliegende Schwelle gelegt.
   Sie muessen nicht exakt stimmen — jede reservierte Hoehe, die nahe
   am Endwert liegt, nimmt den Sprung fast vollstaendig heraus.

   Ergebnis (ungedrosselt gemessen, je Breite):
     vorher   0,447 bis 0,450 auf allen Breiten
     nachher  1400: 0,093 · 1200: 0,105 · 1024: 0,074
              768: 0,101 · 480: 0,100 · 390: 0,106
   Gedrosselt wird es darueber liegen, aber nicht mehr in der
   Groessenordnung von 0,49.

   ACHTUNG BEI DEN SCHWELLEN: 1024 und 768 sind unsere eigenen
   (Abschnitt 25), 1023 ist Oxygens. Das ist kein Tippfehler — die
   KPI-Kacheln schalten bei unserer Schwelle um, der Quellenblock
   bricht bei Oxygens Container-Breite um.

   NEBENWIRKUNG: Unter 768 px ist die Linkliste (Methodik, Impressum,
   Datenschutz) schon vor dem Skript ausgeblendet, nicht erst danach.
   Faellt das JavaScript aus, sind die drei Links auf dem Handy nicht
   erreichbar — bisher waeren sie sichtbar geblieben. Das Dashboard
   selbst braucht ohnehin JavaScript.
   =================================================================== */

/* 28.1 Kennzahlkacheln und Quellenblock */
.viz-root .viz-kpis {
  min-height: 150px;
}
.viz-root #fuss {
  min-height: 102px;
}
@media (max-width: 1024px) {
  .viz-root .viz-kpis {
    min-height: 249px;   /* zwei Spalten statt vier */
  }
}
@media (max-width: 1023px) {
  .viz-root #fuss {
    min-height: 123px;   /* Oxygens Container wird schmaler, Text bricht um */
  }
}
@media (max-width: 560px) {
  .viz-root .viz-kpis {
    min-height: 289px;
  }
  .viz-root #fuss {
    min-height: 143px;
  }
}
@media (max-width: 420px) {
  .viz-root .viz-kpis {
    min-height: 299px;
  }
  .viz-root #fuss {
    min-height: 184px;
  }
}

/* 28.2 Menuezeile: Endzustand von Anfang an.
   Vor dem Skript stehen Absatz und Liste noch nebeneinander und
   brechen um; danach wandert die Liste ins Flyout und die Zeile ist
   40 px hoch. Der Unterschied war bei 480 px ein Ruck von 109 px
   nach oben — der groesste Einzelposten auf schmalen Fenstern. */
@media (max-width: 768px) {
  .viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu {
    flex-wrap: nowrap;
  }
  .viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu > ul {
    display: none;
  }
  .viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu > p {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}


/* ===================================================================
   Abschnitt 29 — GLAS-UEBERZUG UND MENUE VOR DEM SKRIPT
   Version v46, 18.08.2026

   Nach Abschnitt 28 meldete Lighthouse immer noch CLS 0,396 (vorher
   0,492), waehrend ohne Drosselung 0,074 bis 0,106 messbar waren. Die
   "Layout shift culprits" nannten:

     0,231   div.oxy-container-11-101 > ::before
     0,150   div.oxy-html-code-11-116  (die erste Karte)
     0,015   dieselbe Karte, zweiter Sprung

   29.1 DER GROESSTE POSTEN IST EIN MESSARTEFAKT.
   Genau EIN Element traegt die Klasse `.glas`: der Hauptcontainer,
   7874 px hoch. Sein `::before` liegt als `position: absolute;
   inset: 0` darueber und zeichnet nichts als eine 1 px Linie. Waehrend
   die Diagramme rendern, waechst der Container von rund 5900 auf
   7900 px — und der Ueberzug waechst mit. Chrome verbucht diese
   Rechteckaenderung als Layout-Sprung, obwohl sichtbar nichts
   springt: die Linie sitzt ja weiter am Rand.

   Die Linie wandert deshalb an das Element selbst. Gemessen: gleiche
   Breite, gleiche Farbe, gleicher Radius, 2 px mehr Hoehe. Optisch
   identisch, aber ohne mitwachsenden Ueberzug.

   `.glas` wird nur von diesem einen Container benutzt (im Frontend
   geprueft), die Regel trifft also nichts anderes.

   29.2 MENUEZEILE VOR DEM UMHAENGEN.
   Abschnitt 27 und 28 sprechen die Zeile als `.viz-root > .viz-menu, .viz-root > .oxy-html-code-11-146 > .viz-menu`
   an — als DIREKTES Kind. Das ist sie aber erst, nachdem das Skript
   sie aus dem Container gehoben hat. Vorher steckt sie in
   `oxy-html-code-11-104` und keine der Regeln greift. Die Hoehen-
   und Umbruchvorgaben gelten deshalb ab jetzt fuer jedes `.viz-menu`
   unterhalb von `.viz-root`.

   Das seitliche Polster aus Abschnitt 26 bleibt bewusst am direkten
   Kind: vor dem Umhaengen sitzt die Zeile im Container und hat dessen
   Polster schon.
   =================================================================== */

/* 29.1 Glas-Linie ans Element statt in einen Ueberzug */
.viz-root .glas::before {
  content: none;
}
.viz-root .glas {
  border: 1px solid var(--viz-glas-edge, #e5e5e5);
}

/* 29.2 Menuevorgaben auch vor dem Umhaengen */
.viz-root .viz-menu {
  min-height: 40px;
}
@media (max-width: 768px) {
  .viz-root .viz-menu {
    flex-wrap: nowrap;
  }
  .viz-root .viz-menu > ul:not(.viz-menu-flyout-links) {
    display: none;
  }
  .viz-root .viz-menu > p {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ===================================================================
   Abschnitt 30 — SEITE HOERT AUF ZU WACHSEN (NUR ANGEHAENGT)
   Version v47, 18.08.2026

   Grundlage ist eine Performance-Aufzeichnung unter Slow 4G und
   4x CPU (User, 18.08.). Sie zeigt: das schlimmste Sprungbuendel
   liegt bei 4,63 s — genau dann, wenn die letzten Datendateien
   ankommen. DevTools selbst schrieb dazu "Could not detect any
   layout shift culprits". Also nicht weiter nach dem schuldigen
   Element suchen, sondern die Ursache dahinter abstellen: die Seite
   waechst beim Laden um 940 px, weil leere Bloecke gefuellt werden.

   Gemessen, welche Bloecke das sind (828 px Fensterbreite,
   Container-Hoehe 1,2 s nach dem Laden gegen 10 s danach):

     #t-laender        Bundeslaender-Tabelle   0 -> 443 px
     .viz-unterzeile   13 Unterzeilen          0 -> je 18 px
     p[id^=h-]         10 Hinweiszeilen        0 -> je 36-90 px

   Reserviert wird jeweils der KLEINSTE ueber alle Breiten gemessene
   Wert (1400/1024/828/480/390 px). min-height ist eine Untergrenze:
   ist der Inhalt spaeter groesser, waechst der Block normal weiter —
   ist er kleiner, entstuende eine Luecke. Mit dem Minimum kann keine
   Luecke entstehen. Nachgemessen: keine.

   Ergebnis: Wachstum des Containers 940 -> 77 px (828 px Breite)
   bzw. 68 px (1024 px). Die Seite steht beim Laden praktisch still.

   EHRLICH DAZU: In meiner eigenen gedrosselten Messung aendert das
   den CLS-Wert nicht (0,122 -> 0,121). Lighthouse rechnet den
   wachsenden Container aber mit 0,231 an — ob dieser Posten damit
   faellt, zeigt erst der naechste Lauf. Unabhaengig davon ist das
   Ruhigstellen der Seite fuer sich genommen richtig: der Inhalt
   springt beim Laden nicht mehr unter dem Finger weg.
   =================================================================== */

.viz-root .viz-karte .viz-unterzeile {
  min-height: 18px;
}
.viz-root .viz-karte p[id^="h-"] {
  min-height: 36px;
}
.viz-root #h-generationen {
  min-height: 54px;
}
.viz-root #h-eukarte {
  min-height: 72px;
}
.viz-root #t-laender {
  min-height: 424px;
}


/* -------------------------------------------------------------------
   Abschnitt 31 (v45, 19.08.2026) - Einfuehrungstext im Kopfbereich
   SEO-Befund 5: die Startseite lieferte im HTML als einzigen Inhaltstext
   "Daten werden geladen ..." - vierzehn H2 ohne einen Satz dazwischen.
   Der Absatz steht jetzt FEST im Markup des Elements "Quellen" (Seite 11),
   ueber dem Quellenblock, und wird von kern.js nicht ueberschrieben.

   Warum eine eigene Klasse: --viz-font ist seit dem LifeOS-Restyling global
   monospace. Ohne Regel kaeme der Einfuehrungstext in Monospace und waere
   als Fliesstext schwer zu lesen. Figtree wie h1/h2/.viz-unterzeile/.viz-fuss
   (Token --viz-font-titel, siehe Abschnitt 1).

   max-width in ch statt px: begrenzt die Zeile auf rund 70 Zeichen,
   unabhaengig von der Schriftgroesse. Laengere Zeilen verliert das Auge
   beim Ruecksprung.
   ------------------------------------------------------------------- */

.viz-root .viz-intro {
  margin: 0 0 var(--s, 0.8rem);
  max-width: 70ch;
  font-family: var(--viz-font-titel);
  font-size: 1rem;
  line-height: 1.55;
}
.viz-root .viz-intro:last-of-type {
  margin-bottom: var(--m, 1.25rem);
}

/* ===================================================================
   Abschnitt 32 - EINORDNUNGSSAETZE INS RASTER (NUR ANGEHAENGT)
   Version v46, 19.08.2026

   BEFUND
   Seit dem Einbau der Einordnungssaetze (19.08., 14 Karten) sind vier
   Karten zu hoch und der Satz haengt links unter der Kopfzeile in der
   Luft:

     #s-zeitreihe   579 px statt 496
     #s-ausbildung  677 px statt 576
     #s-laender     732 px statt 631
     #s-verlauf     dieselbe Konstruktion

   URSACHE - nicht der Text, sondern die Rastergeometrie.
   Die zehn Saetze, die die Pipeline schon vorher lieferte, tragen eine
   Kennung (#h-dauer, #h-fluss ...) und werden von Abschnitt 10
   ausdruecklich gesetzt: der Satz auf grid-area 2 / 1 bzw. 2 / 4, die
   Grafik auf grid-row 1 / span 2. Die Grafik spannt also ueber beide
   Zeilen, Kopfzeile und Satz stehen daneben - die Karte waechst nicht.

   Die vier neuen Saetze sind reiner WordPress-Text ohne Gegenstueck in
   der Pipeline und wurden deshalb ohne Kennung eingesetzt, als
   <p class="viz-unterzeile">. Keine Regel greift, das Raster stellt sie
   automatisch ab: Zeile 2, Spalte 1. Die Grafik steht aber nur in
   Zeile 1 - also entsteht eine zweite Zeile von 84 bis 102 px, die die
   Karte nach unten aufzieht.

   LOESUNG
   Dieselbe Geometrie wie bei den zehn anderen. Angesprochen wird der
   Satz ueber > p.viz-unterzeile (direktes Kind der Sektion); die
   Unterzeile im Kopf steht in header > div und bleibt unberuehrt. Wird
   spaeter doch eine Kennung id="h-..." ins Oxygen-Markup nachgetragen,
   greift diese Regel unveraendert weiter.

   NACHGEMESSEN am 19.08. im Frontend (1403 px):
     s-zeitreihe  579 -> 496 px   (Referenz s-dauer: 496)
     s-ausbildung 677 -> 576 px
     s-laender    732 -> 631 px
   Tabellenschalter geprueft: die Tabelle oeffnet weiterhin unter der
   Karte (Zeile 3), nicht in die Satzzeile hinein.
   =================================================================== */

#s-zeitreihe > .viz-chart,
#s-ausbildung > .viz-chart,
#s-verlauf > .viz-chart,
#s-laender > #t-laender {
  grid-row: 1 / span 2;
}
#s-zeitreihe > p.viz-unterzeile,
#s-ausbildung > p.viz-unterzeile,
#s-verlauf > p.viz-unterzeile,
#s-laender > p.viz-unterzeile {
  grid-area: 2 / 1;
  align-self: center;
}

/* -------------------------------------------------------------------
   32.1 Einspaltig bis 1024 px zuruecknehmen
   Spiegelbild zu 25.1, wo dasselbe fuer die zehn #h-...-Saetze steht.
   Ohne diesen Block blieben Zeilenspannen und feste Rasterplaetze im
   einspaltigen Umbruch stehen.
   ------------------------------------------------------------------- */
@media (max-width: 1024px) {
  #s-zeitreihe > .viz-chart,
  #s-ausbildung > .viz-chart,
  #s-verlauf > .viz-chart,
  #s-laender > #t-laender,
  #s-zeitreihe > p.viz-unterzeile,
  #s-ausbildung > p.viz-unterzeile,
  #s-verlauf > p.viz-unterzeile,
  #s-laender > p.viz-unterzeile {
    grid-column: 1;
    grid-row: auto;
    align-self: auto;
  }
}


/* -------------------------------------------------------------------
   Abschnitt 33 (v47, 19.08.2026) - Fehlerseite 404
   SEO-Befund 8. Das Markup kommt aus idl-functions.php (idl_404_inhalt),
   weil das Oxygen Zero Theme fuer 404 nichts ausgibt und die Installation
   kein einziges Oxygen-Template hat - eines nur fuer die Fehlerseite
   anzulegen waere ein groesserer Eingriff als noetig.

   Zwei Zeilen genuegen: Luft nach oben und unten, damit die Karte nicht
   an der Fensterkante klebt, und die Verweise in der Textfarbe statt im
   Browserblau (#0000ee), das hier sonst als einzige Farbe der Seite
   auffiele.
   ------------------------------------------------------------------- */

.viz-404 {
  padding: var(--xxl, 3rem) 0;
}
.viz-404 a {
  color: inherit;
}


/* ===================================================================
   ABSCHNITT 34 — DUNKELMODUS (NUR ANGEHAENGT)
   Version v48, 19.08.2026

   ANHAENGEN, NICHT ERSETZEN. Dieser Block kommt UNTEN an die Datei
   `idl.css` im Plugin *Identity Lab – Functions & Code*. Oberhalb
   wird nichts geaendert. Vor dem Speichern das Praefix gegen die
   ausgelieferte Datei diffen (Vorgehen wie bei Abschnitt 32).

   WAS DAS IST
   Das Dashboard folgt ab hier der Systemeinstellung. Kein Schalter,
   kein JavaScript, kein localStorage — User-Entscheid 19.08.:
   „ich will nur auto". Damit ist der Modus beim ersten Bild
   entschieden und aendert sich waehrend des Besuchs nicht.

   WARUM DAS DIE EINFACHE FASSUNG IST
   `kern.js` liest alle Farben EINMAL beim Aufbau der Diagramme
   (`stil()`, Zeile 29) und nie wieder. Steht das Farbschema schon
   vor dem ersten Bild fest, bekommen die 13 ECharts-Grafiken von
   sich aus die richtigen Farben. Ein Schalter haette dagegen einen
   Neuaufbau zur Laufzeit gebraucht — `baueAlles()` ist als Closure
   in `start()` eingeschlossen und muesste als `AMS.neuBauen`
   veroeffentlicht werden, mit Commit und Pages-Deploy. Faellt weg.

   BLEIBENDE LUECKE: Wechselt jemand die Systemeinstellung, waehrend
   die Seite offen ist, folgt die Seite sofort, die Diagramme aber
   erst nach einem Neuladen. Behebbar nur ueber den oben genannten
   Neuaufbau. Bewusst offen gelassen.

   PALETTE B — weiches Anthrazit (User-Entscheid 19.08. nach
   Sichtpruefung gegen A/Tiefschwarz). Alle Werte sind gerechnet:
   0 Verletzungen der Sollkontraste, divergierende Rampe ueber
   CIE76-DeltaE >= 9,4 geprueft. Rechenweg: dunkelmodus-kontrast.py,
   Befunde: dunkelmodus.md.

   NICHT HIER: `docs/index.html` und `docs/embed.html` im Repo
   `arbeitsmarkt-at` tragen noch den alten Dunkelblock in der bunten
   Palette von vor dem Restyling v31. Der wird separat nachgezogen.

   Was hier steht:
     34.1  Tokensatz dunkel
     34.2  Die elf hart codierten Hellwerte aus idl.css
     34.3  Seitenrahmen ausserhalb von .viz-root
     34.4  Rechts- und Methodikseiten (.viz-recht)
     34.5  Druck
   =================================================================== */

/* -------------------------------------------------------------------
   34.1 Tokensatz dunkel

   Spiegelt Abschnitt 1. Zwei Regeln, die beim Entwurf teuer erkauft
   wurden und nicht aus Versehen „aufgeraeumt" werden sollten:

   SERIENRAMPE NICHT SPIEGELN. Der naheliegende Weg — Helligkeit der
   hellen Palette umkehren — zerstoert sie: `--viz-series-3` (#c9c9c9,
   79 % Helligkeit) wuerde zu #363636 und staende bei 1,4:1 auf der
   Karte. Erhalten bleibt die REIHENFOLGE (1 hellster, dann 4, 2, 6,
   3, 5), die Werte sind in die helle Haelfte gestaucht. Alle sechs
   liegen ueber 3,0:1.

   SEQUENZRAMPE UMKEHREN. Hell laeuft sie hell (wenig) -> dunkel
   (viel), dunkel muss sie dunkel -> hell laufen. Sonst verschwindet
   die unterste Stufe im Kartengrund.

   Zwei neue Tokenpaare:
     --viz-invers-*      Umkehrpaar der Aktivpille, damit 34.2 in
                         beiden Schemata dieselbe Regel behaelt
     --viz-maennlich/    Zeitreihe Maenner/Frauen. Standen bis v44
     --viz-weiblich      fest im JavaScript; die Werte hier sind die
                         Dunkelfassung, die Hellwerte bleiben als
                         Rueckfall im Skript stehen.
                         -> oxygen-javascript-zeitreihe-zusatz.txt
   ------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  .viz-root,
  #dashboard {
    color-scheme: dark;

    --viz-surface: #1c1f21;
    --viz-plane: #161819;
    --viz-surface-glas: #1c1f21;
    --viz-surface-glas-border: rgb(255 255 255 / .08);

    --viz-text: #e9eaea;
    --viz-text-2: #e9eaea;
    --viz-muted: #9aa0a3;

    --viz-grid: #2b2f31;
    --viz-axis: #42484c;
    --viz-border: #373d41;

    /* Reihenfolge wie hell: 1 > 4 > 2 > 6 > 3 > 5 */
    --viz-series-1: #e9eaea;
    --viz-series-2: #9ca4a8;
    --viz-series-3: #757d81;
    --viz-series-4: #c6ccd0;
    --viz-series-5: #626a6e;
    --viz-series-6: #868e92;

    /* umgekehrte Leserichtung: 1 wenig, 6 viel */
    --viz-seq-1: #292f32;
    --viz-seq-2: #3c4347;
    --viz-seq-3: #555d62;
    --viz-seq-4: #7b8489;
    --viz-seq-5: #a6aeb2;
    --viz-seq-6: #dde2e4;

    --viz-gut: #3fd069;
    --viz-kritisch: #f77070;

    --viz-div-neutral: #2e3336;
    --viz-div-gut-1: #1a3327;
    --viz-div-gut-2: #204d38;
    --viz-div-gut-3: #276b4b;
    --viz-div-gut-4: #309362;
    --viz-div-schlecht-1: #3a2224;
    --viz-div-schlecht-2: #582c2f;
    --viz-div-schlecht-3: #80393c;
    --viz-div-schlecht-4: #b84a4d;

    --viz-glas-fill: #1c1f21;
    --viz-glas-edge: #373d41;

    --viz-invers-grund: #e9eaea;
    --viz-invers-text: #131516;

    --viz-maennlich: #5c9ee8;
    --viz-weiblich: #e87ba4;
  }

/* -------------------------------------------------------------------
   34.2 Die elf hart codierten Hellwerte aus idl.css

   Ein zweiter Tokensatz reicht NICHT. An elf Stellen steht oben eine
   feste Farbe statt eines Tokens; ohne diesen Unterabschnitt bleiben
   Karten, Kacheln und Sektionen weiss. Die Selektoren sind woertlich
   aus idl.css uebernommen — wer dort etwas umbenennt, muss hier mit.

   Die Selektoren tragen `.viz-root` als Vorfahr, damit sie nicht
   bloss ueber die Reihenfolge gewinnen: wird die Datei je wieder
   geflattet, bleibt die Wirkung erhalten.
   ------------------------------------------------------------------- */
  .viz-root .viz-karte,
  .viz-root .viz-kpi,
  .viz-root .glas,
  .viz-root .viz-karte[data-chart="karte"],
  .viz-root .viz-karte[data-chart="zeitreihe"],
  .viz-root .viz-karte[data-chart="ausbildung"],
  .viz-root #s-verlauf,
  .viz-root #s-generationen,
  .viz-root #s-laender,
  .viz-root #s-fluss,
  .viz-root #s-dauer,
  .viz-root #s-stellen,
  .viz-root #s-schulung,
  .viz-root #s-branche,
  .viz-root #s-eurang,
  .viz-root #s-eukarte {
    background: var(--viz-surface);
  }

  /* Aktivpille und Menueknopf: hell steht Weiss auf #0a0a0a,
     dunkel wird daraus Dunkel auf Hell. */
  .viz-root .viz-modus button[aria-pressed="true"],
  .viz-root .viz-menu-knopf[aria-expanded="true"] {
    color: var(--viz-invers-text);
    background: var(--viz-invers-grund);
    border-color: var(--viz-invers-grund);
  }

  /* `background` bleibt --viz-series-1 wie hell; die Schriftfarbe war
     fest #fff und muss mitkippen, sonst Weiss auf Fastweiss. */
  .viz-root dialog.viz-dialog button.primaer {
    color: var(--viz-invers-text);
  }

  /* Der Schirm des Dialogs steht hell auf 35 % Schwarz — auf dunklem
     Grund traegt das nicht mehr, der Dialog schwebt nicht. */
  .viz-root dialog.viz-dialog::backdrop {
    background: rgb(0 0 0 / 0.68);
  }

  /* Schlagschatten sind auf dunklem Grund fast unsichtbar. Verstaerkt,
     die eigentliche Abgrenzung leistet die Randlinie. */
  .viz-root .viz-menu-flyout .viz-nav,
  .viz-root .viz-menu .viz-menu-flyout-links {
    box-shadow: 0 12px 32px rgb(0 0 0 / 0.55);
  }

/* -------------------------------------------------------------------
   34.3 Seitenrahmen ausserhalb von .viz-root

   Ohne diesen Teil steht ein dunkles Dashboard in einer weissen
   Seite. `color-scheme` am Wurzelelement zieht zusaetzlich
   Bildlaufleisten und Formularelemente des Browsers mit.

   Der Grundton ist eine Spur dunkler als die Karten (#131516 gegen
   #1c1f21) — dieselbe Staffelung wie hell, wo die Karten heller sind
   als der Grund. Sonst verlieren die Karten ihre Kante.
   ------------------------------------------------------------------- */
  :root {
    color-scheme: dark;
  }
  body {
    background: #131516;
    color: #e9eaea;
  }

/* -------------------------------------------------------------------
   34.4 Rechts- und Methodikseiten

   /impressum/, /datenschutz/ und /methodik/ benutzen nicht das
   Dashboard-CSS, sondern die Teilmenge `.viz-recht` (Quelle:
   oxygen-impressum.txt Paragraf 1). Sie definiert ihre Token selbst
   und setzt `color-scheme: light` — beides wird hier ueberschrieben.

   ACHTUNG: greift nur, wenn idl.css auf diesen drei Seiten ueberhaupt
   geladen wird (`wp_enqueue_style` in idl-functions.php). Wird sie
   dort nicht ausgeliefert, gehoert dieser Unterabschnitt zusaetzlich
   in das Element `CSS Code` jeder der drei Seiten.
   ------------------------------------------------------------------- */
  .viz-recht {
    color-scheme: dark;
    --viz-plane: #161819;
    --viz-surface: #1c1f21;
    --viz-text: #e9eaea;
    --viz-muted: #9aa0a3;
    --viz-border: #373d41;
  }

/* -------------------------------------------------------------------
   34.5 Druck
   Papier ist weiss. Ohne diesen Block druckt der Browser je nach
   Einstellung dunkle Flaechen oder — haeufiger — helle Schrift auf
   Weiss, also nichts.
   ------------------------------------------------------------------- */
  @media print {
    :root { color-scheme: light; }
    body { background: #ffffff; color: #0a0a0a; }
    .viz-root .viz-karte,
    .viz-root .viz-kpi,
    .viz-root .glas,
    .viz-recht .viz-karte {
      background: #ffffff;
      color: #0a0a0a;
    }
  }
}


/* -------------------------------------------------------------------
   Abschnitt 34 (v48, 19.08.2026) - CLS: Hoehe der Datenstandzeile
   Lighthouse (Slow 4G, 1440 x 868) nennt zwei Verursacher: die KPI-Zeile
   (oxy-html-code-11-108) und den Container. Beide bewegen sich nicht
   selbst - sie werden geschoben, weil der Kopfbereich seine Hoehe
   aendert. Mit einem PerformanceObserver im 1440er Rahmen nachgemessen:
   eine Verschiebung bei 744 ms, die KPI-Zeile springt 25 px.

   Ein Teil davon ist .viz-lead: im Markup steht "Daten werden geladen ..."
   (eine Zeile), kern.js ersetzt es durch "Registrierte Arbeitslose,
   Stand ... zuletzt aktualisiert am ..." (zwei Zeilen). 18 px, die alles
   darunter nach unten schieben.

   Die Endhoehen sind bei sieben Breiten gemessen. Reserviert wird genau
   der gemessene Wert, nirgends mehr - sichtbar aendert sich dadurch
   nichts, nur der Startzustand stimmt:

     bis 600 px      36 px   zweizeilig (Handy, einspaltig)
     601 - 767 px    18 px   einzeilig (breiteste Spalte im Verhaeltnis)
     768 - 799 px    54 px   dreizeilig (schmalste Spalte ueberhaupt)
     ab 800 px       36 px   zweizeilig

   Erst mit 18 px als Basis gebaut - das war falsch: bei 600 px und
   darunter ist die Zeile wieder zweizeilig. Bei neun Breiten nachgemessen,
   bevor und nachdem die Daten da sind.

   Zweite Massnahme im selben Zug, oben in Abschnitt 1: font-display bei
   Figtree von swap auf optional. Mit swap zeichnet der Browser erst in
   der Systemschrift und bricht neu um, sobald Figtree da ist - Lighthouse
   benennt figtree-latin-wght-normal.woff2 selbst als Verursacher am
   p.viz-intro. Mit optional wird nie nachgetauscht: ist die Schrift nach
   rund 100 ms nicht da, bleibt es fuer diesen Seitenaufruf bei der
   Systemschrift. preconnect und preload stehen seit 18.08., sie kommt
   meist rechtzeitig; ab dem zweiten Aufruf ohnehin aus dem Cache.
   User-Entscheid 19.08.
   ------------------------------------------------------------------- */

.viz-root .viz-lead {
  min-height: 36px;
}
@media (min-width: 601px) and (max-width: 767px) {
  .viz-root .viz-lead { min-height: 18px; }
}
@media (min-width: 768px) and (max-width: 799px) {
  .viz-root .viz-lead { min-height: 54px; }
}
@media (min-width: 800px) {
  .viz-root .viz-lead { min-height: 36px; }
}


/* -------------------------------------------------------------------
   34.6 Ueberschriften des Themes (Nachtrag, am Live-Stand gemessen)

   Befund 19.08.: das Theme setzt in oxy-selectors.css `.h1` und
   `.h2` auf reines Schwarz. Im Dunkelmodus sind das 1,27:1 gegen den
   Grund — die H1 der Startseite, die H1 aller drei Textseiten und die
   fuenf Sektionsueberschriften waren damit praktisch unsichtbar.
   Es war der EINZIGE Befund der maschinellen Kontrastpruefung ueber
   alle sichtbaren Textelemente beider Seitenarten.

   `body` als Vorfahr, damit die Regel nicht auf die Reihenfolge der
   Stylesheets angewiesen ist: `.h1` im Theme hat dieselbe
   Spezifitaet, und ob idl.css davor oder danach geladen wird, haengt
   an der Warteschlange von WordPress.

   Der Rueckfallwert traegt die Textseiten: dort steht die
   Ueberschrift ausserhalb von .viz-root, `--viz-text` ist also gar
   nicht definiert.
   ------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  body .h1,
  body .h2 {
    color: var(--viz-text, #e9eaea);
  }
}


/* -------------------------------------------------------------------
   Abschnitt 35 (v49, 19.08.2026) - CLS: Spaltenaufteilung des Kopfbereichs

   Belegt mit einem PerformanceObserver auf der ECHTEN Seite (nicht im
   iframe - das hatte die Verschiebung gar nicht erst erzeugt). Drei
   Verschiebungen, Slow 4G, 1440 x 868:

     0.142 @3854ms  Menuezeile verlaesst den Container (Abschnitt 36 offen)
     0.091 @3858ms  Kopfbereich 328 -> 253 px   <- diese Regel
     0.033 @4771ms  Quellenspalte 215 -> 264 px <- diese Regel

   Der Kopfbereich ist ein Flex-Container mit zwei Kindern, beide auf
   flex: 0 1 auto - also inhaltsbestimmt. Sobald kern.js die kurze Zeile
   "Daten werden geladen ..." durch den langen Datenstand ersetzt, will
   die linke Spalte mehr Breite. Die rechte wird schmaler, der
   Einfuehrungstext bricht neu um, der Kopf aendert seine Hoehe - und
   alles darunter springt. Deshalb nannte Lighthouse mal die KPI-Zeile,
   mal die Fluss-Karte als Verursacher: es ist jeweils der grosse Block,
   der gerade im Sichtfeld liegt.

   Das Verhaeltnis ist bei sechs Breiten gemessen und konstant
   43,7-43,9 %. Festgesetzt aendert sich am ENDZUSTAND nichts
   (451/548 statt 452/547 bei 1440 px) - nur der erste Aufbau steht
   sofort richtig.

   Nur ab 768 px: darunter ist der Kopf einspaltig, dort waere
   flex-basis eine HOEHE und wuerde das Layout zerlegen.
   ------------------------------------------------------------------- */

@media (min-width: 768px) {
  .viz-root .oxy-container-11-124 > *:first-child {
    flex: 0 0 43.8%;
  }
  .viz-root .oxy-container-11-124 > *:last-child {
    flex: 1 1 0;
    min-width: 0;
  }
}


/* -------------------------------------------------------------------
   Abschnitt 36 (v50, 19.08.2026) - Menuezeile: Wrapper unsichtbar machen

   Die Menuezeile steht seit heute im Markup (Element 146) statt per JS
   umgehaengt zu werden. Ein Oxygen-HTML-Code-Element bringt aber immer
   ein eigenes div mit - dadurch war die Zeile nicht mehr direktes Kind
   von .viz-root, alle elf Regeln .viz-root > .viz-menu griffen ins
   Leere und die Zeile stand plötzlich zentriert und schmal statt
   buendig zum Container.

   Zwei Zeilen loesen das: der Wrapper verschwindet mit display: contents
   aus dem Kastenbaum, damit die Zeile wieder Flex-Kind von .viz-root
   ist. Und die 12 vorhandenen Selektoren sind um den verschachtelten
   Fall erweitert - mechanisch, jede Regel behaelt ihren Inhalt.
   ------------------------------------------------------------------- */

.viz-root > .oxy-html-code-11-146 {
  display: contents;
}


/* -------------------------------------------------------------------
   Abschnitt 37 (v51, 19.08.2026) - CLS: der Zwischenzustand der
   Sprungnavigation

   Gemessen auf der echten Seite, nachdem Menuezeile und Kopfspalten
   erledigt waren - uebrig blieben genau zwei Verschiebungen, vier
   Millisekunden auseinander, ein Hin und Zurueck:

     0.090 @3884ms  Kopf 303 -> 377   KPI 150 -> 92
     0.091 @3888ms  Kopf 377 -> 303   KPI  92 -> 150

   Danach steht alles wieder exakt dort, wo es vorher stand. Netto
   passiert nichts - CLS zaehlt trotzdem beide.

   Ursache: das Nav-Skript haengt .viz-nav als erstes Kind in den
   Container und setzt .viz-nav-raster (Abschnitt 24.2: zweispaltiges
   Raster). Der Inhaltsbereich wird schmaler, der Einfuehrungstext
   bricht um, der Kopf waechst. Millisekunden spaeter loest das
   Flyout-Skript (v37) das Raster wieder auf und schiebt die Leiste in
   den Menue-Flyout - alles springt zurueck.

   Beleg, dass es NUR daran liegt: dieselbe Seite ohne JavaScript
   geladen zeigt bei 1440 px bereits Kopf 303 und KPI 150 - also die
   Endwerte. Der statische Zustand ist fehlerfrei.

   Diese zwei Regeln unterdruecken den Zwischenzustand, ohne die
   Skripte anzufassen: das Raster wird nie wirksam, und solange die
   Leiste im Container haengt, nimmt sie keinen Platz ein. Im Flyout
   gelten die v37-Regeln unveraendert weiter.

   Restrisiko, dem Auftraggeber vorgelegt und angenommen: faellt das
   Flyout-Skript einmal aus, waere die Sprungnavigation unsichtbar
   statt als Spalte sichtbar. User-Entscheid 19.08.
   ------------------------------------------------------------------- */

.viz-root > .container.viz-nav-raster {
  display: block;
}
.viz-root > .container > .viz-nav {
  display: none;
}

/* ===================================================================
   ABSCHNITT 38 — VERFESTIGUNG (NUR ANHAENGEN)
   Version v49, 19.08.2026

   ANHAENGEN, NICHT ERSETZEN. Dieser Block kommt UNTEN an die Datei
   `idl.css` im Plugin *Identity Lab – Functions & Code*. Oberhalb wird
   nichts geaendert. Vor dem Speichern das Praefix gegen die
   ausgelieferte Datei diffen (Vorgehen wie bei Abschnitt 32/34).

   NUMMER 38, NICHT 35: In `idl.css` tragen zwei verschiedene Bloecke
   die Nummer 34 (Dunkelmodus bei Zeile 2050, CLS-Datenstandzeile bei
   2300). Um die Doppelung nicht fortzusetzen, geht es hier bei 38
   weiter — siehe memory.md.

   WARUM ES DIESEN BLOCK BRAUCHT
   Die Sektionen sind vierspaltige Grids. Welches Element in welcher
   Rasterzelle landet, steht in `idl.css` als AUFZAEHLUNG EINZELNER IDs
   (`#s-dauer #h-dauer, #s-stellen #h-stellen, …`) — es gibt keinen
   generischen Selektor `p[id^="h-"]` fuer die Platzierung. Ein neuer
   Abschnitt faellt deshalb durch alle Regeln, die Auto-Platzierung
   stellt seinen Hinweistext in Zeile 2, und die Karte waechst um eine
   ganze Rasterzeile. Exakt der Befund aus Abschnitt 32 (hinweis-raster.md).

   `#s-verfestigung` verhaelt sich wie `#s-dauer`: Kopfzeile links,
   Diagramm rechts ueber zwei Zeilen, Hinweistext unter der Kopfzeile.
   Jede `#s-dauer`-Regel wird deshalb hier fuer `#s-verfestigung`
   gespiegelt — an allen fuenf Stellen, an denen es sie gibt.

   NICHT BETROFFEN: `docs/index.html` auf GitHub Pages. Dort liegt ein
   einfaches Blocklayout ohne Raster, der Abschnitt sitzt ohne Zutun
   richtig. Dieser Block gilt nur fuer die WordPress-Auslieferung.

   MINDESTHOEHE: `.viz-root .viz-karte p[id^="h-"] { min-height: 36px }`
   aus Abschnitt 34 greift generisch und deckt den neuen Hinweistext
   bereits ab. Hier steht dazu nichts.
   =================================================================== */

/* 38.1 Grundraster der Sektion — wie #s-dauer (idl.css Zeile 465).
   Selektor mit .viz-root, damit die Regel Oxygens `.viz-karte`-Vorgabe
   ohne !important schlaegt — siehe 38.8. */
.viz-root #s-verfestigung {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: var(--viz-gap);
  align-items: start;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  padding: var(--xxxxl, 1.25rem);
  background: #ffffff;
}

/* 38.2 Tabelle ueber die volle Breite (Zeile 493). */
#s-verfestigung #t-verfestigung {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}

/* 38.3 Diagramm rechts ueber beide Zeilen (Zeile 580).
   min-height 380 statt 340: zehn liegende Balken brauchen mehr Hoehe
   als die sechs Dauerklassen. */
#s-verfestigung .viz-chart {
  grid-row: 1 / span 2;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  grid-column: 2 / -1;
  padding: 0;
  min-height: 380px;
}

/* 38.4 Kopfzeile links, Zeile 1 (Zeile 609). */
#s-verfestigung .viz-kopfzeile {
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
  grid-column: 1;
}

/* 38.5 DER EIGENTLICHE PUNKT — Hinweistext links, Zeile 2 (Zeile 633).
   Ohne diese Regel reisst die Karte auf. */
#s-verfestigung #h-verfestigung {
  grid-row: 2;
  align-self: center;
  grid-column: 1;
}

/* 38.6 Unter 960 px: eine Spalte, alles untereinander
   (idl.css Zeilen 743 / 781 / 802 / 824). */
@media (max-width: 960px) {
  #s-verfestigung {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
  #s-verfestigung .viz-chart {
    grid-column: 1;
    grid-row: auto;
    padding: 0;
    min-height: 300px;
  }
  #s-verfestigung #h-verfestigung {
    grid-column: 1;
    grid-row: auto;
  }
  #s-verfestigung .viz-kopfzeile {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--s, 0.8rem);
  }
}

/* 38.7 Dieselbe Umstellung unter 1024 px (idl.css Zeilen 1394 / 1432 /
   1453 / 1475). Der Block ist in `idl.css` doppelt vorhanden — einmal
   bei 960, einmal bei 1024. Hier wird beides gespiegelt, damit der
   neue Abschnitt sich nicht anders verhaelt als seine Nachbarn. */
@media (max-width: 1024px) {
  #s-verfestigung {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
  #s-verfestigung .viz-chart {
    grid-column: 1;
    grid-row: auto;
    padding: 0;
    min-height: 300px;
  }
  #s-verfestigung #h-verfestigung {
    grid-column: 1;
    grid-row: auto;
  }
  #s-verfestigung .viz-kopfzeile {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--s, 0.8rem);
  }
}

/* 38.8 Raster durchsetzen — MIT !important, und zwar zwingend.
   Zeile 1678 setzt pauschal `.viz-root .viz-karte { display: block
   !important }`. Ohne eigenes !important gewinnt diese Regel, und der
   Abschnitt faellt aus dem Raster in den Blockfluss.

   ZWISCHENSTAND 19.08.: Ein Anlauf ohne !important wurde probiert und
   wieder zurueckgenommen — er sollte das inline `display:none` wirken
   lassen, nahm damit aber auch das Raster mit. Die Loesung dafuer steht
   in 38.10, nicht hier. */
.viz-root #s-verfestigung {
  display: grid !important;
}

/* 38.10 Solange versteckt, auch wirklich versteckt.
   `kern.js` gibt jeder Sektion `style="display:none"` mit und entfernt
   das Inline-Attribut erst, wenn das Diagramm gezeichnet ist. Gegen das
   pauschale `!important` aus Zeile 1678 verliert dieses Inline-Attribut
   aber — die Karte stand deshalb leer auf der Seite, solange ihr
   Diagrammmodul noch nicht ausgeliefert war (beobachtet 19.08.2026).

   Der Attributselektor greift genau dann, wenn das Inline-Attribut noch
   steht, und verschwindet in dem Moment, in dem `kern.js` es entfernt.
   Danach uebernimmt 38.8.

   Nebenwirkung, erwuenscht: Faellt `verfestigung.json` einmal aus,
   versteckt sich die Karte, statt leer dazustehen. Die Nachbarabschnitte
   koennen das nicht — dort ist es bislang nicht aufgefallen, weil ihre
   Daten immer da waren. */
.viz-root #s-verfestigung[style*="display:none"],
.viz-root #s-verfestigung[style*="display: none"] {
  display: none !important;
}

/* 38.9 Dunkelmodus — Kartenflaeche wie die Nachbarn (Zeile 2201).
   38.1 setzt hart #ffffff, das muss hier zurueckgenommen werden. */
@media (prefers-color-scheme: dark) {
  .viz-root #s-verfestigung {
    background: var(--viz-surface);
  }
}

/* ===================================================================
   ABSCHNITT 40 — KORREKTUR ZU ABSCHNITT 38 (NUR ANHAENGEN)
   Befund und Behebung 20.08.2026

   ANHAENGEN, NICHT ERSETZEN. Dieser Block kommt UNTEN an `idl.css` im
   Plugin *Identity Lab – Functions & Code*. Oberhalb wird nichts
   geaendert; Abschnitt 38 bleibt unangetastet, damit der Diff beweisbar
   ein reiner Anhang ist.

   -------------------------------------------------------------------
   WAS FALSCH WAR

   Abschnitt 38 setzt das Grundraster mit

       .viz-root #s-verfestigung { grid-template-columns: repeat(4, …) }

   Spezifitaet 0,1,1. Die beiden Umbruchbloecke darunter schreiben

       @media (max-width: 960px)  { #s-verfestigung { … 1fr … } }
       @media (max-width: 1024px) { #s-verfestigung { … 1fr … } }

   Spezifitaet 0,1,0 — sie VERLIEREN, obwohl die Media Query zutrifft und
   sie spaeter im Blatt stehen. Spezifitaet schlaegt Reihenfolge, eine
   Media Query aendert daran nichts.

   -------------------------------------------------------------------
   WAS MAN DAVON SAH

   Die Regel fuer die Zeichenflaeche kommt sehr wohl an: sie heisst in
   beiden Faellen `#s-verfestigung .viz-chart` (0,1,1), hat also dieselbe
   Spezifitaet wie ihre Grundregel und gewinnt ueber die Reihenfolge.

   Ergebnis unter 1024 px: Die Sektion bleibt VIERSPALTIG, weil
   `grid-template-columns: 1fr` nicht ankommt — aber das Diagramm
   rutscht von `grid-column: 2 / -1` auf `grid-column: 1`. Es steht damit
   in EINER von vier Spalten, also auf einem Viertel der Kartenbreite,
   waehrend rechts drei leere Spalten stehen. Genau so hat der User es
   am 20.08.2026 in den DevTools bei 1024 px berichtet: die Balken auf
   wenige Pixel gequetscht, die halbe Karte leer.

   Dass das Diagramm zusaetzlich winzig aussieht, hat einen zweiten
   Grund: ECharts rechnet seine Geometrie aus der gemessenen Breite des
   Feldes. Bei einem Viertel der Breite ist auch die Zeichnung ein
   Viertel breit — der Fehler verdoppelt sich optisch.

   -------------------------------------------------------------------
   WER SONST BETROFFEN IST: NUR NOCH `#s-saison`

   Am Live-Stand alle 14 Kartensektionen durchgezaehlt (CSSOM, nicht
   gelesen): betroffen sind ausschliesslich `#s-verfestigung` und
   `#s-saison` — die beiden juengsten. Alle uebrigen zwoelf schreiben
   ihre Grundregel OHNE `.viz-root`; dort haben Grund- und Umbruchregel
   dieselbe Spezifitaet und die Reihenfolge entscheidet richtig.

   `#s-saison` ist in seiner eigenen Quelle korrigiert
   (`code/saison-css-zusatz.css`, Regel 39.13) und NICHT hier: der
   Abschnitt-39-Block steht derzeit seitenlokal in einem `<style>` im
   Body und damit hinter `idl.css`. Eine Korrektur von hier aus wuerde
   von seiner eigenen Grundregel wieder ueberstimmt.

   -------------------------------------------------------------------
   REGEL FUER KUENFTIGE ABSCHNITTE

   Grund- und Umbruchregel einer Sektion muessen DIESELBE Spezifitaet
   haben. Am einfachsten: beide ohne `.viz-root` schreiben. Wird
   `.viz-root` gebraucht (etwa gegen das pauschale
   `.viz-root .viz-karte { display: block !important }` in Zeile 1678),
   dann in ALLEN Regeln der Sektion — nicht nur in der Grundregel.

   Und die Gegenprobe gehoert in den Browser, nicht in die Datei:
   `getComputedStyle(document.getElementById("s-…")).gridTemplateColumns`
   bei der fraglichen Breite ablesen.
   =================================================================== */

@media (max-width: 1024px) {
  .viz-root #s-verfestigung {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
}

@media (max-width: 960px) {
  .viz-root #s-verfestigung {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
}

/* ===================================================================
   ABSCHNITT 41 — SIGNATURZEILE IM FUSS (NUR ANHAENGEN)
   Befund und Behebung 21.08.2026

   ANHAENGEN, NICHT ERSETZEN. Dieser Block kommt UNTEN an `idl.css` im
   Plugin *Identity Lab – Functions & Code*. Oberhalb wird nichts
   geaendert, damit der Diff beweisbar ein reiner Anhang ist.

   WARUM 41 UND NICHT 40: Die Nummer 40 ist doppelt vergeben —
   `code/verfestigung-raster-korrektur.css` steht als Abschnitt 40 live
   in `idl.css`, `code/selbstaendige-css-zusatz.css` traegt dieselbe
   Nummer und ist noch nicht eingespielt. Die Kollision ist hier NICHT
   aufgeloest, nur umgangen; sie gehoert geklaert, bevor der
   Selbstaendigen-Abschnitt ausgeliefert wird. Abschnitt 39 (Saison) ist
   ebenfalls vergeben und steht bisher nur seitenlokal.

   -------------------------------------------------------------------
   WAS FALSCH WAR

   `signaturHtml()` in `kern.js` baut seit dem 19.08. eine Zeile aus
   vier Teilen, getrennt durch `<span class="viz-signatur-teiler">|</span>`
   — bewusst ohne Leerzeichen im Markup, weil der Abstand aus dem
   Flex-`gap` kommen soll und der Teiler beim Umbruch am Zeilenende
   stehen bleiben muss.

   Die zugehoerigen Regeln stehen in den `<style>`-Bloecken von
   `docs/index.html` und `docs/embed.html`. In die WordPress-Auslieferung
   sind sie nie uebernommen worden.

   Am 21.08.2026 auf arbeitsmarkt-monitor.at gemessen, nicht vermutet:
   ueber alle Stilblaetter der Seite (`idl.css`, `oxy-selectors.css`,
   `variables.css`, fuenf Inline-Bloecke) gibt es KEINE einzige Regel,
   deren Selektor `viz-signatur` enthaelt. Ergebnis am Element:

       display      inline      (statt flex)
       margin-top   0px         (statt 14px)
       padding-top  0px         (statt 12px)
       border-top   0px         (statt 1px)
       column-gap   normal      (statt 8px)

   Sichtbare Folge: die Zeile klebt ohne Umbruch am vorhergehenden Text
   — im Befundfall direkt an der roten Stoermeldung — und die drei
   Striche stehen ohne Luft zwischen den Woertern:

       …davon unberührt.arbeitsmarkt-monitor.at|Ein Projekt von …|V 03|20. August 2026

   -------------------------------------------------------------------
   WAS DIESER BLOCK TUT

   Er uebernimmt die Regeln aus `docs/index.html` woertlich und hebt sie
   auf die Spezifitaet `.viz-root .viz-signatur` (0,2,0). Grund ist der
   Befund vom 20.08.: eine Grundregel mit hoeherer Spezifitaet als ihre
   Ausnahme faengt jede spaetere Media Query ab. Hier gibt es zwar noch
   keine Ausnahme — die Angleichung erspart aber, dass eine spaetere
   still ausfaellt.

   Die drei benutzten Token sind am 21.08. auf `.viz-root` der
   Live-Seite als definiert nachgewiesen: `--viz-grid`, `--viz-muted`,
   `--viz-text-2`.

   Nicht enthalten und ausdruecklich nicht noetig: eine Aenderung an
   `kern.js` oder am Oxygen-Markup. Die Zeile bleibt letztes Kind von
   `#fuss` und wird allein durch `display: flex` zu einem eigenen Block.
   =================================================================== */

/* 41.1 Signaturzeile als eigener Absatz unter dem Fuss.

   flex + wrap statt Fliesstext: auf schmalen Fenstern bricht die Zeile
   zwischen den Teilen um und nicht mitten im Namen. `gap: 0 8px` setzt
   die Luft nur waagrecht — senkrecht sollen die Teile beim Umbruch
   nicht auseinanderfallen. */
.viz-root .viz-signatur {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 8px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--viz-grid);
  color: var(--viz-muted);
}

/* 41.2 Links erben die Fussfarbe, bleiben aber als Links erkennbar. */
.viz-root .viz-signatur a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.viz-root .viz-signatur a:hover { color: var(--viz-text-2); }

/* 41.3 Die Striche sind Gliederung, kein Inhalt — im Markup
   `aria-hidden`, hier zurueckgenommen, damit sie die vier Teile nicht
   ueberstimmen. */
.viz-root .viz-signatur-teiler { opacity: .5; }

/* ===================================================================
   ABSCHNITT 42 — SELBSTAENDIGE („DIE ZAHL, DIE NIEMAND ERHEBT",
   NUR ANHAENGEN)
   Erstellt 21.08.2026, Auslieferung hinter Abschnitt 41.
   Live eingespielt am 21.08.2026.

   ANHAENGEN, NICHT ERSETZEN. Dieser Block kommt UNTEN an die Datei
   `idl.css` im Plugin *Identity Lab – Functions & Code*, direkt hinter
   Abschnitt 39. Oberhalb wird nichts geaendert. Vor dem Speichern das
   Praefix gegen die ausgelieferte Datei diffen (Vorgehen wie bei
   Abschnitt 32/34/38/39/41).

   WARUM ES DIESEN BLOCK BRAUCHT — unveraendert der Befund aus
   Abschnitt 32, 38, 39 und 41: Die Sektionen sind vierspaltige Grids, und
   welches Element in welcher Rasterzelle landet, steht in `idl.css`
   als AUFZAEHLUNG EINZELNER IDs. Es gibt keinen generischen Selektor
   `p[id^="h-"]` fuer die Platzierung. Ein neuer Abschnitt faellt
   deshalb durch alle Regeln, die Auto-Platzierung stellt seinen
   Hinweistext in Zeile 2, und die Karte waechst um eine ganze
   Rasterzeile.

   `#s-selbstaendige` verhaelt sich wie `#s-dauer`, `#s-verfestigung`
   und `#s-saison`: Kopfzeile links, Diagramm rechts ueber zwei Zeilen,
   Hinweistext unter der Kopfzeile. Jede `#s-dauer`-Regel ist hier
   gespiegelt.

   ZUR HOEHE — 470 px, weniger als bei 39. Der Abschnitt zeigt zwei
   Panels untereinander, jedes mit Titel, Untertitel, Legende und EINEM
   liegenden Balken. Gemessen belegen Titel (17 px), Untertitel (13 px)
   und Legende (16 px) je Panel rund 60 px, dazu 20 px Achsenzeile —
   bei 470 px bleiben je Balken rund 70 px, das traegt eine Balkenhoehe
   von 48 % bequem. Mehr Hoehe wuerde die beiden Balken nur dicker
   machen, nicht lesbarer: die Aussage ist der Anteil, nicht die Flaeche.

   UND DIESELBE UNSICHTBARE SCHWELLE WIE BEI 39: `selbstaendige.js`
   verschiebt unter 560 px Feldbreite die senkrechte Aufteilung
   (`istSchmal` in kern.js), weil dann beide Legenden auf zwei Zeilen
   umbrechen. Die Media Query bei 560 px unten haelt genau diese
   Schwelle — sie ist an `SCHMAL = 560` in `kern.js` gekoppelt. Wer eine
   der beiden Zahlen aendert, muss die andere mitziehen.

   NICHT BETROFFEN: `docs/index.html` auf GitHub Pages. Dort liegt ein
   einfaches Blocklayout ohne Raster; die Hoehen stehen bereits im
   `<style>`-Block beider Dateien.
   =================================================================== */

/* 42.1 Grundraster der Sektion — wie #s-dauer (idl.css Zeile 465). */
.viz-root #s-selbstaendige {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: var(--viz-gap);
  align-items: start;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  padding: var(--xxxxl, 1.25rem);
  background: #ffffff;
}

/* 42.2 Tabelle ueber die volle Breite (Zeile 493).
   Sie ist hier fuenf Spalten breit (Messung, Gruppe, Wert, Anteil,
   Quelle) und traegt darunter zwei Fliesstextabsaetze plus eine Liste —
   `.viz-tabelle` regelt das Scrollen, hier braucht es nichts. */
#s-selbstaendige #t-selbstaendige {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}

/* 42.3 Diagramm rechts ueber beide Zeilen (Zeile 580). */
#s-selbstaendige .viz-chart {
  grid-row: 1 / span 2;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  grid-column: 2 / -1;
  padding: 0;
  min-height: 470px;
}

/* 42.4 Kopfzeile links, Zeile 1 (Zeile 609). */
#s-selbstaendige .viz-kopfzeile {
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
  grid-column: 1;
}

/* 42.5 DER EIGENTLICHE PUNKT — Hinweistext links, Zeile 2 (Zeile 633).
   Ohne diese Regel reisst die Karte auf. */
#s-selbstaendige #h-selbstaendige {
  grid-row: 2;
  align-self: center;
  grid-column: 1;
}

/* 42.6 Unter 960 px: eine Spalte, alles untereinander
   (idl.css Zeilen 743 / 781 / 802 / 824). */
@media (max-width: 960px) {
  #s-selbstaendige {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
  #s-selbstaendige .viz-chart {
    grid-column: 1;
    grid-row: auto;
    padding: 0;
    min-height: 470px;
  }
  #s-selbstaendige #h-selbstaendige {
    grid-column: 1;
    grid-row: auto;
  }
  #s-selbstaendige .viz-kopfzeile {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--s, 0.8rem);
  }
}

/* 42.7 Dieselbe Umstellung unter 1024 px (idl.css Zeilen 1394 / 1432 /
   1453 / 1475). Der Block ist in `idl.css` doppelt vorhanden — einmal
   bei 960, einmal bei 1024. Beides gespiegelt, damit der neue
   Abschnitt sich nicht anders verhaelt als seine Nachbarn. */
@media (max-width: 1024px) {
  #s-selbstaendige {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
  #s-selbstaendige .viz-chart {
    grid-column: 1;
    grid-row: auto;
    padding: 0;
    min-height: 470px;
  }
  #s-selbstaendige #h-selbstaendige {
    grid-column: 1;
    grid-row: auto;
  }
  #s-selbstaendige .viz-kopfzeile {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--s, 0.8rem);
  }
}

/* 42.8 Legendenumbruch — an `SCHMAL = 560` in kern.js gekoppelt.
   Unterhalb brechen beide Legenden auf zwei Zeilen um; ohne die
   zusaetzliche Hoehe schoebe sich die untere Legende in den oberen
   Balken. */
@media (max-width: 560px) {
  #s-selbstaendige .viz-chart {
    min-height: 560px;
  }
}

/* 42.9 Raster durchsetzen — MIT !important, und zwar zwingend.
   Zeile 1678 setzt pauschal `.viz-root .viz-karte { display: block
   !important }`. Ohne eigenes !important gewinnt diese Regel, und der
   Abschnitt faellt aus dem Raster in den Blockfluss. Siehe 38.8/39.9. */
.viz-root #s-selbstaendige {
  display: grid !important;
}

/* 42.10 Solange versteckt, auch wirklich versteckt — siehe 38.10 und 39.10.
   `index.html` gibt der Sektion `style="display:none"` mit;
   `selbstaendige.js` entfernt das Attribut erst, wenn beide Panels
   Daten haben. Gegen das pauschale `!important` aus Zeile 1678 verliert
   ein Inline-Attribut, deshalb der Attributselektor.

   HIER BESONDERS WICHTIG: `selbstaendige.json` wird NICHT von der
   Pipeline erzeugt. Faellt die Datei aus dem Deploy oder wird sie beim
   Aufraeumen von docs/data mitgeloescht, steigt das Modul aus — ohne
   diese Regel stuende dann eine leere Karte auf der Seite. */
.viz-root #s-selbstaendige[style*="display:none"],
.viz-root #s-selbstaendige[style*="display: none"] {
  display: none !important;
}

/* 42.11 Dunkelmodus — Kartenflaeche wie die Nachbarn (Zeile 2201).
   42.1 setzt hart #ffffff, das muss hier zurueckgenommen werden. */
@media (prefers-color-scheme: dark) {
  .viz-root #s-selbstaendige {
    background: var(--viz-surface);
  }
}

Selbstaendige raster korrektur · CSS
/* ===================================================================
   ABSCHNITT 43 — KORREKTUR ZU ABSCHNITT 42 (NUR ANHAENGEN)
   Befund und Behebung 21.08.2026
 
   ANHAENGEN, NICHT ERSETZEN. Dieser Block kommt UNTEN an `idl.css` im
   Plugin *Identity Lab – Functions & Code*, hinter Abschnitt 42.
   Oberhalb wird nichts geaendert.
 
   -------------------------------------------------------------------
   WAS FALSCH WAR — WORTGLEICH DER FEHLER AUS ABSCHNITT 40
 
   Abschnitt 42 setzt das Grundraster mit
 
       .viz-root #s-selbstaendige { grid-template-columns: repeat(4, …) }
 
   Spezifitaet 0,1,1. Die beiden Umbruchbloecke (42.6 / 42.7) schreiben
 
       @media (max-width: 960px)  { #s-selbstaendige { … 1fr … } }
       @media (max-width: 1024px) { #s-selbstaendige { … 1fr … } }
 
   Spezifitaet 0,1,0 — sie verlieren, obwohl die Media Query zutrifft
   und sie spaeter im Blatt stehen. Spezifitaet schlaegt Reihenfolge.
 
   -------------------------------------------------------------------
   WAS MAN DAVON SAH (User-Screenshot, DevTools 828 px)
 
   Die Sektion bleibt VIERSPALTIG. Die Regel `#s-selbstaendige
   .viz-chart` (0,1,1) kommt dagegen an und schiebt das Diagramm von
   `grid-column: 2 / -1` auf `grid-column: 1` — also in EINE von vier
   Spalten. Kopfzeile und Hinweistext stehen in derselben schmalen
   Spalte, Titel bricht in Einwortzeilen um, die Balken und beide
   Legenden sind auf ein Viertel der Kartenbreite gequetscht und
   rechts steht die halbe Karte leer. ECharts rechnet seine Geometrie
   aus der gemessenen Feldbreite, deshalb schneidet es zusaetzlich die
   Legendentexte ab („Angestellte un…", „beim AMS, aber…").
 
   -------------------------------------------------------------------
   VIERTES MAL DERSELBE FEHLER
 
   38 (verfestigung) → korrigiert in 40. 39 (saison) → in der eigenen
   Quelle korrigiert (39.13). 41 → geprueft. 42 → dieser Block.
   Die Regel aus Abschnitt 40 steht seit 20.08. da und wurde beim
   Kopieren der `#s-dauer`-Vorlage wieder uebergangen: `#s-dauer`
   schreibt seine Grundregel OHNE `.viz-root`, die Kopie MIT.
 
   VERBINDLICH FUER KUENFTIGE ABSCHNITTE:
   Grund- und Umbruchregel einer Sektion muessen DIESELBE Spezifitaet
   haben. Wird `.viz-root` gebraucht (gegen `.viz-root .viz-karte {
   display: block !important }`, idl.css Zeile 1678), dann in ALLEN
   Regeln der Sektion — auch in jeder Media Query.
 
   Gegenprobe gehoert in den Browser, nicht in die Datei:
   `getComputedStyle(document.getElementById("s-selbstaendige"))
     .gridTemplateColumns`
   muss bei 828 px genau EINEN Wert liefern.
   =================================================================== */
 
@media (max-width: 1024px) {
  .viz-root #s-selbstaendige {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
}
 
@media (max-width: 960px) {
  .viz-root #s-selbstaendige {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }
}
 



/* ===================================================================
   ABSCHNITT 44 — BIODIVERSITAETS-DASHBOARD (NUR ANGEHAENGT)
   Erstausgabe, 25.08.2026

   ANHAENGEN, NICHT ERSETZEN. Dieser Block kommt UNTEN an `idl.css` im
   Plugin *Identity Lab – Functions & Code*. Oberhalb wird nichts
   geaendert — dort steht der Bestand der kopierten Schwesterseite.

   WARUM ES IHN BRAUCHT
   Abschnitt 10 platziert die Sektionen des Arbeitsmarkt-Dashboards
   einzeln nach Kennung. Es gibt KEINEN generischen Selektor dafuer.
   Ohne diesen Anhang bekaemen die acht Biodiversitaetskarten keinen
   Rasterplatz: die Auto-Platzierung stellte Hinweis und Notiz in eigene
   Zeilen und die Karte risse rechts auf.

   WAS ANDERS IST ALS BEIM SCHWESTERPROJEKT
   Die Karten haben bis zu SECHS Kinder statt vier — Kopfzeile, Grafik,
   Tabelle, Zusatzsatz (`.viz-notiz`), Hinweiszeile und bei `#s-boden`
   eine zweite Tabelle. Jedes bekommt hier seinen Platz; ein Kind ohne
   Platzangabe erzeugt eine zusaetzliche Rasterzeile.

   SPEZIFITAET: Grundregel und Media Query tragen beide `.viz-root` als
   Vorfahr. Ungleiche Spezifitaet ist der Fehler, der die Sektion auf
   Tablet vierspaltig stehen laesst.

   Was hier steht:
     44.1  Grundraster der acht Sektionen
     44.2  Rasterplaetze und Mindesthoehen je Sektion
     44.4  Neue Klassen: .viz-notiz, .viz-quelle-art, drei KPI-Zusaetze
     44.5  Einspaltig bis 1024 px
     44.6  Dunkelmodus und Druck
     44.7  Das Raster muss `!important` tragen
     44.8  Rasterkinder duerfen schrumpfen
     44.9  Die Tabellenknoepfe wieder einblenden
   =================================================================== */

/* -------------------------------------------------------------------
   44.1 Grundraster — woertlich wie Abschnitt 10, nur mit den
   Kennungen dieses Projekts.
   ------------------------------------------------------------------- */
.viz-root #s-schutzgebiete,
.viz-root #s-vogel,
.viz-root #s-boden,
.viz-root #s-rotelisten,
.viz-root #s-erhaltung,
.viz-root #s-biotoptypen,
.viz-root #s-wald,
.viz-root #s-biolandbau {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: var(--viz-gap);
  align-items: start;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  padding: var(--xxxxl, 1.25rem);
  background: #ffffff;
}

/* -------------------------------------------------------------------
   44.2 Rasterplaetze je Sektion

   Die Textspalte wechselt die Seite, damit die Seite nicht zur Liste
   wird. Links heisst: Kopfzeile/Notiz/Hinweis in Spalte 1, Grafik in
   2 bis 4. Rechts ist das Spiegelbild.

   Die Grafik spannt ueber ALLE Textzeilen (`grid-row: 1 / span N`),
   sonst richtet sich ihre Hoehe nach der ersten Zeile.
   ------------------------------------------------------------------- */
/* schutzgebiete — Textspalte links, 2 Zeilen */
.viz-root #s-schutzgebiete .viz-kopfzeile {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
.viz-root #s-schutzgebiete #h-schutzgebiete {
  grid-column: 1;
  grid-row: 2;
  align-self: center;
}
.viz-root #s-schutzgebiete .viz-chart {
  grid-column: 2 / -1;
  grid-row: 1 / span 2;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 340px;
}
.viz-root #s-schutzgebiete #t-schutzgebiete {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}
/* vogel — Textspalte rechts, 3 Zeilen */
.viz-root #s-vogel .viz-kopfzeile {
  grid-column: 4;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
.viz-root #s-vogel #n-vogel {
  grid-column: 4;
  grid-row: 2;
  align-self: center;
}
.viz-root #s-vogel #h-vogel {
  grid-column: 4;
  grid-row: 3;
  align-self: center;
}
.viz-root #s-vogel .viz-chart {
  grid-column: 1 / 4;
  grid-row: 1 / span 3;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 420px;
}
.viz-root #s-vogel #t-vogel {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}
/* boden — Textspalte links, 2 Zeilen */
.viz-root #s-boden .viz-kopfzeile {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
.viz-root #s-boden #h-boden {
  grid-column: 1;
  grid-row: 2;
  align-self: center;
}
.viz-root #s-boden .viz-chart {
  grid-column: 2 / -1;
  grid-row: 1 / span 2;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 340px;
}
.viz-root #s-boden #t-boden,
.viz-root #s-boden #t-boden-kategorien {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}
/* rotelisten — Textspalte rechts, 3 Zeilen */
.viz-root #s-rotelisten .viz-kopfzeile {
  grid-column: 4;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
.viz-root #s-rotelisten #n-rotelisten {
  grid-column: 4;
  grid-row: 2;
  align-self: center;
}
.viz-root #s-rotelisten #h-rotelisten {
  grid-column: 4;
  grid-row: 3;
  align-self: center;
}
.viz-root #s-rotelisten .viz-chart {
  grid-column: 1 / 4;
  grid-row: 1 / span 3;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 690px;
}
.viz-root #s-rotelisten #t-rotelisten {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}
/* erhaltung — Textspalte links, 3 Zeilen */
.viz-root #s-erhaltung .viz-kopfzeile {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
.viz-root #s-erhaltung #n-erhaltung {
  grid-column: 1;
  grid-row: 2;
  align-self: center;
}
.viz-root #s-erhaltung #h-erhaltung {
  grid-column: 1;
  grid-row: 3;
  align-self: center;
}
.viz-root #s-erhaltung .viz-chart {
  grid-column: 2 / -1;
  grid-row: 1 / span 3;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 260px;
}
.viz-root #s-erhaltung #t-erhaltung {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}
/* biotoptypen — Textspalte rechts, 3 Zeilen */
.viz-root #s-biotoptypen .viz-kopfzeile {
  grid-column: 4;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
.viz-root #s-biotoptypen #n-biotoptypen {
  grid-column: 4;
  grid-row: 2;
  align-self: center;
}
.viz-root #s-biotoptypen #h-biotoptypen {
  grid-column: 4;
  grid-row: 3;
  align-self: center;
}
.viz-root #s-biotoptypen .viz-chart {
  grid-column: 1 / 4;
  grid-row: 1 / span 3;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 300px;
}
.viz-root #s-biotoptypen #t-biotoptypen {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}
/* wald — Textspalte links, 3 Zeilen */
.viz-root #s-wald .viz-kopfzeile {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
.viz-root #s-wald #n-wald {
  grid-column: 1;
  grid-row: 2;
  align-self: center;
}
.viz-root #s-wald #h-wald {
  grid-column: 1;
  grid-row: 3;
  align-self: center;
}
.viz-root #s-wald .viz-chart {
  grid-column: 2 / -1;
  grid-row: 1 / span 3;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 340px;
}
.viz-root #s-wald #t-wald {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}
/* biolandbau — Textspalte rechts, 3 Zeilen */
.viz-root #s-biolandbau .viz-kopfzeile {
  grid-column: 4;
  grid-row: 1;
  align-self: center;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--r, 1rem);
  margin-bottom: 0;
}
.viz-root #s-biolandbau #n-biolandbau {
  grid-column: 4;
  grid-row: 2;
  align-self: center;
}
.viz-root #s-biolandbau #h-biolandbau {
  grid-column: 4;
  grid-row: 3;
  align-self: center;
}
.viz-root #s-biolandbau .viz-chart {
  grid-column: 1 / 4;
  grid-row: 1 / span 3;
  box-sizing: border-box;
  height: auto;
  background: var(--viz-surface);
  padding: 0;
  min-height: 760px;
}
.viz-root #s-biolandbau #t-biolandbau {
  grid-column: 1 / -1;
  box-sizing: border-box;
  background: var(--viz-surface);
  padding: 0;
  margin-top: var(--viz-gap, 1.25rem);
}

/* -------------------------------------------------------------------
   44.4 Klassen, die es in idl.css noch nicht gibt

   Vier davon kommen aus der KPI-Zeile: anders als beim Schwesterprojekt
   traegt hier JEDE Kachel ihr eigenes Bezugsjahr, weil die vier Zahlen
   aus 2023, 2023, 2025 und 2025 stammen. Eine gemeinsame Datumszeile
   waere schlicht falsch.

   `.viz-quelle-art` ist die Herkunftsmarke im Fuss — „laufend" oder
   „Stand 2025". Ohne sie liest sich eine dreijaehrige Zahl wie eine
   tagesaktuelle.
   ------------------------------------------------------------------- */
.viz-root .viz-notiz {
  font-size: var(--xs, 0.8rem);
  color: var(--viz-text-2);
  line-height: 1.55;
  margin: var(--r, 1rem) 0 0;
  padding-top: var(--xxs, 0.4rem);
  border-top: 1px solid var(--viz-grid);
}
.viz-root .viz-quelle-art {
  display: inline-block;
  font-size: var(--xs, 0.72rem);
  padding: 1px 6px;
  border: 1px solid var(--viz-border);
  border-radius: 4px;
  color: var(--viz-muted);
  white-space: nowrap;
}
.viz-root .viz-kpi-einheit {
  font-size: var(--r, 1.1rem);
  font-weight: var(--viz-fw-normal, 400);
  margin-left: 3px;
  letter-spacing: 0;
}
.viz-root .viz-kpi-von {
  font-size: var(--r, 1.1rem);
  font-weight: var(--viz-fw-normal, 400);
  color: var(--viz-muted);
  letter-spacing: 0;
}
.viz-root .viz-kpi-fuss {
  font-size: var(--xs, 0.75rem);
  color: var(--viz-muted);
  margin-top: 7px;
  line-height: 1.45;
}

/* NICHT HIER: `.viz-signatur`. Abschnitt 41 der Datei definiert sie
   bereits auf derselben Spezifitaet (`.viz-root .viz-signatur`) und
   dieselbe Signaturzeile baut auch `kern.js` dieses Projekts. Eine
   zweite Definition waere eine stille Abweichung, die beim naechsten
   Aendern nur an einer Stelle nachgezogen wuerde. */

/* -------------------------------------------------------------------
   44.5 Einspaltig bis 1024 px

   Spiegelbild zu Abschnitt 25.1. Die Schwelle ist 1024 und nicht 960:
   1024 px ist die Hochkantbreite des iPad, und bei vier Spalten bleiben
   dort je Spalte 232 px — zu wenig fuer eine Achsenbeschriftung.

   `grid-row: auto` MUSS mit: ohne das behaelt die Grafik ihre
   Zeilenspanne aus 44.2 und reisst eine leere Zeile auf.
   ------------------------------------------------------------------- */
@media (max-width: 1024px) {
.viz-root #s-schutzgebiete,
.viz-root #s-vogel,
.viz-root #s-boden,
.viz-root #s-rotelisten,
.viz-root #s-erhaltung,
.viz-root #s-biotoptypen,
.viz-root #s-wald,
.viz-root #s-biolandbau {
    grid-template-columns: 1fr;
    padding: var(--s, 0.8rem);
  }

.viz-root #s-schutzgebiete .viz-chart,
.viz-root #s-schutzgebiete #h-schutzgebiete,
.viz-root #s-schutzgebiete #t-schutzgebiete,
.viz-root #s-vogel .viz-chart,
.viz-root #s-vogel #h-vogel,
.viz-root #s-vogel #n-vogel,
.viz-root #s-vogel #t-vogel,
.viz-root #s-boden .viz-chart,
.viz-root #s-boden #h-boden,
.viz-root #s-boden #t-boden,
.viz-root #s-boden #t-boden-kategorien,
.viz-root #s-rotelisten .viz-chart,
.viz-root #s-rotelisten #h-rotelisten,
.viz-root #s-rotelisten #n-rotelisten,
.viz-root #s-rotelisten #t-rotelisten,
.viz-root #s-erhaltung .viz-chart,
.viz-root #s-erhaltung #h-erhaltung,
.viz-root #s-erhaltung #n-erhaltung,
.viz-root #s-erhaltung #t-erhaltung,
.viz-root #s-biotoptypen .viz-chart,
.viz-root #s-biotoptypen #h-biotoptypen,
.viz-root #s-biotoptypen #n-biotoptypen,
.viz-root #s-biotoptypen #t-biotoptypen,
.viz-root #s-wald .viz-chart,
.viz-root #s-wald #h-wald,
.viz-root #s-wald #n-wald,
.viz-root #s-wald #t-wald,
.viz-root #s-biolandbau .viz-chart,
.viz-root #s-biolandbau #h-biolandbau,
.viz-root #s-biolandbau #n-biolandbau,
.viz-root #s-biolandbau #t-biolandbau {
    grid-column: 1;
    grid-row: auto;
    padding: 0;
  }
.viz-root #s-schutzgebiete .viz-kopfzeile,
.viz-root #s-vogel .viz-kopfzeile,
.viz-root #s-boden .viz-kopfzeile,
.viz-root #s-rotelisten .viz-kopfzeile,
.viz-root #s-erhaltung .viz-kopfzeile,
.viz-root #s-biotoptypen .viz-kopfzeile,
.viz-root #s-wald .viz-kopfzeile,
.viz-root #s-biolandbau .viz-kopfzeile {
    grid-column: 1;
    grid-row: auto;
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--s, 0.8rem);
  }

.viz-root #s-schutzgebiete .viz-chart,
.viz-root #s-vogel .viz-chart,
.viz-root #s-boden .viz-chart,
.viz-root #s-rotelisten .viz-chart,
.viz-root #s-erhaltung .viz-chart,
.viz-root #s-biotoptypen .viz-chart,
.viz-root #s-wald .viz-chart,
.viz-root #s-biolandbau .viz-chart {
    min-height: 260px;
  }
  /* Zwei Ausnahmen: liegende Balken brauchen ihre Hoehe auch einspaltig.
     23 Gruppen bzw. rund 30 Meldelaender lassen sich nicht stauchen. */
  .viz-root #s-rotelisten .viz-chart { min-height: 740px; }
  .viz-root #s-biolandbau .viz-chart { min-height: 800px; }
}

/* -------------------------------------------------------------------
   44.6 Dunkelmodus

   Abschnitt 44.1 setzt `background: #ffffff` hart — wie Abschnitt 10.
   Abschnitt 34.2 zaehlt die Sektionen einzeln auf und kennt diese acht
   nicht. Ohne die folgende Regel bleiben sie im Dunkelmodus weiss.
   ------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
.viz-root #s-schutzgebiete,
.viz-root #s-vogel,
.viz-root #s-boden,
.viz-root #s-rotelisten,
.viz-root #s-erhaltung,
.viz-root #s-biotoptypen,
.viz-root #s-wald,
.viz-root #s-biolandbau {
    background: var(--viz-surface);
  }
}
@media print {
.viz-root #s-schutzgebiete,
.viz-root #s-vogel,
.viz-root #s-boden,
.viz-root #s-rotelisten,
.viz-root #s-erhaltung,
.viz-root #s-biotoptypen,
.viz-root #s-wald,
.viz-root #s-biolandbau {
    background: #ffffff;
    color: #0a0a0a;
  }
}

/* -------------------------------------------------------------------
   44.7 Das Raster muss `!important` tragen

   Abschnitt 27.1 setzt `.viz-root .viz-karte { display: block !important }`,
   damit jede Karte ihren Platz von Anfang an belegt (CLS) und ein
   Datenausfall als leerer Rahmen sichtbar bleibt, statt zu verschwinden.
   Das `!important` steht dort, weil `display: none` als Inline-Stil am
   Element haengt.

   Genau deshalb reicht `display: grid` in 44.1 nicht. Am 25.08. im
   Frontend gemessen: `grid-template-columns` stand auf
   `repeat(4, minmax(0px, 1fr))`, `padding` auf 78,52 px — die Regel
   griff also — und `display` trotzdem auf `block`. Spalten ohne
   Rasteranzeige sind wirkungslos; die Karten standen einspaltig.

   Spezifitaet entscheidet, weil beide Regeln `!important` tragen:
   `.viz-root #s-...` ist (0,1,1,0) gegen (0,0,2,0) in 27.1.
   ------------------------------------------------------------------- */
.viz-root #s-schutzgebiete,
.viz-root #s-vogel,
.viz-root #s-boden,
.viz-root #s-rotelisten,
.viz-root #s-erhaltung,
.viz-root #s-biotoptypen,
.viz-root #s-wald,
.viz-root #s-biolandbau {
  display: grid !important;
}

/* -------------------------------------------------------------------
   44.8 Rasterkinder duerfen schrumpfen

   Ein Rasterkind hat von sich aus `min-width: auto` — es wird nie
   schmaler als sein Inhalt. Bei 412 px im Frontend gemessen: die
   Kategorientabelle unter `#s-boden` ist breiter als die Spalte und
   zog sie auf 438 px auf, waehrend die Sektion 369 px breit blieb.
   Ergebnis waren 68 px waagrechter Ueberlauf der ganzen Seite — und
   zwar auch fuer die Grafik daneben, denn beide teilen sich die
   Spalte.

   `min-width: 0` gibt die Schrumpfsperre auf; `overflow-x: auto` an
   der Tabelle sorgt dafuer, dass sie in sich scrollt statt die Seite
   zu verbreitern. Mit beidem: 0 px Ueberlauf, Grafik 342 px.
   ------------------------------------------------------------------- */

.viz-root #s-schutzgebiete > *,
.viz-root #s-vogel > *,
.viz-root #s-boden > *,
.viz-root #s-rotelisten > *,
.viz-root #s-erhaltung > *,
.viz-root #s-biotoptypen > *,
.viz-root #s-wald > *,
.viz-root #s-biolandbau > * {
  min-width: 0;
}
.viz-root #t-boden-kategorien {
  overflow-x: auto;
}

/* -------------------------------------------------------------------
   44.9 Die Tabellenknoepfe wieder einblenden

   Abschnitt 5 der Datei blendet sie aus:

       .viz-tabelle-schalter:not([data-ziel="t-bezirke"]) { display: none; }

   Das ist eine Entscheidung der Schwesterseite, die diese Kopie
   mitgebracht hat. Hier gilt sie nicht: die Zahlentabelle ist der Weg
   zur Rohzahl, und auf GitHub Pages steht derselbe Knopf sichtbar. Ohne
   ihn waere die Tabelle im Markup vorhanden, aber unerreichbar.

   Kein `!important` noetig — die Regel oben hat (0,2,0), diese hier
   (0,1,2,0). Auf die acht Sektionen begrenzt, damit die Entscheidung
   der Schwesterseite gilt, wo sie hingehoert.
   ------------------------------------------------------------------- */

.viz-root #s-schutzgebiete .viz-tabelle-schalter,
.viz-root #s-vogel .viz-tabelle-schalter,
.viz-root #s-boden .viz-tabelle-schalter,
.viz-root #s-rotelisten .viz-tabelle-schalter,
.viz-root #s-erhaltung .viz-tabelle-schalter,
.viz-root #s-biotoptypen .viz-tabelle-schalter,
.viz-root #s-wald .viz-tabelle-schalter,
.viz-root #s-biolandbau .viz-tabelle-schalter {
  display: inline-block;
}
