/* ---------------------------------------------------------------------
 * Dropdown - Verhalten und Zustand, nicht Aussehen
 *
 * Wiederverwendbarer Baustein. Sein erstes Vorkommen ist das
 * Profilmenü der Topbar; Zeilen-Dreipunktmenüs, Filter und Sortierung
 * sollen ihn ohne Neubau benutzen können. Deshalb steht hier NICHTS
 * über Farben, Schatten, Breite oder die Position des Panels - das
 * bleibt vollständig in Bricks.
 *
 * DOM-Vertrag (in Bricks zu setzen, alles als data-Attribut):
 *
 *   [data-sw-dropdown="profil"]              Wrapper
 *     [data-sw-dropdown-ausloeser]           Div mit HTML-Tag "button"
 *       [data-sw-dropdown-kompakt]           faellt unter 991px weg
 *         [data-sw-dropdown-pfeil]           dreht sich beim Oeffnen
 *     [data-sw-dropdown-panel]               Klappteil
 *
 * Der Wert am Wrapper benennt das Vorkommen, nicht den Mechanismus:
 * Alle Regeln hier greifen auf [data-sw-dropdown] ohne Wert. CSS fuer
 * Besonderheiten eines einzelnen Dropdowns haengt an
 * [data-sw-dropdown="profil"] - ein Attribut, zwei Aufgaben.
 *
 * ⚠️ ZWEI SPEZIFITAETS-EBENEN MIT ABSICHT (07.09.2026):
 *
 *   Zustandsregeln    hoch (0,3,0) und darueber. Sie muessen gegen
 *                     Bricks gewinnen: Eine Bricks-Klasse ist immer
 *                     ZWEI Klassen (.klasse.brxe-div = 0,2,0) und
 *                     steht inline im <head>, gewinnt also auch jeden
 *                     Gleichstand. Erreicht ohne !important, indem die
 *                     Wurzel doppelt geschrieben wird.
 *
 *   Der Button-Reset  niedrig (0,1,0). Er soll NUR den
 *                     Browser-Standard raeumen und gegen jede
 *                     Bricks-Klasse VERLIEREN. Stuende er auf (0,3,0),
 *                     wuerde dieses Modul das Aussehen des Ausloesers
 *                     bestimmen - genau die Grenze, die es nicht
 *                     ueberschreiten darf.
 *
 * ------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
 * 1. Der Auslöser ist ein echter <button>
 *
 * Damit kommen Tab-Erreichbarkeit, Enter/Leertaste, die Ankuendigung
 * als Schaltflaeche und der Fokusring vom Browser. Was NICHT vom
 * Browser kommt, sind seine Standardstile: Hintergrund, Rand,
 * Innenabstand, eigene Schriftfamilie, zentrierter Text. Ohne diesen
 * Block saesse ein grauer Kasten um Avatar und Pille.
 *
 * Dasselbe musste bei .app-button nachgezogen werden, als die Klasse
 * auf <button>-Elementen landete (assets/css/list-engine.css:519).
 *
 * Bewusst OHNE display: Bricks stellt den Ausloeser auf flex, und die
 * Anordnung von Avatar und Pille gehoert dorthin.
 * ------------------------------------------------------------------- */

[data-sw-dropdown-ausloeser] {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	font: inherit;
	color: inherit;
	text-align: inherit;
	cursor: pointer;
}

/* ---------------------------------------------------------------------
 * 2. Der Fokusring liegt um den ganzen Auslöser
 *
 * Weil der Ring auf dem <button> selbst sitzt, umfasst er Avatar UND
 * Pille - am heutigen Bricks-Dropdown liegt er nur um den Pfeil und
 * sieht dadurch aus wie ein Fehler.
 *
 * :focus-visible und nicht :focus. Anmerkung zur Begruendung im
 * Auftrag: Der Standardring der Browser ist seit Jahren SELBST an
 * :focus-visible gebunden - ein Mausklick auf einen <button> erzeugt
 * ihn also ohnehin nicht. Erscheint er heute trotzdem, liegt die
 * Ursache in einer :focus-Regel von Bricks, die ich von hier aus nicht
 * sehen kann. Diese Regel setzt den Ring deshalb ausdruecklich neu,
 * statt sich auf den Standard zu verlassen, und ist hoch genug
 * gewichtet, um eine solche Bricks-Regel zu ueberschreiben.
 *
 * ⚠️ KEIN outline: none IRGENDWO IN DIESER DATEI. Ein entfernter Ring
 * ohne Ersatz ist genau der Fehler, den dieser Block abstellt.
 *
 * Ausnahme von der sonst geltenden Zurueckhaltung (vgl.
 * assets/css/termin-karussell.css: "KEIN EIGENER FOKUSRING"): Dort
 * genuegte der Standard, weil ihm nichts entgegenstand. Hier steht
 * moeglicherweise Bricks entgegen. Soll der Ring anders aussehen,
 * genuegt --sw-dropdown-fokusfarbe an einer beliebigen Stelle darueber
 * - es braucht keine zweite Regel.
 * ------------------------------------------------------------------- */

[data-sw-dropdown][data-sw-dropdown] [data-sw-dropdown-ausloeser]:focus-visible {
	outline: 2px solid var(--sw-dropdown-fokusfarbe, var(--brand-green-900));
	outline-offset: 2px;
}

/* ---------------------------------------------------------------------
 * 3. Zu, solange nicht ausdrücklich offen
 *
 * 🔴 EINE EINZIGE REGEL, UND SIE IST DIE GANZE SICHTBARKEIT.
 *
 * Es gibt bewusst KEINE Gegenregel fuer den offenen Zustand. Der Grund
 * ist handfest: Bricks setzt am Panel ein display (flex), und es gibt
 * in CSS keinen Weg, einen ueberschriebenen Autorenwert
 * zurueckzugeben - "revert" fuehrt zum Browser-Standard, nicht zu
 * Bricks' Wert. Waere die Regel unbedingt formuliert, muesste die
 * Gegenregel den Bricks-Wert erraten und ein zweites Mal hinschreiben.
 * Beim naechsten Dropdown mit "display: grid" waere sie falsch.
 *
 * Stattdessen greift die Regel NUR, solange nicht offen ist. Im
 * offenen Zustand trifft sie nicht mehr zu, und Bricks' eigener Wert
 * gilt unveraendert - ohne dass dieses Modul ihn je kennen muss.
 *
 * KEIN AUFBLITZEN BEIM LADEN: Vor dem ersten Lauf des JS steht am
 * Ausloeser kein aria-expanded="true" - die Regel trifft also zu, und
 * das Panel ist zu, bevor irgendein Skript gelaufen ist. Genau dafuer
 * ist die Bedingung negativ formuliert.
 *
 * KEIN ZWEITER ZUSTANDSTRAEGER: gelesen wird ausschliesslich
 * aria-expanded am Ausloeser. Kein [hidden], keine is-offen-Klasse,
 * kein Attribut am Wrapper. Das JS setzt genau diesen einen Wert und
 * fasst die Sichtbarkeit nie selbst an.
 *
 * Spezifitaet: (0,2,0) doppelte Wurzel + (0,2,0) aus dem :has()
 * + (0,1,0) fuer das Panel = (0,5,0). :not() und :has() erben die
 * Spezifitaet ihres staerksten Arguments.
 *
 * :has() ist im Plugin bereits im Einsatz (sidebar.css, Zeile 180) und
 * in allen Zielbrowsern verfuegbar.
 * ------------------------------------------------------------------- */

[data-sw-dropdown][data-sw-dropdown]:not(
	:has([data-sw-dropdown-ausloeser][aria-expanded="true"])
) [data-sw-dropdown-panel] {
	display: none;

	/*
	 * Zugleich die Endwerte des Ausblendens - siehe Abschnitt 4. Sie
	 * stehen HIER und nicht in einer eigenen Regel, damit es bei einer
	 * Bedingung bleibt: Was zu ist, ist unsichtbar und klein, in
	 * derselben Zeile entschieden.
	 */
	opacity: 0;
	transform: scale(var(--sw-dropdown-startgroesse, 0.96));
}

/* ---------------------------------------------------------------------
 * 4. Das Panel wächst beim Öffnen aus seiner Ecke
 *
 * 🔴 DER ENTWURF BLEIBT UNANGETASTET. Verborgen wird weiterhin über
 * display: none, und Bricks' eigener display-Wert gilt im offenen
 * Zustand unverändert. Das geht nur, weil zwei Dinge zusammenkommen:
 *
 *   transition-behavior: allow-discrete  laesst display mitlaufen -
 *       beim Einblenden schaltet es sofort auf Bricks' Wert, beim
 *       Ausblenden erst am Ende, sodass das Panel waehrend des
 *       Verschwindens ueberhaupt sichtbar bleibt.
 *   @starting-style                      gibt die Werte, MIT DENEN ein
 *       Element startet, das gerade erst gerendert wird. Ohne diesen
 *       Block gibt es keinen Vorher-Wert, von dem aus animiert werden
 *       koennte, und das Einblenden spraenge.
 *
 * Beides seit 2024 verfuegbar. Wer es nicht kann, bekommt das Panel
 * ohne Bewegung, aber vollstaendig - ein sauberer Rueckfall, weil die
 * Sichtbarkeit selbst nicht an der Animation haengt, sondern
 * unveraendert an aria-expanded.
 *
 * AUSDRUECKLICH NICHT ueber visibility/opacity statt display: Das
 * haette geheissen, Bricks' display-Wert doch anzufassen oder ein
 * zweites Verbergen danebenzustellen. Die Regel ist mehr wert als die
 * Animation.
 *
 * ⚠️ transform ERZEUGT EINEN STAPELKONTEXT. Solange im Panel nur
 * Links liegen, ist das folgenlos. Soll dort spaeter etwas ueber den
 * Panelrand hinausragen - ein Untermenue, ein Tooltip, eine
 * Auswahlliste -, wird es am Panel abgeschnitten bzw. laesst sich
 * nicht mehr per z-index darueber heben, und die Ursache steht nicht
 * dort, wo der Fehler auftritt. Dann ist DIESE Regel die Stelle, an
 * der zu entscheiden ist: entweder die Animation fuer dieses
 * Vorkommen abschalten (--sw-dropdown-dauer: 0s) oder das ueberragende
 * Element ausserhalb des Panels aufhaengen.
 *
 * Von aussen einstellbar, mit Vorgabewerten - damit ein Dropdown, das
 * links oder nach oben aufklappt, denselben Baustein ohne Aenderung am
 * Modul benutzen kann:
 *
 *   --sw-dropdown-ursprung      Vorgabe top right
 *   --sw-dropdown-dauer         Vorgabe 200ms (gilt auch fuer den Pfeil)
 *   --sw-dropdown-startgroesse  Vorgabe 0.96
 *
 * KEINE feste Breite von hier aus: Breite ist Aussehen und gehoert
 * nach Bricks. Sie wird fuer die Animation auch nicht gebraucht -
 * scale() ist eine Transformation beim Zeichnen und loest keinen
 * Umbruch aus; der Text wird mitskaliert, nicht neu umgebrochen.
 * ------------------------------------------------------------------- */

[data-sw-dropdown][data-sw-dropdown] [data-sw-dropdown-panel] {
	transform-origin: var(--sw-dropdown-ursprung, top right);

	/*
	 * display MUSS in der Liste stehen und braucht allow-discrete -
	 * ohne das verschwaende das Panel beim Schliessen sofort, und man
	 * saehe von der Rueckwaertsbewegung nichts.
	 */
	transition:
		opacity var(--sw-dropdown-dauer, 200ms) ease,
		transform var(--sw-dropdown-dauer, 200ms) ease,
		display var(--sw-dropdown-dauer, 200ms) allow-discrete;
}

/*
 * Die Werte, mit denen das Einblenden beginnt. Der Selektor muss den
 * OFFENEN Zustand beschreiben - @starting-style gilt fuer den Moment,
 * in dem das Element zu rendern beginnt.
 */
@starting-style {
	[data-sw-dropdown][data-sw-dropdown]:has(
		[data-sw-dropdown-ausloeser][aria-expanded="true"]
	) [data-sw-dropdown-panel] {
		opacity: 0;
		transform: scale(var(--sw-dropdown-startgroesse, 0.96));
	}
}

/* ---------------------------------------------------------------------
 * 5. Der Pfeil dreht sich
 *
 * Gelesen aus demselben aria-expanded wie die Sichtbarkeit. Eine
 * eigene Klasse waere eine zweite Wahrheit - und irgendwann zeigte der
 * Pfeil nach oben, waehrend das Menue zu ist.
 *
 * ⚠️ transform GREIFT NICHT AUF EINER INLINE-BOX (im Testaufbau am
 * 07.09.2026 aufgefallen): Ein <i> oder <span> ohne eigenes display
 * ist eine nicht-ersetzte Inline-Box, und auf die wirkt keine
 * Transformation. Der Selektor traf, die Drehung blieb trotzdem aus -
 * ein stiller Ausfall der unangenehmen Sorte.
 *
 * Deshalb eine BODENREGEL auf (0,1,0), nach demselben Muster wie der
 * Button-Reset oben: Sie stellt nur sicher, dass eine Drehung
 * ueberhaupt moeglich ist, und verliert gegen jede Bricks-Klasse
 * (0,2,0) - setzt Bricks dort flex, inline-flex oder block, gilt das,
 * und transformierbar sind diese alle. Ein Vorgabewert, keine
 * Gestaltung.
 * ------------------------------------------------------------------- */

[data-sw-dropdown-pfeil] {
	display: inline-block;
}

[data-sw-dropdown][data-sw-dropdown] [data-sw-dropdown-pfeil] {
	/* Dieselbe Dauer wie das Panel, aus derselben Variablen: Pfeil und
	   Panel gehoeren zu einer Bewegung. Zwei Zahlen wuerden
	   auseinanderlaufen, sobald jemand nur eine aendert. */
	transition: transform var(--sw-dropdown-dauer, 200ms) ease;
}

[data-sw-dropdown][data-sw-dropdown]
	[data-sw-dropdown-ausloeser][aria-expanded="true"]
	[data-sw-dropdown-pfeil] {
	transform: rotate(180deg);
}

/* ---------------------------------------------------------------------
 * 6. Schmale Schirme: der kompakte Teil fällt weg
 *
 * Beim Profilmenue bleibt damit der Avatar allein stehen und ist
 * weiterhin der Ausloeser - er liegt ja INNERHALB des Buttons.
 *
 * ⚠️ 991px UND NICHT 1024: Bricks arbeitet mit 1279 / 991 / 767 / 478,
 * und die bestehenden Media-Queries des Plugins folgen diesem System
 * (assets/css/sidebar.css:743). Die Zahl steht hier ein zweites Mal,
 * weil Media-Queries kein var() lesen koennen - dieselbe Einschraenkung
 * wie in sidebar.css, wo der Wert fuer das JS zusaetzlich als Custom
 * Property ausgegeben wird. Hier braucht ihn kein JS.
 *
 * Generisch fuer jedes Dropdown mit einem kompakten Teil, nicht auf
 * ="profil" beschraenkt.
 * ------------------------------------------------------------------- */

@media (max-width: 991px) {
	[data-sw-dropdown][data-sw-dropdown] [data-sw-dropdown-kompakt] {
		display: none;
	}
}

/* ---------------------------------------------------------------------
 * 7. Wer keine Bewegung will
 *
 * Der Pfeil springt um, statt zu drehen. Der Endzustand ist derselbe -
 * die Drehung ist Darstellung, nicht Zustand.
 * ------------------------------------------------------------------- */

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

	/*
	 * Ohne Uebergang springt das Panel unmittelbar in seinen Zustand -
	 * und zwar VOLLSTAENDIG: opacity und transform gelten nur in der
	 * geschlossenen Regel, im offenen Zustand steht das Panel damit
	 * voll da. Die Bewegung faellt weg, nichts sonst.
	 */
	[data-sw-dropdown][data-sw-dropdown] [data-sw-dropdown-panel] {
		transition: none;
	}
}
