/**
 * Einklappbare App-Sidebar (includes/sidebar.php,
 * assets/js/modules/app/sidebar.js).
 *
 * Markup und Grundoptik liegen in Bricks. Diese Datei enthält nur, was
 * Bricks nicht leisten kann: die Breiten-Variablen, die Regeln des
 * eingeklappten Zustands und die Tooltips.
 *
 * =====================================================================
 * ZWEI REGELN FÜR DIESE DATEI - beide durch Schaden gelernt
 * =====================================================================
 *
 * 1. DIE KLASSE BESCHREIBT NICHTS MEHR (07.09.2026).
 *
 *    html.sichtwechsel-sidebar-eingeklappt SETZT nur noch den Schalter
 *    --sichtwechsel-sidebar-spur, und zwar an genau einer Stelle (siehe
 *    "Drei Stufen"). Jede Regel, die den Spur-Zustand GESTALTET, gehört
 *    in @container style(--sichtwechsel-sidebar-spur: 1) - niemals an
 *    die Klasse.
 *
 *    Warum so streng: Eine Regel an der Klasse sieht ab 1280 px völlig
 *    richtig aus und fehlt zwischen 768 und 1279, wo die Spur ohne
 *    Klasse erzwungen wird. Nichts schlägt fehl, nichts steht im
 *    Protokoll - es sieht nur auf einer Fenstergröße kaputt aus, die
 *    beim Bauen niemand aufhat.
 *
 *    Bewacht von assets/js/modules/app/sidebar-klassenanker.js: Der
 *    meldet in der Konsole, wenn doch wieder eine Regel an der Klasse
 *    hängt.
 *
 * 2. :root:root IST EIN SPEZIFITÄTSTRÄGER, KEINE BEDEUTUNG.
 *
 *    Vor jedem Selektor in den @container-Blöcken steht ":root:root ".
 *    Es trifft dasselbe Element wie "html" und sagt inhaltlich nichts -
 *    es ersetzt die Spezifität, die der frühere Klassenanker
 *    mitbrachte.
 *
 *    🔴 GENAU DARAN IST DER UMBAU EINMAL GESCHEITERT: Beim Wechsel von
 *    "html.sichtwechsel-sidebar-eingeklappt [data-sidebar-gruppe]"
 *    (0,2,1) auf "[data-sidebar-gruppe]" (0,1,0) fiel die Regel unter
 *    Bricks' eigene .sidebar__gruppe.brxe-heading (0,2,0). Die
 *    Gruppenüberschriften standen in der Spur weiter in voller Größe da
 *    und liefen über die 64 px hinaus. Der Klassenanker hatte also zwei
 *    Aufgaben - Zustand UND Spezifität -, und beim Entfernen ging die
 *    zweite still mit verloren.
 *
 *    Mit ":root:root " liegt jeder dieser Selektoren bei mindestens
 *    (0,3,0) und damit eine volle Stufe über einer Bricks-Klasse.
 *    Wer eine Regel ergänzt, schreibt es mit davor.
 * =====================================================================
 *
 * Die Breiten sind LAYOUT-Werte, keine Design-Tokens - dieselbe
 * Abgrenzung wie bei --sichtwechsel-profil-toolbar-*. Sie beschreiben,
 * wie dieses eine Layout gebaut ist, nicht, wie die Marke aussieht, und
 * gehören deshalb nicht ins Core Framework.
 */

/* ---------------------------------------------------------------------
 * Breiten - EINE Quelle für Sidebar UND Inhaltsversatz
 *
 * --sichtwechsel-sidebar-aktuelle-breite ist der einzige Wert, den
 * Layoutregeln lesen sollen. Er zeigt je nach Zustand auf die eine oder
 * die andere Breite; die Umschaltung passiert genau hier, nicht an den
 * Verwendungsstellen.
 *
 * ⚠️ ZWEI STELLEN IN BRICKS MÜSSEN DARAN GEBUNDEN WERDEN, sonst schiebt
 * sich der Inhaltsbereich beim Einklappen nicht mit:
 *   1. Globale Klasse `app__sidebar`: width / min-width / max-width
 *   2. „Main Wrapper": margin-left  (steht dort aktuell fest auf 272px)
 * Beide auf var(--sichtwechsel-sidebar-aktuelle-breite) setzen.
 *
 * Diese Datei setzt die Breite BEWUSST NICHT selbst auf [data-sidebar]:
 * Die Bricks-Klasse hat dieselbe Spezifität, wer gewinnt, hinge an der
 * Ladereihenfolge der Stylesheets. Eine Regel, die je nach Zufall
 * greift, ist schlechter als gar keine.
 *
 * 🔴 EINE BRICKS-KLASSE IST ZWEI KLASSEN (Befund 06.09.2026). Was im
 * Builder als eine Klasse erscheint, schreibt Bricks zusammen mit
 * seiner eigenen Element-Klasse in denselben Selektor:
 *
 *     .app__sidebar.brxe-div { … }
 *
 * Das sind (0,2,0), nicht (0,1,0). Wer die Spezifität einer
 * Bricks-Klasse zählt und die brxe--Klasse vergisst, liegt um eine
 * Stufe daneben - und baut eine Regel, die bei Gleichstand über die
 * Reihenfolge entschieden wird. Diesen Gleichstand gewinnt Bricks: Sein
 * Block steht inline im <head>.
 *
 * Für jede Regel dieser Datei, die gegen eine Bricks-Einstellung
 * antritt, gilt deshalb: mindestens (0,3,0), und nicht knapp.
 * ------------------------------------------------------------------- */

:root {
	--sichtwechsel-sidebar-breite: 272px;
	/* 64px = Icon 20px + 22px Innenabstand je Seite. Trifft das
	   8px-Raster und hält das Icon auf derselben optischen Mittelachse
	   wie im ausgeklappten Zustand. */
	--sichtwechsel-sidebar-breite-eingeklappt: 64px;

	/*
	 * Aus dem Stufenschalter gerechnet statt an zwei Stellen gesetzt.
	 * --spur ist 0 oder 1, die Formel wählt damit genau eine der beiden
	 * Breiten:  272px * 1 + 64px * 0  bzw.  272px * 0 + 64px * 1.
	 *
	 * Eine zweite Regel "wenn Spur, dann schmal" wäre wieder eine
	 * Stelle, die jemand vergessen kann - hier kann die Breite gar
	 * nicht mehr von der Stufe abweichen.
	 */
	--sichtwechsel-sidebar-aktuelle-breite: calc(
		var(--sichtwechsel-sidebar-breite) * (1 - var(--sichtwechsel-sidebar-spur))
		+ var(--sichtwechsel-sidebar-breite-eingeklappt) * var(--sichtwechsel-sidebar-spur)
	);

	/* Kantenlänge der quadratischen Hoverfläche des Umschalters im
	   eingeklappten Zustand. Muss der Fläche der Navigationspunkte
	   entsprechen, die aus der Bricks-Klasse `app-button` kommt.

	   ⚠️ EINZIGER DUPLIZIERTER WERT dieser Datei - siehe Bericht: Für
	   diese Größe gibt es weder im Core Framework noch im Plugin eine
	   gemeinsame Quelle, sie steht ausschließlich in der Bricks-Klasse.
	   Statt sie an drei Stellen zu wiederholen, steht sie hier genau
	   einmal. Ändert sich `app-button`, ist das die eine Stelle, die
	   mitmuss.

	   Als strukturelle Größe (wie --status-dot-size oder die
	   Toolbar-Höhe) ist eine plugin-eigene Custom Property hier
	   regelkonform - anders als beim Radius, siehe unten. */
	--sichtwechsel-sidebar-hoverflaeche: 40px;

	/* Stapelebene der GESAMTEN Sidebar - die eine Stellschraube, wenn
	   Tooltips hinter Inhalten verschwinden. Begründung siehe unten
	   beim Tooltip-Block.

	   Bewusst moderat: hoch genug über gewöhnlichen Inhalts-Containern,
	   aber unterhalb des Bereichs, in dem Bricks seine Overlays und
	   Modals ansiedelt (typisch 1000+). Ein Modal, das unter der
	   Sidebar liegt, wäre der schlechtere Fehler.

	   Deckt ein Container den Tooltip weiterhin ab: HIER erhöhen, nicht
	   am Tooltip - der kann den Kontext der Sidebar nicht verlassen. */
	--sichtwechsel-sidebar-z-index: 500;

	/* Vertikaler Abstand ober- und unterhalb des Trennstrichs im
	   eingeklappten Zustand. Bestimmt, ob der Strich als Trennung
	   zwischen zwei Gruppen wirkt oder als eigene Zeile - hier
	   nachjustieren, nicht an der Regel. */
	--sichtwechsel-sidebar-trenner-abstand: 8px;
}

/* =====================================================================
 * DREI STUFEN - und genau ein Schalter dafür
 *
 *   ab 1280 px    volle Sidebar mit Text; die gespeicherte Vorliebe
 *                 der Nutzerin entscheidet
 *   768-1279 px   Icon-Spur, ERZWUNGEN - die Vorliebe gilt hier nicht
 *   bis 767 px    aus dem Layout, Drawer über den Hamburger
 *
 * 🔴 --sichtwechsel-sidebar-spur IST DER GANZE ZUSTAND (07.09.2026).
 * 0 = volle Sidebar, 1 = Spur. Alles Weitere liest diesen einen Wert:
 * die Breite darunter über calc(), die 22 Spur-Regeln über
 * @container style(), und das JS über getComputedStyle - fürs
 * aria-expanded, damit die Ansage nicht behauptet, was man nicht sieht.
 *
 * WARUM @container style() UND NICHT ZWEI MEDIA-BLÖCKE: Die Bedingung
 * ist eine ODER-Verknüpfung aus einer Breite und einem Selektor
 * ("ab 1280 UND Klasse gesetzt" ODER "768-1279"). CSS kann eine
 * Media-Bedingung nicht mit einem Selektor verodern - die 22
 * Spur-Regeln hätten deshalb zweimal dastehen müssen, einmal je Stufe.
 * Zwei Kopien von 22 Regeln sind genau die Doppelquelle, an der es
 * still auseinanderläuft: Wer die 23. Regel ergänzt, ergänzt sie in
 * einem Block, und im mittleren Bereich sieht die Sidebar halb kaputt
 * aus, ohne dass irgendwo etwas fehlschlägt.
 *
 * Der Stufenschalter dreht das um: Die Breite entscheidet EINMAL, was
 * gilt; die Regeln fragen nur noch danach.
 *
 * ⚠️ RÜCKFALL IN ÄLTEREN BROWSERN: Style-Queries gibt es ab Chrome 111,
 * Safari 18 und Firefox 128. Wer sie nicht kann, sieht die Spur nie -
 * die Sidebar bleibt ab 768 px voll, der Umschalter bewirkt optisch
 * nichts. Sichtbar und harmlos; der Drawer darunter läuft weiter, weil
 * er an einer Media-Query hängt.
 *
 * ⚠️ DIE ZAHLEN STEHEN ZWEIMAL: einmal hier in den Media-Queries,
 * einmal als Custom Property für das JS. Eine Media-Query kann keine
 * Custom Property lesen - dieselbe unauflösbare Doppelung wie beim
 * Drawer-Umbruch, deshalb stehen die Paare direkt beieinander.
 *
 * 1280 und 768 sind Bricks' Umbruchpunkte (1279 / 991 / 767 / 478),
 * jeweils die Zahl darüber. Die Grenzen sind lückenlos und
 * überschneidungsfrei: 767|768 und 1279|1280.
 * ================================================================== */

:root {
	/* Vorgabe: keine Spur. Die beiden Regeln darunter heben sie an. */
	--sichtwechsel-sidebar-spur: 0;

	/* Ab dieser Breite zählt die gespeicherte Vorliebe - Zwilling der
	   Zahl in der Media-Query darunter, für sidebar.js. */
	--sichtwechsel-sidebar-vorliebe-ab: 1280px;
}

/* Stufe 2: Die Breite erzwingt die Spur. KEIN Klassenanker - die
   gespeicherte Vorliebe darf hier nichts bewirken, weder in die eine
   noch in die andere Richtung. */
@media (min-width: 768px) and (max-width: 1279px) {
	:root {
		--sichtwechsel-sidebar-spur: 1;
	}
}

/* Stufe 1: Ab 1280 entscheidet die Nutzerin. html.<klasse> ist (0,1,1)
   und schlägt die :root-Vorgabe (0,1,0) oben. */
@media (min-width: 1280px) {
	html.sichtwechsel-sidebar-eingeklappt {
		--sichtwechsel-sidebar-spur: 1;
	}
}

/* Weiche Bewegung statt Sprung. Nur width/margin animieren, nicht
   `all` - sonst laufen auch Farb- und Schattenwechsel mit Verzögerung.

   🔴 DAUER AUS --sw-panel-duration (09.09.2026, assets/css/help.css):
   Öffnet das Hilfe-Panel nebeneinander, schrumpft links die Sidebar und
   fährt rechts das Panel ein - der Inhalt wird von beiden Seiten
   angefasst. Mit zwei Werten sieht das nach zwei Rucklern aus statt
   nach einer Bewegung. Hier stand .18s, das Panel und der Drawer
   arbeiten mit 240ms; angeglichen wurde auf den bestehenden
   Drawer-Wert, kein neuer erfunden.

   Der Rückfallwert hält die Regel am Leben, falls help.css einmal
   nicht mitgeladen wird. */
[data-sidebar] {
	transition:
		width var(--sw-panel-duration, 240ms) var(--sw-panel-easing, ease),
		min-width var(--sw-panel-duration, 240ms) var(--sw-panel-easing, ease),
		max-width var(--sw-panel-duration, 240ms) var(--sw-panel-easing, ease);

	/* Siehe --sichtwechsel-sidebar-z-index oben und den Tooltip-Block
	   unten: Die Sidebar ist position: fixed und damit selbst ein
	   Stacking Context. Ihre Ebene entscheidet, ob der Tooltip über
	   dem Inhaltsbereich liegt - nicht die Ebene des Tooltips. */
	z-index: var(--sichtwechsel-sidebar-z-index);
}

@media (prefers-reduced-motion: reduce) {
	[data-sidebar] {
		transition: none;
	}
}

/* ---------------------------------------------------------------------
 * Eingeklappter Zustand
 * ------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
 * 🔴 DIE REGEL IST UMGEDREHT (05.09.2026)
 *
 * Vorher wurde Bekanntes einzeln ausgeblendet: [data-sidebar-label],
 * mehr nicht. Alles Neue fiel durch - der Support-Block unten stand
 * eingeklappt mit vollem Text da und brach in schmale Fetzen um. Bei
 * einer Sidebar, in die absehbar weitere Einträge kommen, ist das eine
 * Falle mit Ablaufdatum: Sie schlägt nicht fehl, sie sieht nur beim
 * nächsten Eintrag wieder kaputt aus.
 *
 * Jetzt meldet sich das Sichtbare selbst an. Eingeklappt ist alles
 * verborgen AUSSER:
 *
 *   1. Elemente mit [data-sidebar-icon]      - der Griff
 *   2. deren Inhalt                          - das SVG und seine Pfade
 *   3. deren Vorfahren                       - sonst nähme der
 *                                              display: none des
 *                                              Elternteils das Icon mit
 *   4. [data-sidebar-gruppe]                 - siehe unten
 *
 * Punkt 3 ist der Grund für :has(): Ein verborgenes Elternelement lässt
 * sich von innen nicht wieder sichtbar machen. Die Kette vom
 * Sidebar-Wrapper bis zum Icon muss deshalb ausdrücklich überleben.
 *
 * ⚠️ EIN ATTRIBUT, KEINE KLASSE - anders als vorgeschlagen. Der
 * Dateikopf hält seit dem 30.08.2026 fest: "Kein SELEKTOR dieser Datei
 * hängt an einer Bricks-Klasse". Eine Umbenennung im Builder würde die
 * Regel sonst still aushebeln, und still ist hier das Problem. Der
 * Griff heisst deshalb data-sidebar-icon und nicht sw-sidebar-icon.
 *
 * ⚠️ WAS SICHTBAR BLEIBEN SOLL, BRAUCHT DEN GRIFF - AUCH DER
 * ZÄHLER-BADGE. Er ist der einzige Grund, eingeklappt überhaupt
 * hinzusehen, und trug bisher keine Regel, weil er von der alten
 * Aufzählung schlicht nicht erfasst wurde. Jetzt muss er sich anmelden
 * wie alles andere.
 *
 * [data-sidebar-gruppe] steht als Ausnahme im Selektor statt einen
 * Griff zu bekommen: Es soll gerade NICHT display: none werden - die
 * Überschrift bleibt mit font-size: 0 im Accessibility-Baum und trägt
 * eingeklappt den Trennstrich (siehe den Block darunter). Ein Griff
 * würde sie sichtbar machen, und das ist etwas anderes.
 * ------------------------------------------------------------------- */

@container style(--sichtwechsel-sidebar-spur: 1) {
/* GILT, WENN DIE SPUR GILT - egal aus welchem der beiden Gründe.
   Ob die Nutzerin eingeklappt hat (ab 1280) oder die Breite es
   erzwingt (768-1279), entscheidet der Stufenschalter ganz oben;
   hier steht nur, wie die Spur aussieht. Siehe den Block
   "Drei Stufen". */
	:root:root [data-sidebar] :not(
		[data-sidebar-icon],
		[data-sidebar-icon] *,
		:has([data-sidebar-icon]),
		[data-sidebar-gruppe]
	) {
		display: none;
	}

	/* ---------------------------------------------------------------------
	 * Bereichsüberschriften -> Trennstrich (eingeklappt)
	 *
	 * Eingeklappt ist für die Beschriftung kein Platz. Statt sie
	 * auszublenden, wird sie unsichtbar gemacht und die Gruppe durch eine
	 * Rahmenlinie voneinander getrennt.
	 *
	 * WARUM NICHT display: none: Mit font-size: 0 bleibt die Überschrift im
	 * Accessibility-Baum. Die Gliederung der Navigation wird also
	 * weiterhin vorgelesen, obwohl sie nicht zu sehen ist - besser als der
	 * ursprüngliche Zustand, in dem die Struktur eingeklappt komplett
	 * verlorenging. Ein display: none-Element hätte außerdem gar keine
	 * Rahmenlinie gezeichnet.
	 *
	 * NUR IN DER SPUR - bei einer Rahmenlinie wichtiger als bei der
	 * früheren Pseudo-Element-Lösung: Ohne die umgebende Style-Query
	 * erschiene die Linie auch bei voller Sidebar über jeder
	 * Bereichsüberschrift.
	 * ------------------------------------------------------------------- */

	:root:root [data-sidebar-gruppe] {
		/* Der Strich SELBST - eine Rahmenlinie, kein Pseudo-Element.
		   Vereinfachung 30.08.2026: Die vorherige ::before-Konstruktion
		   ist ersatzlos entfallen; ein border-top braucht kein zusätzliches
		   Element.

		   Auf dem data-Attribut, nicht auf einer Bricks-Klasse: Eine
		   Umbenennung im Builder würde die Plugin-Regel sonst still
		   aushebeln - kein Fehler, nur eine Linie, die verschwindet. Kein
		   SELEKTOR dieser Datei hängt an einer Bricks-Klasse; erwähnt
		   werden sie nur noch in Begründungen. */
		border-top: 1px solid var(--brand-app-3);

		/* Eigene Breite statt der vollen Wrapper-Breite (31.08.2026): Über
		   die ganze Inhaltsbreite gezogen saß der Strich sichtbar
		   außermittig - er übernahm die Breite des Wrappers, dessen
		   horizontale Innenabstände im Kompaktzustand nicht symmetrisch
		   sind.

		   Die Breite ist bewusst dieselbe Variable wie die Hoverfläche der
		   Icons: Der Strich liegt damit exakt so breit wie die
		   Schaltflächen darüber und darunter und ist optisch an ihnen
		   verankert, statt frei zu schweben. Kein neuer Pixelwert. */
		width: var(--sichtwechsel-sidebar-hoverflaeche);

		/* Beschriftung unsichtbar, aber NICHT display: none - sie bleibt
		   dadurch im Accessibility-Baum, die Gliederung der Navigation wird
		   also weiterhin vorgelesen. line-height zusätzlich zu font-size,
		   sonst bliebe je nach Bricks-Einstellung eine Restzeilenhöhe
		   stehen. */
		font-size: 0;
		line-height: 0;

		/* Die von Bricks mitgebrachten Abstände der Überschrift werden
		   zurückgesetzt - sie sind für den TEXT gedacht, der hier keinen
		   Platz mehr braucht.

		   margin-block und margin-inline getrennt statt einer
		   margin-Kurzform: Senkrecht kommt der Abstand aus der einen
		   Stellgröße, waagerecht zentriert `auto` den jetzt schmaleren
		   Kasten. In einer Kurzform ließe sich beides nicht zugleich
		   ausdrücken. */
		padding: 0;
		margin-block: var(--sichtwechsel-sidebar-trenner-abstand);
		margin-inline: auto;
	}

	/* ERSTE GRUPPE OHNE STRICH.
	 *
	 * Oberhalb der ersten Gruppe steht nichts, was der Strich abgrenzen
	 * könnte - er wirkt dort wie ein abgeschnittener Rand statt wie eine
	 * Trennung.
	 *
	 * Sven setzt dafür am ersten Gruppen-Element den WERT "erste":
	 *
	 *     data-sidebar-gruppe="erste"
	 *
	 * Kein zusätzliches Attribut, sondern ein Wert am vorhandenen.
	 *
	 * VORGESCHICHTE: Zuerst stand hier der Geschwister-Kombinator
	 * ([data-sidebar-gruppe] ~ [data-sidebar-gruppe]), der ohne Marker
	 * ausgekommen wäre. Er setzt aber voraus, dass die Überschriften
	 * Geschwister im selben Elternelement sind - im tatsächlichen
	 * Bricks-Aufbau sind sie das nicht, es erschien gar kein Strich (live
	 * bestätigt 30.08.2026).
	 *
	 * WARUM KEIN :first-of-type: bezieht sich auf den ELEMENTTYP, nicht auf
	 * das Attribut - träfe also womöglich das erste <div> überhaupt.
	 *
	 * ACHTUNG BEI UMSORTIERUNG: Wandert eine andere Gruppe nach oben, muss
	 * der Wert mitwandern. */
	:root:root [data-sidebar-gruppe="erste"] {
		border-top: 0;
	}

	/* ---------------------------------------------------------------------
	 * Abstand des Navigationsbereichs nach unten (eingeklappt)
	 *
	 * Bricks setzt am Bereichs-Wrapper ein `margin-bottom: var(--space-s)`.
	 * Eingeklappt ist das zu viel: Der Abstand ist für die Beschriftungen
	 * bemessen, die dort nicht mehr stehen.
	 *
	 * [data-sidebar-bereich] ist der Wrapper, der eine Navigationsgruppe
	 * umschließt - nicht zu verwechseln mit [data-sidebar-gruppe], der
	 * Überschrift darin. Dass beide getrennte Elemente sind, zeigte sich
	 * an zwei Stellen: Der Geschwister-Kombinator griff bei den
	 * Überschriften nicht (jede liegt in ihrem eigenen Wrapper), und die
	 * margin-Regel der Überschrift hatte den Abstand hier nicht
	 * überschrieben.
	 * ------------------------------------------------------------------- */

	:root:root [data-sidebar-bereich] {
		/* Bricks setzt an jedem Navigationsbereich ein
		   `margin-bottom: var(--space-s)`. Der Abstand ist für die
		   ausgeklappte Spalte bemessen, in der unter jeder Gruppe eine
		   Beschriftung steht. Eingeklappt gibt es die nicht mehr, und der
		   Abstand wirkt als Loch.

		   margin-block: 0 statt margin-bottom: 0 - trifft beide Richtungen
		   und macht die Regel unabhängig davon, ob Bricks den Abstand
		   irgendwann oben statt unten setzt.

		   Der Trennstrich behält seine eigenen Abstände über
		   --sichtwechsel-sidebar-trenner-abstand. Diese Regel fasst ihn
		   nicht an; sie räumt nur den Abstand des UMSCHLIESSENDEN Bereichs
		   weg.

		   Kein !important: html.klasse + Attributselektor wiegt schwerer
		   als jede einfache Bricks-Klasse. */
		margin-block: 0;
	}

	/* Icons mittig. Der Innenabstand entfällt, weil die Zentrierung ihn
	   ersetzt - bliebe er stehen, säßen die Icons links der Mitte. */
	:root:root [data-sidebar] a,
	:root:root [data-sidebar-umschalter] {
		justify-content: center;
		padding-left: 0;
		padding-right: 0;
	}

	/* Zwei getrennte Logo-Elemente nebeneinander im Markup, nicht eines mit
	   zwei Zuständen: [data-sidebar-logo] ist das volle Logo,
	   [data-sidebar-logo-kompakt] das Signet für die schmale Spalte.

	   Beide Regeln hängen ausschließlich am Zustand des <html>-Elements,
	   bewusst KEIN JS: Die Zustandsklasse steht durch den
	   Anti-Flash-Schnipsel (includes/sidebar.php) bereits vor dem ersten
	   Rendern fest. Würde JS umschalten, blitzte bei jedem Seitenaufbau
	   kurz das falsche Logo auf - genau das Problem, das der Schnipsel für
	   die Breite löst.

	   Entscheidend ist die Richtung der zweiten Regel: Das kompakte Logo
	   ist im GRUNDZUSTAND verborgen (html ohne Zustandsklasse), nicht erst
	   nachträglich. Andersherum - kompakt sichtbar und erst durch eine
	   Regel versteckt - wäre es beim allerersten Rendern eines
	   ausgeklappten Aufrufs kurz sichtbar. */
	:root:root [data-sidebar-logo] {
		display: none;
	}
}

/* Die Gegenrichtung, aus derselben Quelle: Solange die Spur NICHT
   gilt, ist das Signet verborgen. style(not (…)) statt eines
   Klassen-:not() - sonst hinge diese eine Regel wieder an der
   Vorliebe statt an der Stufe und stünde im mittleren Bereich falsch. */
@container style(not (--sichtwechsel-sidebar-spur: 1)) {
	:root:root [data-sidebar-logo-kompakt] {
		display: none;
	}
}

/* ---------------------------------------------------------------------
 * Aktiver Eintrag im eingeklappten Zustand
 *
 * [aria-current="page"] färbt ausgeklappt die ganze Zeile. Auf 64px
 * bleibt davon ein farbiges Quadrat - das liest sich eher als
 * Hover-Zustand denn als "hier bin ich", vor allem weil daneben kein
 * Text mehr steht, der die Aussage trägt.
 *
 * Die Ergänzung ist bewusst ADDITIV: eine Akzentkante links, zusätzlich
 * zur bestehenden Färbung. Keine zweite Zuordnung, keine zweite Quelle -
 * derselbe Selektor, nur eine weitere Eigenschaft. Bricks' eigene
 * Färbung bleibt unangetastet.
 * ------------------------------------------------------------------- */

@container style(--sichtwechsel-sidebar-spur: 1) {
/* GILT, WENN DIE SPUR GILT - egal aus welchem der beiden Gründe.
   Ob die Nutzerin eingeklappt hat (ab 1280) oder die Breite es
   erzwingt (768-1279), entscheidet der Stufenschalter ganz oben;
   hier steht nur, wie die Spur aussieht. Siehe den Block
   "Drei Stufen". */
	:root:root [data-sidebar] [aria-current="page"] {
		position: relative;
	}

	:root:root [data-sidebar] [aria-current="page"]::before {
		content: "";
		position: absolute;
		left: 0;
		top: 50%;
		transform: translateY(-50%);
		width: 3px;
		height: 60%;
		border-radius: 0 2px 2px 0;
		background-color: var(--status-green-dark);
	}

	/* ---------------------------------------------------------------------
	 * Tooltips - Pflicht, nicht Zierde
	 *
	 * Ohne Labels wäre die Navigation eingeklappt unbedienbar. Der Text
	 * kommt aus data-sidebar-tooltip, das JS aus dem LABEL des jeweiligen
	 * Punkts füllt - es gibt also keine zweite Textquelle, die
	 * auseinanderlaufen könnte.
	 *
	 * :focus-visible ist gleichberechtigt neben :hover, sonst ist die
	 * Navigation nur mit der Maus benutzbar. Den zugänglichen Namen trägt
	 * zusätzlich aria-label am Link (ebenfalls vom JS aus dem Label
	 * gesetzt) - der Tooltip hier ist die SICHTBARE Hälfte, aria-label die
	 * vorgelesene.
	 * ------------------------------------------------------------------- */

	/* ---------------------------------------------------------------------
	 * ⚠️ STAPELREIHENFOLGE - warum ein höherer z-index am Tooltip nicht
	 * genügt (Befund 30.08.2026)
	 *
	 * Die Sidebar trägt über die Bricks-Klasse `app__sidebar`
	 * `position: fixed`. Fixed positionierte Elemente erzeugen IMMER einen
	 * eigenen Stacking Context - unabhängig vom z-index, anders als
	 * relative/absolute, die dafür einen z-index ungleich `auto` brauchen.
	 *
	 * Folge: Der Tooltip kann diesen Kontext nicht verlassen. Sein z-index
	 * sortiert ihn nur INNERHALB der Sidebar. Nach außen konkurriert nicht
	 * der Tooltip mit den Containern des Inhaltsbereichs, sondern die
	 * SIDEBAR ALS GANZES - und die stand bisher auf `z-index: auto`, also
	 * auf Ebene 0 in DOM-Reihenfolge. Jeder Inhalts-Container mit eigenem
	 * z-index gewann damit.
	 *
	 * Deshalb liegt die Stellschraube an der Sidebar
	 * (--sichtwechsel-sidebar-z-index), nicht am Tooltip.
	 *
	 * Innerhalb dieses Stylesheets erzeugt KEIN Vorfahr des Tooltips einen
	 * weiteren Kontext - geprüft auf transform, filter, opacity < 1,
	 * will-change, isolation und position mit z-index:
	 *   [data-sidebar-header]   position: relative, KEIN z-index -> kein Kontext
	 *   [data-sidebar-tooltip]  position: relative, KEIN z-index -> kein Kontext
	 *   [aria-current="page"]   position: relative, KEIN z-index -> kein Kontext
	 * Die opacity-Übergänge liegen auf Geschwistern und Pseudo-Elementen,
	 * nicht auf Vorfahren.
	 *
	 * SOLLTE DIE ERHÖHUNG NICHT REICHEN, liegt ein weiterer Kontext im
	 * Bricks-Markup ZWISCHEN Sidebar und Tooltip (z. B. ein Wrapper mit
	 * transform oder opacity). Dann ist die Lösung nicht "noch höher",
	 * sondern den Tooltip aus dem Kontext zu holen: als Element am <body>,
	 * per JS positioniert. Das ist deutlich mehr Aufwand und sollte erst
	 * gebaut werden, wenn dieser Weg nachweislich scheitert.
	 * ------------------------------------------------------------------- */

	:root:root [data-sidebar-tooltip] {
		position: relative;
	}

	:root:root [data-sidebar-tooltip]::after {
		content: attr(data-sidebar-tooltip);
		position: absolute;
		left: calc(100% + 10px);
		top: 50%;
		transform: translateY(-50%);

		/* Hoch innerhalb der Sidebar - mehr kann dieser Wert nicht
		   leisten, siehe den Kasten oben. Er sortiert den Tooltip über die
		   übrigen Navigationspunkte, nicht über den Inhaltsbereich. */
		z-index: 1000;
		padding: 6px 10px;
		border-radius: 8px;
		background-color: var(--brand-green-900);
		color: var(--brand-app-1);
		font-size: 13px;
		line-height: 1.3;
		white-space: nowrap;
		pointer-events: none;
		opacity: 0;
		visibility: hidden;
		transition: opacity .12s ease;
	}

	:root:root [data-sidebar-tooltip]:hover::after,
	:root:root [data-sidebar-tooltip]:focus-visible::after {
		opacity: 1;
		visibility: visible;
	}
}

@media (prefers-reduced-motion: reduce) {
	[data-sidebar-tooltip]::after {
		transition: none;
	}
}

/* Der Umschalter ist ein echter <button>; Bricks liefert das Icon als
   Kind. Ohne diese Rücksetzung trüge er den Browser-Button-Look. */
[data-sidebar-umschalter] {
	display: inline-flex;
	align-items: center;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	cursor: pointer;
}

/* Das Icon zeigt eingeklappt in die andere Richtung - dieselbe Grafik,
   gespiegelt, statt einer zweiten Datei. */
@container style(--sichtwechsel-sidebar-spur: 1) {
/* GILT, WENN DIE SPUR GILT - egal aus welchem der beiden Gründe.
   Ob die Nutzerin eingeklappt hat (ab 1280) oder die Breite es
   erzwingt (768-1279), entscheidet der Stufenschalter ganz oben;
   hier steht nur, wie die Spur aussieht. Siehe den Block
   "Drei Stufen". */
	:root:root [data-sidebar-umschalter] img,
	:root:root [data-sidebar-umschalter] svg {
		transform: scaleX(-1);
	}

	/* ---------------------------------------------------------------------
	 * Sidebar-Header im eingeklappten Zustand: Signet, beim Ansteuern
	 * Umschalter
	 *
	 * Ruhezustand zeigt nur [data-sidebar-logo-kompakt]. Bei :hover oder
	 * :has(:focus-visible) auf dem Header-Container tauscht das Signet
	 * gegen den Umschalter - an derselben Position, auf derselben Grundfläche, damit
	 * nichts springt. Ausgeklappt bleibt alles wie bisher: Diese Regeln
	 * hängen sämtlich am eingeklappten Zustand des <html>-Elements.
	 *
	 * Braucht einen eigenen Marker [data-sidebar-header] am Header-Container
	 * (Bricks-Klasse sidebar__header):
	 * CSS kann nicht vom Umschalter auf dessen Elternelement zielen, und
	 * :hover/:has(:focus-visible) müssen genau dort greifen.
	 *
	 * :has(:focus-visible) statt :focus-within (Korrektur 29.08.2026):
	 * :focus-within greift auch, wenn der Fokus per MAUSKLICK gesetzt
	 * wurde - der Umschalter blieb nach einem Klick sichtbar und behielt
	 * seine Fläche, der Header fiel nie in den Ruhezustand zurück.
	 * :focus-visible ist die Tastatur-Variante, und :has() trägt sie vom
	 * Button auf den Header hoch.
	 *
	 * AUSDRÜCKLICH NICHT über blur() im Klick-Handler gelöst: Das ist die
	 * verbreitete Abkürzung und sie ist falsch. Sie nimmt den Fokus aus
	 * dem Dokument, wer per Tastatur navigiert, landet danach wieder am
	 * Seitenanfang. Der Fokus bleibt auf dem Button - er soll nur nicht
	 * mehr wie ein Hover aussehen.
	 *
	 * ⚠️ WARUM NUR opacity UND KEIN visibility AM UMSCHALTER:
	 * `visibility: hidden` nimmt ein Element genauso aus der
	 * Tabulator-Reihenfolge wie `display: none`. Beides würde also exakt
	 * das verhindern, wofür :has(:focus-visible) hier gebraucht wird - der
	 * Umschalter wäre nie fokussierbar, der Fokus könnte nie im Header
	 * landen, und der Zustand träte ausschließlich per Maus ein. Der
	 * Umschalter bekommt deshalb ausschließlich opacity.
	 *
	 * Das Signet darf visibility benutzen - es ist dekorativ und nicht
	 * fokussierbar. Es trägt zusätzlich dauerhaft pointer-events: none,
	 * damit es den darüberliegenden Umschalter nie abfängt.
	 *
	 * Nebenwirkung, bewusst in Kauf genommen: Der unsichtbare Umschalter
	 * liegt über der gesamten Header-Fläche und ist dort auch im Ruhezustand
	 * klickbar. Ein Klick aufs Signet klappt die Sidebar also aus - was
	 * genau das ist, was ein Klick dort erwartbar tut.
	 * ------------------------------------------------------------------- */

	:root:root [data-sidebar-header] {
		position: relative;

		/* Bricks setzt am Header justify-content: space-between und einen
		   asymmetrischen Innenabstand (links 12px, rechts 20px) - beides
		   sinnvoll für die ausgeklappte Zeile aus Logo LINKS und Umschalter
		   RECHTS. Eingeklappt liegt beides übereinander in der Mitte; die
		   ausgeklappten Werte würden das Signet um mehrere Pixel von der
		   Mittelachse wegschieben.

		   Die Achse ist der eigentliche Prüfpunkt: Signet, Umschalter und
		   alle Navigations-Icons müssen auf EINER senkrechten Linie liegen.
		   Der Innenabstand wird deshalb links wie rechts auf 0 gesetzt -
		   die Zentrierung übernimmt die Positionierung, ein Restabstand
		   würde sie nur wieder verschieben. Oben/unten bleibt unangetastet,
		   das ist die Kopfhöhe. */
		justify-content: center;
		padding-left: 0;
		padding-right: 0;
	}

	:root:root [data-sidebar-header] [data-sidebar-logo-kompakt] {
		pointer-events: none;
		opacity: 1;
		visibility: visible;
		transition: opacity .12s ease;
	}

	:root:root [data-sidebar-header]:hover [data-sidebar-logo-kompakt],
	:root:root [data-sidebar-header]:has(:focus-visible) [data-sidebar-logo-kompakt] {
		opacity: 0;
		visibility: hidden;
	}

	/* inset: 0 gibt dem Umschalter exakt die Grundfläche des Headers - das
	   ist die "gleiche Grundfläche", die das Springen verhindert. */
	:root:root [data-sidebar-header] [data-sidebar-umschalter] {
		position: absolute;
		inset: 0;

		/* Der Umschalter trägt die Bricks-Klasse app-button mit
		   width/min-width/max-width und height/min-height/max-height auf je
		   40px. FESTE MASSE SCHLAGEN inset: 0 - der Button säße sonst als
		   40x40-Kachel in der oberen linken Ecke, statt die Headerfläche
		   einzunehmen. Alle sechs Werte müssen deshalb aufgehoben werden,
		   nicht nur width/height: min-width und max-height allein würden
		   die Auflösung schon wieder verhindern.

		   Die Alternative wäre gewesen, die 40x40 zu behalten und den
		   Button per top/left 50% plus translate zu zentrieren. Dann wäre
		   aber nur diese kleine Fläche klickbar - die bestätigte
		   Nebenwirkung "Klick aufs Signet klappt aus" ginge weitgehend
		   verloren. */
		width: auto;
		height: auto;
		min-width: 0;
		max-width: none;
		min-height: 0;
		max-height: none;

		/* Beide Achsen: justify-content zentriert waagerecht, align-items
		   senkrecht. Letzteres steht zwar schon in der Grundregel für
		   [data-sidebar-umschalter], hat dort aber dieselbe Spezifität wie
		   .app-button - wer gewinnt, hinge an der Ladereihenfolge. Hier ist
		   die Regel spezifisch genug, dass sie sicher greift. */
		justify-content: center;
		align-items: center;

		opacity: 0;
		transition: opacity .12s ease;
	}

	:root:root [data-sidebar-header]:hover [data-sidebar-umschalter],
	:root:root [data-sidebar-header]:has(:focus-visible) [data-sidebar-umschalter] {
		opacity: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	[data-sidebar-header] [data-sidebar-logo-kompakt],
	[data-sidebar-header] [data-sidebar-umschalter] {
		transition: none;
	}
}

/* ---------------------------------------------------------------------
 * Hoverfläche des Umschalters (eingeklappt)
 *
 * Der Button füllt eingeklappt den ganzen Header - das ist gewollt, es
 * ist die Klickfläche. Sein Hover-Hintergrund aus der Bricks-Klasse
 * `app-button` färbt dadurch aber die gesamte Fläche.
 *
 * Lösung: Der Button selbst wird hintergrundlos, die sichtbare Fläche
 * liegt auf einem zentrierten Pseudo-Element in derselben Größe und
 * Form wie bei den Navigationspunkten. Der Button behält seine volle
 * Ausdehnung - er wird ausdrücklich NICHT auf 40x40 verkleinert, sonst
 * wäre die ganzflächige Klickfläche wieder weg und ein Klick aufs
 * Signet würde nicht mehr ausklappen.
 *
 * ::before, nicht ::after: ::after ist bereits vom Tooltip belegt.
 *
 * RADIUS OHNE DUPLIKAT: border-radius: inherit nimmt den Wert vom
 * Button, also aus derselben Bricks-Klasse `app-button`, die auch die
 * Navigationspunkte rundet. Kein zweiter Wert, der auseinanderlaufen
 * könnte - und kein hartkodierter Radius, für den es ohnehin kein
 * Token gäbe (Core Framework kennt --radius-s = 8px und --radius-m =
 * 12px; die 10px liegen dazwischen, siehe Bericht).
 *
 * Farbe aus dem Token --brand-green-60, derselbe Hover-Ton wie bei den
 * Navigationspunkten und den Segmented-Buttons in app-forms.css.
 * ------------------------------------------------------------------- */

@container style(--sichtwechsel-sidebar-spur: 1) {
/* GILT, WENN DIE SPUR GILT - egal aus welchem der beiden Gründe.
   Ob die Nutzerin eingeklappt hat (ab 1280) oder die Breite es
   erzwingt (768-1279), entscheidet der Stufenschalter ganz oben;
   hier steht nur, wie die Spur aussieht. Siehe den Block
   "Drei Stufen". */
	:root:root [data-sidebar-header] [data-sidebar-umschalter],
	:root:root [data-sidebar-header] [data-sidebar-umschalter]:hover,
	:root:root [data-sidebar-header] [data-sidebar-umschalter]:focus-visible {
		background-color: transparent;
	}

	:root:root [data-sidebar-header] [data-sidebar-umschalter]::before {
		content: "";
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		width: var(--sichtwechsel-sidebar-hoverflaeche);
		height: var(--sichtwechsel-sidebar-hoverflaeche);
		border-radius: inherit;
		background-color: var(--brand-green-60);
		opacity: 0;
		transition: opacity .12s ease;
	}

	:root:root [data-sidebar-header] [data-sidebar-umschalter]:hover::before,
	:root:root [data-sidebar-header] [data-sidebar-umschalter]:focus-visible::before {
		opacity: 1;
	}

	/* Das Icon muss über der Fläche liegen. Ohne eigenen Stapelkontext
	   zeichnet das Pseudo-Element über den Inhalt des Buttons - das Icon
	   verschwände hinter der Hoverfläche. */
	:root:root [data-sidebar-header] [data-sidebar-umschalter] > * {
		position: relative;
		z-index: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	[data-sidebar-header] [data-sidebar-umschalter]::before {
		transition: none;
	}
}

/* =====================================================================
 * Mobil: die Sidebar wird ein Drawer
 *
 * Unterhalb des Umbruchpunkts verschwindet die Sidebar aus dem Layout;
 * der Toggle schiebt sie als Ebene über den Inhalt.
 *
 * 🔴 HIER GIBT ES DIE ICON-SPUR NICHT. Unter 768 px zwei Zustände,
 * nicht drei: ganz weg oder als Ebene darüber. Die Spur-Regeln weiter
 * oben greifen hier nicht, weil der Stufenschalter
 * --sichtwechsel-sidebar-spur unterhalb von 768 px auf 0 steht: Die
 * eine Media-Query, die ihn anhebt, beginnt genau dort.
 *
 * Die Einklapp-Klasse bleibt am <html> gespeichert und wirkt beim
 * Zurückwechseln auf den grossen Schirm sofort wieder - sie tut hier
 * unten nur nichts.
 *
 * ⚠️ DER UMBRUCHPUNKT STEHT ZWEIMAL in dieser Datei, und das ist eine
 * Doppelung, die sich nicht auflösen lässt: Eine Media-Query kann
 * keine Custom Property lesen. Die Variable darunter ist die Quelle
 * für alles andere - JavaScript liest sie von dort, statt die Zahl
 * noch ein drittes Mal zu tragen. Wer sie ändert, ändert die beiden
 * Zeilen hier zusammen; sie stehen deshalb direkt untereinander.
 *
 * 🔴 767 UND NICHT MEHR 991 (07.09.2026). Zwischen 768 und 1279 gibt
 * es jetzt die Icon-Spur (siehe "Drei Stufen" oben) - der Drawer
 * beginnt erst darunter. Vorher lag die Grenze bei 991, und zwischen
 * 768 und 991 war die Sidebar bereits weg.
 *
 * 767 und nicht 800: Bricks' eigene Umbruchpunkte sind 1279 / 991 /
 * 767 / 478 (bricks/includes/breakpoints.php). Ein eigener Wert
 * daneben ergäbe einen Streifen, in dem Bricks' Responsive-Werte schon
 * umgeschaltet haben und unsere noch nicht.
 * ================================================================== */

:root {
	--sichtwechsel-sidebar-umbruch: 767px;
	/* Zwilling der Zahl in der Media-Query unten - siehe oben. */

	/* Breite des Drawers. 85 % und nicht 100 %: Der sichtbare Streifen
	   daneben sagt "das liegt obendrauf" und ist zugleich die Fläche
	   zum Schliessen. */
	--sichtwechsel-sidebar-drawer-breite: 85%;
	--sichtwechsel-sidebar-drawer-max: 320px;
}

@media (max-width: 767px) {
	/*
	 * Der Inhalt nimmt die volle Breite. Über die eine Variable, an der
	 * in Bricks sowohl die Sidebarbreite als auch der margin-left des
	 * Main-Wrappers hängen - keine zweite Regel für den
	 * Inhaltsbereich.
	 *
	 * 🔴 :root UND NICHT html (Befund 06.09.2026). Hier stand
	 * "html { … }", und die Zeile hat nie gegriffen: Die Variable wird
	 * oben auf :root gesetzt, und :root ist eine Pseudo-Klasse (0,1,0),
	 * html ein Typselektor (0,0,1). Beide treffen dasselbe Element,
	 * also gewinnt :root - unabhängig von Reihenfolge und Media-Query.
	 * Der Hauptcontainer hielt den Platz der Sidebar weiter frei,
	 * obwohl die Sidebar längst als Drawer darüberlag.
	 *
	 * Kein Fehler, keine Meldung, nur ein Rand, den niemand bestellt
	 * hat - und sichtbar erst auf einem Gerät, das beim Bauen niemand
	 * aufhat.
	 *
	 * ⚠️ DIE LEHRE, für die nächste Stelle dieser Art: Verschwindet ein
	 * Element, muss der Platz, den es reserviert hat, AUS DERSELBEN
	 * QUELLE mitverschwinden. Deshalb steht hier die Variable und nicht
	 * der Abstand am Container: Zwei Regeln, die zusammengehören und
	 * getrennt gepflegt werden, laufen genau hier auseinander.
	 */
	:root {
		/* Überschreibt die calc()-Formel oben: Unter 768 gibt es keine
		   Sidebar im Layout, also auch keinen Platz für sie. */
		--sichtwechsel-sidebar-aktuelle-breite: 0px;
	}

	/*
	 * 🔴 DREIMAL DAS ATTRIBUT, UND DAS IST GERECHNET (06.09.2026).
	 *
	 * Der Drawer öffnete, das Overlay erschien, translateX(0) griff -
	 * und die Sidebar blieb unsichtbar, weil sie 0 px breit war.
	 *
	 * BRICKS SCHREIBT SEINE EIGENE ELEMENT-KLASSE IN DENSELBEN
	 * SELEKTOR. Was im Builder wie eine Klasse aussieht, kommt als
	 * zwei heraus:
	 *
	 *     .app__sidebar.brxe-div { width: var(--…-aktuelle-breite); … }
	 *
	 * Das sind (0,2,0), nicht (0,1,0). Die frühere Fassung stand mit
	 * [data-sidebar][data-sidebar] bei denselben (0,2,0) - Gleichstand,
	 * und den entscheidet die Reihenfolge, die Bricks mit seinem
	 * Inline-Block im <head> für sich hat. Unsere Breite kam nie an,
	 * Bricks' 0 px blieb stehen.
	 *
	 * ⚠️ DAS GILT FÜR JEDE REGEL, DIE GEGEN EINE BRICKS-KLASSE ANTRITT,
	 * nicht nur hier: Wer die Spezifität einer Bricks-Klasse zählt,
	 * muss die brxe--Klasse mitzählen, sonst liegt die Rechnung um eine
	 * Stufe daneben. Und eine Regel, die bei Gleichstand nur über die
	 * Reihenfolge gewinnen würde, gewinnt gegen Bricks gar nicht.
	 *
	 * Drei Attribute ergeben (0,3,0) und schlagen die zwei Klassen
	 * damit eindeutig - nicht knapp, sondern eine volle Stufe darüber.
	 */
	[data-sidebar][data-sidebar][data-sidebar] {
		position: fixed;
		inset-block: 0;
		inset-inline-start: 0;
		z-index: 100;

		width: var(--sichtwechsel-sidebar-drawer-breite);
		max-width: var(--sichtwechsel-sidebar-drawer-max);

		/*
		 * min-width ausdrücklich auf 0, obwohl das der Vorgabewert ist:
		 * Bricks setzt die Eigenschaft an derselben Klasse auf die
		 * Variable, und die steht mobil ohnehin auf 0 - engt also
		 * nichts ein. Eine Untergrenze ist keine Obergrenze; die
		 * Breite kam von width und max-width, und beide stehen jetzt
		 * hier. Die Zeile hält den Wert trotzdem fest, damit eine
		 * künftige Bricks-Einstellung ihn nicht unbemerkt anhebt.
		 */
		min-width: 0;

		/* Ausserhalb des Bildes geparkt. transform und nicht left:
		   Eine Positionsänderung zwänge den Browser bei jedem
		   Einzelbild zum Neuberechnen des Layouts. */
		transform: translateX(-100%);
		transition: transform 240ms ease;

		/* Eine lange Navigation muss im Drawer scrollen können, ohne
		   die Seite dahinter mitzunehmen. */
		overflow-y: auto;
		overscroll-behavior: contain;
	}

	html.sichtwechsel-sidebar-offen [data-sidebar][data-sidebar][data-sidebar] {
		transform: translateX(0);
	}

	/*
	 * Die abgedunkelte Fläche. Ein echtes Element, kein Pseudo: Sie
	 * muss den Tipp zum Schliessen entgegennehmen, und das kann ein
	 * Pseudo-Element des <html> nicht.
	 */
	.sw-sidebar-abdunklung {
		position: fixed;
		inset: 0;
		z-index: 99;
		background-color: rgb(0 0 0 / 45%);
		opacity: 0;
		visibility: hidden;
		transition: opacity 240ms ease, visibility 0s linear 240ms;
	}

	html.sichtwechsel-sidebar-offen .sw-sidebar-abdunklung {
		opacity: 1;
		visibility: visible;
		transition: opacity 240ms ease;
	}

	/*
	 * Die Seite dahinter darf nicht scrollen. Am <html>, nicht am
	 * <body>: iOS Safari nimmt overflow: hidden nur dort zuverlässig
	 * an.
	 */
	html.sichtwechsel-sidebar-offen {
		overflow: hidden;
	}

	/*
	 * Logos: volles Logo, kein Signet - unabhängig davon, ob die
	 * Einklapp-Klasse gespeichert ist. Ohne diese beiden Zeilen zeigte
	 * ein Konto, das zuletzt eingeklappt war, im Drawer beide Logos:
	 * Das Ausblenden des vollen liegt oben im min-width-Block, das
	 * Ausblenden des Signets hängt an html:not(.eingeklappt) - und das
	 * trifft dann nicht zu.
	 */
	[data-sidebar-logo] {
		display: revert;
	}

	[data-sidebar-logo-kompakt] {
		display: none;
	}
}

/* =====================================================================
 * Wo welcher Umschalter zu sehen ist
 *
 * 🔴 DIE LAGE IM BAUM SAGT ES SCHON - kein neues Attribut (07.09.2026):
 * Ein Umschalter INNERHALB von [data-sidebar] ist nur bedienbar, wenn
 * die Sidebar da ist; einer AUSSERHALB ist der Weg hinein, wenn sie
 * weg ist. Also: der äußere nur bis 767, der innere folgt der Sidebar
 * von selbst.
 *
 * ANLASS: Der Umschalter in der Topbar trug die projekteigene Klasse
 * d-mobile-only, die erst unter 600 px einblendet. Zwischen 600 und
 * 991 war die Sidebar schon weg und der Knopf noch nicht da - ein
 * Bereich ganz ohne Navigation, live. Die Zahl gehört an EINE Stelle,
 * und das ist diese Datei; d-mobile-only kommt am Hamburger weg.
 *
 * :not([data-sidebar] *) statt eines eigenen Attributs am äußeren
 * Knopf: Ein Attribut wäre eine zweite Aussage über etwas, das im
 * Markup schon steht - und die kann fehlen, wenn jemand das Element
 * dupliziert.
 *
 * Spezifität: [attr][attr] (0,2,0) plus :not(…), das die Spezifität
 * seines stärksten Arguments erbt ([data-sidebar] * = (0,1,0)),
 * ergibt (0,3,0) - eine volle Stufe über einer Bricks-Klasse.
 * ================================================================== */

@media (min-width: 768px) {
	[data-sidebar-umschalter][data-sidebar-umschalter]:not([data-sidebar] *) {
		display: none;
	}
}

/* ---------------------------------------------------------------------
 * 🔴 IM SPUR-BEREICH GIBT ES NICHTS ZU SCHALTEN (07.09.2026)
 *
 * Zwischen 768 und 1279 px erzwingt die Media-Query
 * --sichtwechsel-sidebar-spur: 1, und die gespeicherte Vorliebe kommt
 * dagegen nicht an - beim Bau gemessen und als "Zeichen für Zeichen
 * identisch" bestätigt. Die Folge blieb damals ungezogen: Der
 * Umschalter in der Sidebar stand weiter da und bewirkte nichts. Ein
 * Knopf, der nichts tut, ist schlechter als kein Knopf - er sieht aus
 * wie ein Fehler in der Anwendung.
 *
 * ZWEI DINGE MÜSSEN WEG, nicht eines:
 *
 *   1. Der Umschalter selbst.
 *   2. Der Tausch am Logo. Im Spur-Zustand zeigt der Kopf im Ruhezustand
 *      das Signet und blendet es bei :hover bzw. Tastaturfokus aus,
 *      damit der Umschalter darunter erscheint (siehe den Block
 *      "Kopfzeile"). Bliebe nur Punkt 1, verschwände das Signet beim
 *      Darüberfahren und es käme NICHTS nach - eine leere Fläche, wo
 *      vorher ein Logo war. Der Tausch verspricht ausserdem eine
 *      Bedienbarkeit, die es hier nicht gibt.
 *
 * Der äußere Umschalter ist in diesem Bereich schon durch die Regel
 * darüber weg. Im Spur-Bereich steht damit KEIN Umschalter - richtig
 * so, denn es gibt keinen zweiten Zustand, in den man wechseln könnte.
 *
 * NICHT max-width: 1279 ALLEIN: Unterhalb von 768 ist die Sidebar ein
 * Drawer, und der Umschalter darin schliesst ihn (sidebar-drawer.js,
 * Klick auf einen Umschalter im offenen Drawer). Dort ist er also sehr
 * wohl bedienbar und muss bleiben.
 *
 * Spezifität: :root:root:root (0,3,0) statt der sonst üblichen
 * doppelten Wurzel - diese Regeln müssen die Regeln der
 * @container-Blöcke überstimmen, die selbst schon bei (0,5,0) liegen.
 * Über die Reihenfolge zu gewinnen wäre hier zwar möglich, aber genau
 * die Sorte stiller Abhängigkeit, die diese Datei sonst vermeidet.
 * ------------------------------------------------------------------- */

@media (min-width: 768px) and (max-width: 1279px) {
	:root:root:root [data-sidebar] [data-sidebar-umschalter] {
		display: none;
	}

	:root:root:root [data-sidebar-header]:hover [data-sidebar-logo-kompakt],
	:root:root:root [data-sidebar-header]:has(:focus-visible) [data-sidebar-logo-kompakt] {
		opacity: 1;
		visibility: visible;
	}
}

/*
 * Kein Einschieben für alle, die keine Bewegung wollen - der Drawer
 * erscheint, statt zu fahren. Ausserhalb der max-width-Query, damit die
 * Regel unabhängig vom Umbruchpunkt gilt.
 */
@media (prefers-reduced-motion: reduce) {
	[data-sidebar][data-sidebar][data-sidebar],
	.sw-sidebar-abdunklung {
		transition: none;
	}
}
