*, *::before, *::after { box-sizing: border-box; }
/* Groessen mit dem Schluesselwort `auto` animierbar machen (Aufgabe BAL-080).
   Ohne diese Angabe wird zwischen `auto` und einem Pixelwert nicht
   interpoliert: Die Breite eines Dialogs lief beim Vollbildwechsel weich,
   die Hoehe sprang. Browser ohne Unterstuetzung verhalten sich wie bisher -
   die Hoehe springt dort, alles andere bleibt unberuehrt. */
:root { interpolate-size: allow-keywords; }

html, body, .app_mount { height: 100%; min-height: 100%; margin: 0; }
body { background: var(--surface-soft); color: var(--fg-1); font-family: var(--font-sans); font-weight: var(--w-light); font-size: 15px; line-height: var(--lh-normal); overflow: hidden; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
button, input, textarea, select { font: inherit; color: inherit; }
/* Kein Hineinzoomen beim Fokus unter iOS (BAL-219, BAL-220). Safari
   vergroessert die Seite, sobald ein Feld mit weniger als 16 px Schrift den
   Fokus bekommt, und nimmt das nicht zurueck. Deshalb auf Touch-Geraeten jedes
   Texteingabefeld mit mindestens 16 px - an `pointer: coarse` statt an der
   Breite, damit auch ein iPad erfasst ist und der Desktop bleibt, wie er ist.
   `:is()` traegt die Spezifitaet seines staerksten Arguments (0,9,1) auf alle
   drei Feldarten; damit schlaegt die Regel die Klassenregeln der Komponenten
   (hoechstens 0,3,0), ohne `!important`. Kaestchen, Schieber, Datei- und
   Knopffelder haben keine Schrift, die zaehlt, und bleiben aussen vor.
   NICHT `maximum-scale=1` im Viewport: Das sperrt auf Android auch das Zoomen
   mit zwei Fingern, und wer vergroessern muss, koennte es nicht mehr. */
@media (pointer: coarse) {
  :is(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="image"]), textarea, select) { font-size: max(16px, 1em); }
}
button { border: 0; background: transparent; cursor: pointer; }
a { color: var(--q-highlight-2); text-decoration: none; }
/* Fokusring fuer Elemente, denen der Referenzentwurf KEINEN eigenen gibt.
   Urspruenglich Befunde A11Y-004 und A11Y-005, Aufgabe BAL-067; berichtigt
   mit BAL-095.

   GEMESSEN auf dem Dashboard: Von 47 fokussierbaren Elementen haetten ohne
   diese Regel 46 gar keine Kennzeichnung - und alle 46 sind Schaltflaechen,
   Zeilen, Kacheln oder Navigationseintraege. Fuer die ist der Ring noetig,
   der Entwurf sieht dort nichts vor.

   EINGABEFELDER UND TABELLENZEILEN SIND AUSGENOMMEN. Eingabefelder
   kennzeichnet der Entwurf durchgaengig
   anders: border-color auf --q-highlight-3, bei den randlosen Suchfeldern an
   der Huelle samt weissem Grund. Diese Regeln stehen alle noch in dieser
   Datei. Der zusaetzliche Ring legte sich darueber, sodass im Fokus ZWEI
   Ringe in ZWEI Farben zu sehen waren - teal aus dem Entwurf, dunkelblau von
   hier. Beanstandet von der Auftraggeberin und behoben.
   Tabellenzeilen tragen seit BAL-096 eine Flaeche statt einer Umrandung - eine
   Zeile ist display: table-row und bildet kein eigenes Malrechteck, weshalb
   von der Umrandung nur Striche uebrig blieben. Siehe tr:focus-visible unten.

   DER BEFUND A11Y-004 WAR FALSCH: Er stellte fest, das globale Suchfeld sei
   im Fokus "in JEDER Eigenschaft identisch" zum Ruhezustand. Gemessen wurde
   aber das EINGABEFELD, waehrend der Entwurf die HUELLE kennzeichnet.
   Nachgemessen an der Huelle: Rahmen wechselt auf rgb(21,165,181), Grund von
   rgb(241,242,242) auf Weiss. Eine Kennzeichnung war immer da.

   --q-highlight-2 deckend ergibt 13,36 : 1 gegen Weiss. Der Versatz von 2px
   setzt den Ring neben das Element, damit er auch auf dunklen Flaechen (etwa
   dem aktiven Segment einer Pille) auf hellem Grund steht. */
:focus-visible:not(input):not(select):not(textarea):not(tr) { outline: 2px solid var(--q-highlight-2); outline-offset: 2px; }
.hidden { display: none !important; }

/* Das Suchfeld der Klappliste ist der einzige randlose Suchbereich OHNE eigene
   Fokuskennzeichnung im Entwurf - .fsel ist eine Balance-eigene Komponente, die
   es dort nicht gibt. Es bekommt deshalb dieselbe Sprache wie die uebrigen vier
   (.global_search, .ltb-search, .detail-search, .planner-search), die ihre
   Kennzeichnung jeweils an ihrer eigenen Regel tragen. */
.fsel-search:focus-within { border-bottom-color: var(--q-highlight-3); }


/* Markenzeichen — hochgestellt und kleiner (BAL-168).

   `<sup>` allein täte es fast: Der Browser stellt hoch und verkleinert auf etwa
   83 %. Für ein ® ist das zu groß — es steht dann als eigenes Zeichen neben dem
   Wort statt als Beifügung dazu. 0,55 em ist die Größenordnung, in der Marken
   üblicherweise gesetzt werden.

   `line-height: 0`, damit die Hochstellung die Zeile nicht auseinanderzieht —
   sonst wächst jede Überschrift, in der die Marke vorkommt, um ein paar Pixel.

   Die Klasse steht AN `<sup>` und ersetzt es nicht: Das Element trägt die
   Bedeutung, die Klasse nur das Maß. Wo die Marke als reiner Text auftritt
   (Fenstertitel, `title`- und `aria-label`-Attribute, Meldungen, Exporte, der
   Kopf der heruntergeladenen Mitschrift), bleibt das nackte Zeichen stehen —
   dort gibt es keine Auszeichnung, und ein `<sup>` ergäbe sichtbare spitze
   Klammern. */
.marke-r { font-size: 0.55em; vertical-align: super; line-height: 0; }

.ui_icon { display: inline-block; flex-shrink: 0; vertical-align: middle; }
.ui_icon_mask { background-color: currentColor; -webkit-mask: var(--icon-url) center / contain no-repeat; mask: var(--icon-url) center / contain no-repeat; }
.app_shell_nav_item_active .ui_icon_mask, .button .ui_icon_mask { color: currentColor; }
/* Die zweite Spalte ist `minmax(0, 1fr)` und nicht `1fr` (Aufgabe BAL-181).
   Das ist kein Feinschliff, sondern der Unterschied zwischen "die Anwendung
   passt ins Fenster" und "nicht".

   `1fr` ist die Kurzform von `minmax(auto, 1fr)`. Das Mindestmass `auto` ist
   die Min-Content-Breite des Inhalts - die Spalte kann also NICHT schmaler
   werden als ihr breitester unteilbarer Inhalt, egal wie schmal das Fenster
   ist. Der Ueberschuss schiebt sich aus dem Bild, und zwar die GANZE Seite:
   nicht der Inhalt scrollt, sondern das Fenster wandert ueber die Anwendung -
   samt Seitenleiste, die dabei verschwindet.

   GEMESSEN am 2026-09-15 bei 820x900 auf dem Dashboard: documentElement
   .scrollWidth 1058 bei innerWidth 820, seitlich verschiebbar um 238px.
   Natuerliche Mindestbreite je Bereich zwischen 1021px (Budget) und 1146px
   (Benachrichtigungen). Betroffen war damit das ganze Band von 781px - dort
   endet der Umbruch, der das Schmallayout traegt - bis rund 1150px: iPad
   hoch, geteilte Fenster, kleine Notebookfenster, 150-175% Zoom.
   Bildbeleg: docs/user-experience/responsive/bilder/820-huelle-seitlich-verschoben.png

   Mit `minmax(0, 1fr)` darf die Spalte beliebig schmal werden. Der Inhalt
   scrollt dann dort, wo er es ohnehin tut (`.module_list_body` traegt
   `overflow-x: auto`), statt die Seite zu verbreitern.

   WARUM KEIN ZUSAETZLICHER UMBRUCHPUNKT bei etwa 1000px, der die Seitenleiste
   in den schmalen Zustand zwingt (Entscheidung E-5 der Bestandsaufnahme): Das
   Breitlayout ist damit bei JEDER Breite tragfaehig statt nur diesseits und
   jenseits einer weiteren Schwelle, die mitgepflegt werden muesste.

   Vollstaendige Erhebung: docs/user-experience/responsive-design.md, R-01. */
.app_shell { display: grid; grid-template-columns: var(--sidebar-width, 256px) minmax(0, 1fr); grid-template-rows: 62px 1fr; grid-template-areas: "sidebar topbar" "sidebar main"; height: 100vh; min-height: 100vh; background: var(--surface-soft); transition: grid-template-columns var(--dur-base) var(--ease-std); }
.app_shell_sidebar_collapsed { --sidebar-width: 76px; }
.app_shell_sidebar { grid-area: sidebar; display: flex; flex-direction: column; gap: 2px; overflow: hidden; min-height: 0; padding: 18px 14px; background: var(--surface); border-right: 1px solid var(--divider); }
/* Scrollbereich der Navigation (Referenzdesign 2026-10-06, styles.css v80):
   Marke oben und Fuss unten bleiben stehen, nur die Eintraege dazwischen
   rollen. Vorher rollte die ganze Leiste, und bei niedrigen Fenstern
   verschwand der Fuss mit Einklappen und Konto unter dem Rand. Der
   Ausgleich -14px/14px laesst die Rollleiste am Rand der Leiste stehen statt
   im Abstand. Unter 780 px (waagrechte Leiste, Schublade) wirkt der Baustein
   nicht: display: contents laesst die bisherigen Regeln unveraendert greifen. */
.app_shell_brand, .app_shell_sidebar_footer { flex-shrink: 0; }
.app_shell_sidebar_scroll { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 2px; margin: 0 -14px; padding: 0 14px 8px; overflow-x: hidden; overflow-y: auto; scrollbar-width: thin; }
.app_shell_sidebar_scroll > * { flex-shrink: 0; }
@media (max-width: 780px) { .app_shell_sidebar_scroll { display: contents; } }
/* ── Marke oben links: Lockup der Variante 1e "Schnittmenge" ──────────────

   Entwurf docs/design/logo/project/Quantiz Balance Logo.dc.html. Geschichte:
   1c "Gleichgewicht" (BAL-195), ab BAL-200 ohne Zeichen mit Quantiz-
   Wortmarke, 1d "Welle" (BAL-202), 1e (BAL-203), Signetgroesse (BAL-204).

   SEIT BAL-210: Zeichen und Schriftzug, OHNE die Zeile "Budgets ·
   Beauftragungen" (so beauftragt). Der Schriftzug steht dafuer hoeher und
   kraeftiger und passt sich Mission Control an: Comfortaa Medium (500 statt
   300), Versalien, Petrol, 22 statt 17 px, Sperrung 0,15 statt 0,5 em -
   "nicht mehr so breit". Gemessen in der Seitenleiste: 133 px Schriftzug,
   die Lockup endet bei 217 von 219 px. Verglichen und verworfen: Versalien
   20 px / 0,22 em (131 px, wirkte duenner), "Balance" gemischt 26 px
   (117 px, passt weniger zu Mission Control, das Versalien fuehrt).
   Was unten ueber Zeile und Masse steht, ist die Geschichte bis BAL-205.

   Die Lockup bestand aus dem Zeichen, "Balance" und der Zeile "Budgets ·
   Beauftragungen" darunter - OHNE die Quantiz-Wortmarke und ohne den
   Trennstrich, der sie von "Balance" trennte.

   FUENF BENANNTE MASSE STATT EINES MASSSTABS (BAL-204). Bis dahin hing alles
   an `--marke` in festen Verhaeltnissen. Das ging, solange die Lockup
   gleichmaessig skalierte - jetzt soll das Zeichen WACHSEN und die Schrift
   dabei kleiner werden, und dafuer ist ein einziger Massstab das falsche
   Werkzeug. Die Nennerzahl wechselte ausserdem mit jeder Aufgabe (44, dann
   66, dann 72), was beim Lesen jedes Mal die Frage aufwarf, worauf sie sich
   bezieht. Benannte Masse beantworten das von selbst. Vorbild ist die
   Nachbaranwendung Mission Control (T-270), die denselben Satz fuehrt.

   DIE GROESSEN SIND GEMESSEN, NICHT GESETZT. Die Seitenleiste bietet innen
   219 px. Mission Control bringt darin ein 74-px-Signet unter, weil sein
   Name zweizeilig und kurz ist (MISSION / CONTROL). Balance hat einen langen
   Schriftzug und eine Zeile aus 24 Zeichen nebeneinander - beide waren bei
   den Groessen aus BAL-203 rund 150 px breit, und mehr als 50 px blieben dem
   Zeichen nicht. Das Signet waechst hier also NUR gegen die Schrift.

   Gemessen und der Auftraggeberin vorgelegt: Signet 50 (Schrift unveraendert,
   nur +14 %), Signet 64 ("Balance" 18, Zeile 9) oder Signet 72 ("Balance" 17,
   Zeile 8,5) - die letzte Zeile sind genau die Groessen, die Mission Control
   ebenfalls verwendet. GEWAEHLT: 72.

   DER ABSTAND STEHT SEIT BAL-205 AUF 8 PX statt der 22 des Entwurfs, so
   beauftragt. Er gilt an BEIDEN Orten: Die Kopfleiste hatte bis dahin einen
   eigenen, groesseren Wert (15 px), weil sie mit 22 px zu weit auseinander
   gelaufen waere - bei 8 px waere dieser Wert GROESSER als der der
   Seitenleiste gewesen, und die Ueberschreibung ist deshalb entfallen.
   Gemessen wird die Lockup damit 203,6 statt 217,6 px breit; die frei
   gewordenen 14 px bleiben als Luft stehen und sind NICHT in ein groesseres
   Zeichen geflossen - beauftragt war der Abstand, nicht die Signetgroesse.

   Die Zeile verliert dabei ihre Sperrung. 24 Zeichen mal 0,10 em kosten bei
   8,5 px rund 20 px Breite, und die fehlen dem Zeichen. Versalien und der
   Wortabstand halten sie auch ungesperrt lesbar.

   GEMESSEN WIRD AM TEXTBLOCK, NICHT AM SCHRIFTZUG: `letter-spacing: 0.5em`
   steht mit `margin-right: -0.5em`, und der negative Rand zaehlt in
   `getBoundingClientRect()` nicht mit (BAL-203).

   Farben: "Balance" in Petrol, so der Entwurf - auf Weiss 2,9 : 1, zulaessig,
   weil Text als Teil eines Logos von WCAG 1.4.3 ausgenommen ist. Die Zeile
   steht in `--fg-2` und nicht im #BBBBBB des Entwurfs; das ist `--q-medium`,
   eine Dekorfarbe mit 1,9 : 1.

   Alle vererbbaren Angaben stehen ausdruecklich - die globalen Grundregeln
   haben in diesem Projekt schon mehrfach in eine Komponente hineingewirkt. */
.app_shell_brand, .app_shell_topbar_brand {
  --marke-signet: 72px;        /* Kantenlaenge des Zeichens */
  --marke-abstand: 8px;        /* Zeichen zu Textblock (BAL-205, so beauftragt) */
  --marke-schrift: 22px;       /* "BALANCE" (BAL-210, vorher 17 px) */
}
/* Unten 4 statt 20 px (BAL-217): Die Kreise fuellen nur 46 % des 72-px-
   Zeichenkastens, darunter liegen in der Grafik selbst rund 19 px leer. Mit 20 px
   Innenabstand standen sichtbar rund 61 px zwischen Kreisen und "Uebersicht",
   im Entwurf (34-px-Zeichen) rund 47. Der Rand in der Grafik gehoert zum
   Zeichen und bleibt; gekuerzt ist nur der Abstand ausserhalb. */
.app_shell_brand { display: flex; align-items: center; gap: var(--marke-abstand); padding: 6px 4px 4px; white-space: nowrap; }
.app_shell_brand_mark { width: var(--marke-signet); height: var(--marke-signet); flex: 0 0 auto; object-fit: contain; display: block; }
.app_shell_brand_text { display: flex; flex-direction: column; min-width: 0; }
.app_shell_brand_name { font-family: var(--font-display); font-weight: var(--w-regular); font-size: var(--marke-schrift); line-height: 1; letter-spacing: 0.15em; margin-right: -0.15em; text-transform: uppercase; color: var(--q-highlight-3); }
/* Eingeklappt steht das Zeichen ALLEIN (BAL-202, so beauftragt). Der Grund,
   aus dem BAL-200 den Markenblock hier ganz entfernt hatte, ist damit
   entfallen: Es gab kein Zeichen mehr, und weder Wortmarke noch "Balance"
   tragen in 48 px nutzbarer Breite. Das Zeichen tut es - es ist quadratisch
   und in dieser Groesse gezeichnet. Zentriert, weil die Navigationssymbole
   darunter es ebenfalls sind.

   EIGENE SIGNETGROESSE (BAL-204): Die Leiste ist 76 px breit und bietet
   innen 48 px (76 abzueglich 2 x 14 Polsterung). Die 72 px der
   ausgeklappten Leiste passen dort nicht - ohne diese Zeile liefe das
   Zeichen ueber die Leiste hinaus. 44 px lassen ihm 2 px Luft je Seite und
   stellen es eine Stufe groesser als die Navigationssymbole darunter.
   Dieselbe Loesung wie in Mission Control (dort 44 px in 56 px). */
.app_shell_sidebar_collapsed .app_shell_brand { justify-content: center; padding-left: 0; padding-right: 0; --marke-signet: 44px; }
.app_shell_sidebar_collapsed .app_shell_brand_text { display: none; }
.app_shell_nav_section { margin-top: 12px; padding: 8px 10px 6px; font-size: 10px; letter-spacing: var(--tracking-xwide); text-transform: uppercase; color: #737373; font-weight: var(--w-bold); white-space: nowrap; }
.app_shell_sidebar_collapsed .app_shell_nav_section { height: 1px; margin: 13px 14px 9px; padding: 0; font-size: 0; background: var(--divider); }
.app_shell_nav_items { display: flex; flex-direction: column; gap: 2px; }
.app_shell_nav_item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 9px 11px; border-radius: 10px; color: var(--q-dark); font-size: 14px; font-weight: var(--w-regular); text-align: left; transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.app_shell_nav_item:hover { background: var(--surface-soft); }
.app_shell_nav_item_active { background: var(--q-highlight-2); color: #fff; }
.app_shell_nav_item_sub { padding-left: 30px; font-size: 13px; }
.app_shell_nav_item_icon { width: 20px; flex: 0 0 20px; display: grid; place-items: center; color: currentColor; opacity: 0.86; }
.app_shell_nav_item_title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app_shell_nav_item_count { margin-left: auto; min-width: 22px; padding: 2px 8px; border-radius: 999px; background: var(--surface-soft); color: var(--q-dark); font-size: 11px; font-weight: var(--w-bold); text-align: center; }
.app_shell_nav_item_active .app_shell_nav_item_count { background: rgba(255, 255, 255, 0.18); color: #fff; }
.app_shell_sidebar_collapsed .app_shell_nav_item { justify-content: center; padding: 11px 0; }
.app_shell_sidebar_collapsed .app_shell_nav_item_title, .app_shell_sidebar_collapsed .app_shell_nav_item_count { display: none; }
.app_shell_sidebar_footer { margin-top: auto; }
.app_shell_sidebar_divider { height: 1px; margin: 12px 0; background: var(--divider); }
.app_shell_user { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px; border-radius: 12px; text-align: left; }
.app_shell_user_avatar { width: 34px; height: 34px; border-radius: 50%; background: var(--q-highlight-2); color: #fff; display: grid; place-items: center; font-family: var(--font-display); font-weight: var(--w-bold); }
.app_shell_user_text small { display: block; color: #737373; font-size: 11px; }
.app_shell_sidebar_collapsed .app_shell_user_text { display: none; }
.app_shell_topbar { grid-area: topbar; display: flex; align-items: center; gap: 14px; padding: 0 24px; background: var(--surface); border-bottom: 1px solid var(--divider); }
.app_shell_breadcrumb { font-family: var(--font-display); font-weight: var(--w-bold); color: var(--q-highlight-2); font-size: 18px; white-space: nowrap; }
/* Die Marke der Kopfleiste steht nur unterhalb des Umbruchs (BAL-190); oben
   traegt sie die Seitenleiste. Siehe die Begruendung an `renderTopbarMarke()`. */
.app_shell_topbar_brand { display: none; }
.app_shell_topbar_spacer { flex: 1; }
.app_shell_main { grid-area: main; overflow: auto; padding: 26px 30px 64px; }
.app_shell_icon_button { width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; position: relative; color: var(--q-dark); transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.app_shell_icon_button:hover, .app_shell_icon_button_active { background: var(--surface-soft); }
.app_shell_dot { position: absolute; top: 7px; right: 8px; width: 9px; height: 9px; border-radius: 50%; background: var(--danger); border: 2px solid #fff; }
/* Zaehler statt Punkt am Glockensymbol (BAL-169). Der Punkt sagte nur DASS
   etwas offen ist; die Zahl sagt WIE VIEL - der Unterschied zwischen einem
   Hinweis und zwoelf entscheidet, ob man gleich hinsieht.

   Groesse, GEWICHT, Zeilenhoehe, Farbe und Grund alle ausdruecklich: Das
   Element sitzt in einer Schaltflaeche, und `button` erbt ueber
   `font: inherit` die Grundschrift des Koerpers (15px, w-light) - ohne eigene
   Angaben stuende hier eine viel zu grosse, duenne Zahl.

   Die Breite waechst mit der Stelligkeit (min-width + padding), der Kreis
   bleibt bis 9 rund. Ab 100 steht 99+ - eine dreistellige Zahl sprengt die
   Schaltflaeche, und die genaue Menge ist dann ohnehin nicht die Auskunft,
   auf die es ankommt.

   `aria-hidden`, weil die Zahl bereits im `aria-label` der Schaltflaeche
   steht - sonst hoerte man sie zweimal, einmal davon ohne Einheit. */
.app_shell_zaehler {
  position: absolute; top: 3px; right: 2px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: grid; place-items: center;
  border-radius: var(--radius-pill); border: 2px solid #fff;
  background: var(--danger); color: var(--q-white);
  font-family: var(--font-sans); font-size: 10px; font-weight: var(--w-bold);
  line-height: 1; letter-spacing: 0; font-variant-numeric: tabular-nums;
}

/* `min-width: 0` ist die ZWEITE Haelfte der Berichtigung von BAL-181 - die
   erste steht an `.app_shell`.

   Nachdem die Inhaltsspalte schmaler werden durfte, blieb ein Rest: Bei 820px
   massen alle zwoelf Bereiche weiterhin 58 bis 183px Ueberschuss. Gemessen lag
   es nicht mehr am Inhalt (`.app_shell_main` 564px bei 549px Inhalt, also
   Platz uebrig), sondern an DIESER Leiste: `.app_shell_topbar` ist eine
   flex-Reihe mit `nowrap`, und ihr Inhalt verlangte 659px in 564px. Die drei
   Symbolschalter am rechten Ende standen bei x=825, 870 und 915 - ausserhalb
   eines 820px breiten Fensters.

   Die Ursache ist dieselbe wie beim Raster, nur in flex: Ein flex-Element hat
   `min-width: auto` und schrumpft daher nicht unter seine Min-Content-Breite.
   Fuer dieses Feld ist das die Eigenbreite des `<input>` - ein Eingabefeld
   bringt eine Vorgabebreite von rund 20 Zeichen mit, und `min-width: 0` am
   Feld selbst (Zeile darunter) hilft nicht, weil die Huelle die Min-Content-
   Breite ihrer Kinder als eigenes Mindestmass nimmt. Deshalb schrumpfte das
   Feld nur bis 262px und keinen Pixel weiter.

   GEMESSEN vor und nach dieser einen Zeile bei 820px: Ueberschuss 95px -> 0,
   Suchfeld 262px -> 143px. `width: 360px` bleibt als Wunschbreite stehen und
   gilt unveraendert, sobald das Fenster sie hergibt.

   Geprueft wurde auch die naheliegende Alternative `flex: 0 1 360px`: Sie
   aendert nichts, weil `flex-shrink` bereits 1 ist. Das Mindestmass war das
   Hindernis, nicht der Schrumpffaktor. */
.global_search { position: relative; display: flex; align-items: center; gap: 8px; width: 360px; min-width: 0; padding: 7px 14px; border: 1px solid transparent; border-radius: 999px; background: var(--surface-soft); transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std); }
.global_search:focus-within { border-color: var(--q-highlight-3); background: #fff; }
.global_search_icon { width: 16px; height: 16px; color: var(--q-medium); display: grid; place-items: center; }
.global_search_input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font-size: 13.5px; font-weight: var(--w-regular); }
.global_search_hint kbd { padding: 3px 5px; border: 1px solid var(--q-bright); border-radius: 5px; background: #fff; color: #777; font-size: 10px; }
.global_search_panel { position: absolute; top: calc(100% + 10px); left: 0; z-index: 80; width: min(520px, calc(100vw - 48px)); max-height: min(620px, calc(100vh - 96px)); overflow: hidden; padding: 6px; border: 1px solid #ececec; border-radius: 18px; background: #fff; box-shadow: var(--shadow-elevated); }
.global_search_scroll { max-height: min(536px, calc(100vh - 156px)); overflow: auto; }
.global_search_group_title { padding: 10px 12px 6px; font-size: 11px; letter-spacing: var(--tracking-xwide); text-transform: uppercase; color: #888; font-weight: var(--w-bold); }
.global_search_count { display: inline-flex; margin-left: 6px; padding: 1px 8px; border-radius: 999px; background: var(--surface-soft); color: var(--q-medium); letter-spacing: 0; }
.global_search_item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 12px; border-radius: 11px; text-align: left; }
.global_search_item:hover, .global_search_item_active { background: var(--surface-soft); }
.global_search_item_active { outline: 1px solid rgba(21,165,181,0.24); }
.global_search_item_icon { width: 24px; color: var(--q-medium); display: grid; place-items: center; }
.global_search_item_title { display: block; color: var(--q-highlight-2); font-weight: var(--w-bold); }
.global_search_item_description { display: block; color: #777; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.global_search_item_go { margin-left: auto; color: var(--q-medium); opacity: 0.45; }
.global_search_item:hover .global_search_item_go, .global_search_item_active .global_search_item_go { opacity: 1; }
.global_search_footer { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 6px -6px -6px; padding: 10px 12px; border-top: 1px solid var(--divider); background: var(--surface-soft); color: var(--q-medium); font-size: 11.5px; }
.global_search_footer span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.global_search_footer kbd { min-width: 20px; padding: 2px 5px; border: 1px solid var(--q-bright); border-radius: 5px; background: #fff; color: var(--q-dark); font-size: 10px; text-align: center; }

.button { display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 9px 18px; border: 1px solid transparent; border-radius: 999px; font-weight: var(--w-bold); font-size: 13.5px; white-space: nowrap; transition: background var(--dur-fast), border-color var(--dur-fast), transform var(--dur-fast); }
.button:active { transform: scale(0.98); }
.button_primary { background: var(--q-highlight-2); color: #fff; }
.button_primary:hover { background: #0a253c; }
.button_accent { background: var(--q-highlight-1); color: var(--q-highlight-2); }
.button_ghost { background: #fff; border-color: var(--q-medium); color: var(--q-dark); }
.button_ghost:hover { border-color: var(--q-highlight-2); }
.button_quiet { padding: 7px 12px; background: transparent; color: var(--q-dark); }
.button_quiet:hover { background: var(--surface-soft); }
.button_small { padding: 6px 12px; font-size: 12.5px; }
.button_danger { border-color: transparent; color: var(--danger); }
.button_danger:hover { border-color: rgba(192,72,72,0.28); background: #f8e0e0; }
.button_danger_fill { background: var(--danger); color: #fff; }
.button_danger_fill:hover { background: #a93636; }
.button_danger .ui_icon, .button_danger_fill .ui_icon { color: currentColor; }
.action-icons { display: inline-flex; align-items: center; justify-content: flex-end; gap: 4px; }
.icon-action { width: 30px; height: 30px; display: inline-grid; place-items: center; border-radius: 8px; color: var(--q-medium); transition: background var(--dur-fast), color var(--dur-fast); }
.icon-action:hover, .icon-action:focus-visible { background: var(--surface-soft); color: var(--q-highlight-2); }
.icon-action-danger:hover, .icon-action-danger:focus-visible { background: #f8e0e0; color: var(--danger); }

.page_header { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 24px; }
/* `min-width: 0` am Titelblock (BAL-182). Nachdem BAL-181 der Inhaltsspalte
   erlaubt hat zu schrumpfen, wurde diese Reihe zwischen 781 und rund 1150px
   eng - genau in dem Band, das es vorher gar nicht gab, weil sich dort die
   ganze Seite verbreiterte. GEMESSEN bei 820px nach BAL-181: Der Kopf der
   Benachrichtigungen schob seine Bedienelemente 161px ueber den
   Inhaltsbereich hinaus, die Freigaben 87px, die Beauftragungen 90px. Der
   Titelblock hielt seine Min-Content-Breite und liess den Bedienelementen
   nichts uebrig.

   HIER STAND ZUERST `flex-wrap: wrap`, UND DAS WAR FALSCH. Flex bricht um,
   BEVOR es schrumpft: Die Entscheidung faellt anhand der Wunschbreiten, und
   die Wunschbreite des Titelblocks ist seine Max-Content-Breite - eine
   mehrzeilige Beschreibung. Gemessen bei 1440px mit `wrap`: Die
   Bedienelemente sassen nicht mehr rechtsbuendig bei x=1395, sondern
   linksbuendig bei x=662 unter dem Titel, und der Kopf wuchs von 205 auf
   269px. Das haette den Referenzentwurf auf jedem Schreibtisch veraendert,
   um ein Problem zu loesen, das es nur auf schmalen Geraeten gibt.

   `min-width: 0` allein genuegt: Der Titelblock schrumpft, die Bedienelemente
   bleiben rechts, und unterhalb 780px steht der Kopf ohnehin auf Spalte.
   Gemessen nach der Berichtigung bei 1440px: Bedienelemente wieder bei
   x=1395, Kopfhoehe wieder 205px. */
.page_header > *:first-child { min-width: 0; }
.page_header_pretext { margin-bottom: 7px; font-size: 11px; letter-spacing: var(--tracking-xwide); text-transform: uppercase; color: var(--q-highlight-2); font-weight: var(--w-bold); }
.page_header_title { margin: 0; font-family: var(--font-display); font-size: 30px; line-height: 1.15; color: var(--q-dark); }
.page_header_description { max-width: 70ch; margin-top: 8px; color: #777; font-size: 13.5px; }
/* Zweigeteilter Kopf (BAL-114, nach einem Vorbild der Auftraggeberin): oben
   der Erklaerabsatz, darunter die Handlungen mit eigener Beschriftung.
   Praefixfamilie page_header_* fortgesetzt - die Klassen stellen sich damit
   nicht neben den Kopf, sondern hinein (POL-001: lange Reihe, wie die
   Geschwister pretext, title, description, controls).

   Die Aufzaehlung ist eine echte <ul>: Fuer Hilfsmittel eine Liste mit
   Eintraegen, fuer das Auge durch die Trennzeichen unten eine Zeile wie im
   Vorbild. Der Mittelpunkt kommt aus ::before und traegt aria-hidden von
   selbst - er ist erzeugter Inhalt und wird nicht vorgelesen. Eine
   aneinandergereihte Zeichenkette waere vorgelesen ein Satzbrei gewesen. */
.page_header_actions { margin-top: 14px; max-width: 78ch; }
.page_header_actions_label { margin-bottom: 5px; color: var(--q-highlight-2); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
/* list-style und padding ausdruecklich: Die globale ul-Regel setzt beides,
   und ein Textbaustein setzt alles selbst, was er braucht. */
.page_header_actions_list { margin: 0; padding: 0; list-style: none; color: #777; font-size: 13.5px; font-weight: var(--w-light); line-height: 1.6; }
/* KEIN Flex-Behaelter: display:flex blockiert seine Kinder, der inline-Wunsch
   am li verpufft (gemessen: display kam als "block" heraus). Dann bricht die
   Zeile nur zwischen den Eintraegen und laesst Luecken. Als normaler
   Textfluss fuellen die Handlungen die Zeile wie im Vorbild. */
.page_header_actions_list li { display: inline; }
.page_header_actions_list li + li::before { content: " · "; padding: 0 6px; color: #b4b4b4; }
/* Die Kennzahl schliesst den Erklaerabsatz ab und hebt sich vom Fliesstext
   ab, ohne eine eigene Zeile zu brauchen. */
/* Die Kennzahl des Bereichs - seit BAL-201 ein EIGENER Block unter dem
   Erklaerabsatz statt einer fett gesetzten Spanne an dessen Ende
   (Beanstandung der Auftraggeberin: "steht hinten dran ... sollte irgendwie
   ein eigener Absatz zumindest sein").

   Als Pille und nicht nur als eigene Zeile: Fett allein hat schon vorher
   nicht gereicht, um die Zahl aus dem Text zu heben - sie stand in
   derselben Groesse, derselben Farbe und derselben Zeile. Die Pille ist im
   Haus kein neues Mittel; `ltb-badge`, `status_badge` und `pk-now` setzen
   Zahlen und Zustaende auf dieselbe Weise ab.

   `inline-flex` an einem `p`: Das Element schrumpft damit auf seinen Inhalt
   (eine Pille ueber die halbe Seitenbreite waere keine), beginnt aber
   trotzdem eine eigene Zeile - sein Vorgaenger `page_header_description`
   ist ein Block.

   Alle vererbbaren Angaben stehen ausdruecklich, auch Rand und Zeilenhoehe:
   Es ist ein `p`, und die globalen Grundregeln haben in diesem Projekt
   inzwischen viermal in eine Komponente hineingewirkt. */
.page_header_count { display: inline-flex; align-items: center; margin: 12px 0 0; padding: 5px 12px; border: 1px solid var(--divider); border-radius: var(--radius-pill); background: var(--surface); color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); line-height: 1.35; }

.page_header_controls { display: flex; align-items: center; gap: 10px; }

.mission_control { display: flex; flex-direction: column; gap: 22px; }
.mission_control_header, .module_list_header, .detail_panel_header, .ai_drawer_header, .notification_center_header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
/* `minmax(0, ...)` an beiden Spalten - dieselbe Ursache wie an `.app_shell`
   und `.list-cards` (BAL-181, Befund R-06). GEMESSEN bei 360px, als nur die
   Regel im 1100er-Umbruch auf eine Spalte stellte: `.mission_control_column`
   war 345px breit in einem 317px breiten Behaelter, also genau um die
   Polsterung des Inhaltsbereichs zu breit, und `.app_shell_main` musste
   quer scrollen. Gefunden beim Nachmessen von BAL-182. */
.mission_control_body { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 18px; align-items: start; }
.mission_control_column { display: flex; flex-direction: column; gap: 18px; }
.summary_tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.summary_tiles_item { display: flex; flex-direction: column; gap: 4px; min-height: 128px; padding: 18px 20px; border: 1px solid #ececec; border-radius: 16px; background: #fff; text-align: left; overflow: hidden; position: relative; transition: transform var(--dur-fast), box-shadow var(--dur-fast), border-color var(--dur-fast); }
.summary_tiles_item:hover { transform: translateY(-1px); border-color: var(--q-highlight-3); box-shadow: var(--shadow-soft); }
.summary_tiles_item_header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.summary_tiles_item_label { color: #777; font-size: 11.5px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); }
.summary_tiles_item_value { font-family: var(--font-display); font-weight: var(--w-bold); color: var(--q-highlight-2); font-size: 30px; line-height: 1.05; }
.summary_tiles_item_description { color: var(--q-dark); font-size: 12px; }
.summary_tiles_item_icon { width: 36px; height: 36px; border-radius: 10px; background: var(--surface-soft); color: var(--q-highlight-2); display: grid; place-items: center; transition: background var(--dur-fast), color var(--dur-fast); }
.summary_tiles_item:hover .summary_tiles_item_icon { background: var(--q-highlight-3); color: #fff; }
.summary_tiles_item_warning .summary_tiles_item_value { color: var(--warning); }
.summary_tiles_item_danger .summary_tiles_item_value { color: var(--danger); }
.summary_tiles_item_success .summary_tiles_item_value { color: var(--success); }

/* Die weisse Karte der Einstellungsbereiche. .admin-block teilt sich die
   Deklaration mit .content_card, statt eine vierte fast gleiche zu bekommen
   (BAL-143): Das Muster stand schon dreimal im Stylesheet - .content_card,
   .module_list_body, .exp-card -, und eine weitere Kopie waere die, die beim
   naechsten Anfassen zurueckbleibt.

   VORHER hatte .admin-block ueberhaupt keine Regel. Gemessen ueber alle 14
   Einstellungsbereiche: Im KI-Assistenten lagen 25 von 25 Erklaerungstexten
   auf dem grauen Seitengrund, in den Schnittstellen 12 von 12 - in jedem
   anderen Bereich mit Fliesstext lagen sie auf Weiss. */
.content_card,
.admin-block { padding: 22px 24px; border: 1px solid #ececec; border-radius: 18px; background: #fff; box-shadow: 0 0 10px rgba(0,0,0,0.06); }
.content_card_header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.content_card_title { margin: 0; color: var(--q-dark); font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: var(--w-bold); }
.content_card_control { color: #777; font-size: 12.5px; }
.progress_indicator { display: flex; flex-direction: column; gap: 6px; border-radius: 12px; transition: background var(--dur-fast); }
.progress_indicator:hover { background: #fafbfa; }
.progress_indicator_text { display: flex; align-items: center; justify-content: space-between; font-size: 12px; }
.progress_indicator_progress_bar { height: 9px; overflow: hidden; border-radius: 999px; background: var(--surface-soft); }
.progress_indicator_progress_bar_value { height: 100%; border-radius: inherit; background: var(--q-highlight-3); }
.progress_indicator_success { background: var(--success); }
.progress_indicator_warning { background: var(--warning); }
.progress_indicator_danger { background: var(--danger); }
.util { height: 8px; overflow: hidden; border-radius: 999px; background: var(--surface-soft); position: relative; }
.util-bar { height: 100%; border-radius: inherit; background: var(--q-highlight-3); transition: width var(--dur-base) var(--ease-std); }
.util-bar.ok { background: var(--success); }
.util-bar.mid { background: var(--warning); }
.util-bar.high { background: #e08a2b; }
.util-bar.over { background: var(--danger); }
.util-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; font-size: 12px; }
.util-row .pct { font-family: var(--font-display); font-weight: var(--w-bold); }
.pct.ok { color: var(--success); }
.pct.mid { color: var(--warning); }
.pct.high { color: #e08a2b; }
.pct.over { color: var(--danger); }

.gauge_cards { display: grid; grid-template-columns: 1fr; gap: 12px; }
.gauge_card { width: 100%; padding: 16px; border: 1px solid #ececec; border-radius: 16px; background: #fff; text-align: left; transition: transform var(--dur-fast), box-shadow var(--dur-fast), border-color var(--dur-fast); }
.gauge_card:hover { transform: translateY(-1px); border-color: var(--q-highlight-3); box-shadow: var(--shadow-soft); }
.gauge_card:focus-visible { border-color: var(--q-highlight-3); box-shadow: var(--shadow-soft); }
.gauge_card_header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.gauge_card_title { font-family: var(--font-display); font-weight: var(--w-bold); font-size: 15px; color: var(--q-highlight-2); line-height: 1.2; }
.gauge_card_description { margin-top: 3px; color: var(--q-medium); font-size: 12px; }
.gauge_card_body { display: flex; align-items: center; gap: 18px; }
.gauge_ring { position: relative; width: 92px; height: 92px; flex: 0 0 92px; color: var(--q-highlight-3); }
.gauge_ring_progress { stroke: currentColor; transition: stroke-dashoffset var(--dur-base) var(--ease-std); }
.gauge_card_success .gauge_ring { color: var(--success); }
.gauge_card_warning .gauge_ring { color: var(--warning); }
.gauge_card_danger .gauge_ring { color: var(--danger); }
.gauge_ring_value { position: absolute; inset: 0; display: grid; place-items: center; font-family: var(--font-display); font-weight: var(--w-bold); font-size: 18px; color: var(--q-dark); }
.gauge_stats { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.gauge_stat { display: flex; justify-content: space-between; gap: 10px; color: var(--q-medium); font-size: 12.5px; }
.gauge_stat strong { color: var(--q-dark); font-family: var(--font-display); font-weight: var(--w-bold); white-space: nowrap; }
.dash-contingents { display: grid; grid-template-columns: 1fr; gap: 16px; }
.dash-contingent-tile { display: flex; align-items: center; gap: 14px; width: 100%; padding: 4px 2px; border-radius: 12px; cursor: pointer; text-align: left; transition: background var(--dur-fast), transform var(--dur-fast); }
.dash-contingent-tile:hover, .dash-contingent-tile:focus-visible { background: var(--surface-soft); transform: translateY(-1px); }
.dash-contingent-ring { position: relative; width: 58px; height: 58px; flex: 0 0 58px; color: var(--q-highlight-3); }
.dash-contingent-tile-success .dash-contingent-ring { color: var(--success); }
.dash-contingent-tile-warning .dash-contingent-ring { color: var(--warning); }
.dash-contingent-tile-danger .dash-contingent-ring { color: var(--danger); }
.dash-contingent-ring .gauge_ring_progress { stroke: currentColor; }
.dash-contingent-ring > span { position: absolute; inset: 0; display: grid; place-items: center; color: var(--q-dark); font-family: var(--font-display); font-size: 12.5px; font-weight: var(--w-bold); }
.dash-contingent-copy { flex: 1; min-width: 0; }
.dash-contingent-title { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--q-highlight-2); font-size: 13px; font-weight: var(--w-bold); }
.dash-contingent-meta { display: block; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--q-medium); font-size: 11.5px; }
.gauge-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.gauge-card { display: flex; flex-direction: column; gap: 14px; width: 100%; padding: 20px; border: 1px solid #ececec; border-radius: 16px; background: #fff; cursor: pointer; text-align: left; transition: transform var(--dur-fast) var(--ease-std), box-shadow var(--dur-fast) var(--ease-std), border-color var(--dur-fast) var(--ease-std); }
.gauge-card:hover, .gauge-card:focus-visible { transform: translateY(-1px); border-color: var(--q-highlight-3); box-shadow: 0 6px 18px rgba(0,0,0,0.07); }
.gauge-card-success .gauge-ring { color: var(--success); }
.gauge-card-warning .gauge-ring { color: var(--warning); }
.gauge-card-danger .gauge-ring { color: var(--danger); }
.gauge-card .g-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.gauge-card .g-title { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 16px; font-weight: var(--w-bold); line-height: 1.2; }
.gauge-card .g-sub { margin-top: 3px; color: var(--q-medium); font-size: 12px; }
.gauge-ring-row { display: flex; align-items: center; gap: 18px; }
.gauge-ring { position: relative; width: 92px; height: 92px; flex-shrink: 0; color: var(--q-highlight-3); }
.gauge-ring .gauge_ring_progress { stroke: currentColor; }
.gauge-ring .g-pct { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--q-dark); font-family: var(--font-display); font-size: 19px; font-weight: var(--w-bold); line-height: 1; white-space: nowrap; }
.gauge-stats { flex: 1; display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.gauge-stat { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; color: var(--q-dark); font-size: 12.5px; }
.gauge-stat .gs-label { color: var(--q-medium); }
.gauge-stat .gs-val { color: var(--q-dark); font-family: var(--font-display); font-weight: var(--w-bold); white-space: nowrap; }
.gauge-card .g-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding-top: 12px; border-top: 1px dashed var(--divider); color: var(--q-medium); font-size: 11.5px; }
.gauge-card .row-acts { opacity: 0.55; transition: opacity var(--dur-fast) var(--ease-std); }
.gauge-card:hover .row-acts, .gauge-card:focus-visible .row-acts { opacity: 1; }

.module_list { display: flex; flex-direction: column; gap: 16px; }
.module_list_toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 16px; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; position: relative; }
.module_list > .module_list_toolbar { margin-bottom: 0; }
.module_list_toolbar_spacer { flex: 1; }
.module_list_search, .module_list_select { min-height: 38px; padding: 8px 12px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; color: var(--q-dark); font-size: 13px; }
.module_list_search:focus, .module_list_select:focus { border-color: var(--q-highlight-3); }
/* Gemeinsame Hoehe aller Bedienelemente der Listenleiste (BAL-163).
   Vorher bildete jede Klasse ihre Hoehe selbst: Suchfeld 42 px,
   Schaltflaechen 37 px, Ansichtsumschalter 36 px - drei Werte
   nebeneinander in derselben Zeile. Wer hier ein viertes Bedienelement
   ergaenzt, nimmt dieses Mass und muss nicht drei Regeln nachschlagen. */
.module_list_toolbar, .list-toolbar { --ltb-hoehe: 38px; }
.ltb-search { display: flex; align-items: center; gap: 9px; flex: 1; min-width: 240px; min-height: var(--ltb-hoehe, 38px); padding: 0 15px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; transition: border-color var(--dur-fast); }
.ltb-search:focus-within { border-color: var(--q-highlight-3); }
.ltb-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--q-dark); font-size: 13.5px; }
.ltb-search .ui_icon { color: var(--q-medium); opacity: 0.6; }
.ltb-clear { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; color: var(--q-medium); }
.ltb-clear:hover { background: var(--surface-soft); }
.ltb-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ltb-btn { position: relative; display: inline-flex; align-items: center; gap: 7px; min-height: var(--ltb-hoehe, 38px); padding: 8px 13px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); overflow: hidden; transition: border-color var(--dur-fast), background var(--dur-fast); }
.ltb-btn .ui_icon { opacity: 0.7; }
.ltb-btn:hover { border-color: var(--q-medium); }
/* Zwei Aussagen, zwei Darstellungen (BAL-147).

   Bis hierher trug .active beides: bei Filter und Planungsklammer "ein Wert
   ist gesetzt", bei Sortierung und Export "das Pop-over ist offen". Gemessen
   am 2026-09-06 bei geoeffnetem Pop-over: Filter Rand rgb(231,231,231) auf
   weiss - also wie zugeklappt -, Sortierung Rand rgb(16,49,78) auf
   rgb(241,242,242). Derselbe Knopf, dieselbe Handlung, zwei Bilder.

   OFFEN haengt jetzt am ARIA-Attribut und nicht an einer zweiten Klasse: So
   koennen Darstellung und Ansage nicht auseinanderlaufen - was der
   Screenreader meldet, ist genau das, was hier eingefaerbt wird.

   WERT GESETZT behaelt den Markenrand, verliert aber die Flaeche - sonst
   waeren die beiden Zustaende wieder dasselbe Bild. Der Filter traegt
   zusaetzlich sein Zaehlabzeichen, die Farbe ist also nicht die einzige
   Kodierung. */
.ltb-btn.active { border-color: var(--q-highlight-2); }
.ltb-btn[aria-expanded="true"] { border-color: var(--q-medium); background: var(--surface-soft); }
/* Beides zugleich - ein offener Filter mit gesetzten Werten: Der Markenrand
   gewinnt, die Flaeche zeigt weiterhin das Aufgeklappte. */
.ltb-btn.active[aria-expanded="true"] { border-color: var(--q-highlight-2); }
.ltb-badge { min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: var(--q-highlight-2); color: #fff; font-size: 10.5px; font-weight: var(--w-bold); display: inline-flex; align-items: center; justify-content: center; }
.ltb-reset { color: var(--q-dark); border-color: var(--q-medium); }
.ltb-reset:hover { border-color: var(--q-highlight-2); background: var(--surface-soft); color: var(--q-highlight-2); }
.ltb-pop-wrap { position: relative; }
.ltb-pop { position: absolute; top: calc(100% + 8px); right: 0; z-index: 30; min-width: 280px; max-height: min(640px, calc(100vh - 180px)); overflow: auto; padding: 16px; border: 1px solid var(--divider); border-radius: 14px; background: #fff; box-shadow: 0 14px 36px rgba(0,0,0,0.16); animation: ui-pop-in var(--dur-fast) var(--ease-std); transform-origin: top right; }
.ltb-pop-sort { min-width: 260px; }
.ltb-pop-export { min-width: 240px; }
.ltb-facet + .ltb-facet { margin-top: 14px; }
.ltb-facet-label { margin-bottom: 8px; color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.ltb-facet-opts { display: flex; flex-wrap: wrap; gap: 6px; }
.ltb-date-range { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ltb-date-range label { display: flex; flex-direction: column; gap: 5px; color: var(--q-medium); font-size: 11px; font-weight: var(--w-bold); }
.ltb-date-range .finput { min-height: 36px; padding: 7px 9px; font-size: 12.5px; }
.ltb-range-input { position: relative; display: flex; align-items: center; }
.ltb-range-input .finput { padding-right: 28px; }
.ltb-range-suffix { position: absolute; right: 9px; color: var(--q-medium); font-size: 12px; pointer-events: none; }
.ltb-number-range { display: flex; flex-direction: column; gap: 10px; }
.ltb-slider, .q-slider { --range-low: 0; --range-high: 100; --range-min: 0; --range-max: 100; position: relative; height: 30px; }
.ltb-slider::before, .ltb-slider::after, .q-slider::before, .q-slider::after { content: ''; position: absolute; left: 0; right: 0; top: 14px; height: 4px; border-radius: 999px; }
.ltb-slider::before, .q-slider::before { background: var(--divider); }
.ltb-slider::after, .q-slider::after { left: calc((var(--range-min) - var(--range-low)) / (var(--range-high) - var(--range-low)) * 100%); right: calc(100% - (var(--range-max) - var(--range-low)) / (var(--range-high) - var(--range-low)) * 100%); background: var(--q-highlight-3); }
.ltb-slider input[type="range"], .q-slider input[type="range"] { position: absolute; inset: 0; z-index: 1; width: 100%; height: 30px; margin: 0; background: transparent; pointer-events: none; appearance: none; -webkit-appearance: none; }
.ltb-slider input[type="range"]::-webkit-slider-runnable-track, .q-slider input[type="range"]::-webkit-slider-runnable-track { height: 4px; background: transparent; }
.ltb-slider input[type="range"]::-moz-range-track, .q-slider input[type="range"]::-moz-range-track { height: 4px; background: transparent; }
.ltb-slider input[type="range"]::-webkit-slider-thumb, .q-slider input[type="range"]::-webkit-slider-thumb { width: 16px; height: 16px; margin-top: -6px; border: 2px solid #fff; border-radius: 50%; background: var(--q-highlight-2); box-shadow: 0 1px 5px rgba(0,0,0,0.24); pointer-events: auto; appearance: none; -webkit-appearance: none; cursor: pointer; }
.ltb-slider input[type="range"]::-moz-range-thumb, .q-slider input[type="range"]::-moz-range-thumb { width: 16px; height: 16px; border: 2px solid #fff; border-radius: 50%; background: var(--q-highlight-2); box-shadow: 0 1px 5px rgba(0,0,0,0.24); pointer-events: auto; cursor: pointer; }
.ltb-chip { display: inline-flex; align-items: center; gap: 5px; padding: 5px 11px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; color: var(--q-dark); font-size: 12.5px; transition: border-color var(--dur-fast), background var(--dur-fast), color var(--dur-fast); }
.ltb-chip:hover { border-color: var(--q-medium); }
.ltb-chip.on { border-color: var(--q-highlight-2); background: var(--q-highlight-2); color: #fff; font-weight: var(--w-bold); }
.ltb-pop-reset { width: 100%; margin-top: 14px; padding: 8px; border-radius: 9px; color: var(--q-highlight-3); font-size: 12.5px; font-weight: var(--w-bold); text-align: center; }
.ltb-pop-reset:hover { background: var(--surface-soft); }
.ltb-sort-list { display: flex; flex-direction: column; gap: 2px; }
.ltb-sort-opt { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; padding: 8px 10px; border-radius: 9px; color: var(--q-dark); font-size: 13px; text-align: left; transition: background var(--dur-fast), color var(--dur-fast); }
.ltb-sort-opt:hover { background: var(--surface-soft); }
.ltb-sort-opt.on { background: var(--surface-active); color: var(--q-highlight-2); font-weight: var(--w-bold); }
.ltb-export-opt { display: flex; align-items: center; gap: 9px; width: 100%; padding: 10px 11px; border-radius: 9px; color: var(--q-dark); font-size: 13px; text-align: left; transition: background var(--dur-fast), color var(--dur-fast); }
.ltb-export-opt:hover { background: var(--surface-soft); color: var(--q-highlight-2); }
/* Hinweis unter den Exportformaten (BAL-213): sagt, WAS ausgegeben wird. Ohne ihn
   ist nicht zu erkennen, ob der Export die Liste oder den Bestand meint. */
.ltb-export-hint { max-width: 240px; margin: 6px 11px 2px; color: var(--fg-2); font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.45; }
/* Segmented Control (Quantiz Design System, Stand 2026-09-02).
   Pill-Track mit 3px Innenabstand, keine Trennlinien, aktives Segment als
   vollstaendig gerundete Navy-Pille. Vorher: rechteckiger Rahmen mit
   `overflow:hidden` und `border-left` zwischen den Segmenten. */
.fseg { display: inline-flex; gap: 3px; padding: 3px; margin-top: 4px; border: 1px solid var(--q-bright); border-radius: 999px; background: #fff; width: 100%; }
.fseg-btn { flex: 1; padding: 9px 14px; border-radius: 999px; font-size: 14px; font-weight: var(--w-bold); color: var(--q-dark); background: transparent; text-align: center; cursor: pointer; transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.fseg-btn input { position: absolute; opacity: 0; pointer-events: none; }
.fseg-btn:hover { background: var(--surface-soft); }
.fseg-btn.on, .fseg-btn.on:hover { background: var(--q-highlight-2); color: #fff; }
/* Wert zwischen zwei festen Grenzen (BAL-162).

   Der Regler ist zum Zielen da, das Feld zum Treffen: Wer 0,8 statt 0,7
   braucht, soll es eintippen koennen und nicht zielen muessen. Deshalb
   BEIDES nebeneinander und nicht der Regler allein.

   Die Fuellung entsteht aus denselben Regeln wie beim Zweigriff-Regler der
   Listenfilter - dort spannt sie zwischen zwei Griffen, hier vom unteren
   Ende bis zum Wert. Dafuer genuegt es, --range-min auf die Untergrenze zu
   setzen; eine eigene Regel braucht es nicht. */
.q-regler { display: flex; align-items: center; gap: 14px; width: 100%; }
.q-regler .q-slider { flex: 1; min-width: 90px; }
/* Die Zahl bleibt schmal und rechtsbuendig: Sie ist die Ablesestelle, nicht
   das Hauptbedienelement - und untereinander stehende Zahlen fluchten. */
.q-regler input[type="number"] { flex: 0 0 84px; width: 84px; text-align: right; }
.q-regler input[type="range"]:focus-visible { outline: 2px solid var(--q-highlight-3); outline-offset: 2px; border-radius: 999px; }
/* Im Aufklappmenue des Assistenten ist weniger Platz: Dort steht die Zahl
   enger und der Regler niedriger. */
.ai-pop-row .q-regler { gap: 10px; }
.ai-pop-row .q-regler input[type="number"] { flex: 0 0 68px; width: 68px; }
.ai-pop-row .q-slider { height: 26px; }
.ai-pop-row .q-slider::before, .ai-pop-row .q-slider::after { top: 12px; }
.ai-pop-row .q-slider input[type="range"] { height: 26px; }

.ltb-views { display: inline-flex; align-items: center; gap: 2px; min-height: var(--ltb-hoehe, 38px); padding: 2px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; }
.ltb-view-btn { width: 34px; height: 100%; min-height: 30px; border-radius: 999px; color: var(--q-medium); display: grid; place-items: center; transition: background var(--dur-fast), color var(--dur-fast); }
.ltb-view-btn:hover { background: var(--surface-soft); }
.ltb-view-btn.on { background: var(--q-highlight-2); color: #fff; }
.summary_tiles_compact { grid-template-columns: repeat(3, 1fr); }
.budget_tree_card { padding: 0; overflow: auto; }
.tree { display: flex; flex-direction: column; }
.tree-head { display: grid; grid-template-columns: minmax(280px, 1fr) 130px 130px 120px 96px 106px; gap: 14px; min-width: 900px; padding: 11px 16px; border-bottom: 1px solid var(--divider); color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.tree-head .r { text-align: right; }
.tree-node { display: grid; grid-template-columns: minmax(280px, 1fr) 130px 130px 120px 96px 106px; align-items: center; gap: 14px; min-width: 900px; width: 100%; padding: 13px 16px; border-bottom: 1px solid #f1f2f2; cursor: pointer; text-align: left; transition: background var(--dur-fast) var(--ease-std); }
.tree-node:hover { background: #fafbfa; }
.tree-node.lvl-1 { background: #fcfcfb; }
.tree-node .t-title { display: flex; align-items: center; gap: 10px; min-width: 0; }
.tree-node .t-title > div { min-width: 0; }
.tree-node .t-caret { width: 16px; height: 16px; display: grid; place-items: center; flex-shrink: 0; color: var(--q-medium); cursor: pointer; border-radius: 4px; transition: transform var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.tree-node .t-caret:hover, .tree-node .t-caret:focus-visible { background: var(--surface-soft); color: var(--q-highlight-3); }
.tree-node .t-caret.open { transform: rotate(90deg); }
.tree-node .t-caret.leaf { visibility: hidden; cursor: default; }
.tree-node .t-name { color: var(--q-highlight-2); font-size: 14px; font-weight: var(--w-bold); line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tree-node.lvl-1 .t-name, .tree-node.lvl-2 .t-name { color: var(--q-dark); font-weight: var(--w-regular); }
.tree-node .t-meta { margin-top: 2px; color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-regular); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tree-indent { display: inline-block; flex-shrink: 0; }
.tree-node .t-amt { text-align: right; font-size: 13px; }
.tree-node .t-amt .big { color: var(--q-dark); font-family: var(--font-display); font-weight: var(--w-bold); }
.tree-node .t-amt .big.danger { color: var(--danger); }
.tree-node .t-amt small { display: block; color: var(--q-medium); font-size: 11px; }
.tree-node .r { text-align: right; }
.tree-node .row-acts { opacity: 0.55; transition: opacity var(--dur-fast) var(--ease-std); }
.tree-node:hover .row-acts, .tree-node:focus-within .row-acts { opacity: 1; }
.module_list_body { overflow: auto; border: 1px solid #ececec; border-radius: 18px; background: #fff; box-shadow: 0 0 10px rgba(0,0,0,0.04); }
.module_list_table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
.module_list_table th { position: sticky; top: 0; z-index: 1; padding: 12px 14px; border-bottom: 1px solid var(--divider); background: #fff; color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-align: left; text-transform: uppercase; }
.module_list_table th:last-child, .module_list_table td:last-child { text-align: right; }
.module_list_table td { padding: 13px 14px; border-bottom: 1px solid #f1f2f2; color: var(--q-dark); vertical-align: middle; }
.module_list_table tr { cursor: pointer; }
.module_list_table tbody tr:hover { background: #fafbfa; }
.module_list_table tbody tr:last-child td { border-bottom: 0; }
.module_list_table .row-acts { opacity: 0.55; transition: opacity var(--dur-fast) var(--ease-std); }
.module_list_table tr:hover .row-acts, .module_list_table tr:focus-within .row-acts { opacity: 1; }
.module_list_item_title { display: block; color: var(--q-highlight-2); font-weight: var(--w-bold); font-size: 13.5px; }
.module_list_item_description { display: block; color: #777; font-size: 11.5px; }
.status_badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 11px 3px 9px; border-radius: 999px; font-size: 11.5px; font-weight: var(--w-bold); white-space: nowrap; }
.status_badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.status_badge_success { background: #eef5dc; color: #5a8516; }
.status_badge_warning { background: #fbf1d8; color: #9b6f16; }
.status_badge_danger { background: #f8e0e0; color: #b83232; }
.status_badge_info { background: #def0f2; color: #0e7e8b; }
.status_badge_neutral { background: #ececec; color: #666; }

.row { display: flex; align-items: center; gap: 10px; }
.row.between { justify-content: space-between; align-items: flex-start; }
.sec-sub { color: var(--q-medium); font-size: 12.5px; font-weight: var(--w-regular); }
.admin_page { display: flex; flex-direction: column; gap: 18px; }
.admin-layout { display: grid; grid-template-columns: 224px minmax(0, 1fr); gap: 22px; align-items: start; }
.admin-nav { display: flex; flex-direction: column; gap: 2px; position: sticky; top: 0; }
.admin-nav-item { display: flex; align-items: center; gap: 11px; width: 100%; padding: 10px 13px; border-radius: 10px; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-regular); text-align: left; transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.admin-nav-item:hover { background: var(--surface-soft); }
.admin-nav-item.active { background: var(--q-highlight-2); color: #fff; font-weight: var(--w-bold); }
.admin-tabs { display: flex; flex-wrap: nowrap; gap: 2px; border-bottom: 1px solid var(--divider); overflow-x: auto; overflow-y: hidden; }
.admin-tabs::-webkit-scrollbar { height: 8px; }
.admin-tabs::-webkit-scrollbar-track { background: var(--surface-soft); border-radius: 999px; }
.admin-tabs::-webkit-scrollbar-thumb { background: var(--q-medium); border-radius: 999px; }
.admin-tab { display: inline-flex; align-items: center; gap: 8px; padding: 11px 16px 13px; margin-bottom: -1px; border-bottom: 3px solid transparent; color: var(--q-medium); font-size: 13.5px; font-weight: var(--w-bold); white-space: nowrap; transition: color var(--dur-fast), border-color var(--dur-fast); }
.admin-tab:hover { color: var(--q-dark); }
.admin-tab.active { color: var(--q-highlight-2); border-bottom-color: var(--q-highlight-2); }
.admin-content { min-width: 0; }
.admin-sec-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.admin-h2 { margin: 0 0 4px; color: var(--q-dark); font-family: var(--font-display); font-size: 20px; font-weight: var(--w-bold); }
/* Die Zahl der Spalten richtet sich nach dem Platz, statt fest vier zu sein
   (BAL-182). GEMESSEN bei 820px mit `repeat(4, 1fr)`: vier Kacheln von je
   146px passten nicht in den 243px breiten Inhaltsbereich der Einstellungen,
   und der ganze Bereich musste quer scrollen.

   `repeat(4, minmax(0, 1fr))` war der erste Versuch und WAR FALSCH - er hat
   den Querscroller zwar beseitigt, aber um den Preis von vier 50px schmalen
   Kacheln, aus denen Zahl und Beschriftung sichtbar herausliefen
   (`.ak-label` "ORGANISATIONSEINHEITEN" mass 67px in einer 49px breiten
   Kachel, `overflow: visible`). Eine Spalte, die schmaler werden darf als
   ihr Inhalt, ist nur dort richtig, wo der Inhalt umbrechen oder kuerzen
   kann - eine Kennzahlkachel kann beides nicht.

   `auto-fit` mit einer Mindestbreite von 140px legt statt dessen die Zahl der
   Spalten um: vier auf dem Schreibtisch, zwei ab etwa 300px Inhaltsbreite,
   eine darunter. 140px sind gemessen die Breite der laengsten Beschriftung
   plus Polsterung. */
.admin-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 14px; margin-bottom: 18px; }
.admin-kpi { padding: 16px 18px; border: 1px solid #ececec; border-radius: 14px; background: #fff; }
.admin-kpi .ak-num { color: var(--q-highlight-2); font-family: var(--font-display); font-weight: var(--w-bold); font-size: 26px; line-height: 1; }
.admin-kpi .ak-of { color: var(--q-medium); font-size: 15px; }
.admin-kpi .ak-label { margin-top: 8px; color: var(--q-medium); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }

/* Einstellungen › Funktionen — Funktionsumfang global und je Entität */
.feat-list { display: flex; flex-direction: column; gap: 14px; }
/* Abhaengige Funktionen (Aufgabe BAL-077): eingerueckt und mit einer Kante,
   damit die Zugehoerigkeit zur Beauftragungskette sichtbar ist. Keine neue
   Komponente - nur eine Zusatzklasse an der vorhandenen Karte. */
/* Der Pfeil ist reine Zierde und steht deshalb als eigenes Element mit
   aria-hidden im Markup, nicht als ::before-Inhalt: Pseudo-Element-Inhalte
   werden von manchen Hilfsmitteln vorgelesen und von keinem zuverlaessig.
   Die Aussage traegt das Textmerkmal daneben (Aufgabe BAL-079). */
.feat-pfeil { margin-right: 8px; color: var(--q-medium); font-weight: var(--w-regular); }
.feat-eltern { margin-left: 8px; padding: 1px 7px; border-radius: 999px; background: var(--surface-soft); color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; vertical-align: middle; }
.feat-abhaengig { margin-left: 26px; border-left: 3px solid var(--q-bright); }
/* Kein Zeichen im ::before: Der erste Entwurf setzte dort U+21B3 als
   CSS-Escape, geschrieben ueber eine Werkzeugkette, die den Backslash
   verschluckte - JavaScript las \21 daraufhin als oktale Escape-Sequenz
   und schrieb das Steuerzeichen 0x11 in die Datei. Am Bildschirm stand ein
   Ersatzkasten mit "B3". Die Zugehoerigkeit tragen jetzt Einrueckung, Kante
   und ein Textmerkmal an der Karte - das liest auch ein Hilfsmittel vor. */
.feat-card { transition: opacity var(--dur-base) var(--ease-std), background var(--dur-base) var(--ease-std); }
.feat-card.feat-off { background: var(--q-highlight-4); }
.feat-head { display: flex; align-items: flex-start; gap: 14px; }
.feat-mark { display: grid; place-items: center; flex-shrink: 0; width: 40px; height: 40px; border-radius: 50%; background: var(--q-highlight-4); }
.feat-card.feat-off .feat-mark { background: #fff; opacity: 0.55; }
.feat-titles { flex: 1; min-width: 0; }
.feat-name { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 15px; font-weight: var(--w-bold); }
.feat-desc { max-width: 72ch; margin-top: 4px; color: var(--q-medium); font-size: 12.5px; line-height: 1.5; text-wrap: pretty; }
.feat-master { display: flex; align-items: center; flex-shrink: 0; gap: 12px; }
.feat-scope-label { margin: 20px 0 10px; color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.feat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(212px, 1fr)); gap: 10px; }
.feat-ent { display: flex; align-items: center; gap: 10px; padding: 11px 13px; border: 1px solid var(--divider); border-radius: 12px; background: #fff; }
.feat-ent.on { border-color: color-mix(in oklch, var(--q-highlight-1) 60%, var(--divider)); }
.feat-ent.off { background: var(--q-highlight-4); }
.feat-ent.na { opacity: 0.55; }
.feat-ent-ic { display: grid; place-items: center; flex-shrink: 0; width: 22px; height: 22px; }
.feat-ent-label { flex: 1; min-width: 0; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); }
.feat-ent.off .feat-ent-label { color: var(--q-medium); }
.feat-ent-na { color: var(--q-medium); font-size: 11px; }
.feat-offnote { margin-top: 16px; }
.info-note { display: flex; align-items: flex-start; gap: 9px; margin-bottom: 14px; padding: 11px 13px; border: 1px solid var(--divider); border-radius: 11px; background: var(--surface-soft); color: var(--q-dark); font-size: 12.5px; line-height: 1.5; }
.info-note b { color: var(--q-highlight-2); font-weight: var(--w-bold); }

.role-grid, .set-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.role-card, .set-card { display: flex; flex-direction: column; gap: 10px; padding: 16px 18px; border: 1px solid #ececec; border-radius: 14px; background: #fff; text-align: left; transition: box-shadow var(--dur-fast), transform var(--dur-fast), border-color var(--dur-fast); }
.role-card:hover, .set-card:hover { transform: translateY(-1px); border-color: var(--q-highlight-3); box-shadow: 0 4px 14px rgba(0,0,0,0.06); }
.role-card:focus-visible, .set-card:focus-visible, .index-card:focus-visible { border-color: var(--q-highlight-3); box-shadow: 0 4px 14px rgba(0,0,0,0.06); }
.role-title, .sc-name, .ai-profile-name { display: flex; align-items: center; flex-wrap: wrap; gap: 9px; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 15px; font-weight: var(--w-bold); line-height: 1.25; }
.role-sys { padding: 2px 7px; border-radius: 5px; background: var(--surface-soft); color: var(--q-medium); font-family: var(--font-sans); font-size: 9.5px; font-weight: var(--w-bold); letter-spacing: 0.05em; text-transform: uppercase; }
.role-desc, .sc-sub, .ai-profile-desc { margin-top: 5px; color: var(--q-medium); font-size: 12.5px; line-height: 1.5; }
.role-users { flex-shrink: 0; color: var(--q-dark); font-size: 12px; font-weight: var(--w-bold); white-space: nowrap; }
.role-perms { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; padding-top: 14px; border-top: 1px solid var(--divider); }
/* In Tabellenzellen (Benutzer-/Rollenliste) dienen die Chip-Gruppen nur als
   Inhalt einer Spalte – die als Kartentrenner gedachte Oberlinie/Abstand darf
   dort nicht erscheinen. */
.module_list_table td .role-perms { margin-top: 0; padding-top: 0; border-top: 0; }
.perm-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border-radius: 999px; font-size: 11.5px; }
.perm-chip.on { background: var(--q-highlight-2); color: #fff; font-weight: var(--w-bold); }
.perm-chip.off { background: var(--surface-soft); color: var(--q-medium); }
.set-card .sc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.set-card .sc-meta, .ai-profile-meta { display: flex; flex-wrap: wrap; gap: 8px 16px; color: var(--q-dark); font-size: 12px; }
.set-card .sc-meta b, .ai-profile-meta b { color: var(--q-medium); font-weight: var(--w-regular); }
.set-card .sc-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding-top: 10px; border-top: 1px solid var(--divider); }
.set-card .row-acts { opacity: 0.55; transition: opacity var(--dur-fast) var(--ease-std); }
.set-card:hover .row-acts, .set-card:focus-visible .row-acts { opacity: 1; }
.admin-card-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-top: auto; padding-top: 10px; border-top: 1px solid var(--divider); }
.role-card .admin-card-actions { justify-content: space-between; }
.ai-profile-main { display: flex; align-items: flex-start; gap: 15px; }
.ai-profile-mark { width: 42px; height: 42px; border-radius: 11px; background: var(--q-highlight-2); color: #fff; display: grid; place-items: center; flex-shrink: 0; }
.ai-profile-mark .ui_icon { filter: brightness(0) invert(1); }
.index-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.index-card { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; text-align: left; }
.idx-ic { width: 36px; height: 36px; border-radius: 10px; background: var(--surface-soft); color: var(--q-highlight-2); display: grid; place-items: center; }
.idx-label { color: var(--q-medium); font-size: 12.5px; font-weight: var(--w-bold); }
.idx-num { color: var(--q-dark); font-family: var(--font-display); font-size: 28px; font-weight: var(--w-bold); line-height: 1.1; }
.idx-num .idx-of { color: var(--q-medium); font-size: 16px; }
.idx-foot { color: var(--q-medium); font-size: 11.5px; }
.admin-audit-list { padding: 2px; }
.set-katalog { display: flex; flex-direction: column; gap: 34px; }
.set-fieldset { display: flex; flex-direction: column; gap: 16px; }
.set-katalog-reg { gap: 12px; }
.set-katalog-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.set-katalog-title { display: inline-flex; align-items: center; gap: 9px; padding: 8px 12px; border-radius: 13px; background: var(--q-dark); color: #fff; font-family: var(--font-display); font-size: 16px; font-weight: var(--w-bold); box-shadow: 0 8px 18px rgba(75,75,75,0.12); }
.set-katalog-title .ui_icon { opacity: 0.9; }
.set-katalog-count { min-width: 25px; padding: 2px 9px; border-radius: 999px; background: var(--q-highlight-1); color: var(--q-highlight-2); font-family: var(--font-sans); font-size: 12px; font-weight: var(--w-bold); text-align: center; }
.set-field-hint { margin: 6px 0 2px; color: var(--q-medium); font-size: 12.5px; line-height: 1.45; }
.set-empty-hint { margin: 0; color: var(--q-medium); font-size: 13px; }
.refcfg-list { box-shadow: 0 0 10px rgba(0,0,0,0.04); }
.set-katalog-primary { font-weight: var(--w-bold); }
.set-katalog-num { text-align: center; }
.refcfg-table th.set-katalog-num, .refcfg-table td.set-katalog-num { text-align: center; }
.set-katalog-act { width: 76px; text-align: right; }
.set-katalog-act .row-actions { justify-content: flex-end; }
.set-usage-pill { display: inline-block; min-width: 34px; padding: 3px 9px; border-radius: 999px; background: color-mix(in srgb, var(--q-highlight-3) 16%, transparent); color: var(--q-highlight-2); font-size: 12px; font-weight: var(--w-bold); }
.set-usage-pill.zero { background: var(--surface-soft); color: var(--q-medium); }
.row-actions { display: inline-flex; align-items: center; gap: 2px; }
.row-edit { display: inline-grid; place-items: center; width: 30px; height: 30px; border: 1px solid transparent; border-radius: 8px; background: none; cursor: pointer; transition: background var(--dur-fast) var(--ease-std), border-color var(--dur-fast) var(--ease-std); }
.row-edit:hover { border-color: var(--divider); background: var(--surface-soft); }
.row-del:hover { border-color: color-mix(in srgb, var(--danger) 14%, transparent); background: color-mix(in srgb, var(--danger) 10%, transparent); }
.catalog-dialog { width: min(520px, calc(100vw - 48px)); max-width: none; }
.catalog-dialog.fullscreen { width: calc(100vw - 28px); max-width: none; }
.catalog-dialog:not(.fullscreen) { height: min(460px, calc(100vh - 48px)); }
.catalog-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--divider); color: var(--q-medium); font-size: 12px; }
.list-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.list-card { display: flex; flex-direction: column; gap: 7px; width: 100%; padding: 16px 18px; border: 1px solid #ececec; border-radius: 14px; background: #fff; cursor: pointer; text-align: left; transition: border-color var(--dur-fast), box-shadow var(--dur-fast), transform var(--dur-fast); }
.list-card:hover { transform: translateY(-1px); border-color: var(--q-highlight-3); box-shadow: 0 6px 18px rgba(0,0,0,0.07); }
.list-card:focus-visible { outline: 2px solid var(--q-highlight-3); outline-offset: 2px; }
.list-card .lc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.list-card .lc-title { display: flex; align-items: center; gap: 7px; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 14.5px; font-weight: var(--w-bold); line-height: 1.25; }
.list-card .lc-sub { color: var(--q-medium); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-card .lc-mid { color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); }
.list-card .lc-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 3px; padding-top: 11px; border-top: 1px solid #f1f2f2; color: var(--q-medium); font-size: 12px; }
.list-card .lc-foot .num { color: var(--q-dark); font-family: var(--font-display); font-size: 15px; font-weight: var(--w-bold); }
.list-card .row-acts, .topic-card .row-acts, .kb-card .row-acts { opacity: 0.55; transition: opacity var(--dur-fast) var(--ease-std); }
.list-card:hover .row-acts, .list-card:focus-visible .row-acts, .topic-card:hover .row-acts, .topic-card:focus-visible .row-acts, .kb-card:hover .row-acts, .kb-card:focus-visible .row-acts { opacity: 1; }
.doc-ic { width: 34px; height: 34px; border-radius: 10px; background: color-mix(in srgb, var(--doc-color, var(--q-medium)) 14%, transparent); color: var(--doc-color, var(--q-medium)); display: grid; place-items: center; flex-shrink: 0; }
.doc-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--q-highlight-2); font-family: var(--font-display); font-weight: var(--w-bold); font-size: 14.5px; }
.ext-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 34px; padding: 3px 8px; border-radius: 999px; color: #fff; font-size: 10.5px; font-weight: var(--w-bold); text-transform: uppercase; }
.help-hero { display: flex; align-items: center; gap: 24px; margin-bottom: 4px; padding: 30px 32px; border-radius: 18px; background: var(--q-highlight-2); color: #fff; position: relative; overflow: hidden; }
.help-hero::after { content: ""; position: absolute; right: -90px; bottom: -120px; width: 280px; height: 280px; border-radius: 50%; background: radial-gradient(circle, rgba(198,211,28,0.36), transparent 70%); pointer-events: none; }
.help-hero .hh-mark { width: 56px; height: 56px; border-radius: 14px; background: rgba(255,255,255,0.12); display: grid; place-items: center; flex-shrink: 0; }
.help-hero .hh-mark .ui_icon { filter: brightness(0) invert(1); }
.help-hero h2 { margin: 0 0 6px; color: #fff; font-family: var(--font-display); font-size: 22px; font-weight: var(--w-bold); }
.help-hero p { max-width: 60ch; margin: 0; color: rgba(255,255,255,0.82); font-size: 13.5px; line-height: 1.5; }
.help-hero .button { position: relative; z-index: 1; color: var(--q-highlight-2); }
.kb-bar { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin: 6px 0 0; }
.sec-title { color: var(--q-dark); font-family: var(--font-display); font-size: 17px; font-weight: var(--w-bold); }
.kb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.kb-card { display: flex; flex-direction: column; min-height: 220px; padding: 20px; border: 1px solid #ececec; border-radius: 14px; background: #fff; cursor: pointer; text-align: left; transition: border-color var(--dur-fast), box-shadow var(--dur-fast), transform var(--dur-fast); }
.kb-card:hover { transform: translateY(-1px); border-color: var(--q-highlight-3); box-shadow: 0 6px 18px rgba(0,0,0,0.07); }
.kb-card:focus-visible { border-color: var(--q-highlight-3); box-shadow: 0 6px 18px rgba(0,0,0,0.07); }
.kb-card-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.kb-card .kb-ic { width: 42px; height: 42px; border-radius: 11px; background: color-mix(in srgb, var(--kb-color, var(--q-highlight-3)) 14%, transparent); color: var(--kb-color, var(--q-highlight-3)); display: grid; place-items: center; }
.kb-card h3 { margin: 0 0 6px; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 15px; font-weight: var(--w-bold); line-height: 1.25; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.kb-card p { flex: 1; margin: 0; color: var(--q-medium); font-size: 12.5px; line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.kb-type-badge { padding: 3px 9px; border: 1px solid currentColor; border-radius: 999px; font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: 0.04em; text-transform: uppercase; }
.kb-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 14px; }
.kb-tag { color: var(--q-highlight-3); font-size: 11px; font-weight: var(--w-bold); }
.kb-foot-meta { color: var(--q-medium); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topic-card { display: flex; flex-direction: column; gap: 10px; width: 100%; padding: 16px 18px; border: 1px solid #ececec; border-radius: 14px; background: #fff; cursor: pointer; text-align: left; transition: border-color var(--dur-fast), box-shadow var(--dur-fast), transform var(--dur-fast); }
.topic-card:hover { transform: translateY(-1px); border-color: var(--q-highlight-3); box-shadow: 0 4px 14px rgba(0,0,0,0.06); }
.topic-card:focus-visible { border-color: var(--q-highlight-3); box-shadow: 0 4px 14px rgba(0,0,0,0.06); }
.topic-card .tc-title { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 15.5px; font-weight: var(--w-bold); line-height: 1.25; }
.topic-card .tc-desc { color: var(--q-medium); font-size: 12.5px; line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.topic-card .tc-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; margin-top: auto; padding-top: 12px; border-top: 1px solid var(--divider); color: var(--q-dark); font-size: 11.5px; }
.topic-card .tc-foot .m { display: flex; align-items: baseline; gap: 4px; }
.topic-card .tc-foot .m strong { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 13px; font-weight: var(--w-bold); }
.topic-sub { display: flex; flex-wrap: wrap; gap: 6px; }
.topic-sub .ts { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; background: var(--surface-soft); color: var(--q-dark); font-size: 11.5px; }
.notification_feed { display: flex; flex-direction: column; gap: 10px; }
.notif { display: flex; align-items: center; gap: 13px; width: 100%; padding: 14px 16px; border: 1px solid #ececec; border-left: 3px solid var(--q-medium); border-radius: 12px; background: #fff; cursor: pointer; text-align: left; transition: box-shadow var(--dur-fast), transform var(--dur-fast), border-color var(--dur-fast); }
.notif:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(0,0,0,0.06); }
.notif:focus-visible { box-shadow: 0 4px 14px rgba(0,0,0,0.06); }
.notif.t-alarm, .notif.t-escalation { border-left-color: var(--danger); }
.notif.t-warning { border-left-color: var(--warning); }
.notif.t-appointment { border-left-color: var(--q-highlight-3); }
.notif.t-info { border-left-color: var(--q-highlight-2); }
.notif.unread { background: #fcfdf6; }
.notif .n-ic { width: 34px; height: 34px; border-radius: 9px; background: var(--surface-soft); color: var(--q-highlight-2); display: grid; place-items: center; flex-shrink: 0; }
.notif.t-alarm .n-ic, .notif.t-escalation .n-ic { color: var(--danger); }
.notif.t-warning .n-ic { color: var(--warning); }
.notif .n-body { flex: 1; min-width: 0; display: block; }
.notif .n-title { color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); line-height: 1.3; }
.notif .n-text { display: block; margin-top: 3px; color: var(--q-medium); font-size: 12.5px; line-height: 1.45; }
.notif .n-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; margin-top: 6px; color: var(--q-medium); font-size: 11px; }
.notif .n-new { color: var(--q-highlight-3); font-weight: var(--w-bold); }
.notif .n-when { color: var(--q-medium); font-size: 11px; white-space: nowrap; }
.notif .n-edit { width: 30px; height: 30px; border-radius: 8px; color: var(--q-medium); display: grid; place-items: center; flex-shrink: 0; opacity: 0.55; transition: opacity var(--dur-fast), background var(--dur-fast); }
.notif:hover .n-edit, .notif:focus-visible .n-edit { opacity: 1; background: var(--surface-soft); }
.notif .n-actions { opacity: 0.55; transition: opacity var(--dur-fast); }
.notif:hover .n-actions, .notif:focus-visible .n-actions { opacity: 1; }

.notification_center { position: relative; }
.notification_center_panel, .quick_create_panel { position: absolute; top: calc(100% + 10px); right: 0; z-index: 80; width: min(410px, calc(100vw - 32px)); overflow: hidden; border: 1px solid #ececec; border-radius: 18px; background: #fff; box-shadow: var(--shadow-elevated); }
.notification_center_body { max-height: 390px; overflow: auto; }
.notification_center_item { display: flex; align-items: flex-start; gap: 11px; width: 100%; padding: 12px 18px; border-bottom: 1px solid #f4f5f4; text-align: left; background: #fff; transition: background var(--dur-fast); }
.notification_center_item:hover { background: var(--surface-soft); }
.notification_center_item_unread { background: rgba(21,165,181,0.04); }
.notification_center_item_title { display: block; color: var(--q-dark); font-weight: var(--w-bold); font-size: 13px; }
.notification_center_item_description { display: block; margin-top: 2px; color: #777; font-size: 11.5px; }
.notification_center_footer { display: flex; gap: 8px; padding: 11px 14px; background: var(--surface-soft); border-top: 1px solid var(--divider); }
.quick_create_panel { width: 240px; padding: 6px; }
.quick_create_item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 10px; border-radius: 10px; text-align: left; color: var(--q-dark); transition: background var(--dur-fast); }
.quick_create_item:hover { background: var(--surface-soft); }
.quick_create_item_icon { width: 28px; height: 28px; border-radius: 8px; background: var(--surface-soft); color: var(--q-highlight-2); display: grid; place-items: center; }

.detail_panel_overlay, .modal_window_overlay { position: fixed; inset: 0; z-index: 40; background: rgba(16,49,78,0.18); backdrop-filter: blur(2px); opacity: 0; pointer-events: none; transition: opacity var(--dur-base) var(--ease-std); }
.detail_panel_overlay_open, .modal_window_overlay_open, .detail-modal-bg.open { opacity: 1; pointer-events: auto; }
.detail_panel { position: fixed; top: 16px; right: 16px; bottom: 16px; z-index: 41; display: flex; flex-direction: column; width: 720px; max-width: calc(100vw - 32px); overflow: hidden; border-radius: 18px; background: #fff; box-shadow: 0 16px 48px rgba(0,0,0,0.18); transform: translateX(8px) scale(0.98); opacity: 0; pointer-events: none; transition: transform var(--dur-base) var(--ease-std), opacity var(--dur-base) var(--ease-std); }
/* 8 statt 16 px Versatz (BAL-208, Nachtrag): Unter 780 px steht das Fenster
   12 px vom Rand; 16 px Versatz schoben das geschlossene, unsichtbare Fenster
   0,3 px ueber den rechten Rand - genug, damit ein mobiler Browser die Seite
   aufweitet. Geschlossene Ebenen duerfen nie ueber den Rand ragen. */
.detail_panel_open, .detail-panel.open { transform: translateX(0) scale(1); opacity: 1; pointer-events: auto; animation: detail-panel-in var(--dur-base) var(--ease-std); }
.detail_no_animation { animation: none !important; transition: none !important; }
/* Bereits geoeffnete Ebenen sollen nach einem Re-Render nicht erneut einfliegen. */
.layer_no_animation { animation: none !important; }
.detail_panel_header { padding: 22px 24px; border-bottom: 1px solid var(--divider); }
.detail-head { display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 12px; }
.detail-head.has-back { padding-top: 16px; }
.detail-head-nav { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; text-align: left; }
.detail-head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; width: 100%; text-align: left; }
.detail-title-wrap { display: flex; align-items: flex-start; justify-content: flex-start; flex: 1 1 auto; gap: 14px; min-width: 0; text-align: left; }
.detail-title-wrap > div { min-width: 0; }
.detail-entity-chip { width: 40px; height: 40px; border-radius: 11px; background: var(--q-highlight-2); color: #fff; display: grid; place-items: center; flex-shrink: 0; }
.detail-entity-chip .ui_icon { filter: brightness(0) invert(1); }
.detail-backlink { display: inline-flex; align-items: center; gap: 7px; max-width: calc(100% - 44px); padding: 4px 8px 4px 6px; margin-left: -6px; border-radius: 8px; color: var(--q-highlight-3); font-size: 13px; font-weight: var(--w-light); }
.detail-backlink:hover { background: var(--surface-soft); color: var(--q-highlight-2); }
.detail-backlink .ui_icon { transform: rotate(180deg); }
.detail_panel_title_pretext { color: var(--q-highlight-3); font-size: 10.5px; letter-spacing: var(--tracking-xwide); text-transform: uppercase; font-weight: var(--w-bold); text-align: left; }
.detail_panel_title { margin: 6px 0 0; font-family: var(--font-display); font-weight: var(--w-bold); font-size: 21px; color: var(--q-dark); letter-spacing: -0.01em; line-height: 1.2; text-align: left; }
.detail_panel_controls { display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.detail_panel_tabs { display: flex; flex-shrink: 0; align-items: stretch; gap: 4px; min-height: 52px; padding: 0 24px; border-bottom: 1px solid var(--divider); overflow-x: auto; overflow-y: hidden; }
/* Der Strich des aktiven Reiters: 3px stark und OHNE negativen Aussenabstand
   (BAL-192).
 *
 * Gemeldet von der Auftraggeberin: Man sieht ihn kaum - und nach einem ersten
 * Versuch, ihn von 2px auf 3px zu verstaerken, sah man noch WENIGER. Der
 * Grund lag nicht an der Staerke, sondern am Zusammenspiel zweier Regeln:
 *
 * `.detail_panel_tabs` traegt `overflow-y: hidden` (damit die waagrechte
 * Verschiebung keine senkrechte nach sich zieht). Alles, was unter den
 * Inhaltskasten des Scrollers reicht, wird damit ABGESCHNITTEN. Der Reiter
 * zog seinen Rand mit `margin-bottom: -1px` genau dorthin - und sobald die
 * Leiste eine waagrechte Scrollleiste bekommt, schrumpft der Inhaltskasten um
 * deren Hoehe und schneidet noch mehr ab.
 *
 * GEMESSEN am 2026-09-15 im Detailbereich einer Beauftragung mit sieben
 * Reitern: Leiste 62px hoch, Inhaltskasten 46px - dazwischen 15px
 * Scrollleiste. Vom 2,67px starken Rand lagen 1,9px unterhalb des
 * Inhaltskastens; sichtbar blieben 0,8px. Der Versuch mit -2px hatte den
 * sichtbaren Teil also halbiert statt ihn zu vergroessern.
 *
 * Ohne negativen Abstand liegt der Rand vollstaendig im Inhaltskasten und ist
 * in voller Staerke zu sehen - mit Scrollleiste wie ohne. Er ueberdeckt dann
 * die 1px-Trennlinie der Leiste nicht mehr; das war ohnehin nur solange der
 * Fall, wie keine Scrollleiste dazwischenlag. */
.detail_panel_tab { display: inline-flex; align-items: center; gap: 7px; padding: 12px 4px 13px; margin-right: 10px; margin-bottom: 0; border-bottom: 3px solid transparent; color: var(--q-medium); font-size: 13.5px; font-weight: var(--w-bold); white-space: nowrap; }
/* Hover nur mit echtem Zeiger (BAL-238): Auf Touchgeraeten bleibt :hover am
   zuletzt beruehrten Punkt kleben - nach dem Neuzeichnen traf das einen
   anderen Reiter, der dann wie gewaehlt aussah. */
@media (hover: hover) { .detail_panel_tab:hover { color: var(--q-dark); } }
.detail_panel_tab { -webkit-tap-highlight-color: transparent; }
.detail_panel_tab_active, .detail-tab.on { color: var(--q-highlight-2); border-bottom-color: var(--q-highlight-2); }
.detail_panel_tab .dt-count { min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: var(--surface-soft); color: var(--q-dark); display: inline-flex; align-items: center; justify-content: center; font-size: 10.5px; font-weight: var(--w-bold); }
.detail_panel_tab_active .dt-count, .detail-tab.on .dt-count { background: var(--q-highlight-2); color: #fff; }
.detail_panel_body { flex: 1; overflow: auto; padding: 22px 24px; }
.detail_panel_footer { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 14px 22px; border-top: 1px solid var(--divider); }
.detail-foot { background: var(--surface-soft); }
.detail-foot-l, .detail-foot-r { display: inline-flex; align-items: center; gap: 10px; min-width: 0; }
.detail-foot-l { flex: 1; overflow: hidden; }
.muted { color: var(--q-medium); }
.danger-text { color: var(--danger); font-weight: var(--w-bold); }
.link-btn { display: inline-flex; align-items: center; gap: 6px; color: var(--q-highlight-3); font-size: 12.5px; font-weight: var(--w-bold); line-height: 1.2; text-align: left; }
.link-btn:hover { color: var(--q-highlight-2); }

/* ── field_list: Beschriftung und Wert untereinander (Aufgabe BAL-183) ──────
 *
 * HIER STANDEN BIS 2026-09-15 ZWEI KOMPONENTEN FUER DIESELBE ROLLE:
 * `.field-row`/`.field-label`/`.field-val` und `field_list_item`/
 * `field_list_label`/`field_list_value`. Ein Anti-Pattern nach ucs.md 25.4
 * ("parallele Klassennamen fuer gleiche semantische Rollen"), und zwar eines
 * mit Zaehnen: Die beiden Familien waren NICHT deckungsgleich.
 *
 * Gemessen vor der Zusammenfuehrung:
 *   - `.field-row` hatte `minmax(0, 1fr)`, `field_list_item` nur `1fr` -
 *     letzteres konnte also nicht unter seine Min-Content-Breite schrumpfen
 *     (dieselbe Falle wie in BAL-181).
 *   - `.field-val` hatte `min-width: 0`, `field_list_value` nicht.
 *   - `.field-val` fuehrte sechs Kindregeln (`.muted`, zwei aufeinander
 *     folgende `status_badge`, `.util-row`, `.util`, `strong`,
 *     `.detail-link-btn`), die es in der anderen Familie nicht gab.
 *   - `field_list_value pre` gab es nur in der anderen.
 * Die Zusammenfuehrung ist deshalb die VEREINIGUNG beider Regelsaetze unter
 * den ucs-konformen Namen, keine blosse Umbenennung. Wer nur umbenannt haette,
 * haette sechs Regeln stillschweigend verloren.
 *
 * Das Markup benutzte durchgehend die Bindestrich-Namen; `field_list_label`
 * und `field_list_value` standen im CSS, kamen aber in app.js kein einziges
 * Mal vor. Die ucs-konforme Familie war also die tote.
 */
.field_list { display: flex; flex-direction: column; }
/* Dichte: `kompakt` fuer Karten und Baumknoten, wo der Platz knapp ist.
   Als `data-`Attribut und nicht als Klasse, weil es ein Modus ist und keine
   strukturelle Auspraegung (ucs.md 7.2). */
.field_list[data-field-list-dichte="kompakt"] .field_list_item { padding: 6px 0; }
.field_list_item { display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 14px; padding: 11px 0; border-bottom: 1px dashed var(--divider); align-items: center; }
.field_list_item:last-child { border-bottom: 0; }
.field_list_item.top { align-items: start; }
/* Leitkennzahl der Zeile. In der Tabelle war sie an ihrer Spaltenposition
   erkennbar; im Stapel geht diese Ordnung verloren und sie braucht eine
   eigene, benannte Auszeichnung (ucs.md 7.1). Hoechstens eine je Liste -
   sonst hebt sich nichts mehr ab. */
.field_list_item_hervorgehoben .field_list_value { color: var(--q-highlight-2); font-family: var(--font-display); font-weight: var(--w-bold); }
.field_list_label { color: var(--q-medium); font-size: 10.5px; letter-spacing: var(--tracking-xwide); text-transform: uppercase; font-weight: var(--w-bold); }
.field_list_value { min-width: 0; color: var(--q-dark); font-size: 13.5px; overflow-wrap: anywhere; }
.field_list_value .big { font-family: var(--font-display); font-weight: var(--w-bold); font-size: 18px; color: var(--q-highlight-2); }
.field_list_value .muted { font-size: 12px; }
.field_list_value .status_badge + .status_badge { margin-left: 8px; }
.field_list_value .util-row { margin-bottom: 6px; }
.field_list_value .util { width: 100%; }
.field_list_value strong { font-weight: var(--w-bold); }
.field_list_value pre { margin: 0; white-space: pre-wrap; }
.field_list_value .detail-link-btn { margin: 0; padding: 0; vertical-align: baseline; }

/* Benannter optionaler Bereich der Karte, der genau ein `field_list` aufnimmt
 * (ucs.md 5 und 8.1). Ohne ihn stuende `field_list` unmittelbar in
 * `.list-card` und muesste deren `gap`-Rhythmus mittragen - die Karte wuerde
 * die Abstandslogik eines fremden Bausteins mitregeln.
 *
 * In der Karte stapelt das Feld IMMER, nicht erst unterhalb des Umbruchs: Eine
 * Karte ist nie breit genug fuer 130px Beschriftungsspalte plus Wert.
 */
.list_card_felder { margin-top: 2px; padding-top: 9px; border-top: 1px solid #f1f2f2; }
.list_card_felder .field_list_item { grid-template-columns: minmax(0, 1fr); gap: 3px; }
.detail-section-label { margin: 22px 0 10px; color: var(--q-medium); font-size: 10.5px; letter-spacing: var(--tracking-xwide); text-transform: uppercase; font-weight: var(--w-bold); }
.detail-section-label:first-child { margin-top: 0; }
.detail-field-card { border: 1px solid #f1f2f2; border-radius: 12px; padding: 0 14px; background: #fff; }
.detail-inline-select-wrap { position: relative; display: inline-block; min-width: 132px; }
.detail-inline-select { width: 100%; min-height: 32px; padding: 5px 26px 5px 10px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); appearance: none; -webkit-appearance: none; cursor: pointer; }
.detail-inline-select-wrap::after { content: ""; position: absolute; right: 10px; top: 50%; width: 8px; height: 8px; margin-top: -4px; background: var(--q-medium); clip-path: polygon(50% 75%, 0 25%, 100% 25%); opacity: .55; pointer-events: none; }
.detail-inline-select:focus { border-color: var(--q-highlight-3); box-shadow: 0 0 0 3px rgba(21,165,181,.14); }
.detail-inline-select-coded .detail-inline-select { padding-left: 26px; border-color: color-mix(in srgb, var(--select-tone) 36%, var(--divider)); color: var(--select-tone); background: color-mix(in srgb, var(--select-tone) 9%, #fff); }
.detail-inline-select-coded::after { background: var(--select-tone); }
.detail-search { display: flex; align-items: center; gap: 9px; margin: 0 0 16px; padding: 9px 13px; border: 1px solid transparent; border-radius: 10px; background: var(--surface-soft); transition: border-color var(--dur-fast), background var(--dur-fast); }
.detail-search:focus-within { border-color: var(--q-highlight-3); background: #fff; }
.detail-search .ui_icon { color: var(--q-medium); opacity: 0.65; }
.detail-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--q-dark); font-size: 13.5px; }
.detail-search .ps-clear { width: 22px; height: 22px; border-radius: 50%; color: var(--q-medium); display: grid; place-items: center; }
.detail-search .ps-clear:hover { background: var(--divider); }
.detail-contingent-summary { display: flex; align-items: center; gap: 18px; margin-bottom: 16px; padding: 16px; border: 1px solid #ececec; border-radius: 16px; background: linear-gradient(135deg, #fff, var(--surface-soft)); }
.detail-tab-actions { display: flex; justify-content: flex-end; gap: 8px; margin-bottom: 12px; }
.assoc-toggle { display: flex; gap: 4px; padding: 4px; margin: 0 0 16px auto; width: fit-content; background: var(--surface-soft); border-radius: 12px; }
.assoc-pill { display: inline-flex; align-items: center; gap: 7px; padding: 7px 13px; border-radius: 9px; font-size: 12.5px; font-weight: var(--w-regular); color: var(--q-dark); background: transparent; transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std), box-shadow var(--dur-fast) var(--ease-std); }
.assoc-pill:hover { color: var(--q-highlight-2); }
.assoc-pill.on { background: #fff; color: var(--q-highlight-2); font-weight: var(--w-bold); box-shadow: 0 0 6px 0 rgba(0,0,0,0.10); }
.assoc-n { min-width: 18px; height: 18px; padding: 0 5px; display: inline-flex; align-items: center; justify-content: center; border-radius: 9px; font-size: 11px; font-weight: var(--w-bold); background: var(--q-bright); color: var(--q-dark); }
.assoc-pill.on .assoc-n { background: var(--q-highlight-3); color: #fff; }
.detail-contingent-success .detail-contingent-ring { color: var(--success); }
.detail-contingent-warning .detail-contingent-ring { color: var(--warning); }
.detail-contingent-danger .detail-contingent-ring { color: var(--danger); }
.detail-contingent-ring { position: relative; width: 74px; height: 74px; flex: 0 0 74px; color: var(--q-highlight-3); }
.detail-contingent-ring .gauge_ring_progress { stroke: currentColor; }
.detail-contingent-ring > span { position: absolute; inset: 0; display: grid; place-items: center; color: var(--q-dark); font-family: var(--font-display); font-size: 14px; font-weight: var(--w-bold); }
.detail-contingent-ring-lg { width: 92px; height: 92px; flex-basis: 92px; }
.detail-contingent-ring-lg > span { font-size: 18px; }
.detail-contingent-summary-copy { flex: 1; min-width: 0; }
.dcs-title { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 17px; font-weight: var(--w-bold); }
.dcs-meta { margin-top: 3px; color: var(--q-medium); font-size: 12.5px; }
.dcs-kpis { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin-top: 13px; }
.dcs-kpis span, .dcc-stats span { min-width: 0; padding: 8px 10px; border-radius: 10px; background: #fff; }
.dcs-kpis strong, .dcc-stats strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--q-dark); font-family: var(--font-display); font-size: 14px; font-weight: var(--w-bold); }
.dcs-kpis small, .dcc-stats small { display: block; margin-top: 2px; color: var(--q-medium); font-size: 10.5px; text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.detail-contingent-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.detail-contingent-card { display: flex; align-items: center; gap: 14px; width: 100%; padding: 14px; border: 1px solid #ececec; border-radius: 14px; background: #fff; text-align: left; transition: transform var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast); }
.detail-contingent-card:hover, .detail-contingent-card:focus-visible { transform: translateY(-1px); border-color: var(--q-highlight-3); box-shadow: var(--shadow-soft); }
.detail-contingent-card-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.dcc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.dcc-title { display: block; color: var(--q-highlight-2); font-weight: var(--w-bold); line-height: 1.25; }
.dcc-sub { display: block; margin-top: 2px; color: var(--q-medium); font-size: 11.5px; }
.dcc-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.dcc-stats span { padding: 7px 8px; background: var(--surface-soft); }
.dcc-stats strong { font-size: 12.5px; }
.mini-list { display: flex; flex-direction: column; gap: 6px; }
.mini-item { width: 100%; padding: 10px 12px; border: 1px solid var(--divider); border-radius: 10px; display: flex; align-items: center; justify-content: space-between; gap: 10px; background: #fff; text-align: left; transition: border-color var(--dur-fast), background var(--dur-fast), transform var(--dur-fast); }
.mini-item[role="button"] { cursor: pointer; }
.mini-item:hover { border-color: var(--q-highlight-3); background: #fafbfa; }
.mini-item .mi-title { display: block; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); }
.mini-item .mi-sub { display: block; margin-top: 1px; color: var(--q-medium); font-size: 11.5px; }
.mini-item .mi-right { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex-shrink: 0; text-align: right; }
.mini-item .mi-right .num { font-family: var(--font-display); font-weight: var(--w-bold); font-size: 13px; color: var(--q-dark); white-space: nowrap; }
.mini-item .mi-right .mi-2nd { font-size: 11px; color: var(--q-medium); white-space: nowrap; }
.mini-item .mi-right .mi-2nd.neg { color: var(--danger); }
.mini-item .mi-bar { width: 96px; margin-top: 4px; }
.mini-item .mi-gauge-wrap { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.gauge-ring-sm .g-pct { font-size: 10px; }
.document-mini-actions { flex-shrink: 0; }
.docs-drop { width: 100%; display: flex; align-items: center; gap: 12px; padding: 14px 16px; border: 2px dashed var(--q-medium); border-radius: 12px; background: #fff; text-align: left; transition: border-color var(--dur-fast), background var(--dur-fast); margin-bottom: 18px; }
.docs-drop:hover { border-color: var(--q-highlight-3); background: #fafbfa; }
.docs-drop-ic { width: 36px; height: 36px; border-radius: 10px; background: var(--surface-soft); color: var(--q-highlight-2); display: grid; place-items: center; flex-shrink: 0; }
.docs-drop-txt { display: flex; flex-direction: column; gap: 2px; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.docs-drop-sub { color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-regular); }
.kb-file-block { display: flex; align-items: center; gap: 13px; padding: 14px 16px; border: 1px solid var(--divider); border-radius: 12px; background: #fff; margin-bottom: 6px; }
.document-file-block { cursor: pointer; transition: border-color var(--dur-fast), background var(--dur-fast); }
.document-file-block:hover, .document-file-block:focus-visible { border-color: var(--q-highlight-3); background: #fafbfa; }
.kb-file-meta { flex: 1; min-width: 0; }
.kb-file-name { color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-file-sub { margin-top: 2px; color: var(--q-medium); font-size: 11.5px; }
.doc-detail-ic { width: 44px; height: 44px; }
.document-download-icon { flex-shrink: 0; }
/* Die runden Schaltflaechen der Dialogkoepfe (Aufgabe BAL-193).
 *
 * `border-radius: 50%` statt 9px: Auf Wunsch der Auftraggeberin ein Kreis und
 * kein Quadrat mit abgerundeten Ecken - gleichfoermig mit der
 * Nachbaranwendung Mission Control. Die Klasse traegt die Kopfschalter aller
 * Dialoge (Vollbild, Fenster, Schliessen) und daneben die Zeilenaktionen der
 * Verwaltungslisten; alle werden damit rund.
 *
 * 50 % und nicht 999px: Beide ergeben beim Quadrat denselben Kreis, aber 50 %
 * bleibt einer, falls die Flaeche einmal nicht mehr quadratisch ist - dann
 * entsteht eine Ellipse statt einer Pille mit geraden Flanken. */
.planner-icon-btn { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; transition: background var(--dur-fast); }
.planner-icon-btn:hover { background: var(--surface-soft); }

/* Hoehe folgt dem Inhalt, gedeckelt bei 640px beziehungsweise der
   Fensterhoehe. Vorher stand dort eine FESTE Hoehe: Ein kurzer Dialog
   liess unten einen leeren Block stehen - gemessen am 2026-09-03 beim
   Dialog "Neue Zahlung" 486px Inhalt in einem 640px hohen Fenster.
   Lange Dialoge sind unberuehrt, ihr Inhalt scrollt weiterhin (Themen 711px,
   Beauftragung 1299px). Befund DES-004, Aufgabe BAL-079. Das Vorbild stand
   schon im Stylesheet: .decision-modal loeste dasselbe fuer einen Dialog. */
/* Seit BAL-207 (Dialog-Standard) 820 x 860 statt 640 x 640, Radius 24 und der
   Schatten des Referenzdesigns (docs/design/application/project/workdialog.css,
   Abschnitt "Kompakte Dialoge"). Die kompakten Dialoge tragen damit dieselben
   Masse in Kopf und Fuss wie der Arbeitsdialog; ihre Groesse bleibt ansonsten
   eine Obergrenze - kurze Dialoge wachsen nur so hoch wie ihr Inhalt. */
.modal_window { position: fixed; top: 50%; left: 50%; z-index: 61; display: flex; flex-direction: column; width: min(820px, calc(100vw - 64px)); height: auto; max-height: min(860px, calc(100vh - 64px)); overflow: hidden; border-radius: 24px; background: #fff; box-shadow: 0 24px 64px rgba(16,49,78,0.22), 0 0 0 1px rgba(16,49,78,0.04); transform: translate(-50%, -50%); transition: width var(--dur-base) var(--ease-std), height var(--dur-base) var(--ease-std), max-height var(--dur-base) var(--ease-std), border-radius var(--dur-base) var(--ease-std); animation: modal-window-in var(--dur-base) var(--ease-std); }
/* `max-height: none` im Vollbild. Ohne diese Angabe deckelt die Obergrenze aus
   der Grundregel (min(640px, ...)) die Vollbildhoehe: Gemessen am 2026-09-03
   blieb das Fenster bei 640px stehen, waehrend die Breite bis 1681px lief.
   Das Vorbild steht im selben Stylesheet - der Kontingentdialog macht es
   genauso. Aufgabe BAL-080. */
/* Die Obergrenze traegt im Vollbild einen konkreten Wert, kein `none`:
   Zwischen einem Schluesselwort und einem Pixelwert wird nicht interpoliert,
   und der Rueckweg sprang deshalb von 1194px auf 640px, bevor der Uebergang
   ueberhaupt lief (gemessen 2026-09-03). */
.modal_window.fullscreen { width: calc(100vw - 28px); height: calc(100vh - 28px); max-height: calc(100vh - 28px); border-radius: 16px; }
.modal_window_header { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 18px 24px 18px 28px; border-bottom: 1px solid var(--divider); flex-shrink: 0; }
.fmodal-head-l { display: flex; gap: 16px; align-items: center; min-width: 0; }
.fmodal-head-actions { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; }
.fmodal-chip { width: 44px; height: 44px; border-radius: 13px; background: var(--q-highlight-2); color: #fff; display: grid; place-items: center; flex-shrink: 0; }
.fmodal-chip .ui_icon { filter: brightness(0) invert(1); }
.modal_window_title { margin: 4px 0 0; font-family: var(--font-display); font-size: 21px; color: var(--q-dark); line-height: 1.15; }
.fmodal-head .eyebrow { color: var(--q-highlight-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.modal_window_body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 26px 36px 32px; }
.modal_window_footer { display: flex; justify-content: flex-end; gap: 10px; padding: 14px 24px 14px 28px; border-top: 1px solid var(--divider); background: #fff; flex-shrink: 0; }
.fmodal-foot { align-items: center; justify-content: space-between; gap: 12px; border-radius: 0 0 14px 14px; }
.fmodal-foot-l, .fmodal-foot-r { display: inline-flex; align-items: center; gap: 10px; min-width: 0; }
.fmodal-foot-l { flex: 1; justify-content: flex-start; }
.fmodal-foot-r { justify-content: flex-end; }
.confirm_overlay { position: fixed; inset: 0; z-index: 130; background: rgba(16,49,78,0.34); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.confirm-card { position: fixed; left: 50%; top: 50%; z-index: 131; width: min(460px, calc(100vw - 40px)); overflow: hidden; border: 1px solid var(--divider); border-radius: var(--radius-lg); background: var(--surface); box-shadow: 0 24px 70px rgba(16,49,78,0.30); transform: translate(-50%, -50%); text-align: left; }
.confirm-card .confirm-body { display: flex; align-items: flex-start; gap: 15px; padding: 26px 26px 20px; }
.confirm-card .confirm-ic { width: 46px; height: 46px; flex-shrink: 0; border-radius: var(--radius-pill); display: grid; place-items: center; background: var(--surface-soft); color: var(--q-highlight-2); }
.confirm-card .confirm-ic.danger { background: #f8e0e0; color: var(--danger); }
.confirm-card .confirm-avatar { width: 52px; height: 52px; flex-shrink: 0; border-radius: var(--radius-pill); display: grid; place-items: center; background: var(--q-highlight-2); color: var(--q-white); font-family: var(--font-display); font-size: 18px; font-weight: var(--w-bold); }
.confirm-card .confirm-title { margin: 2px 0 7px; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 19px; font-weight: var(--w-bold); line-height: 1.25; }
.confirm-card .confirm-msg { margin: 0; color: var(--q-dark); font-size: 14px; line-height: 1.55; text-wrap: pretty; }
.confirm-card .confirm-msg strong { font-weight: var(--w-bold); }
/* Verweis aus der Rückfrage hinaus (BAL-194, Kontodialog -> Anmeldeverfahren).
   Reihe confirm-* wie der ganze Dialog. Alle vererbbaren Angaben geschlossen
   gesetzt, damit keine globale Regel hineinwirkt; Farbe wie der Titel. */
.confirm-card .confirm-link { display: inline-flex; align-items: center; gap: 7px; margin-top: 12px; color: var(--q-highlight-2); font-size: 14px; font-weight: var(--w-bold); line-height: 1.4; text-decoration: underline; text-underline-offset: 3px; }
.confirm-card .confirm-link:hover { text-decoration-thickness: 2px; }
.confirm-card .confirm-foot { display: flex; align-items: center; gap: 12px; padding: 16px 26px; border-top: 1px solid var(--divider); background: var(--surface-soft); }
.confirm-card .confirm-foot-main { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; }
/* Umbrechen statt abschneiden, in JEDER Breite (BAL-210). Die Telefonregel
   unter 560 px stapelt die Schaltflaechen; diese Zeilen sorgen dafuer, dass
   auch dazwischen nichts aus der Karte laeuft - etwa bei vergroesserter
   Systemschrift oder wenn ein Geraet die Seite breiter rechnet als sein
   Bildschirm (so geschehen vor BAL-209: "Abmelden" abgeschnitten). Passt alles
   in eine Zeile, aendert sich nichts. */
.confirm-card .confirm-foot { flex-wrap: wrap; }
.confirm-card .confirm-foot-main { flex-wrap: wrap; justify-content: flex-end; max-width: 100%; }

.planner-overlay { position: fixed; inset: 0; z-index: 60; background: rgba(16,49,78,0.22); backdrop-filter: blur(3px); opacity: 0; pointer-events: none; transition: opacity var(--dur-base) var(--ease-std); }
.planner-overlay.open { opacity: 1; pointer-events: auto; }
/* `grid-template-rows: minmax(0, 1fr)` ist NICHT Kosmetik, sondern der Grund,
   warum in dieser Karte ueberhaupt gescrollt werden kann (BAL-188).

   GEMESSEN am 2026-09-15 im Einrichtungsassistenten bei 1280 x 620: Die Karte
   war 596 px hoch, Schiene und Rumpf aber 1138 px - sie liefen 542 px ueber den
   unteren Rand hinaus, wo `overflow: hidden` sie abschnitt. Die Fussleiste mit
   "Weiter" endete bei y = 1150, die Karte bei y = 608: unerreichbar. Eine
   Bildlaufleiste gab es nirgends, und zwar folgerichtig - `.planner-scroll`
   und die Kapitelliste meldeten `scrollHeight === clientHeight`, weil sie
   selbst mitgewachsen waren.

   Ursache: Das Raster hatte Spalten, aber keine Zeilen. Die einzige, implizite
   Zeile ist damit `auto` und richtet sich nach dem INHALT statt nach der festen
   Hoehe der Karte. Die Kinder tragen zwar `min-height: 0` und `overflow: auto`,
   das nuetzt aber nichts, solange die Zeile unter ihnen beliebig wachsen darf.

   Der Fehler steckt in der gemeinsamen Karte und betraf Import- und
   Planungsassistenten genauso; er fiel dort nur nie auf, weil deren Inhalt
   kuerzer ist als die Karte. Deshalb hier behoben und nicht in einer Variante.
   Nach der Aenderung: Schiene und Rumpf 596 px, Fussleiste innerhalb der Karte,
   Ueberlauf 213 px im Inhalt und 558 px in der Kapitelliste - beide scrollen. */
.planner-card { position: fixed; z-index: 61; top: 50%; left: 50%; width: min(960px, calc(100vw - 48px)); height: min(680px, calc(100vh - 48px)); display: grid; grid-template-columns: 264px minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); overflow: hidden; border-radius: 22px; background: #fff; box-shadow: 0 24px 64px rgba(0,0,0,0.24); transform: translate(-50%, -50%); transition: width var(--dur-base) var(--ease-std), height var(--dur-base) var(--ease-std), max-height var(--dur-base) var(--ease-std), border-radius var(--dur-base) var(--ease-std); }
.planner-card.fullscreen { width: calc(100vw - 24px); height: calc(100vh - 24px); border-radius: 16px; }
.planner-rail { display: flex; flex-direction: column; min-width: 0; padding: 26px 22px; background: var(--q-highlight-2); color: #fff; }
.planner-rail-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 30px; }
.planner-rail-brand img { width: 36px; height: 36px; padding: 5px; border-radius: 9px; background: #fff; }
.planner-rail-mark { width: 36px; height: 36px; display: grid; place-items: center; border-radius: 9px; background: #fff; color: var(--q-highlight-2); flex-shrink: 0; }
.planner-rail-brand .prb-title { color: #fff; font-family: var(--font-display); font-size: 16px; font-weight: var(--w-bold); line-height: 1.1; }
.planner-rail-brand .prb-sub { margin-top: 2px; color: rgba(255,255,255,0.7); font-size: 11px; letter-spacing: var(--tracking-wide); }
.planner-steps { display: flex; flex-direction: column; gap: 4px; }
.planner-step { display: flex; align-items: center; gap: 13px; width: 100%; padding: 11px 12px; border-radius: 11px; color: #fff; text-align: left; transition: background var(--dur-fast); }
.planner-step:hover { background: rgba(255,255,255,0.08); }
.planner-step.active { background: rgba(255,255,255,0.12); }
.planner-step .ps-num { width: 26px; height: 26px; display: grid; place-items: center; border-radius: 50%; background: rgba(255,255,255,0.16); color: #fff; font-family: var(--font-display); font-size: 13px; font-weight: var(--w-bold); flex-shrink: 0; }
.planner-step.active .ps-num { box-shadow: 0 0 0 2px var(--q-highlight-1); }
.planner-step.done .ps-num { background: var(--q-highlight-1); box-shadow: none; }
.planner-step .ps-label { color: #fff; font-size: 14px; opacity: 0.92; }
.planner-step.active .ps-label { font-weight: var(--w-bold); opacity: 1; }
.planner-assist { display: flex; align-items: flex-start; gap: 11px; margin-top: auto; padding: 14px; border-radius: 13px; background: rgba(255,255,255,0.08); }
.planner-assist .pa-badge { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 8px; background: rgba(255,255,255,0.18); flex-shrink: 0; }
.planner-assist .pa-text { color: rgba(255,255,255,0.9); font-size: 12.5px; line-height: 1.5; }
.planner-body { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }
.planner-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; padding: 22px 28px 16px; border-bottom: 1px solid var(--divider); flex-shrink: 0; }
.planner-head .eyebrow { white-space: nowrap; }
.planner-head h2 { margin: 6px 0 0; color: var(--q-dark); font-family: var(--font-display); font-size: 22px; font-weight: var(--w-bold); }
.planner-head-actions { display: flex; gap: 6px; flex-shrink: 0; }
.planner-bound-banner { display: flex; align-items: flex-start; gap: 10px; margin: 12px 28px 0; padding: 11px 13px; border: 1px solid var(--divider-active); border-radius: 12px; background: var(--surface-active); color: var(--q-highlight-2); font-size: 12.5px; line-height: 1.45; }
.planner-bound-banner b { color: var(--q-dark); }
.planner-bound-banner .planner-bound-link { display: inline; margin-left: 0; padding: 0; vertical-align: baseline; line-height: inherit; }
.planner-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 24px 28px; }
.planner-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 28px; border-top: 1px solid var(--divider); flex-shrink: 0; }
.planner-form { max-width: 600px; }
.planner-form-wide { max-width: 700px; }
.planner-card.fullscreen .planner-form, .planner-card.fullscreen .planner-form-wide { max-width: 100%; }
.planner-sub-label, .seg-field > label, .planner-field > span { color: var(--q-medium); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.seg-field { display: flex; flex-direction: column; gap: 8px; }
.planner-tabs { display: flex; gap: 4px; border-bottom: 2px solid var(--divider); }
.planner-tab { display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px 12px; margin-bottom: -2px; border-bottom: 2px solid transparent; color: var(--q-medium); font-weight: var(--w-bold); }
.planner-tab:hover { color: var(--q-dark); }
.planner-tab.on { border-bottom-color: var(--q-highlight-2); color: var(--q-highlight-2); }
.seg-help { color: var(--q-medium); font-size: 12.5px; line-height: 1.45; }
.planner-field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 18px; }
.planner-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.planner-field-wide { grid-column: 1 / -1; }
/* Formularfelder des Planungsassistenten und der Positionslisten.
   HIER IST SCHON EINMAL ETWAS SCHIEFGEGANGEN: Mit BAL-076 wurde
   .imp-verworfen IN diese Selektorliste geschrieben statt in eine eigene
   Regel; ein Kommentar mitten in der Liste hat den Fehler unsichtbar gemacht.
   Folge, gemessen: Diese Felder verloren Rahmen, weissen Grund und scharfe
   Ecken und bekamen den Stil des Importberichts - border 2px inset
   (Browser-Standard), Hintergrund #f1f2f2, Radius 8px, 10px Abstand oben,
   Schrift 12,5px. Behoben mit BAL-094.

   Der Zugriff geht jetzt ueber das DIREKTE Kind: .planner-field enthaelt auch
   zusammengesetzte Bausteine - .fsel mit eigenem Ausloeser und Suchfeld - und
   die duerfen die Masze eines Formularfeldes nicht erben. Genau daran war das
   Suchfeld der Klappliste 40px hoch geworden.
   Gemessene Menge: 5 Felder mit direktem input (Neue Bezeichnung, Periode ab
   und bis) gegen 2 Felder mit verschachtelter Auswahl (Bestehende Planung,
   Organisationseinheit). */
.planner-field > input, .planner-field > select, .ytb-name-input, .pos-name, .pos-input input, .imp-textarea { width: 100%; border: 2px solid var(--q-medium); border-radius: 0; background: #fff; color: var(--q-dark); transition: border-color var(--dur-fast); }
.planner-field > input, .planner-field > select { min-height: 40px; padding: 10px 12px; }
.planner-field > input:focus, .planner-field > select:focus, .ytb-name-input:focus, .pos-name:focus, .pos-input input:focus, .imp-textarea:focus { border-color: var(--q-highlight-3); }

/* Bericht ueber uebergangene Importzeilen (DEV-015, BAL-076) - eigene Regel. */
.imp-verworfen { margin-top: 10px; padding: 10px 12px; border-radius: 8px; background: var(--surface-soft); color: var(--q-dark); font-size: 12.5px; line-height: var(--lh-normal); }
.imp-verworfen ul { margin: 6px 0 0; padding-left: 18px; list-style: disc; font-weight: var(--w-regular); }
.imp-verworfen li { margin: 2px 0; }
.finput:disabled { background: var(--surface-soft); color: var(--q-medium); cursor: not-allowed; }
.ffield.disabled { opacity: 0.82; }
.year-topics, .pos-list, .imp-modes { display: flex; flex-direction: column; gap: 8px; }
.year-topics { margin-top: 6px; }
.planner-search { display: flex; align-items: center; gap: 9px; margin-bottom: 4px; padding: 9px 13px; border: 1px solid transparent; border-radius: 10px; background: var(--surface-soft); transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std); }
.planner-search:focus-within { border-color: var(--q-highlight-3); background: #fff; }
.planner-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--q-dark); font-size: 13.5px; }
.planner-search .ps-clear { width: 22px; height: 22px; display: grid; place-items: center; border-radius: 50%; flex-shrink: 0; }
.planner-search .ps-clear:hover { background: var(--divider); }
.topic-check { display: flex; align-items: center; gap: 13px; width: 100%; padding: 13px 15px; border: 1px solid var(--divider); border-radius: 12px; background: #fff; text-align: left; transition: border-color var(--dur-fast), background var(--dur-fast); }
.topic-check:hover { border-color: var(--q-medium); }
.topic-check.on { border-color: var(--q-highlight-2); background: #fafbf3; }
.topic-check .tc-box { width: 24px; height: 24px; display: grid; place-items: center; border: 2px solid var(--q-medium); border-radius: 7px; flex-shrink: 0; }
.topic-check.on .tc-box { border-color: var(--q-highlight-2); background: var(--q-highlight-2); color: #fff; }
.topic-check .tc-title { display: block; color: var(--q-dark); font-weight: var(--w-bold); }
.topic-check .tc-meta { display: block; margin-top: 2px; color: var(--q-medium); font-size: 12px; }
.topic-check .tc-main { min-width: 0; }
.topic-check .tc-amt { margin-left: auto; color: var(--q-highlight-2); font-family: var(--font-display); font-weight: var(--w-bold); white-space: nowrap; }
.basis-note { display: flex; align-items: flex-start; gap: 8px; margin-top: 8px; color: var(--q-medium); font-size: 12px; line-height: 1.5; }
/* Die Fehlerfassung des Hinweises (BAL-178). Sie traegt einen Rand - die
   Grundfassung hat keinen, und eine blosse Randfarbe zeichnet deshalb nichts.
   Und sie traegt --q-dark statt --q-medium: Letzteres ist eine Dekorfarbe
   (auf Weiss 1,9 : 1) und fuer eine Meldung, die gelesen werden muss, zu
   wenig. --q-dark misst auf weisser Karte 7,78 : 1. */
.basis-note-fehler {
  padding: 10px 12px;
  border: 1px solid var(--danger);
  border-radius: var(--radius-sm);
  color: var(--q-dark);
}
.planner-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-top: 22px; padding: 16px 18px; border-radius: 13px; background: var(--surface-soft); }
.planner-toggle-row .pt-title { color: var(--q-dark); font-size: 14px; font-weight: var(--w-bold); }
.planner-toggle-row .pt-sub { max-width: 46ch; margin-top: 3px; color: var(--q-medium); font-size: 12px; line-height: 1.45; }
.year-topic-block { margin-bottom: 12px; padding: 14px 16px; border: 1px solid var(--divider); border-radius: 14px; background: #fff; }
.year-topic-block .ytb-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.ytb-name-input { padding: 5px 8px; border-color: transparent; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 15px; font-weight: var(--w-bold); }
.ytb-name-input:hover { border-color: var(--divider); }
.pos-row { display: grid; align-items: center; gap: 12px; }
.pos-row.struct { grid-template-columns: 28px 1fr 120px 30px; padding: 6px 0; }
.pos-row.head, .pos-row.amt, .pos-row.total, .ytb-subtotal { grid-template-columns: 1fr 110px 130px 56px; }
.pos-row.head { padding: 4px 0 8px; border-bottom: 1px solid var(--divider); color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.pos-row.amt { padding: 5px 0; }
.pos-row.amt.bound { margin: 2px 0 5px; padding: 9px 10px; border: 1px solid #dfe9c7; border-radius: 10px; background: #f8faf2; }
.pos-row .pos-idx { width: 26px; height: 26px; display: grid; place-items: center; border-radius: 50%; background: var(--surface-soft); color: var(--q-medium); font-family: var(--font-display); font-size: 12px; font-weight: var(--w-bold); }
.pos-name { padding: 9px 12px; }
.pos-prev, .pos-prev-val { color: var(--q-medium); font-size: 12.5px; }
.pos-del { width: 28px; height: 28px; display: grid; place-items: center; border-radius: 8px; color: var(--q-medium); }
.pos-del:hover { background: var(--surface-soft); }
.pos-input input { padding: 7px 10px; text-align: right; font-family: var(--font-display); font-weight: var(--w-bold); }
.pos-name-static small { display: block; margin-top: 2px; color: var(--q-highlight-2); font-size: 11px; font-weight: var(--w-bold); }
.pos-delta { font-size: 12px; font-weight: var(--w-bold); }
.pos-delta.up { color: var(--danger); } .pos-delta.down { color: var(--success); } .pos-delta.flat { color: var(--q-medium); }
.ytb-subtotal { display: grid; gap: 12px; margin-top: 4px; padding-top: 9px; border-top: 1px dashed var(--divider); color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); }
.year-amt-group { margin-bottom: 16px; }
.year-amt-group .yag-title { padding: 4px 0 2px; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 14px; font-weight: var(--w-bold); }
.year-grand { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 8px; padding: 16px 20px; border-radius: 14px; background: var(--q-highlight-2); color: #fff; }
.year-grand .yg-label { color: rgba(255,255,255,0.82); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.year-grand .yg-val { color: #fff; font-family: var(--font-display); font-size: 23px; font-weight: var(--w-bold); }
.review-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; overflow: hidden; border: 1px solid var(--divider); border-radius: 12px; background: var(--divider); }
.review-item { display: flex; flex-direction: column; gap: 5px; padding: 14px 16px; background: #fff; }
.review-item.big { grid-column: 1 / -1; background: var(--surface-soft); }
.review-item .ri-label { color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.review-item .ri-val { color: var(--q-dark); font-size: 14px; }
.review-item .ri-total { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 24px; font-weight: var(--w-bold); }
.plaus { display: flex; align-items: flex-start; gap: 12px; margin-top: 22px; padding: 16px 18px; border-radius: 13px; }
.plaus.ok { background: #eef5dc; } .plaus.warn { background: #fbf1d8; }
.plaus-title { display: block; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.plaus-line { display: block; margin-top: 5px; color: var(--q-dark); font-size: 12.5px; }
.planner-done { max-width: 480px; margin: 0 auto; padding: 40px 20px; text-align: center; }
.planner-done .pd-mark { width: 72px; height: 72px; display: grid; place-items: center; margin: 0 auto 22px; border-radius: 20px; background: var(--success); color: #fff; }
.planner-done h3 { margin: 0 0 10px; color: var(--q-dark); font-family: var(--font-display); font-size: 22px; font-weight: var(--w-bold); }
.planner-done p { margin: 0 0 24px; color: var(--q-medium); font-size: 14px; line-height: 1.6; }
.imp-format-row { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; padding: 12px 14px; border-radius: 12px; background: var(--surface-soft); }
/* Die graue Erlaeuterung sass mit 0 px an der Auswahl darueber (gemessen im
   Rechnungs-Import) - sie trug nur einen Abstand nach UNTEN. Sie ist ein
   HINWEIS zu dem Feld darueber (sie nennt das Format, das aus der gewaehlten
   Quelle folgt), und dafuer sieht die Abstandsordnung 8 px vor
   (docs/css/structure/einstellungen_rhythmus.md: "Hinweis nach einem Feld -
   8 px, keine Linie"). Zusammen mit den 18 px darunter steht sie damit eng bei
   dem, was sie erklaert, und deutlich getrennt vom naechsten Block.

   Am Geschwisterselektor und nicht an der Klasse: Bei Importarten ohne
   Quellenauswahl (Themen, Budgets) ist die Zeile das ERSTE Element des
   Rumpfes, und dort waere ein Abstand nach oben falsch. */
.seg-field + .imp-format-row { margin-top: 8px; }
.imp-format-badge { flex-shrink: 0; padding: 4px 11px; border-radius: 999px; background: var(--q-highlight-2); color: #fff; font-family: var(--font-display); font-size: 12px; font-weight: var(--w-bold); letter-spacing: 0.04em; }
.imp-format-note { color: var(--q-medium); font-size: 12.5px; line-height: 1.45; }
.imp-textarea { min-height: 220px; padding: 14px 16px; resize: vertical; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 12.5px; line-height: 1.6; white-space: pre; }
.imp-file-row { display: flex; align-items: center; gap: 9px; margin-top: 8px; padding: 10px 14px; border: 1px dashed var(--divider); border-radius: 10px; color: var(--q-medium); font-size: 12px; }
/* Ablegen einer Datei (BAL-213): Die Zone zeigt, dass sie die Datei annimmt. */
.imp-file-row_aktiv { border-color: var(--q-highlight-3); background: color-mix(in srgb, var(--q-highlight-3) 8%, #fff); color: var(--q-highlight-2); }
.bright-dot { color: var(--q-bright); }
.imp-source-seg { display: flex; flex-direction: column; gap: 8px; }
.imp-source-opt { display: flex; align-items: flex-start; gap: 12px; width: 100%; padding: 12px 15px; border: 1px solid var(--divider); border-radius: 12px; background: #fff; text-align: left; transition: border-color var(--dur-fast), background var(--dur-fast); }
.imp-source-opt:hover { border-color: var(--q-medium); }
.imp-source-opt.on { border-color: var(--q-highlight-2); background: #fafbf3; }
.imp-mode { display: flex; align-items: flex-start; gap: 12px; width: 100%; padding: 12px 15px; border: 1px solid var(--divider); border-radius: 12px; background: #fff; text-align: left; transition: border-color var(--dur-fast), background var(--dur-fast); }
.imp-mode:hover { border-color: var(--q-medium); }
.imp-mode.on { border-color: var(--q-highlight-2); background: #fafbf3; }
.imp-radio { width: 18px; height: 18px; display: grid; place-items: center; margin-top: 1px; border: 2px solid var(--q-medium); border-radius: 50%; flex-shrink: 0; }
.imp-mode.on .imp-radio, .imp-source-opt.on .imp-radio { border-color: var(--q-highlight-2); }
.imp-radio-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--q-highlight-2); }
.imp-mode-label, .imp-mode-desc { display: block; }
.imp-mode-label { color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.imp-mode-desc { margin-top: 2px; color: var(--q-medium); font-size: 12px; }
.imp-summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.imp-stat { padding: 14px 16px; border: 1px solid var(--divider); border-radius: 12px; text-align: center; }
.imp-stat-num { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 26px; font-weight: var(--w-bold); line-height: 1; }
.imp-stat-label { margin-top: 7px; color: var(--q-medium); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.imp-stat-create { border-color: #ddebc0; background: #f2f7e6; } .imp-stat-create .imp-stat-num { color: #5a8516; }
.imp-stat-update { border-color: #d2deec; background: #eaf0f6; } .imp-stat-update .imp-stat-num { color: var(--q-highlight-2); }
.imp-stat-skip .imp-stat-num { color: var(--q-medium); }
.imp-stat-error { border-color: #f0d3d0; background: #fbedec; } .imp-stat-error .imp-stat-num { color: var(--danger); }
.import-ready-mark { background: var(--q-highlight-3) !important; }
.imp-preview-note { display: flex; align-items: center; gap: 8px; margin: 14px 0; color: var(--q-medium); font-size: 12.5px; }
.imp-table .imp-note { margin-top: 4px; color: var(--q-medium); font-size: 11px; }
.imp-table .imp-row-error { background: #fdf6f5; }
.imp-table .imp-row-skip { opacity: 0.62; }

/* Export & Import (Einstellungen) */
.exp-card { padding: 18px 20px; border: 1px solid #ececec; border-radius: 18px; background: #fff; box-shadow: 0 0 10px rgba(0,0,0,0.04); }
.admin-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 0; }
.admin-toggle-row + .admin-toggle-row { border-top: 1px solid var(--divider); }
.atr-title { color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.atr-desc { margin-top: 2px; color: var(--q-medium); font-size: 12px; }
.exp-presets { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; }
.exp-preset { display: flex; align-items: flex-start; gap: 11px; padding: 12px 14px; border: 1px solid var(--divider); border-radius: 12px; background: #fff; text-align: left; transition: border-color var(--dur-fast), background var(--dur-fast); }
.exp-preset:hover { border-color: var(--q-medium); }
.exp-preset.on { border-color: var(--q-highlight-2); background: #fafbf3; }
.exp-radio { width: 18px; height: 18px; display: grid; place-items: center; margin-top: 1px; border: 2px solid var(--q-medium); border-radius: 50%; flex-shrink: 0; }
.exp-preset.on .exp-radio { border-color: var(--q-highlight-2); }
.exp-radio-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--q-highlight-2); }
.exp-preset-txt { display: flex; flex-direction: column; min-width: 0; }
.exp-preset-label { color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.exp-preset-desc { margin-top: 2px; color: var(--q-medium); font-size: 12px; }
.exp-group + .exp-group { margin-top: 16px; }
.exp-group-label { margin-bottom: 9px; color: var(--q-medium); font-size: 10.5px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); }
.exp-ent-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 10px; }
.exp-ent { display: flex; align-items: center; gap: 10px; padding: 11px 13px; border: 1px solid var(--divider); border-radius: 12px; background: #fff; text-align: left; transition: border-color var(--dur-fast), background var(--dur-fast); }
.exp-ent:hover { border-color: var(--q-medium); }
.exp-ent.on { border-color: var(--q-highlight-2); background: #fafbf3; }
.exp-ent.auto { border-color: #d2deec; background: #f4f8fc; border-style: dashed; }
.exp-check { width: 18px; height: 18px; display: grid; place-items: center; border: 1.5px solid var(--q-medium); border-radius: 6px; flex-shrink: 0; background: #fff; }
.exp-ent.on .exp-check, .exp-ent.auto .exp-check { border-color: var(--q-highlight-2); background: var(--q-highlight-2); color: #fff; }
.exp-ent-ic { display: inline-flex; opacity: 0.72; flex-shrink: 0; }
.exp-ent-txt { display: flex; flex-direction: column; min-width: 0; }
.exp-ent-label { color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.exp-ent-count { margin-top: 1px; color: var(--q-medium); font-size: 11.5px; }
.exp-formats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; }
.exp-format { display: flex; flex-direction: column; gap: 6px; padding: 14px 15px; border: 1px solid var(--divider); border-radius: 12px; background: #fff; text-align: left; transition: border-color var(--dur-fast), background var(--dur-fast); }
.exp-format:hover { border-color: var(--q-medium); }
.exp-format.on { border-color: var(--q-highlight-2); background: #fafbf3; }
.exp-format-ic { display: inline-flex; opacity: 0.8; }
.exp-format-name { color: var(--q-dark); font-size: 14px; font-weight: var(--w-bold); }
.exp-format-desc { color: var(--q-medium); font-size: 12px; line-height: 1.4; }
.exp-actionbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 14px; padding: 16px 20px; border-radius: 16px; background: var(--q-highlight-2); color: #fff; }
.exp-actionbar-done { background: #3a7d34; }
.exp-summary { display: flex; align-items: center; gap: 14px; min-width: 0; }
.exp-summary-num { font-family: var(--font-display); font-size: 30px; font-weight: var(--w-bold); line-height: 1; }
.exp-summary-txt { font-size: 13px; opacity: 0.94; }
.exp-summary-txt .muted { opacity: 0.7; color: inherit; }
.exp-done { display: inline-flex; align-items: center; gap: 6px; padding: 6px 11px; border-radius: 999px; background: rgba(255,255,255,0.18); font-size: 12.5px; font-weight: var(--w-bold); }
.exp-actionbar .button_primary { background: #fff; color: var(--q-highlight-2); }
.exp-actionbar .button_primary[disabled] { opacity: 0.55; }
.exp-drop { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 34px 20px; border: 2px dashed var(--divider); border-radius: 14px; background: #fbfcf8; text-align: center; cursor: pointer; transition: border-color var(--dur-fast), background var(--dur-fast); }
.exp-drop:hover, .exp-drop.drag { border-color: var(--q-highlight-2); background: #f5f8ec; }
.exp-drop-ic { display: inline-flex; margin-bottom: 4px; }
/* Inhalt einer Schaltflaeche und damit Inline-Element (A11Y-024): Ein button
   darf keine Bloecke enthalten. display:block stellt die Darstellung her. */
.exp-drop-title { display: block; color: var(--q-dark); font-size: 14px; font-weight: var(--w-bold); }
.exp-drop-sub { display: block; color: var(--q-medium); font-size: 12.5px; }
.exp-error { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding: 10px 13px; border: 1px solid #f0d3d0; border-radius: 10px; background: #fbedec; color: var(--danger); font-size: 12.5px; }
.content_form { display: flex; flex: 1 1 auto; flex-direction: column; min-height: 0; }
.content_form_item_group { display: grid; gap: 16px 18px; }
.fform-grid { grid-template-columns: 1fr 1fr; }
.content_form_item_group_caption { color: var(--q-highlight-2); font-size: 11px; letter-spacing: var(--tracking-xwide); text-transform: uppercase; font-weight: var(--w-bold); }
.content_form_item { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ffield-full { grid-column: 1 / -1; }
.content_form_item_caption { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 24px; }
.content_form_item_caption label, .ffield-label { color: var(--q-medium); font-size: 11px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); }
.req { margin-left: 3px; color: var(--danger); }
.content_form_input, .finput { width: 100%; min-height: 40px; padding: 10px 12px; border: 2px solid var(--q-medium); border-radius: 0; background: #fff; color: var(--q-dark); font-family: var(--font-sans); font-size: 14px; transition: border-color var(--dur-fast) var(--ease-std); }
.content_form_input:focus, .finput:focus { border-color: var(--q-highlight-3); }
.ftextarea { resize: vertical; min-height: 72px; line-height: 1.5; }
.finput-adorn { position: relative; display: flex; align-items: center; }
.finput-adorn .finput { padding-right: 44px; }
.finput-suffix { position: absolute; right: 12px; color: var(--q-medium); font-size: 13px; font-weight: var(--w-bold); pointer-events: none; }
.ffield-hint { margin-top: 2px; color: var(--q-medium); font-size: 11.5px; line-height: 1.35; }
.fform-readout { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 13px 16px; border: 1px solid var(--divider); border-radius: 12px; background: #f8faf8; }
.fr-label { color: var(--q-medium); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.fr-val { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 18px; font-weight: var(--w-bold); }
.fr-sub { margin-left: 8px; color: var(--q-medium); font-family: var(--font-sans); font-size: 12px; font-weight: var(--w-regular); }
.budget-check { display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; border-radius: 12px; font-size: 12.5px; line-height: 1.45; }
.budget-check.ok { border: 1px solid rgba(75, 141, 76, 0.24); background: #eef7ee; color: #2f7130; }
.budget-check.warn { border: 1px solid rgba(192, 72, 72, 0.26); background: #f8e7e7; color: #963636; }
/* Sachlicher Hinweis ohne Wertung - zarter Grauton, damit er sich vom Formular
   absetzt, ohne wie eine Meldung auszusehen (BAL-104). */
.budget-check.neutral { border: 1px solid var(--divider); background: var(--surface-soft); color: var(--q-dark); }
.budget-check .bc-icon { flex: 0 0 auto; margin-top: 1px; }
.budget-check .bc-body { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 5px; }
.budget-check .bc-title { color: var(--q-dark); font-weight: var(--w-bold); }
.budget-check .bc-text { color: currentColor; }
.budget-check .bc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 7px; margin-top: 4px; }
.budget-check .bc-grid span { min-width: 0; padding: 7px 8px; border-radius: 9px; background: rgba(255,255,255,0.56); }
/* overflow-wrap: Ein Etikett aus EINEM langen Wort - "UNTERPOSITIONEN", durch
   Versalien und Sperrung noch breiter - konnte nicht umbrechen und lief aus
   seiner Kachel heraus (BAL-105, beim Ansehen des fertigen Blocks gefunden).
   min-width:0 an der Kachel allein reicht dafuer nicht: Es erlaubt dem
   Rasterfeld zu schrumpfen, nicht dem Wort zu brechen. */
.budget-check .bc-grid small { display: block; overflow-wrap: anywhere; color: var(--q-medium); font-size: 10px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.budget-check .bc-grid b { display: block; margin-top: 2px; color: var(--q-dark); font-family: var(--font-display); font-size: 13px; }
.budget-check .bc-grid b.ok { color: #2f7130; }
.budget-check .bc-grid b.danger { color: #963636; }
/* Verweis auf die bestehenden Beauftragungen der Position (BAL-099).
   Er sitzt unter den Kennzahlen und traegt die Farbe des Blocks, damit er
   nicht wie ein fremdes Bedienelement in der Meldung wirkt. */
.budget-check .bc-link { display: inline-flex; align-items: center; gap: 7px; align-self: flex-start; margin-top: 6px; padding: 6px 10px; border-radius: 9px; background: rgba(255,255,255,0.62); color: var(--q-dark); font-size: 12px; font-weight: var(--w-bold); text-decoration: none; transition: background var(--dur-fast) var(--ease-std); }
.budget-check .bc-link:hover { background: #fff; }
.budget-check .bc-link small { color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-light); }
/* Ohne Beauftragungen kein Verweis, sondern ein Satz - ein Link in eine
   leere Liste waere ein Versprechen ohne Deckung. */
.budget-check .bc-link-leer { align-self: flex-start; margin-top: 6px; color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-light); }
.filepick { display: flex; align-items: center; gap: 10px; width: 100%; }
.fform-toggle.on { background: var(--surface-active); border: 1px solid var(--divider-active); }
.cont-subfield { display: contents; }
.cont-subfield[hidden] { display: none; }
[data-cont-block][hidden] { display: none !important; }
.pay-section { display: flex; flex-direction: column; gap: 14px; }
.pay-auto-note { display: flex; align-items: flex-start; gap: 9px; padding: 11px 13px; border: 1px solid #d2deec; border-radius: 12px; background: #eaf0f6; color: var(--q-highlight-2); font-size: 12.5px; line-height: 1.45; }
.pay-auto-note .ui_icon { margin-top: 1px; flex-shrink: 0; }
.pay-editor { display: flex; flex-direction: column; gap: 16px; padding: 16px; border: 1px solid var(--divider); border-radius: 14px; background: var(--surface-soft); }
.pay-editor[hidden] { display: none !important; }
.pay-editor-top { display: flex; flex-wrap: wrap; gap: 18px 24px; align-items: flex-end; }
.pay-editor-top .content_form_item { flex: 1 1 220px; }
.pay-editor-top .content_form_item:last-child { flex: 0 1 160px; }
.pay-quick { display: flex; flex-direction: column; gap: 8px; padding: 0; }
.pay-section-bar { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.pay-section-bar[hidden] { display: none !important; }
.section-popout-bar { padding: 10px 12px; border: 1px dashed var(--divider); border-radius: 12px; background: #fff; }
.pay-section-hint { color: var(--q-medium); font-size: 12px; }
.planner-sub-label { color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.pay-quick-btns { display: flex; flex-wrap: wrap; gap: 6px; }
.pay-quick-btn { min-width: 34px; height: 34px; padding: 0 10px; border: 1px solid var(--q-medium); border-radius: 9px; background: #fff; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); transition: border-color var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.pay-quick-btn:hover { border-color: var(--q-highlight-2); color: var(--q-highlight-2); }
.pay-quick-btn.wide { min-width: 96px; }
.pay-rows { display: flex; flex-direction: column; gap: 7px; overflow-x: auto; }
.pay-row { display: grid; grid-template-columns: minmax(180px, 1fr) 140px 130px 116px 30px; gap: 10px; align-items: center; min-width: 680px; }
.pay-row-head { padding: 0 2px 2px; color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.pay-row-head .r { text-align: right; }
.pay-inp { width: 100%; min-height: 38px; padding: 8px 10px; border: 2px solid var(--q-medium); border-radius: 0; background: #fff; color: var(--q-dark); font-family: var(--font-sans); font-size: 13.5px; }
.pay-inp:focus { border-color: var(--q-highlight-3); }
.pay-inp.r { text-align: right; }
.pay-inp-amt { position: relative; display: flex; align-items: center; }
.pay-inp-amt .pay-inp { padding-right: 26px; }
.pay-eur { position: absolute; right: 9px; top: 50%; transform: translateY(-50%); color: var(--q-medium); font-size: 12.5px; font-weight: var(--w-bold); pointer-events: none; }
.pay-sel-wrap { position: relative; }
.pay-sel { appearance: none; -webkit-appearance: none; cursor: pointer; padding-right: 22px; }
.pay-sel-wrap::after { content: ""; position: absolute; right: 9px; top: 50%; width: 9px; height: 9px; margin-top: -5px; background: var(--q-medium); clip-path: polygon(50% 75%, 0 25%, 100% 25%); opacity: 0.45; pointer-events: none; }
.pay-editor-actions { display: flex; gap: 18px; align-items: center; }
.pay-readout { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 16px; border-radius: 12px; border: 1px solid var(--divider-active); background: var(--surface-active); }
.pay-readout.ok { border-color: var(--divider-active); background: var(--surface-active); }
.pay-readout.warn { border-color: #F0DCB4; background: #FBF4E4; }
.pay-readout > span:first-child { display: flex; align-items: baseline; gap: 10px; }
.pay-mismatch { color: #B07A12; font-size: 12.5px; font-weight: var(--w-bold); }
.pay-readout.ok .pay-mismatch { color: var(--success); }
.pay-empty { min-width: 680px; padding: 18px; }
.pay-editor-tl { display: flex; flex-direction: column; }
.pay-timeline { display: flex; flex-direction: column; gap: 10px; }
.pay-tl-chart { display: grid; gap: 6px; align-items: end; height: 132px; padding-top: 16px; }
.pay-timeline.compact .pay-tl-chart { height: 96px; }
.pay-tl-col { display: flex; flex-direction: column; align-items: center; height: 100%; min-width: 0; }
.pay-tl-val { height: 14px; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 10.5px; font-weight: var(--w-bold); white-space: nowrap; }
.pay-tl-bar-wrap { flex: 1; width: 100%; display: flex; align-items: flex-end; justify-content: center; }
.pay-tl-bar { width: 60%; max-width: 34px; min-height: 2px; display: flex; flex-direction: column-reverse; overflow: hidden; border-radius: 5px 5px 0 0; }
.pay-tl-seg { width: 100%; }
.pay-tl-x { display: flex; flex-direction: column; align-items: center; margin-top: 7px; line-height: 1.2; }
.pay-tl-q { color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); }
.pay-tl-y { color: var(--q-medium); font-size: 9.5px; opacity: 0.8; }
.pay-tl-legend { display: flex; flex-wrap: wrap; gap: 14px; padding-top: 6px; border-top: 1px dashed var(--divider); }
.pay-tl-leg { display: inline-flex; align-items: center; gap: 6px; color: var(--q-dark); font-size: 11.5px; }
.pay-tl-dot { width: 9px; height: 9px; border-radius: 3px; }
.pay-tl-empty { padding: 18px; }
.dedicated-form-modal { z-index: 132; width: min(900px, calc(100vw - 44px)); height: min(720px, calc(100vh - 44px)); }
.dedicated-form-modal[data-dedicated-modal="contingent"] { width: min(680px, calc(100vw - 44px)); height: auto; max-height: min(560px, calc(100vh - 44px)); }
.dedicated-form-modal.fullscreen { width: calc(100vw - 28px); height: calc(100vh - 28px); border-radius: 16px; }
/* Konkreter Wert statt `none`, damit die Hoehe beim Verlassen des Vollbilds
   laeuft statt zu springen - dieselbe Ursache wie bei .modal_window
   (Aufgabe BAL-080). */
.dedicated-form-modal[data-dedicated-modal="contingent"].fullscreen { max-height: calc(100vh - 44px); }
.dedicated-overlay { z-index: 131; }
.dedicated-body .pay-editor { border: 0; padding: 0; background: transparent; }
.dedicated-body .cont-subfield { display: block; }
.dedicated-body.fform-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 18px; }
.pay-detail-list .mini-item { cursor: default; }
.pay-detail-actions { gap: 10px; flex-shrink: 0; }
.pay-detail-select { width: 124px; min-height: 34px; padding-top: 6px; padding-bottom: 6px; }
/* Sechs Kacheln statt drei (BAL-107): Auftragswert, in Rechnung gestellt,
   bezahlt, offen, ueberfaellig und der noch nicht fakturierte Rest. Feste
   drei Spalten haetten die letzten drei abgeschnitten; auto-fit bricht sie
   nach Platz um. overflow-wrap am Etikett, weil "IN RECHNUNG GESTELLT" durch
   Versalien und Sperrung breit wird - derselbe Fall wie bei .bc-grid small
   (BAL-105). */
.pay-invoice-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 8px; margin-bottom: 10px; }
.pay-invoice-summary > div { min-width: 0; padding: 11px 13px; border: 1px solid var(--divider); border-radius: 11px; background: #fff; }
.pis-label { display: block; overflow-wrap: anywhere; color: var(--q-medium); font-size: 10px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.pis-sub { display: block; margin-top: 2px; color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-light); }
.pis-val { display: block; margin-top: 4px; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 16px; font-weight: var(--w-bold); }
.pis-val.ok { color: var(--success); }
.pis-val.warn { color: var(--warning); }
.pis-val.danger { color: var(--danger); }
.pis-val.muted { color: var(--q-medium); }
/* Der Balken sitzt direkt unter den Kacheln und gehoert zu ihnen. */
.pay-invoice-summary + .meter { margin: -2px 0 12px; }
.pay-invoice-item { cursor: pointer; }
.pay-invoice-actions { display: inline-flex; align-items: center; gap: 10px; flex-shrink: 0; }
.pay-invoice-actions .detail-inline-select-wrap { min-width: 118px; }
.fform-toggle { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 14px 16px; border: 1px solid var(--divider); border-radius: 12px; background: var(--surface-soft); }
.ft-text { cursor: pointer; }
/* Dieselbe Textspalte, aber ohne Schalter daneben: Im Abschnitt
   Benachrichtigungen eines bestehenden Datensatzes steht rechts eine
   Schaltflaeche, kein Schiebeschalter (BAL-169, Beanstandung 2026-09-10).
   Dann ist der Text auch kein `label`, und ein Zeigefinger auf ihm verspraeche
   eine Wirkung, die er nicht hat. */
.ft-text-fest { cursor: default; }
.ft-title { color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
/* --q-dark, NICHT --q-medium (gemessen 2026-09-10). `.ft-sub` steht nie auf
   Weiss: ausgeschaltet auf --surface-soft (#f1f2f2), eingeschaltet auf dem
   gruenen #F4F7EE von `.fform-toggle.on`. Gemessen ergab --q-medium (#bbbbbb)
   dort 1,79 : 1 beziehungsweise 1,77 : 1 - Dekorfarbe unter Text, derselbe
   Fehler wie schon dreimal in dieser Aufgabe. Auch --fg-2 traegt hier NICHT
   (4,05 : 1 und 4,19 : 1): Die Farbe besteht nur auf reinem Weiss. Die
   Abstufung zur Ueberschrift traegt jetzt Groesse und Gewicht, nicht
   Helligkeit. Betrifft alle sechs Schalterabschnitte der Formulare. */
.ft-sub { margin-top: 2px; color: var(--q-dark); font-size: 12px; line-height: 1.35; }
.switch { position: relative; display: inline-flex; width: 44px; height: 24px; flex: 0 0 auto; cursor: pointer; }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch .knob { position: absolute; inset: 0; border-radius: 999px; background: #d8ddd8; transition: background var(--dur-fast) var(--ease-std); }
.switch .knob::after { content: ''; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.22); transition: transform var(--dur-fast) var(--ease-std); }
.switch input:checked + .knob { background: var(--q-highlight-3); }
.switch input:checked + .knob::after { transform: translateX(20px); }
.switch input:focus-visible + .knob { outline: 2px solid var(--q-highlight-3); outline-offset: 3px; }
.switch[disabled] { cursor: default; opacity: 0.5; }
.switch.on .knob { background: var(--q-highlight-3); }
.switch.on .knob::after { transform: translateX(20px); }
.planner-toggle-row .switch { width: 46px; height: 26px; }
.fselect-wrap { position: relative; }
.fselect { appearance: none; -webkit-appearance: none; padding-right: 38px; cursor: pointer; }
.fselect-caret { position: absolute; right: 14px; top: 50%; width: 8px; height: 8px; transform: translateY(-65%) rotate(45deg); border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; color: var(--q-medium); pointer-events: none; transition: transform var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.fselect-coded .fselect { padding-left: 34px; border-color: color-mix(in srgb, var(--select-tone) 46%, var(--q-medium)); color: var(--select-tone); font-weight: var(--w-bold); background: color-mix(in srgb, var(--select-tone) 8%, #fff); }
.fselect-coded .fselect:focus { border-color: var(--select-tone); box-shadow: 0 0 0 3px color-mix(in srgb, var(--select-tone) 18%, transparent); }
.fselect-coded .fselect-caret { color: var(--select-tone); }
.fselect-dot { position: absolute; left: 13px; top: 50%; z-index: 1; width: 9px; height: 9px; border-radius: 50%; background: var(--select-tone); transform: translateY(-50%); pointer-events: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--select-tone) 18%, transparent); }
.fselect-tone-success { --select-tone: var(--success); }
.fselect-tone-warning { --select-tone: var(--warning); }
.fselect-tone-danger { --select-tone: var(--danger); }
.fselect-tone-info { --select-tone: var(--q-highlight-3); }
.fselect-tone-neutral { --select-tone: var(--q-medium); }
.fselect-option-success { color: var(--success); }
.fselect-option-warning { color: var(--warning); }
.fselect-option-danger { color: var(--danger); }
.fselect-option-info { color: var(--q-highlight-3); }
.fselect-option-neutral { color: var(--q-medium); }
.coded-select { position: relative; }
.coded-select-trigger { position: relative; display: flex; align-items: center; gap: 9px; width: 100%; min-height: 40px; padding: 10px 38px 10px 13px; border: 2px solid color-mix(in srgb, var(--select-tone) 46%, var(--q-medium)); border-radius: 0; background: color-mix(in srgb, var(--select-tone) 7%, #fff); color: var(--select-tone); font-size: 14px; font-weight: var(--w-bold); text-align: left; transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std), box-shadow var(--dur-fast) var(--ease-std); }
.coded-select-trigger:hover, .coded-select-trigger.open { border-color: var(--select-tone); background: #fff; }
.coded-select-trigger:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--select-tone) 18%, transparent); }
.coded-select-trigger .fselect-caret { color: var(--select-tone); }
.coded-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.coded-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--select-tone); flex: 0 0 9px; box-shadow: 0 0 0 3px color-mix(in srgb, var(--select-tone) 16%, transparent); }
.coded-select-pop { position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 95; overflow: hidden; border: 1px solid var(--divider); border-radius: 12px; background: #fff; box-shadow: 0 12px 32px rgba(0,0,0,0.16); }
.coded-select-list { max-height: 240px; overflow-y: auto; padding: 6px; }
.coded-select-option { display: flex; align-items: center; gap: 9px; width: 100%; padding: 9px 11px; border-radius: 9px; color: var(--q-dark); font-size: 13.5px; text-align: left; transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.coded-select-option .coded-dot { box-shadow: none; }
.coded-select-option:hover, .coded-select-option.on { background: color-mix(in srgb, var(--select-tone) 10%, #fff); color: var(--select-tone); }
.coded-select-option .fo-check { margin-left: auto; color: var(--select-tone); font-weight: var(--w-bold); }
.fsel { position: relative; }
.text-suggest { position: relative; }
.text-suggest-pop { top: calc(100% + 4px); }
.text-suggest-opt .fo-label { color: var(--q-dark); }
.fsel-trigger { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 40px; padding: 10px 38px 10px 12px; border: 2px solid var(--q-medium); border-radius: 0; background: #fff; color: var(--q-dark); font-size: 14px; text-align: left; transition: border-color var(--dur-fast) var(--ease-std); position: relative; }
.fsel-trigger:hover { border-color: var(--q-dark); }
.fsel-trigger.open { border-color: var(--q-highlight-3); }
.fsel-trigger.open .fselect-caret { transform: translateY(-35%) rotate(225deg); color: var(--q-highlight-3); }
.fsel-val, .fsel-ph { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fsel-val { color: var(--q-dark); }
.fsel-ph { color: var(--q-medium); }
.fsel-pop { position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 90; overflow: hidden; border: 1px solid var(--divider); border-radius: 12px; background: #fff; box-shadow: 0 12px 32px rgba(0,0,0,0.16); }
.fsel-search { display: flex; align-items: center; gap: 9px; padding: 10px 12px; border-bottom: 1px solid var(--divider); }
.fsel-search .ui_icon { color: var(--q-medium); opacity: 0.45; }
.fsel-search input { flex: 1; min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0; outline: 0; background: transparent; color: var(--q-dark); font-size: 13.5px; line-height: var(--lh-normal); }
.fsel-list { max-height: 240px; overflow-y: auto; padding: 6px; }
.fsel-opt { display: flex; align-items: center; gap: 8px; width: 100%; padding: 9px 11px; border-radius: 9px; color: var(--q-dark); font-size: 13.5px; text-align: left; transition: background var(--dur-fast) var(--ease-std); }
.fsel-opt[hidden] { display: none !important; }
.fsel-opt:hover, .fsel-opt.kbd-active { background: var(--surface-soft); }
.fsel-opt.on { background: var(--surface-active); }
.fsel-opt .fo-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--w-regular); }
.fsel-opt .fo-sub { margin-left: auto; flex-shrink: 0; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--q-medium); font-size: 11.5px; }
.fsel-opt.on .fo-sub { margin-left: 0; }
.fo-check { margin-left: auto; color: var(--q-highlight-2); opacity: 0.8; }
.fsel-empty { padding: 18px 12px; color: var(--q-medium); font-size: 12.5px; text-align: center; }
.button:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
.upload-drop { width: 100%; min-height: 180px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 32px 20px; border: 2px dashed var(--q-medium); border-radius: 14px; background: #fff; text-align: center; transition: border-color var(--dur-fast), background var(--dur-fast); }
.upload-drop:hover { border-color: var(--q-highlight-3); background: #fafbfa; }
.upload-drop.drag { border-color: var(--q-highlight-3); border-style: solid; background: var(--surface-active); }
.upload-drop .ud-ic { width: 52px; height: 52px; border-radius: 14px; background: var(--surface-soft); color: var(--q-highlight-2); display: grid; place-items: center; margin-bottom: 4px; }
.upload-drop .ud-title { color: var(--q-dark); font-size: 14.5px; font-weight: var(--w-bold); }
.upload-drop .ud-link { color: var(--q-highlight-3); text-decoration: underline; }
.upload-drop .ud-hint { color: var(--q-medium); font-size: 12px; }
.ud-files { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.ud-files-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 2px; color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.ud-file { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--divider); border-radius: 11px; background: #fff; }
.ud-file .doc-ic { width: 38px; height: 38px; }
.ud-file-meta { flex: 1; min-width: 0; }
.ud-file-name { display: block; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ud-file-size { display: block; margin-top: 2px; color: var(--q-medium); font-size: 11.5px; }

.ai_drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 70; display: flex; flex-direction: column; width: min(392px, 100vw); border-left: 1px solid var(--divider); background: #fff; box-shadow: -8px 0 28px rgba(0,0,0,0.08); clip-path: inset(0 0 0 100%); visibility: hidden; transition: clip-path var(--dur-base) var(--ease-std), visibility 0s linear var(--dur-base); }
.ai_drawer_open { clip-path: inset(0 0 0 -40px); visibility: visible; transition: clip-path var(--dur-base) var(--ease-std), visibility 0s; }
/* Geschlossen liegt die Schublade an ihrem Platz und ist weggeschnitten
   (clip-path), statt per translateX(100%) RECHTS NEBEN dem Bild zu warten.
   GEMESSEN am 2026-10-04 (Telefon-Emulation 390 px, isMobile): Die
   verschobene Schublade (390-780 px) zaehlte als Seiteninhalt, der Browser
   verbreiterte die Seite auf 785 px und zoomte heraus - die Telefonansicht
   (bis 780 px) griff nicht, Scheinwerfer und Karte der Bereichshilfe sassen
   neben dem sichtbaren Ausschnitt. clip-path aendert den Ueberlauf nicht.
   -40px links: Platz fuer den Schatten. */
.ai_drawer_header { padding: 18px 20px; border-bottom: 1px solid var(--divider); }
.ai_drawer_title { margin: 0; font-family: var(--font-display); font-size: 15px; color: var(--q-highlight-2); }
.ai_drawer_body { flex: 1; overflow: auto; display: flex; flex-direction: column; gap: 14px; padding: 18px 20px; }
.ai_drawer_message { max-width: 92%; padding: 12px 14px; border-radius: 14px; font-size: 13.5px; }
/* Zeilenumbrueche nur in der FRAGE: Sie ist reiner Text, und eine mit
   Umschalt+Enter eingegebene Zeile soll erhalten bleiben. Die Antwort traegt
   erzeugtes Markup (Absaetze, Aufzaehlungen); dort machte pre-wrap jede
   Einrueckung der Vorlage zu sichtbarem Leerraum (BAL-118). */
.ai_drawer_message_user { align-self: flex-end; max-width: 82%; background: var(--q-highlight-2); color: #fff; border-bottom-right-radius: 4px; white-space: pre-wrap; }
.ai_drawer_message_assistant { align-self: flex-start; background: var(--surface-soft); color: var(--q-dark); border-bottom-left-radius: 4px; }
.ai_drawer_footer { display: flex; gap: 8px; padding: 14px 16px; border-top: 1px solid var(--divider); }
.ai_drawer_input { flex: 1; min-height: 42px; max-height: 120px; resize: vertical; padding: 10px 14px; border: 1px solid var(--divider); border-radius: 18px; }
.ai_drawer_input:focus { border-color: var(--q-highlight-3); }

/* ── Assistent: Herkunft, Schnelleinstellungen, Wartezustand (BAL-115) ───────
   Uebernommen aus der Nachbaranwendung Mission Control: Die Ebene steht als
   Abzeichen an der Antwort, damit erkennbar bleibt, WIE sie zustande kam.
   Praefixreihe `ai_drawer_*` fortgesetzt; die kurzen `ai-*` gehoeren zum
   Innenleben einer Nachricht und folgen der kurzen Reihe (POL-001), wie
   `bc-*` innerhalb von `.budget-check`. */
.ai_drawer_head_actions { display: inline-flex; align-items: center; gap: 4px; }
.ai_drawer_message_error { border-left: 3px solid var(--danger); background: rgba(192,72,72,0.08); color: var(--q-dark); }
/* Die Auszeichnung des Modells: Aufzaehlung und Absaetze setzen alles selbst,
   was sie brauchen - die globalen p- und ul-Regeln wirken sonst hinein. */
.ai_drawer_message p { margin: 0 0 6px; font-size: 13.5px; font-weight: var(--w-light); line-height: 1.55; color: inherit; }
.ai_drawer_message p:last-child { margin-bottom: 0; }
.ai-liste { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 7px; }
.ai-liste li { position: relative; padding-left: 12px; font-size: 13.5px; font-weight: var(--w-light); line-height: 1.5; }
.ai-liste li::before { content: ""; position: absolute; left: 0; top: 8px; width: 4px; height: 4px; border-radius: 50%; background: var(--q-highlight-3); }
.ai-liste strong { font-weight: var(--w-bold); }
/* Kennung als Verweis: erkennbar anklickbar, aber kein Knopf im Fliesstext. */
/* Abgebrochene oder unvollstaendige Antwort. Sie bleibt stehen - sie ist
   gelesen worden -, darf aber nicht aussehen wie eine vollstaendige: Ein
   abgeschnittener Satz kann fachlich falsch sein (BAL-121). */
.ai_drawer_message_angehalten { border-left: 3px solid var(--q-highlight-1); }
.ai-unvollstaendig { display: flex; align-items: center; gap: 5px; margin-top: 8px; color: var(--q-medium); font-size: 11px; font-weight: var(--w-bold); }
.ai-unvollstaendig .ui_icon { flex-shrink: 0; }

/* Verweis auf einen Datensatz. Seit BAL-121 traegt er den NAMEN statt der
   rohen Kennung und davor das Sinnbild seiner Art - er soll sich lesen wie
   ein Wort im Satz, nicht wie ein Datenbankschluessel. Deshalb erbt er die
   Schriftgroesse der Zeile und traegt nur eine leichte Flaeche. */
.ai-ref { display: inline-flex; align-items: center; gap: 3px; padding: 1px 6px; border: 0; border-radius: 5px; background: rgba(21,165,181,0.14); color: var(--q-highlight-2); font: inherit; font-weight: var(--w-bold); cursor: pointer; vertical-align: baseline; text-align: left; }
.ai-ref .ui_icon { flex-shrink: 0; opacity: 0.75; }
.ai-ref:hover { background: rgba(21,165,181,0.26); }
.ai-herkunft { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--divider); color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.ai-ebene { padding: 2px 7px; border-radius: 999px; background: var(--q-highlight-2); color: #fff; }
/* .ai-sprech traegt seit BAL-165 die Form von .ai-kopieren (siehe dort).
   Die frueheren Pillenregeln sind entfallen. */
/* Wartezustand: Der Assistent wartet nicht anders als der Rest der Anwendung. */
.ai-wartet { display: flex; align-items: center; gap: 9px; color: var(--q-medium); font-size: 12.5px; }
/* Leerzustand: eine Aussage und Vorschlaege - kein Beispielinhalt, der wie
   eine echte Antwort aussaehe. */
.ai-leer { color: var(--q-medium); font-size: 13px; }
.ai-leer p { margin: 0 0 10px; font-size: 13px; font-weight: var(--w-light); color: var(--q-medium); }
.ai-vorschlaege { display: flex; flex-direction: column; gap: 6px; }
.ai-vorschlag { padding: 9px 12px; border: 1px solid var(--divider); border-radius: 11px; background: #fff; color: var(--q-dark); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; }
.ai-vorschlag:hover { border-color: var(--q-highlight-3); }
/* Hinweis am Fuss: Die Antworten sind Auskuenfte, keine Entscheidungen. */
.ai_drawer_hinweis { display: flex; align-items: flex-start; gap: 7px; padding: 10px 16px 14px; border-top: 1px solid var(--divider); color: var(--q-medium); font-size: 11px; font-weight: var(--w-light); line-height: 1.45; }


/* ── Assistent: Kopf, Eingabezeile, Aufklappmenue (BAL-118) ─────────────────
   Angeglichen an die Nachbaranwendung Mission Control. Drei Unterschiede
   waren beanstandet: Die Schnelleinstellungen lagen als Band unter dem Kopf
   statt als Aufklappmenue am Zahnrad der Eingabezeile, der Kopf trug kein
   Zeichen, und der Senden-Knopf war eine beschriftete Schaltflaeche statt des
   runden Knopfes neben dem Feld. */
.ai_drawer_header { display: flex; align-items: center; gap: 12px; }
.ai-mark { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 9px; background: var(--q-highlight-2); display: grid; place-items: center; }
.ai-mark .ui_icon { filter: brightness(0) invert(1); }
.ai_drawer_title { flex: 1; min-width: 0; }
.ai-head-btn { width: 30px; height: 30px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--q-medium); display: grid; place-items: center; cursor: pointer; }
.ai-head-btn:hover { background: var(--surface-soft); color: var(--q-dark); }

/* Die Eingabezeile: Zahnrad, Feld, runder Senden-Knopf - in dieser Folge.
   `position: relative` ist der Bezugspunkt des Aufklappmenues. */
.ai_drawer_footer { align-items: flex-end; position: relative; }
.ai_drawer_input { min-height: 38px; max-height: 140px; resize: none; overflow-y: auto; padding: 9px 14px; font-size: 13px; line-height: 1.5; }
/* Auf Touch-Geraeten 16 px - die allgemeine Regel am Dateianfang (BAL-220). */
.ai-opt-wrap { position: relative; flex-shrink: 0; }
.ai-gear { width: 36px; height: 36px; padding: 0; border: 1px solid var(--divider); border-radius: 50%; background: #fff; color: var(--q-medium); display: grid; place-items: center; position: relative; cursor: pointer; transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std); }
.ai-gear:hover, .ai-gear.active { border-color: var(--q-highlight-3); background: var(--surface-soft); }
/* Der Punkt sagt: Hier ist etwas von der Vorgabe abgewichen. Ohne ihn muesste
   man das Menue oeffnen, um zu sehen, ob etwas anders eingestellt ist. */
.ai-gear.dirty::after { content: ""; position: absolute; top: 2px; right: 2px; width: 8px; height: 8px; border-radius: 50%; background: var(--q-highlight-1); border: 1.5px solid #fff; }
.ai-send { width: 36px; height: 36px; padding: 0; border: 0; border-radius: 50%; background: var(--q-highlight-2); color: #fff; display: grid; place-items: center; flex-shrink: 0; cursor: pointer; }
.ai-send .ui_icon { filter: brightness(0) invert(1); }
.ai-send:hover { background: var(--q-highlight-3); }
/* Waehrend die Antwort laeuft, ist derselbe Knopf der Abbruch (BAL-121):
   gleiche Stelle, gleiche Groesse - der Daumen trifft dieselbe Flaeche. */
.ai-send-stop { background: var(--q-linie); }
.ai-send-stop:hover { background: var(--danger); }

/* Das Aufklappmenue oeffnet nach OBEN: Es haengt an der Fusszeile, und nach
   unten waere kein Platz. */
.ai-pop { position: absolute; bottom: calc(100% + 10px); left: 0; z-index: 5; width: 320px; max-width: calc(100vw - 40px); overflow: hidden; border: 1px solid var(--divider); border-radius: 16px; background: #fff; box-shadow: 0 12px 32px rgba(0,0,0,0.16); animation: ai-pop-in var(--dur-fast) var(--ease-std); }
@keyframes ai-pop-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
.ai-pop-head { display: flex; align-items: flex-start; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--divider); }
.ai-pop-title { font-family: var(--font-display); font-size: 13.5px; font-weight: var(--w-bold); color: var(--q-highlight-2); }
.ai-pop-sub { margin-top: 2px; color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-light); line-height: 1.4; }
.ai-pop-x { flex-shrink: 0; margin-left: auto; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--q-medium); display: grid; place-items: center; cursor: pointer; }
.ai-pop-x:hover { background: var(--surface-soft); }
.ai-pop-body { display: flex; flex-direction: column; gap: 14px; max-height: 60vh; overflow-y: auto; padding: 14px 16px; }
.ai-pop-row { display: flex; flex-direction: column; gap: 5px; }
.ai-pop-row-toggle { flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; }
.ai-pop-toggle-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ai-pop-label { color: var(--q-dark); font-size: 12px; font-weight: var(--w-bold); }
.ai-pop-hint { color: var(--q-medium); font-size: 11px; font-weight: var(--w-light); line-height: 1.4; }
/* Gruppenueberschrift: Die Gruppen unterscheiden sich in ihrer Reichweite,
   das muss ablesbar sein. */
.ai-pop-group { padding-bottom: 6px; margin-bottom: -4px; border-bottom: 1px solid var(--divider); color: var(--q-medium); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.ai-pop-group:not(:first-child) { margin-top: 6px; }
.ai-pop-group-sub { font-weight: var(--w-light); text-transform: none; letter-spacing: 0; }
.ai-pop-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; padding: 12px 16px; border-top: 1px solid var(--divider); background: var(--surface-soft); }
.ai-pop-mehr { margin-left: auto; white-space: nowrap; padding: 0; border: 0; background: none; color: var(--q-highlight-2); font: inherit; font-size: 11.5px; font-weight: var(--w-bold); text-align: right; cursor: pointer; }
.ai-pop-mehr:hover { text-decoration: underline; }

/* Schiebeschalter - dieselbe Form wie im Vorbild. Ein Knopf mit role="switch"
   statt eines Kontrollkaestchens: Er traegt seinen Zustand selbst und braucht
   keine Beschriftung daneben, um bedienbar zu sein. */
.ai-switch { position: relative; flex-shrink: 0; width: 42px; height: 24px; padding: 0; border: 0; border-radius: 999px; background: var(--q-linie); cursor: pointer; transition: background var(--dur-fast) var(--ease-std); }
.ai-switch.on { background: var(--q-highlight-1); }
.ai-switch:disabled { opacity: 0.4; cursor: default; }
.ai-switch-knob { position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.25); transition: transform var(--dur-fast) var(--ease-std); pointer-events: none; }
.ai-switch.on .ai-switch-knob { transform: translateX(18px); }
/* Laufende Sprachausgabe: Der Knopf zeigt, dass gerade gesprochen wird, und
   haelt auf denselben Klick an. Ohne diese Rueckmeldung war nicht zu erkennen,
   ob die Ausgabe ueberhaupt begonnen hat (BAL-118). */
@media (prefers-reduced-motion: reduce) { .ai-pop { animation: none; } }



/* Die entstehende Antwort (BAL-120). Solange nur der Fortschritt dasteht,
   ist die Blase eine Zeile; sobald Text kommt, wird sie zur Antwort. Der Text
   steht waehrend des Aufbaus als reiner Text - halbfertiges Markup saehe
   kaputt aus -, deshalb hier die Zeilenumbrueche. */
/* Der Ablauf steht UNTER dem entstehenden Text und bleibt sichtbar, bis die
   Antwort steht. Bis BAL-121 verschwand er, sobald Text kam - und damit sah
   niemand die Qualitaetspruefung, die NACH der Antwort laeuft und eine
   bereits gezeigte Fassung noch verwerfen kann. */
.ai-strom-fortschritt { display: block; color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-light); }
.ai-strom-text:empty { display: none; }
.ai-strom-text { display: block; white-space: pre-wrap; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-light); line-height: 1.55; }
/* Mit Text ist die Blase keine Wartezeile mehr: Die Punkte bleiben, ruecken
   aber ueber den Text statt neben ihn. */
.ai-wartet:has(.ai-strom-text:not(:empty)) { display: block; }

/* ── Assistent: Spracheingabe (BAL-119) ─────────────────────────────────────
   Mikrofonknopf in der Eingabezeile und die Statuszeile darueber. Aufbau und
   Masse wie im Vorbild Mission Control; der Pegelbalken wird zur Laufzeit
   direkt beschrieben und nicht ueber ein Neuzeichnen gesetzt. */
.ai-mic { width: 36px; height: 36px; padding: 0; border: 1px solid var(--divider); border-radius: 50%; background: #fff; color: var(--q-medium); display: grid; place-items: center; flex-shrink: 0; cursor: pointer; transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std); }
.ai-mic:hover { border-color: var(--q-highlight-3); }
.ai-mic-an { border-color: var(--danger); background: var(--danger); }
.ai-mic-punkt { width: 12px; height: 12px; border-radius: 50%; background: #fff; animation: ai-puls 1.1s var(--ease-std) infinite; }
.ai-listening .ai-mic-punkt { background: var(--danger); }
@keyframes ai-puls { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.ai-listening { display: flex; align-items: center; gap: 10px; flex-shrink: 0; padding: 9px 16px; border-top: 1px solid var(--divider); background: var(--surface-soft); }
.ai-listening-text { min-width: 0; color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-light); }
.ai-listening-stop { margin-left: auto; white-space: nowrap; padding: 3px 9px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; color: var(--q-dark); font: inherit; font-size: 11px; font-weight: var(--w-bold); cursor: pointer; }
.ai-listening-stop:hover { border-color: var(--q-highlight-3); }
/* Pegel: 70 px reichen, um Sprechen von Stille zu unterscheiden - mehr waere
   eine Messanzeige, und gemessen wird hier nichts. */
.ai-meter { width: 70px; height: 6px; flex-shrink: 0; overflow: hidden; border-radius: 999px; background: #fff; }
.ai-meter-fill { display: block; height: 100%; border-radius: 999px; background: var(--q-highlight-3); transition: width 0.08s linear; }
.ai-vad { white-space: nowrap; color: var(--q-highlight-1); font-size: 10.5px; font-weight: var(--w-bold); }
.ai-mic-error { display: flex; align-items: center; gap: 8px; flex-shrink: 0; padding: 8px 16px; border-top: 1px solid var(--divider); background: rgba(192,72,72,0.08); color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-light); line-height: 1.4; }
.ai-mic-error .ui_icon { flex-shrink: 0; }
@media (prefers-reduced-motion: reduce) { .ai-mic-punkt { animation: none; } }




/* ── Assistent: Quellenkarten unter der Antwort (BAL-127) ───────────────────
   Die Verweise IM Antworttext fuehren zu einzelnen Datensaetzen. Diese Karten
   beantworten die andere Frage: Worauf beruht die Antwort ueberhaupt?
   Waagerecht scrollend, weil die Karten nebeneinander vergleichbar sind und
   eine senkrechte Liste die Antwort darunter aus dem Blick schoebe. */
.ai-quellen-schalter { display: inline-flex; align-items: center; gap: 3px; padding: 2px 7px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; color: var(--q-dark); font: inherit; font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; cursor: pointer; }
.ai-quellen-schalter:hover { border-color: var(--q-highlight-3); }
.ai-quellen-schalter.on { border-color: var(--q-highlight-2); background: var(--q-highlight-2); color: #fff; }
.ai-quellen-schalter.on .ui_icon { filter: brightness(0) invert(1); }
.ai-quellen { display: flex; gap: 8px; margin: 9px 0 0; padding: 0 0 6px; list-style: none; overflow-x: auto; scroll-snap-type: x proximity; }
/* Die Karte hat eine feste Breite: Nur so entsteht der Eindruck einer Reihe,
   durch die man blaettert - bei mitwachsender Breite waere es eine Tabelle. */
.ai-quelle { flex: 0 0 208px; scroll-snap-align: start; display: flex; flex-direction: column; gap: 5px; padding: 10px 11px; border: 1px solid var(--divider); border-radius: 11px; background: #fff; }
.ai-quelle-kopf { display: flex; flex-direction: column; gap: 1px; }
.ai-quelle-titel { color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-bold); line-height: 1.3; }
.ai-quelle-mass { color: var(--q-medium); font-size: 10px; font-weight: var(--w-light); }
/* Der Auszug bricht nach vier Zeilen ab: Die Karte soll erkennen lassen, WAS
   in der Quelle steht, und sie nicht ein zweites Mal abbilden. */
.ai-quelle-auszug { display: -webkit-box; -webkit-line-clamp: 4; line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; color: var(--q-medium); font-size: 11px; font-weight: var(--w-light); line-height: 1.45; }
.ai-quelle-link { display: inline-flex; align-items: center; gap: 3px; margin-top: auto; padding: 0; border: 0; background: none; color: var(--q-highlight-2); font: inherit; font-size: 10.5px; font-weight: var(--w-bold); cursor: pointer; }
.ai-quelle-link:hover { text-decoration: underline; }

/* ── Assistent: Zusammensetzung des Kontexts (BAL-126) ──────────────────────
   Was mit jeder Frage an die Ausfuehrungsschicht geht - ein Balken ueber dem
   Zeichenbudget, darunter je eine Zeile mit Schalter, Beschreibung und
   gemessener Groesse. Der Balken ist die Komponente `meter`; sie traegt seit
   BAL-126 auch andere Einheiten als Euro. */
.ai-kontext { display: flex; flex-direction: column; gap: 12px; padding: 14px 0 4px; }
.ai-kontext-kopf { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.ai-kontext-summe { color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.ai-kontext-hinweis { color: var(--q-medium); font-size: 11px; font-weight: var(--w-light); }
.ai-kontext-zeilen { display: flex; flex-direction: column; }
.ai-kontext-zeile { display: flex; align-items: flex-start; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--divider); }
.ai-kontext-zeile:last-child { border-bottom: 0; }
/* Ein abgeschalteter Block bleibt lesbar, tritt aber zurueck: Er ist eine
   Entscheidung, kein Fehler. */
.ai-kontext-zeile-aus .ai-kontext-titel, .ai-kontext-zeile-aus .ai-kontext-sub { color: var(--q-medium); }
.ai-kontext-marke { flex-shrink: 0; padding-top: 4px; }
.ai-kontext-leer { background: transparent; border: 1px solid var(--divider); }
.ai-kontext-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ai-kontext-titel { color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); }
.ai-kontext-sub { max-width: 62ch; color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-light); line-height: 1.45; }
.ai-kontext-mass { flex-shrink: 0; text-align: right; color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-bold); white-space: nowrap; }
.ai-kontext-quellen { display: block; color: var(--q-medium); font-weight: var(--w-light); }
/* Vier Segmentfarben fuer die Kontextbloecke. Sie sind keine Statusfarben -
   ein Block ist weder gut noch schlecht -, deshalb die neutralen Toene der
   Marke statt Gruen/Gelb/Rot. */
.meter-seg-ctx1, .meter-chip-ctx1 { background: var(--q-highlight-2); }
.meter-seg-ctx2, .meter-chip-ctx2 { background: var(--q-highlight-3); }
.meter-seg-ctx3, .meter-chip-ctx3 { background: var(--q-highlight-1); }
.meter-seg-ctx4, .meter-chip-ctx4 { background: var(--q-highlight-5); }
@media (max-width: 780px) {
  .ai-kontext-zeile { flex-wrap: wrap; }
  .ai-kontext-mass { text-align: left; }
}

/* ── Komponente: ladeanzeige (BAL-122) ──────────────────────────────────────
   Umsetzung der Entwurfsvariante QZ-L09 („Punkte") aus
   docs/design/loading_animations/ - drei Punkte in den Markenfarben, versetzt
   im Takt. Der Entwurf beschreibt sie als „kompakt genug fuer Buttons,
   Tabellenzeilen und Formulare"; genau das ist ihr Einsatzbereich: die
   Wartestellen der Anwendung.

   Die Werte sind dem Entwurf entnommen und gegen die Token geprueft: Lime
   #c6d31c, Petrol #15a5b5, Navy #10314e stehen dort wie hier, deshalb Token
   statt Literale. Takt 1,2 s, Versatz 0,15 s je Punkt, Hub 0,7 der
   Punktgroesse - alles wie in QZ-L09.

   WARUM UEBERHAUPT BEWEGUNG. Ein stehendes Wort ist von einem
   stehengebliebenen Bildschirm nicht zu unterscheiden. Die Anzeige behauptet
   dabei bewusst KEINEN Fortschritt - kein Balken, keine Prozentzahl. Wie lange
   ein Abruf dauert, weiss niemand; eine Zahl waere erfunden.

   DREI VORGAENGERFASSUNGEN sind in ihr aufgegangen (gemessen vor dem Umbau):
     - `.ai-punkte` mit `@keyframes ai-blink`: dieselbe Anzeige, aber einfarbig
       petrol, 5 px und mit eigenem Takt (1,05 s / 0,18 s).
     - `.pg-spinner` mit `@keyframes pg-dreh`: ein drehender Ring beim
       Nachladen von Listen - eine zweite Formensprache fuer denselben Zustand.
     - Drei reine Textstellen („Einstellungen werden geladen…") mit einem
       stehenden Info-Symbol davor.
   Vier Formen fuer einen Zustand waren drei zu viel.

   NICHT AUF GEFUELLTEM GRUND. In einer navyfarbenen Schaltflaeche waere der
   Navy-Punkt unsichtbar; von drei Markenfarben blieben zwei. Solche Knoepfe
   behalten ihren Wortwechsel.

   Uebernommen aus der Nachbaranwendung Mission Control, wo QZ-L09 bereits als
   Komponente steht; die Token sind in beiden Anwendungen dieselben.
   Doku: docs/css/structure/ladeanzeige.md, Blueprint:
   blueprints/blueprint_ladeanzeige.html */

/* `--ladeanzeige-punkt` ist der EINZIGE Groessenwert: Abstand, Bahnhoehe und
   Hub leiten sich daraus ab. Eine weitere Groesse kostet damit eine Zeile,
   nicht einen zweiten Satz Regeln. */
.ladeanzeige { --ladeanzeige-punkt: 8px; display: flex; align-items: center; gap: 10px; }
/* `align-items: flex-end` verankert die Punkte unten: Der Hub geht nach oben,
   und die Reihe behaelt ihre Hoehe, statt die Zeile bei jedem Takt zu schieben. */
.ladeanzeige_punkte { display: flex; align-items: flex-end; gap: calc(var(--ladeanzeige-punkt) * 0.9); height: calc(var(--ladeanzeige-punkt) * 1.7); flex-shrink: 0; }
/* Reihenfolge Lime · Petrol · Navy wie im Entwurf. Der Versatz erzeugt die
   Welle; bei gleichem Start blinkten alle drei zugleich. */
.ladeanzeige_punkt { width: var(--ladeanzeige-punkt); height: var(--ladeanzeige-punkt); border-radius: 50%; animation: ladeanzeige-punkt calc(1.2s / var(--q-loader-speed, 1)) var(--ease-std) infinite; }
.ladeanzeige_punkt:nth-child(1) { background: var(--q-highlight-1); }
.ladeanzeige_punkt:nth-child(2) { background: var(--q-highlight-3); animation-delay: calc(0.15s / var(--q-loader-speed, 1)); }
.ladeanzeige_punkt:nth-child(3) { background: var(--q-highlight-2); animation-delay: calc(0.3s / var(--q-loader-speed, 1)); }
@keyframes ladeanzeige-punkt {
  0%, 100% { transform: translateY(0); opacity: 0.35; }
  40% { transform: translateY(calc(var(--ladeanzeige-punkt) * -0.7)); opacity: 1; }
}
/* Die Beschriftung setzt ihre Schriftwerte ausdruecklich: Der Baustein soll
   nicht davon abhaengen, in welchem Behaelter er landet. */
.ladeanzeige_text { margin: 0; font-family: var(--font-sans); font-size: 12.5px; font-weight: var(--w-light); line-height: 1.4; color: var(--q-medium); }
/* Drei unabhaengige Achsen, deshalb drei data-Attribute statt einer
   Modifier-Kette: Lage im Textfluss, Groesse, Herkunft der Schriftwerte. */
.ladeanzeige[data-lage="inline"] { display: inline-flex; vertical-align: middle; }
.ladeanzeige[data-lage="mittig"] { justify-content: center; }
.ladeanzeige[data-groesse="gross"] { --ladeanzeige-punkt: 10px; gap: 12px; }
.ladeanzeige[data-groesse="klein"] { --ladeanzeige-punkt: 6px; gap: 8px; }
/* Ton: Die Beschriftung uebernimmt Schrift und Farbe ihrer Umgebung - fuer
   Stellen, an denen die Schrift bereits gesetzt ist und eine graue
   Beschriftung mitten darin deaktiviert aussaehe. */
.ladeanzeige[data-ton="erbt"] .ladeanzeige_text { font: inherit; color: inherit; }
/* Ohne Bewegung bleibt der Zustand erkennbar: Die drei Punkte stehen in voller
   Deckkraft da. Eine unsichtbare Ladeanzeige waere schlechter als eine
   unbewegte. */
@media (prefers-reduced-motion: reduce) {
  .ladeanzeige_punkt { animation: none; opacity: 1; }
}

/* ── Komponente: ki_kennzeichnung (BAL-117) ─────────────────────────────────
   Kennzeichnung des KI-Systems nach dem einheitlichen Schema der Verwaltung
   (Digital Austria) und der Transparenzpflicht nach Art. 50 KI-VO
   (EU) 2024/1689. Aufbau, Klassenlogik und Optik nach dem Vorbild der
   Nachbaranwendung Mission Control; die Gestaltungswerte sind in beiden
   Anwendungen dieselben, deshalb liess sich die Optik nahezu unveraendert
   uebernehmen.

   Drei Auspraegungen desselben Sachverhalts:
     ki_kennzeichnung_bar  — Leiste an der Nutzungsstelle
     ki_kennzeichnung      — Tafel im Dialog
     ki_kennzeichnung_help — dieselbe Tafel als Erlaeuterung

   Eigenstaendige Komponente, deshalb durchgaengiges Praefix nach ucs.md.
   Doku: docs/css/structure/ki_kennzeichnung.md

   Das gemeinsame Zeichen traegt jede Auspraegung; die Groesse ist der einzige
   Unterschied und wird ueber data-size gesteuert, damit nicht drei Varianten
   desselben Kreises nebeneinanderstehen. */
.ki_kennzeichnung_mark {
  flex: 0 0 auto; border-radius: 50%;
  background: var(--q-highlight-1); color: var(--q-highlight-2);
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: var(--w-bold); letter-spacing: 0;
}
.ki_kennzeichnung_mark[data-size="md"] { width: 22px; height: 22px; font-size: 9px; }
.ki_kennzeichnung_mark[data-size="lg"] { width: 38px; height: 38px; font-size: 13px; }
.ki_kennzeichnung_mark[data-size="xl"] { width: 44px; height: 44px; font-size: 16px; }

/* Leiste: schmal, unmittelbar unter dem Kopf, dauerhaft ueber dem Verlauf.
   Sie ist die eigentliche Kennzeichnung im Sinne der Transparenzpflicht —
   sichtbar, ohne dass jemand danach sucht. */
.ki_kennzeichnung_bar {
  display: flex; align-items: center; gap: 9px; flex-shrink: 0;
  padding: 9px 20px; background: var(--surface-soft);
  border-bottom: 1px solid var(--divider);
}
.ki_kennzeichnung_bar_text {
  min-width: 0; color: var(--q-dark);
  font-size: 11.5px; font-weight: var(--w-light); line-height: 1.4;
}
.ki_kennzeichnung_bar_text b { color: var(--q-highlight-2); font-weight: var(--w-bold); }
.ki_kennzeichnung_bar_control {
  margin-left: auto; white-space: nowrap;
  padding: 3px 9px; border: 1px solid var(--divider); border-radius: 999px;
  background: #fff; color: var(--q-dark);
  font: inherit; font-size: 11px; font-weight: var(--w-bold); cursor: pointer;
}
.ki_kennzeichnung_bar_control:hover { border-color: var(--q-highlight-3); }

/* Tafel */
.ki_kennzeichnung { display: flex; flex-direction: column; gap: 16px; }
.ki_kennzeichnung_header { display: flex; align-items: flex-start; gap: 13px; }
.ki_kennzeichnung_header_text { min-width: 0; }
.ki_kennzeichnung_eyebrow {
  color: var(--q-highlight-2); font-size: 10.5px; font-weight: var(--w-bold);
  letter-spacing: var(--tracking-xwide); text-transform: uppercase;
}
.ki_kennzeichnung_title {
  margin: 3px 0 0; font-family: var(--font-display); font-size: 19px; color: var(--q-dark);
}
.ki_kennzeichnung_description {
  margin-top: 4px; color: var(--q-medium);
  font-size: 13px; font-weight: var(--w-light); line-height: 1.5;
}
.ki_kennzeichnung_result {
  display: flex; align-items: flex-start; gap: 13px;
  padding: 13px 15px; border-radius: 13px; background: var(--surface-soft);
}
.ki_kennzeichnung_result_num {
  flex: 0 0 auto; padding: 4px 11px; border-radius: 999px;
  background: var(--q-highlight-2); color: #fff;
  font-family: var(--font-display); font-size: 13px; font-weight: var(--w-bold);
}
.ki_kennzeichnung_result_text {
  color: var(--q-dark); font-size: 13px; font-weight: var(--w-light); line-height: 1.5;
}
/* Einleitender Absatz der Tafel (BAL-140). Groesse, Gewicht, Zeilenhoehe und
   Farbe ausdruecklich - die globale p-Regel hat sich hier schon mehrfach
   hineingemischt. */
.ki_kennzeichnung_lead {
  margin: 0; color: var(--q-medium);
  font-size: 13px; font-weight: var(--w-light); line-height: 1.6;
}
.ki_kennzeichnung_lead strong { color: var(--q-dark); font-weight: var(--w-bold); }

.ki_kennzeichnung_criteria {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px;
}
.ki_kennzeichnung_criterion {
  padding: 13px 15px; border: 1px solid var(--divider); border-radius: 13px;
}
/* Kopf der Karte: Kriterium links, Stufenangabe rechts (BAL-140). Vorher
   standen beide untereinander und die Stufe klebte am Namen. */
.ki_kennzeichnung_criterion_header {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
}
.ki_kennzeichnung_criterion_label {
  color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
}
.ki_kennzeichnung_criterion_step {
  color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-regular); white-space: nowrap;
}
.ki_kennzeichnung_criterion_title {
  margin-top: 5px; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold);
}
/* Die Skala ist ein PEGEL: Sie fuellt alle erreichten Stufen, nicht nur die
   gewaehlte. Bei Stufe 3 von 4 sind drei Segmente gefuellt - das liest sich
   als Hoehe, waehrend ein einzelner Strich nur eine Position zeigt. */
.ki_kennzeichnung_criterion_scale { display: flex; gap: 4px; margin: 9px 0 8px; }
.ki_kennzeichnung_criterion_scale span {
  flex: 1 1 0; height: 5px; border-radius: 3px; background: var(--q-bright);
}
.ki_kennzeichnung_criterion_scale span.is_on { background: var(--q-highlight-3); }
/* Zwei Kriterien, zwei Farben - sonst laesen sich die Balken als eine Skala. */
.ki_kennzeichnung_criterion[data-kriterium="wirkung"] .ki_kennzeichnung_criterion_scale span.is_on { background: var(--q-highlight-1); }
.ki_kennzeichnung_criterion_description {
  margin: 0; color: var(--q-medium);
  font-size: 12px; font-weight: var(--w-light); line-height: 1.5;
}

/* Ableitung: Matrix und Legende nebeneinander (BAL-140). Zeile = Wirkung,
   Spalte = Eigenstaendigkeit - dieselbe Leserichtung wie im Schema, damit die
   markierte Zelle mit der Tabelle dort uebereinstimmt. */
.ki_kennzeichnung .ki_kennzeichnung_derivation {
  display: grid; grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  gap: 18px; align-items: start;
}
.ki_kennzeichnung_matrix { display: grid; grid-template-columns: auto 1fr; gap: 6px 8px; align-items: center; }
.ki_kennzeichnung_matrix_axis_y {
  writing-mode: vertical-rl; transform: rotate(180deg); justify-self: center;
  color: var(--q-medium); font-size: 10px; font-weight: var(--w-bold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
}
.ki_kennzeichnung_matrix_axis_x {
  grid-column: 2; text-align: center;
  color: var(--q-medium); font-size: 10px; font-weight: var(--w-bold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
}
.ki_kennzeichnung_matrix_grid { display: grid; grid-template-columns: auto repeat(4, 1fr); gap: 3px; }
.ki_kennzeichnung_matrix_label {
  display: grid; place-items: center;
  color: var(--q-medium); font-size: 10px; font-weight: var(--w-bold);
}
.ki_kennzeichnung_matrix_cell {
  display: grid; place-items: center; padding: 7px 0; border-radius: 7px;
  background: var(--surface-soft); color: var(--q-dark);
  font-size: 11.5px; font-weight: var(--w-bold);
}
/* Abstufung von unauffaellig bis warnend - ABGELEITET aus den eigenen Marken
   der Anwendung (success, warning, danger) statt aus fremden Hexwerten, sonst
   stuenden vier Farben neben der Palette, die nirgends sonst vorkommen.
   Die Zahl bleibt in der Zelle: Farbe ist nicht die einzige Kodierung. */
.ki_kennzeichnung_matrix_cell[data-kategorie="1"] { background: color-mix(in srgb, var(--success) 12%, #fff); }
.ki_kennzeichnung_matrix_cell[data-kategorie="2"] { background: color-mix(in srgb, var(--success) 26%, #fff); }
.ki_kennzeichnung_matrix_cell[data-kategorie="3"] { background: color-mix(in srgb, var(--warning) 26%, #fff); }
.ki_kennzeichnung_matrix_cell[data-kategorie="4"] { background: color-mix(in srgb, var(--danger) 22%, #fff); }
/* Die aktive Zelle traegt einen Punkt und einen Ring, KEINE Vollfaerbung: Eine
   ausgefuellte Zelle verdeckte ihre eigene Kategorie. */
.ki_kennzeichnung_matrix_cell_active { box-shadow: inset 0 0 0 2px var(--q-highlight-2); }
.ki_kennzeichnung_matrix_cell_dot { width: 9px; height: 9px; border-radius: 50%; background: var(--q-highlight-2); }

.ki_kennzeichnung_legend { display: flex; flex-direction: column; gap: 7px; }
.ki_kennzeichnung_legend_label {
  color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
}
.ki_kennzeichnung_legend_description {
  margin: 0; color: var(--q-medium);
  font-size: 12px; font-weight: var(--w-light); line-height: 1.5;
}
.ki_kennzeichnung_legend_items { margin: 2px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 5px; }
.ki_kennzeichnung_legend_item {
  display: flex; align-items: center; gap: 8px; margin: 0;
  color: var(--q-medium); font-size: 12px; font-weight: var(--w-regular); line-height: 1.4;
}
/* Die aktuelle Kategorie traegt Farbe UND Schriftschnitt UND ein Wortzeichen -
   wer die Farbe nicht unterscheidet, liest das Zeichen. */
.ki_kennzeichnung_legend_item_active { color: var(--q-dark); font-weight: var(--w-bold); }
.ki_kennzeichnung_dot { flex: 0 0 10px; width: 10px; height: 10px; border-radius: 50%; }
.ki_kennzeichnung_dot[data-kategorie="1"] { background: color-mix(in srgb, var(--success) 45%, #fff); }
.ki_kennzeichnung_dot[data-kategorie="2"] { background: var(--success); }
.ki_kennzeichnung_dot[data-kategorie="3"] { background: var(--warning); }
.ki_kennzeichnung_dot[data-kategorie="4"] { background: var(--danger); }
.ki_kennzeichnung_tag {
  margin-left: auto; padding: 1px 8px; border-radius: 999px;
  background: var(--q-highlight-2); color: #fff;
  font-size: 10px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase;
}

@media (max-width: 780px) {
  .ki_kennzeichnung .ki_kennzeichnung_derivation { grid-template-columns: 1fr; }
}

/* Pflichtangaben. Eine fehlende Angabe wird ausgewiesen, nicht weggelassen —
   eine unvollstaendige Kennzeichnung soll als unvollstaendig erkennbar sein. */
.ki_kennzeichnung_facts { display: flex; flex-direction: column; gap: 10px; }
.ki_kennzeichnung_fact { display: grid; grid-template-columns: 190px 1fr; gap: 14px; align-items: start; }
.ki_kennzeichnung_fact_label {
  color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
}
.ki_kennzeichnung_fact_value {
  color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-light); line-height: 1.5;
}
.ki_kennzeichnung_fact_value.is_missing { color: var(--q-medium); font-style: italic; }

/* Kein Guetesiegel — verpflichtender Bestandteil von Tafel und Erlaeuterung. */
.ki_kennzeichnung_hint {
  padding: 11px 14px; border-left: 3px solid var(--q-highlight-3);
  border-radius: 0 9px 9px 0; background: var(--surface-soft);
  color: var(--q-dark); font-size: 12px; font-weight: var(--w-light); line-height: 1.5;
}
.ki_kennzeichnung_footer {
  display: flex; flex-direction: column; gap: 8px;
  padding-top: 13px; border-top: 1px solid var(--divider);
}
.ki_kennzeichnung_footer_link {
  align-self: flex-start; padding: 0; border: 0; background: none;
  color: var(--q-highlight-2); font: inherit; font-size: 12.5px; font-weight: var(--w-bold);
  text-decoration: none; cursor: pointer;
}
.ki_kennzeichnung_footer_link:hover { text-decoration: underline; }

/* Erlaeuterung */
.ki_kennzeichnung_help_block { display: flex; flex-direction: column; gap: 7px; }
.ki_kennzeichnung_help_text {
  color: var(--q-medium); font-size: 12.5px; font-weight: var(--w-light); line-height: 1.55;
}
.ki_kennzeichnung_bullets {
  margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 7px;
}
.ki_kennzeichnung_bullet {
  position: relative; padding-left: 13px; color: var(--q-medium);
  font-size: 12.5px; font-weight: var(--w-light); line-height: 1.5;
}
.ki_kennzeichnung_bullet::before {
  content: ""; position: absolute; left: 0; top: 8px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--q-highlight-3);
}
.ki_kennzeichnung_bullet b { color: var(--q-dark); font-weight: var(--w-bold); }
/* Der Kennzeichnungsprozess ist eine Reihenfolge, keine Aufzaehlung: als
   <ol> traegt er Nummern statt Punkte. */
ol.ki_kennzeichnung_bullets { counter-reset: ki_schritt; }
ol.ki_kennzeichnung_bullets .ki_kennzeichnung_bullet { padding-left: 22px; counter-increment: ki_schritt; }
ol.ki_kennzeichnung_bullets .ki_kennzeichnung_bullet::before {
  content: counter(ki_schritt); top: 0; width: auto; height: auto; border-radius: 0;
  background: none; color: var(--q-highlight-3); font-size: 11px; font-weight: var(--w-bold);
}

/* Ableitung: die Matrix mit ihrer Beschriftung als eigener Block. */
.ki_kennzeichnung_derivation { display: flex; flex-direction: column; gap: 2px; }

/* Die Erlaeuterung ist dieselbe Tafel in ausfuehrlich; sie braucht mehr Luft
   zwischen den Bloecken, weil sie fortlaufend gelesen wird. */
.ki_kennzeichnung_help { gap: 20px; }

/* Beide Dialoge liegen ueber der Schublade (z-index 70) — sonst stuende die
   Kennzeichnung hinter dem Assistenten, aus dem sie geoeffnet wurde. Die
   Erlaeuterung wiederum liegt ueber der Tafel: eigene Ebene, damit die Tafel
   beim Schliessen der Erlaeuterung stehen bleibt. */
.ki_kennzeichnung_overlay { z-index: 118; }
.ki_kennzeichnung_modal { z-index: 119; width: min(680px, calc(100vw - 48px)); }
.ki_kennzeichnung_overlay_top { z-index: 120; }
.ki_kennzeichnung_modal_top { z-index: 121; }

@media (max-width: 720px) {
  .ki_kennzeichnung_fact { grid-template-columns: 1fr; gap: 3px; }
}


/* Verwaltungsbereich der Kennzeichnung (BAL-117). Die Bewertungsmaske klappt
   unter ihrer Zeile auf und speichert fuer sich; deshalb sitzt sie in einer
   eigenen Tabellenzeile ueber die volle Breite. */
/* Die Zeile ist seit BAL-139 selbst die Schaltflaeche in den Datensatz -
   .kennz-zeile-auf (Hervorhebung der aufgeklappten Zeile) gibt es nicht mehr,
   weil nichts mehr aufklappt. */
.kennz-zeile { cursor: pointer; }
.kennz-zeile:hover > td { background: var(--surface-soft); }
.kennz-zeile:focus-visible { outline: 2px solid var(--q-highlight-2); outline-offset: -2px; }
/* Die Maskenzeile ist zugleich erste und LETZTE Zelle ihrer Reihe und erbt
   damit `.module_list_table td:last-child { text-align: right }` - ohne diese
   Ruecknahme stuenden alle Beschriftungen der Maske rechtsbuendig. */
.module_list_table .kennz-maske-zeile > td { padding: 0 0 14px; background: var(--surface-soft); text-align: left; }
.kennz-maske { margin: 0 14px; display: flex; flex-direction: column; gap: 4px; }
.kennz-textarea { min-height: 66px; resize: vertical; line-height: 1.5; }
.kennz-vorschlaege { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 0 0 10px; }
/* Kurzlink zur Erlaeuterung, mitten im Fliesstext einer Beschriftung. */
.kennz-inline-link { display: inline; font-size: inherit; vertical-align: baseline; }

/* Einstellungen des Assistenten (BAL-115). Kurze Reihe `ai-*` wie im
   Innenleben der Schublade; der Block sitzt in `.admin-block` und uebernimmt
   dessen Rahmen. */
.ai-conf { display: flex; flex-direction: column; gap: 2px; }
.ai-zustand { display: flex; align-items: flex-start; gap: 8px; margin: 6px 0 12px; padding: 10px 12px; border-radius: 11px; font-size: 12.5px; font-weight: var(--w-light); line-height: 1.45; }
.ai-zustand.ok { background: rgba(111,163,28,0.10); color: var(--q-dark); }
.ai-zustand.fehler { background: rgba(192,72,72,0.10); color: var(--q-dark); }
.ai-zustand strong { font-weight: var(--w-bold); }
.ai-feld { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; padding: 11px 0; border-bottom: 1px solid var(--divider); }
.ai-feld-kopf { min-width: 0; }
.ai-feld-titel { display: block; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); }
.ai-feld-sub { margin-top: 2px; max-width: 62ch; color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-light); line-height: 1.45; }
.ai-feld-eingabe { width: 150px; flex: 0 0 150px; }
.ai-feld .fselect-wrap { flex: 0 0 260px; width: 260px; }
/* Zwischenueberschrift im Einstellungsabschnitt: Die Kontextbloecke sind
   eine eigene Entscheidungsgruppe und nicht die naechste Zahl (BAL-125). */
/* Die Trennlinie steht ZWISCHEN zwei Gruppen, nicht vor der ersten
   (BAL-150). Ohne :not(:first-child) zog eine Gruppe, die als erstes
   Element in ihrer Karte steht, eine Linie ueber sich - gemeldet an der
   Box "Uebertragung in die Ausfuehrungsschicht" in der Wissensbasis.
   Woertlich dieselbe Bedingung, die .ffield-gruppe seit BAL-136 hat; sie
   war hier nur nie mitgezogen worden. */
.ai-conf-gruppe { margin-top: 20px; }
.ai-conf-gruppe:not(:first-child) { padding-top: 16px; border-top: 1px solid var(--divider); }
.ai-conf-fuss { display: flex; align-items: center; gap: 12px; margin-top: 14px; }
/* Waage der beiden Suchwege (BAL-131). Der Balken steht fuer sich zwischen
   den Schaltern und den Zahlenfeldern; er traegt seine Legende selbst und
   braucht deshalb nur Luft, keine eigene Rahmung. */
.ai-retr-waage { margin: 14px 0 4px; }
.ai-conf-hinweis { color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-light); }
@media (max-width: 780px) {
  .ai-feld { flex-direction: column; gap: 8px; }
  .ai-feld-eingabe, .ai-feld .fselect-wrap { width: 100%; flex: 1 1 auto; }
}


.empty_state { padding: 46px 20px; color: #777; text-align: center; }
.detail-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; min-height: 150px; border: 1px dashed var(--divider); border-radius: 14px; background: linear-gradient(180deg, #fff, #fafbfa); }
.detail-empty .de-ic { width: 48px; height: 48px; display: grid; place-items: center; border-radius: 14px; background: var(--surface-soft); color: var(--q-medium); opacity: .75; }
.detail-empty .de-text { max-width: 34ch; color: var(--q-medium); font-size: 13px; line-height: 1.45; }

@keyframes ui-pop-in { from { opacity: 0; transform: translateY(-6px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes modal-window-in { from { opacity: 0; transform: translate(-50%, -48%) scale(0.98); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
@keyframes detail-panel-in { from { opacity: 0; transform: translateX(8px) scale(0.98); } to { opacity: 1; transform: translateX(0) scale(1); } }

/* Verweise-Editor (xref-card) — Optik gemaess Referenzdesign */
.xref-field { min-width: 0; }
.xref-card { min-width: 0; overflow: hidden; background: var(--surface-soft); border: 1px solid var(--divider); border-radius: 14px; padding: 16px 18px; }
.xref-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.xref-title { font-size: 11px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); color: var(--q-medium); }
.xref-add { display: inline-flex; align-items: center; gap: 6px; }
.xref-hint { font-size: 11.5px; color: var(--q-medium); line-height: 1.45; margin-top: 6px; }
.xref-empty { font-size: 12.5px; color: var(--q-medium); line-height: 1.5; margin-top: 12px; padding: 14px; background: #fff; border: 1px dashed var(--divider); border-radius: 10px; }
.xref-rows { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.xref-row { display: grid; grid-template-columns: 160px 1fr 1.15fr 38px; gap: 10px; align-items: center; min-width: 0; }
.xref-row .content_form_item { min-width: 0; margin: 0; }
.xref-row-head span { font-size: 10px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); color: var(--q-medium); }
.xref-row .finput, .xref-row .fselect-wrap .finput { padding: 8px 10px; font-size: 13px; }
.xref-del { width: 34px; height: 38px; border-radius: 8px; display: grid; place-items: center; border: 0; background: transparent; color: var(--danger); cursor: pointer; transition: background var(--dur-fast, .15s) ease; }
.xref-del:hover { background: #fff; }
.extref-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.extref-chip { display: inline-flex; align-items: center; gap: 7px; max-width: 100%; padding: 6px 10px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; color: var(--q-dark); }
.extref-label { color: var(--q-medium); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.extref-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--w-bold); }

@media (max-width: 1100px) {
  .summary_tiles { grid-template-columns: repeat(2, 1fr); }
  .mission_control_body { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 780px) {
  body { overflow: auto; }
  .app_shell { grid-template-columns: 1fr; grid-template-rows: auto auto 1fr; grid-template-areas: "topbar" "sidebar" "main"; min-height: 100vh; }
  .app_shell_sidebar { grid-area: sidebar; flex-direction: row; overflow-x: auto; padding: 10px; border-right: 0; border-bottom: 1px solid var(--divider); }
  .app_shell_brand, .app_shell_nav_section { display: none; }
  /* Der Fuss der Seitenleiste blieb hier frueher ganz weg - und mit ihm das
     Abmelden. Befund A11Y-022, Aufgabe BAL-069: `[data-action="logout"]` ist
     die EINZIGE Abmeldestelle im gesamten Frontend; unterhalb 780px und bei
     200% Zoom gab es damit ueberhaupt keinen Weg mehr aus der Sitzung.
     Jetzt wandert der Fuss ans Ende der nun waagrechten Leiste und bleibt
     dort stehen (`sticky`), auch wenn die Leiste seitlich gescrollt wird -
     sonst waere er auf schmalen Geraeten hinter den Navigationssymbolen
     verschwunden, also wieder nicht erreichbar. */
  .app_shell_sidebar_footer { display: flex; align-items: center; margin: 0 0 0 auto; position: sticky; right: 0; padding-left: 10px; background: var(--surface); }
  /* Verlaufshinweis an der Kante, an der die Navigation weitergeht (BAL-182,
     Befund R-09). GEMESSEN bei 390px: Die waagrechte Leiste fuehrt 760px
     Inhalt in 390px Sichtfeld - etwa die Haelfte der zwoelf Eintraege ist zu
     sehen, die Beschriftungen sind hier entfernt, und nichts deutete an, dass
     rechts noch welche stehen.

     DER VERLAUF HAENGT AM FUSS UND NICHT AN DER LEISTE. Zwei Gruende:
     - Eine Maske auf `.app_shell_sidebar` haette den Fuss mit ausgeblendet -
       und der traegt seit BAL-069 die EINZIGE Abmeldestelle der Anwendung
       (Befund A11Y-022). Die durfte nicht blasser werden.
     - Der Fuss ist `sticky` und steht ohnehin genau dort, wo die Eintraege
       verschwinden. `right: 100%` setzt den Verlauf unmittelbar links davon,
       also an die tatsaechliche Verschwindekante, und er wandert beim Scrollen
       mit.

     Unterhalb 780px ueberlaeuft die Leiste bei jeder wirklichen Geraetebreite;
     nur im 20px schmalen Band zwischen 761 und 780px passt der Inhalt und der
     Verlauf zeigt etwas an, das nicht da ist. Dafuer eine zweite Regel zu
     schreiben, waere mehr Aufwand als der Fehler wert. */
  .app_shell_sidebar_footer::before { content: ""; position: absolute; top: 0; bottom: 0; right: 100%; width: 28px; background: linear-gradient(to left, var(--surface), rgba(255, 255, 255, 0)); pointer-events: none; }
  /* Dieselbe Kante an der Reiterleiste des Detailbereichs (Befund R-10).
     GEMESSEN bei 390px: 852px Inhalt in 366px Sichtbreite. Hier gibt es
     keinen `sticky` Nachbarn, an den sich der Verlauf haengen koennte -
     stattdessen wird das Pseudoelement selbst zum `sticky` flex-Element am
     rechten Rand des Scrollers. `margin-left: -28px` sorgt dafuer, dass es
     keine eigene Breite in der Leiste beansprucht, sondern sich ueber den
     letzten sichtbaren Reiter legt.

     Die Reiterleiste passt unterhalb 780px nie: Der Bereich ist hoechstens
     `calc(100vw - 24px)` breit, also 756px bei 780px Fenster - gegenueber
     852px Inhalt. */
  .detail_panel_tabs::after { content: ""; position: sticky; right: 0; flex: 0 0 28px; margin-left: -28px; align-self: stretch; background: linear-gradient(to left, #fff, rgba(255, 255, 255, 0)); pointer-events: none; }
  .app_shell_sidebar_footer [data-action="toggle-sidebar"], .app_shell_sidebar_divider { display: none; }
  .app_shell_user { width: auto; white-space: nowrap; }
  .app_shell_nav_items { flex-direction: row; }
  .app_shell_nav_item { min-width: 52px; justify-content: center; }
  .app_shell_nav_item_title { display: none; }
  /* Die acht Zaehler verschwanden im Schmallayout ersatzlos mit der Beschriftung.
     Sie bleiben jetzt als Bildmarke am Symbol; den Namen des Bedienelements
     traegt `aria-label` ("Themen, 8"), damit die Zahl nicht selbst zum Namen
     wird - deshalb ist die Marke `aria-hidden`. */
  .app_shell_nav_item { position: relative; }
  .app_shell_nav_item_count { position: absolute; top: 2px; right: 4px; display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; margin: 0; padding: 0 4px; font-size: 10px; line-height: 1; }
  /* ── Die einblendbare Navigation (Aufgabe BAL-191) ───────────────────────
   *
   * Zweite Auspraegung der Navigation auf schmalen Geraeten, waehlbar unter
   * Einstellungen > Darstellung. Die erste bleibt die waagrechte Symbolleiste
   * darunter; welche gilt, entscheidet `navSchubladeAktiv()` in app.js und
   * setzt `.app_shell_nav_schublade` an die Huelle.
   *
   * WARUM SIE DIE REGELN DER SYMBOLLEISTE ZURUECKNIMMT statt eigene zu
   * bekommen: Der 780er-Block stellt die Seitenleiste auf `flex-direction:
   * row`, blendet Marke, Abschnittsueberschriften und Beschriftungen aus und
   * setzt die Zaehler als Bildmarke an die Symbole. Genau das soll hier NICHT
   * gelten - die eingeblendete Leiste sieht aus wie am Schreibtisch, mit
   * Beschriftungen. Deshalb stehen unten Rueckstellungen und keine zweite
   * Navigation: Eine zweite waere eine parallele Struktur fuer dieselbe Rolle
   * (ucs.md 25.4), und die Eintraege kaemen aus derselben Funktion.
   *
   * `position: fixed` und `translateX(-100%)`: Die Leiste liegt ueber dem
   * Inhalt statt ihn zu verschieben - auf 390px waere ein Verschieben nur ein
   * anderes Wort fuer "unsichtbar".
   *
   * `visibility: hidden` zusaetzlich zur Verschiebung: Ohne sie bliebe die
   * geschlossene Leiste ein Ziel fuer die Tabulatortaste, das niemand sieht.
   * Das Markup setzt daneben `inert`; die Regel hier haelt den Zustand auch
   * dort, wo der Browser `inert` noch nicht kennt.
   */
  .app_shell_nav_schublade .app_shell_sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 90;
    width: min(300px, 86vw); flex-direction: column; overflow-y: auto; overflow-x: hidden;
    padding: 18px 14px; border-right: 1px solid var(--divider); border-bottom: 0;
    box-shadow: 6px 0 28px rgba(16, 49, 78, 0.18);
    transform: translateX(-100%); visibility: hidden;
    transition: transform var(--dur-base) var(--ease-std), visibility 0s linear var(--dur-base);
  }
  .app_shell_nav_offen .app_shell_sidebar { transform: translateX(0); visibility: visible; transition: transform var(--dur-base) var(--ease-std), visibility 0s; }
  /* Zurueckgestellt: alles, was die waagrechte Leiste ausmacht. */
  .app_shell_nav_schublade .app_shell_brand,
  .app_shell_nav_schublade .app_shell_nav_section { display: block; }
  .app_shell_nav_schublade .app_shell_brand { display: flex; }
  .app_shell_nav_schublade .app_shell_nav_items { flex-direction: column; }
  .app_shell_nav_schublade .app_shell_nav_item { min-width: 0; justify-content: flex-start; position: static; }
  .app_shell_nav_schublade .app_shell_nav_item_title { display: block; }
  .app_shell_nav_schublade .app_shell_nav_item_count { position: static; min-width: 0; height: auto; margin-left: auto; padding: 1px 7px; font-size: 11px; }
  .app_shell_nav_schublade .app_shell_sidebar_footer { position: static; margin: auto 0 0; padding-left: 0; }
  .app_shell_nav_schublade .app_shell_sidebar_divider { display: block; }
  .app_shell_nav_schublade .app_shell_user { width: 100%; white-space: normal; }
  /* Unterhalb 560px bleibt vom Benutzer nur das Kuerzel stehen (BAL-069) -
     in der waagrechten Leiste haette der Name die halbe Bildschirmbreite
     genommen. In der 300px breiten Schublade ist der Platz da, also steht er
     wieder. Die Regel gewinnt ueber ihre hoehere Spezifitaet, nicht ueber die
     Reihenfolge: Der 560er-Block steht weiter unten in dieser Datei. */
  .app_shell_nav_schublade .app_shell_user_text { display: block; }
  /* Die Flaeche hinter der Leiste. Ein `button` und kein `div`: Sie schliesst,
     und was schliesst, ist ein Bedienelement - mit Namen fuer Hilfsmittel.
     `tabindex="-1"` im Markup, weil Escape und der Schalter in der Kopfleiste
     die Wege der Tastatur sind; ein drittes Ziel dazwischen waere nur ein
     weiterer Halt ohne eigene Bedeutung. */
  .app_shell_nav_backdrop {
    position: fixed; inset: 0; z-index: 89; display: block; width: 100%; height: 100%;
    background: rgba(16, 49, 78, 0.22); backdrop-filter: blur(2px);
    opacity: 0; pointer-events: none; cursor: default;
    transition: opacity var(--dur-base) var(--ease-std);
  }
  .app_shell_nav_offen .app_shell_nav_backdrop { opacity: 1; pointer-events: auto; }
  .app_shell_nav_knopf { order: -1; }
  @media (prefers-reduced-motion: reduce) {
    .app_shell_nav_schublade .app_shell_sidebar, .app_shell_nav_backdrop { transition: none; }
  }

  /* Abstand 10px statt 14px (BAL-190). Gerechnet fuer 390px: Die Marke misst
     110px, daneben stehen fuenf Bedienelemente zu je 38px - zusammen 300px in
     366px verfuegbarer Breite. Bei 14px Abstand brauchen die sechs
     Zwischenraeume 84px und das letzte Symbol rutscht in eine zweite Zeile;
     bei 10px sind es 60px, und alles steht in einer. Ist die einblendbare
     Navigation gewaehlt, kommt ihr Schalter dazu und die Zeile bricht wieder
     um - das war vor dieser Aufgabe genauso. */
  .app_shell_topbar { flex-wrap: wrap; height: auto; padding: 12px; gap: 10px; }
  /* Marke statt Bereichsueberschrift in der ersten Zeile (BAL-190). Die
     Ueberschrift ruecht darunter in eine eigene, viel kleinere Zeile - sie
     beantwortet "wo bin ich", die Marke "was ist das hier", und auf einem
     Telefon war Letzteres bisher gar nicht zu sehen.

     Die Reihenfolge entsteht ueber `order`, nicht ueber eine zweite
     DOM-Struktur: Zeile 1 traegt alles mit `order: 0` (Marke, Abstandhalter,
     die Symbolschalter), Zeile 2 die Ueberschrift (`order: 1`), Zeile 3 die
     Suche (`order: 3`, schon vorher so). Beide unteren nehmen die volle
     Breite und brechen damit von selbst um.

     Die Ueberschrift bekommt die Schreibweise der Vortexte des Hauses
     (11px, Versalien, --tracking-xwide, --fg-2) - dieselbe wie
     `.page_header_pretext`. `--fg-2` und nicht `--q-medium`: Letzteres ist
     eine Dekorfarbe und ergaebe auf Weiss nur 1,9 : 1. */
  /* Die Kopfleiste fuehrt dieselbe Lockup in EIGENEN Massen (BAL-204).
     Die 72 px der Seitenleiste waeren hier zu viel: Die Kopfleiste ist
     62 px hoch, und die Symbolschalter daneben messen 38 px. 44 px sind
     die Groesse, die sie vor BAL-204 hatte - die Zeilenaufteilung bleibt
     damit unveraendert. Schrift und Zeile folgen den neuen Groessen der
     Seitenleiste; die Lockup wird dadurch schmaler als zuvor und laesst
     den Symbolschaltern mehr Platz. Dieselbe Trennung wie in Mission
     Control, das seiner Kopfleiste ebenfalls einen eigenen Satz gibt. */
  .app_shell_topbar_brand { display: flex; align-items: center; gap: var(--marke-abstand); min-width: 0; white-space: nowrap; --marke-signet: 44px; --marke-schrift: 18px; }
  .app_shell_breadcrumb { order: 1; width: 100%; font-family: var(--font-sans); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; color: var(--fg-2); }
  .global_search { order: 3; width: 100%; }
  .app_shell_main { padding: 20px 14px 44px; }
  .page_header { align-items: flex-start; flex-direction: column; }
  /* Der Kopf stellt sich seit jeher auf Spalte - die Reihe der Bedienelemente
     DARIN blieb aber eine Reihe ohne Umbruch (Aufgabe BAL-182, Befund R-05).
     GEMESSEN bei 390px in einem 347px breiten Inhaltsbereich: Freigaben
     422px, Budget 376px. Bei den Freigaben standen davon 46px ausserhalb des
     Fensters, bei Budget war "Neue Budgetposition" am rechten Rand
     angeschnitten (Bildbeleg
     docs/user-experience/responsive/bilder/390-budget-baum.png).

     `flex-wrap: wrap` allein genuegt nicht: Die Schaltflaechen tragen
     `white-space: nowrap` und sind einzeln breiter, als eine halbe Zeile
     hergibt. Mit `flex: 1 1 auto` teilen sie sich die Zeile, solange zwei
     nebeneinander passen, und stapeln sonst - statt in fester Breite
     nebeneinander stehen zu bleiben.

     `justify-content: flex-start`, damit die umgebrochene zweite Zeile links
     beginnt wie der Text darueber und nicht rechtsbuendig unter dem Kopf
     haengt. */
  .page_header_controls { flex-wrap: wrap; justify-content: flex-start; width: 100%; }
  .page_header_controls > .button { flex: 1 1 auto; }
  /* Dieselbe Reihe in den Einstellungen (Rollen & Rechte,
     Organisationseinheiten): GEMESSEN bei 390px fuehrte der Abschnittskopf
     der Organisationseinheiten 493px Inhalt in 347px Sichtbreite. */
  .admin-sec-head { align-items: flex-start; flex-wrap: wrap; }
  /* Sprachausgabe: 404px Inhalt in 297px. Stammt aus Befund R-13 - dort als
     vermeintliches Beschneiden gefuehrt, tatsaechlich eine nicht umbrechende
     Reihe und damit ein Fall fuer genau diese Stufe. */
  .ai-conf-fuss { flex-wrap: wrap; }
  .summary_tiles { grid-template-columns: 1fr; }
  .admin-layout { grid-template-columns: 1fr; }
  .admin-nav { position: static; }
  .admin-kpis, .index-grid { grid-template-columns: 1fr; }
  .role-grid, .set-grid { grid-template-columns: 1fr; }
  /* `minmax(0, 1fr)` aus demselben Grund wie an `.app_shell` (BAL-181): Eine
     `1fr`-Spalte kann nicht schmaler werden als ihr breitester unteilbarer
     Inhalt. GEMESSEN bei 390px in einem 347px breiten Behaelter: Kachel
     Beauftragungen 408px, Kachel Dateien 442px - die Kinder der Karte massen
     dabei nur 371px, die Karte war also breiter als alles, was in ihr steht.
     Ausloeser ist `.lc-sub` mit `white-space: nowrap`: Fuer eine nicht
     umbrechende Zeile ist die Min-Content-Breite die volle Textbreite. Mit
     `minmax(0, ...)` darf die Spalte schrumpfen, und `.lc-sub` kuerzt dann
     wie vorgesehen mit Auslassungspunkten.

     `.plan-cards` braucht dieselbe Regel, steht hier aber NICHT: Es wird erst
     weiter unten in dieser Datei definiert und wuerde diese ueberschreiben.
     Seine Ausnahme liegt deshalb neben seiner Definition. */
  .list-cards, .kb-grid { grid-template-columns: minmax(0, 1fr); }
  .help-hero { align-items: flex-start; flex-direction: column; padding: 24px; }
  .content_form_item, .field_list_item { grid-template-columns: minmax(0, 1fr); gap: 5px; }
  .module_list_toolbar { align-items: stretch; flex-direction: column; }
  .module_list_search, .module_list_select, .module_list_toolbar .button, .ltb-search, .ltb-actions, .ltb-btn { width: 100%; }
  .ltb-actions { align-items: stretch; flex-direction: column; }
  .ltb-views { align-self: flex-start; }
  .ltb-pop { left: 0; right: auto; width: min(100%, calc(100vw - 28px)); }
  .ltb-date-range { grid-template-columns: 1fr; }
  /* Eine Spalte heisst ZWEI Zeilen: Schiene oben (Schritte liegen hier
     nebeneinander, Hoehe nach Inhalt), Rumpf darunter mit dem Rest. Ohne die
     zweite Zeilenangabe faellt der Rumpf in eine implizite `auto`-Zeile und
     laeuft wieder unten heraus - derselbe Fehler wie in der Grundregel
     (BAL-188), nur eine Ebene tiefer. */
  .planner-card { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); width: calc(100vw - 24px); height: calc(100vh - 24px); border-radius: 16px; }
  .planner-rail { padding: 14px 16px; }
  .planner-rail-brand, .planner-assist { display: none; }
  .planner-steps { flex-direction: row; overflow-x: auto; }
  .planner-step { flex: 0 0 auto; width: auto; }
  .planner-head, .planner-scroll, .planner-foot { padding-left: 18px; padding-right: 18px; }
  .planner-bound-banner { margin-left: 18px; margin-right: 18px; }
  .planner-field-grid, .review-grid, .imp-summary { grid-template-columns: 1fr; }
  .pos-row.struct, .pos-row.head, .pos-row.amt, .ytb-subtotal { grid-template-columns: 1fr; align-items: stretch; }
  .pos-row.head { display: none; }
  .topic-check { align-items: flex-start; }
  .topic-check .tc-amt { margin-left: 0; }
  /* `column-reverse` drehte im Schmallayout nur das BILD um, nicht die
     Tabulatorfolge - die folgt dem DOM. Gemessen bei 390x844 im Dialog
     "Thema bearbeiten": sichtbar Speichern (y=679), Abbrechen (y=729),
     Loeschen (y=780); getabbt dagegen Loeschen, Abbrechen, Speichern - exakt
     umgekehrt. Wer aus dem letzten Feld weitertabbte, landete zuerst auf der
     zerstoerenden Aktion. Befund A11Y-023, Aufgabe BAL-069.
     Mit CSS laesst sich die Tabulatorfolge nicht aendern, also wird das Bild
     gleichgerichtet: Die Reihenfolge ist jetzt in beiden Layouts dieselbe wie
     im Breitlayout von links nach rechts - Loeschen, Abbrechen, Speichern.
     Sichtbare Folge: Auf schmalen Geraeten steht "Speichern" nicht mehr oben,
     sondern unten. */
  .planner-foot { align-items: stretch; flex-direction: column; }
  .planner-foot .button, .planner-foot .row { width: 100%; }
  .planner-foot .row { flex-direction: column; align-items: stretch; }
  .modal_window { width: calc(100vw - 24px); height: calc(100vh - 24px); border-radius: 16px; }
  .modal_window_header { padding: 18px 18px 14px; }
  .modal_window_body { padding: 18px; }
  .modal_window_footer, .fmodal-foot { align-items: stretch; flex-direction: column; padding: 12px 18px; }
  .modal_window_footer .button { width: 100%; }
  .fmodal-foot-l, .fmodal-foot-r { width: 100%; flex-direction: column; align-items: stretch; }
  .fform-grid { grid-template-columns: 1fr; }
  .xref-row { grid-template-columns: 1fr; }
  .xref-row-head { display: none; }
  .xref-del { width: auto; justify-self: flex-start; }
  .pay-editor-top { flex-direction: column; align-items: stretch; }
  .pay-editor-top .content_form_item, .pay-editor-top .content_form_item:last-child { flex-basis: auto; width: 100%; }
  .pay-quick, .pay-readout { align-items: flex-start; flex-direction: column; }
  .budget-check .bc-grid { grid-template-columns: 1fr 1fr; }
  .dedicated-form-modal { width: calc(100vw - 24px); height: calc(100vh - 24px); }
  .dedicated-form-modal[data-dedicated-modal="contingent"] { width: calc(100vw - 24px); height: auto; max-height: calc(100vh - 24px); }
  .dedicated-form-modal[data-dedicated-modal="contingent"].fullscreen { height: calc(100vh - 24px); max-height: calc(100vh - 24px); }
  .dedicated-body.fform-grid { grid-template-columns: 1fr; }
  .upload-drop { min-height: 148px; padding: 24px 16px; }
  .detail_panel { top: 12px; right: 12px; bottom: 12px; max-width: calc(100vw - 24px); border-radius: 16px; }
  .detail_panel_header { padding: 18px; }
  .detail_panel_tabs { padding: 0 18px; }
  .detail_panel_body { padding: 18px; }
  .kb-file-block { flex-wrap: wrap; }
  .detail-contingent-summary, .detail-contingent-card { align-items: flex-start; flex-direction: column; }
  .detail-contingent-grid, .dcs-kpis, .dcc-stats { grid-template-columns: 1fr; }
  .detail-head-row, .detail_panel_footer { align-items: stretch; flex-direction: column; }
  .detail_panel_controls, .detail-foot-r { justify-content: flex-start; }
}

/* Auf dem Telefon (gemessen bei 390px) belegte der wieder eingeblendete Fuss
   mit Name und Rollenzeile die halbe Bildschirmbreite und verdeckte die
   Navigation. Unterhalb 560px bleibt deshalb nur das Kuerzel stehen; den Namen
   des Bedienelements traegt weiterhin sein `title` ("Abmelden oder Benutzer
   wechseln") - die Funktion geht also nicht verloren, nur ihre Beschriftung.
   Befund A11Y-022, Aufgabe BAL-069. */
@media (max-width: 560px) {
  .app_shell_user_text { display: none; }
  .app_shell_user { padding: 6px; }
  /* Marke auf dem Telefon: die VOLLE Lockup (BAL-200, Entscheidung der
     Auftraggeberin). BAL-196 hatte hier auf Zeichen und "Balance" gekuerzt,
     weil die vollstaendige Lockup mit Zeichen zu breit war und "Balance"
     beim gleichmaessigen Verkleinern auf 10,2 px gefallen waere. Beide
     Gruende sind mit dem Wegfall des Zeichens erledigt: Die Lockup ist bei
     36 px Massstab schmaler als die gekuerzte Fassung von BAL-196 war.
     Es bleibt deshalb bei den Werten des 780er-Blocks - eine eigene Regel
     fuer diese Breite gibt es nicht mehr. */
}

/* ── Freigabe-Workflow (Budgetplanungen) ─────────────────────────────── */
/* Rollenumschalter der Freigaben (BAL-092). Er folgt jetzt der Form der
   uebrigen Segmented Controls: Pille, Rahmen in --q-bright, gefuellter aktiver
   Eintrag in --q-highlight-2, gleich breite Haelften - dieselben Werte, die
   .fseg und .fseg-btn fuehren.

   Gleich hoch ist die GEFUELLTE PILLE, nicht der helle Rahmen darum. Erst
   war es umgekehrt geloest (align-self: stretch am Rahmen); gemessen ergab
   das zwar deckungsgleiche Rahmen, aber eine Pille von 32,25px gegen einen
   Knopf von 39,58px - und verglichen wird, was man sieht. Beanstandet und
   berichtigt.

   Die Hoehe ist dabei NICHT ausgerechnet: Die Pille traegt dasselbe
   Kastenmodell wie .button - Rahmen 1px, Polster 9px, Schriftgroesse 13,5px.
   Damit stimmt sie konstruktionsbedingt und bleibt richtig, wenn .button
   einmal geaendert wird. Der Rahmen darum ist entsprechend hoeher; das ist
   die Bauart aller Segmented Controls hier (im Sortier-Panel Spur 46px,
   Pille 38px).

   Einzeilig bleibt der Schalter trotzdem: Der Kontoname stand als zweite
   Zeile darin und steht jetzt in title und aria-label. */
.plan-role-seg { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 3px; padding: 3px; border: 1px solid var(--q-bright); border-radius: 999px; background: #fff; }
.plan-role-btn { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 9px 16px; border: 1px solid transparent; border-radius: 999px; font-size: 13.5px; font-weight: var(--w-bold); color: var(--q-medium); }
.plan-role-btn:hover { background: var(--surface-soft); }
.plan-role-btn.on, .plan-role-btn.on:hover { background: var(--q-highlight-2); color: #fff; }
.plan-role-btn.on .ui_icon { color: #fff; }
/* Groesse und Gewicht traegt der Schalter selbst - siehe oben. */
.plan-filterbar { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 16px; }
.plan-filter { display: inline-flex; align-items: center; gap: 7px; padding: 7px 14px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); }
.plan-filter:hover { border-color: var(--q-medium); }
.plan-filter.on { border-color: var(--q-highlight-2); background: var(--q-highlight-2); color: #fff; }
.pf-count { display: inline-grid; place-items: center; min-width: 19px; height: 19px; padding: 0 5px; border-radius: 999px; background: var(--surface-soft); color: var(--q-dark); font-size: 10.5px; font-weight: var(--w-bold); }
.plan-filter.on .pf-count, .pdt.on .pf-count { background: rgba(255,255,255,0.22); color: #fff; }
/* Status-Schnellfilter, inline in die Freigaben-Toolbar integriert (wie die Filter-/Sortier-Elemente) */
.ltb-quickchips { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 2px; padding-left: 8px; margin-left: 4px; border-left: 1px solid var(--divider); }
.ltb-quickchip { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 6px 12px; border: 0; border-radius: 999px; background: transparent; color: var(--q-medium); font-size: 13px; font-weight: var(--w-bold); transition: color var(--dur-fast), background var(--dur-fast); }
.ltb-quickchip:hover { color: var(--q-dark); background: var(--surface-soft); }
.ltb-quickchip.on { color: var(--q-dark); background: var(--surface-soft); }
.ltb-quickchip .pf-count { min-width: 18px; height: 18px; background: rgba(0,0,0,0.06); color: var(--q-dark); }
.ltb-quickchip.on .pf-count { background: var(--q-highlight-2); color: #fff; }
@media (max-width: 720px) { .ltb-quickchips { padding-left: 0; margin-left: 0; border-left: 0; } }
/* Kacheldarstellung der Planungen (analog Referenzdesign) */
.plan-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
/* Einspaltig unterhalb des Umbruchs (BAL-181). `minmax(320px, 1fr)` erzeugt
   sonst eine 320px breite Spalte in einem 317px breiten Behaelter - gemessen
   bei 360px Sichtfeld. Drei Pixel, aber sie legen einen Querscroller ueber die
   ganze Liste.

   DIESER BLOCK STEHT HIER UND NICHT IM GROSSEN 780er-BLOCK WEITER OBEN, und
   das ist kein Geschmack: Jener Block steht VOR der Definition von
   `.plan-cards`. Beide Selektoren haben dieselbe Spezifitaet,
   also gewinnt der spaetere - die Regel dort oben war wirkungslos und beim
   Nachmessen daran erkennbar, dass die Spalte weiterhin 320px mass. Wer eine
   weitere Ausnahme fuer eine spaet definierte Komponente braucht, legt sie
   ebenso neben die Komponente. */
@media (max-width: 780px) {
  .plan-cards { grid-template-columns: minmax(0, 1fr); }
}
.plan-card { text-align: left; background: #fff; border-radius: 18px; border: 1px solid #ececec; box-shadow: 0 0 10px rgba(0,0,0,0.06); padding: 18px; cursor: pointer; display: flex; flex-direction: column; gap: 12px; transition: transform var(--dur-fast) var(--ease-std), box-shadow var(--dur-fast) var(--ease-std); }
.plan-card:hover, .plan-card:focus-visible { transform: translateY(-2px); box-shadow: 0 4px 18px rgba(16,49,78,0.12); }
.pc-top { display: flex; align-items: center; gap: 8px; }
.pc-top .pt-round { margin-left: auto; }
.pc-title { font-size: 16px; font-weight: var(--w-bold); color: var(--q-highlight-2); font-family: var(--font-display); line-height: 1.2; }
.pc-oe { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--q-medium); }
.pc-oe .ui_icon { opacity: 0.6; }
.pc-amounts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 10px 0; border-top: 1px solid var(--divider); border-bottom: 1px solid var(--divider); }
.pc-amounts > div { display: flex; flex-direction: column; gap: 2px; }
.pc-k { font-size: 10.5px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); color: var(--q-medium); }
.pc-v { font-size: 15px; font-family: var(--font-display); color: var(--q-dark); }
.pc-v.strong { font-weight: var(--w-bold); color: var(--q-highlight-2); }
.pc-bar-track { position: relative; height: 8px; border-radius: 999px; background: var(--surface-soft); overflow: hidden; }
.pc-bar-fill { position: absolute; inset: 0 auto 0 0; border-radius: 999px; }
.pc-bar-mark { position: absolute; top: -2px; bottom: -2px; left: calc(100% - 2px); width: 2px; background: var(--q-highlight-2); opacity: 0.55; }
.pc-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.pc-when { font-size: 11px; color: var(--q-medium); white-space: nowrap; }
.plan-table { padding: 0; overflow-x: auto; }
.plan-thead, .plan-trow { display: grid; grid-template-columns: minmax(200px, 1.5fr) minmax(110px, 0.7fr) 105px 105px minmax(150px, 1fr) 118px; gap: 10px; align-items: center; padding: 12px 16px; min-width: 820px; }
.plan-thead { border-bottom: 1px solid var(--divider); color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.plan-thead span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-trow { width: 100%; border-bottom: 1px solid var(--divider); background: #fff; text-align: left; cursor: pointer; transition: background var(--dur-fast); }
.plan-trow:last-child { border-bottom: 0; }
.plan-trow:hover, .plan-trow:focus-visible { background: var(--surface-soft); }
.plan-trow .pt-title { display: flex; align-items: center; gap: 8px; color: var(--q-highlight-2); font-size: 14px; font-weight: var(--w-bold); }
.pt-round { flex-shrink: 0; padding: 2px 8px; border-radius: 999px; background: var(--q-highlight-4); color: var(--q-highlight-2); font-size: 10.5px; font-weight: var(--w-bold); }
.plan-trow .pt-meta { margin-top: 3px; color: var(--q-medium); font-size: 11.5px; }
.plan-trow .pt-oe { color: var(--q-dark); font-size: 12.5px; }
.plan-trow .pt-num { font-family: var(--font-display); font-size: 13.5px; color: var(--q-medium); }
.plan-trow .pt-num.strong { color: var(--q-dark); font-weight: var(--w-bold); }
.dev-chip { display: inline-flex; align-items: center; gap: 7px; padding: 4px 11px; border-radius: 999px; font-size: 11.5px; font-weight: var(--w-bold); white-space: nowrap; }
.dev-chip.dev-ok { background: #eef5dc; color: #557a15; }
.dev-chip.dev-mid { background: #fbf1d8; color: #8a6414; }
.dev-chip.dev-over { background: #f8e0e0; color: var(--danger); }
.dev-chip.dev-none { background: var(--surface-soft); color: var(--q-medium); }
.dev-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

/* Zielwert-Fortschritt (Balken - Ring - Zahlen) */
.tbar { margin: 14px 0; padding: 15px 18px; border: 1px solid var(--divider); border-radius: 14px; background: #fff; }
.tbar.dev-ok { border-color: #dce8bf; background: #fafcf3; }
.tbar.dev-mid { border-color: #efdfb4; background: #fdfaf1; }
.tbar.dev-over { border-color: #f0c4bc; background: #fdf4f2; }
.tbar-topbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.tbar-caption { color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.tbar-switch { display: inline-flex; gap: 2px; background: #fff; border: 1px solid var(--divider); border-radius: 999px; padding: 2px; }
.tbar-switch-btn { display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px; border-radius: 999px; font-size: 11.5px; font-weight: var(--w-bold); color: var(--q-medium); cursor: pointer; transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.tbar-switch-btn:hover { color: var(--q-dark); }
.tbar-switch-btn.on { background: var(--q-highlight-2); color: #fff; }
.tbar-switch-btn .ic { opacity: 0.85; }
.tbar-none { display: flex; align-items: center; justify-content: space-between; gap: 16px; background: var(--surface-soft); border-style: dashed; }
.tbar-none-l { display: flex; align-items: flex-start; gap: 10px; }
.tbar-none-t { color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); }
.tbar-none-s { margin-top: 2px; color: var(--q-medium); font-size: 12px; max-width: 52ch; }
.tbar-none-r { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.tbar-k { color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.tbar-total { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 20px; font-weight: var(--w-bold); }
.tbar-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 9px; }
.tbar-head-l { display: inline-flex; align-items: center; gap: 8px; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); }
.tbar-head-r { font-size: 12.5px; font-weight: var(--w-bold); }
.tbar-railwrap { position: relative; padding: 4px 0 2px; }
.tbar-track { height: 10px; overflow: hidden; border-radius: 999px; background: var(--surface-soft); }
.tbar-fill { height: 100%; border-radius: 999px; transition: width var(--dur-fast); }
.tbar-mark { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--q-dark); }
.tbar-mark-cap { position: absolute; top: -15px; left: 0; color: var(--q-dark); font-size: 9.5px; font-weight: var(--w-bold); letter-spacing: 0.06em; text-transform: uppercase; }
.tbar-scale { display: flex; justify-content: space-between; margin-top: 8px; color: var(--q-medium); font-size: 11px; }
.tbar-scale-mid { font-weight: var(--w-bold); }
.tbar-nums { display: flex; flex-wrap: wrap; gap: 22px; margin-top: 8px; }
.tbar-num { display: flex; flex-direction: column; gap: 2px; }
.tbar-num .tbar-v { color: var(--q-dark); font-family: var(--font-display); font-size: 15px; font-weight: var(--w-bold); }
.tbar-gauge { display: flex; align-items: center; gap: 18px; }
.tbar-gauge-ring { position: relative; flex-shrink: 0; width: 84px; height: 84px; }
.tbar-gauge-ring .gauge_ring_progress { stroke: currentColor; }
.tbar-gauge-pct { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--q-dark); font-family: var(--font-display); font-size: 17px; font-weight: var(--w-bold); line-height: 1; }
.tbar-gauge-head, .tbar-number-head { display: flex; align-items: center; gap: 8px; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); }

/* Plan-Detail-Overlay - keine Rail-Spalte, daher einspaltiges Grid.
   Die Breite selbst kommt bereits aus .planner-card (min(960px, ...) bzw.
   .fullscreen); ein zusaetzliches max-width hier wuerde nicht mit
   transitioniert und die Breitenanimation beim Verlassen des Vollbilds
   sichtbar abschneiden. */
.plan-card-detail { grid-template-columns: minmax(0, 1fr); }
.plan-card-detail .planner-body { grid-column: 1 / -1; }
.plan-detail-head { align-items: flex-start; }
.plan-detail-head .pdh-l { display: flex; align-items: center; gap: 14px; min-width: 0; }
.pdh-titlerow { display: flex; align-items: center; gap: 12px; min-width: 0; }
.pdh-titlerow h2 { margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-detail-tabs { display: flex; gap: 4px; padding: 0 26px; border-bottom: 1px solid var(--divider); }
.pdt { display: inline-flex; align-items: center; gap: 7px; padding: 10px 14px; margin-bottom: -1px; border-bottom: 2px solid transparent; color: var(--q-medium); font-size: 13px; font-weight: var(--w-bold); }
.pdt:hover { color: var(--q-dark); }
.pdt.on { border-bottom-color: var(--q-highlight-2); color: var(--q-highlight-2); }
.plan-detail-inner { max-width: 860px; margin: 0 auto; padding: 4px 2px 20px; }
.plan-card-detail.fullscreen .plan-detail-inner { max-width: 100%; }
.pdh-chip { border-radius: 11px; }
.pdh-chip .ui_icon { background: #fff; }
.pdh-metabar { display: flex; flex-wrap: wrap; gap: 32px; padding: 14px 18px; margin-bottom: 20px; background: var(--surface-soft); border-radius: 14px; }
.pdh-meta { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pdh-meta-k { color: var(--q-medium); font-size: 10px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.pdh-meta-v { display: inline-flex; align-items: center; gap: 7px; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.avatar-sm { display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; color: #fff; flex-shrink: 0; line-height: 1; font-family: var(--font-display); font-weight: var(--w-bold); letter-spacing: 0.01em; text-transform: uppercase; }
.note-callout { display: flex; gap: 12px; margin: 12px 0; padding: 14px 16px; border-radius: 13px; background: #fbf1d8; }
.note-callout.act-rejected { background: #f8e0e0; }
.note-callout.act-submitted { background: var(--surface-soft); }
.note-callout .nc-ic { flex-shrink: 0; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 9px; background: rgba(255,255,255,0.65); color: var(--q-dark); }
.note-callout .nc-head { color: var(--q-dark); font-size: 12px; font-weight: var(--w-bold); }
.note-callout .nc-body { margin-top: 3px; color: var(--q-dark); font-size: 13px; line-height: 1.5; white-space: pre-line; }
.approver-edit-row { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin: 12px 0; padding: 13px 16px; border: 1px dashed var(--divider); border-radius: 13px; background: #fff; }
.approver-edit-row .aer-t { color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); }
.approver-edit-row .aer-s { margin-top: 2px; color: var(--q-medium); font-size: 12px; }
.diff-banner { display: flex; gap: 12px; margin: 6px 0 12px; padding: 12px 15px; border: 1px solid #dbe4f0; border-radius: 12px; background: #f2f6fb; }
.diff-banner-ic { flex-shrink: 0; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 8px; background: #fff; color: var(--q-highlight-2); }
.diff-banner-head { color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); }
.diff-banner-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 5px; font-size: 12px; }
.diff-legend { font-weight: var(--w-bold); }
.diff-legend.add { color: #557a15; }
.diff-legend.mod { color: #8a6414; }
.diff-legend.del { color: var(--danger); }
.diff-vol { color: var(--q-medium); }
.pos-list.ro { border: 1px solid var(--divider); border-radius: 13px; padding: 4px 14px 6px; background: #fff; }
.pos-row.einzel { grid-template-columns: 34px 1fr 130px 64px; padding: 8px 0; }
.pos-row.einzel.pe-row { grid-template-columns: 34px 1fr 140px 30px; }
.pos-row.amt.pe-row { grid-template-columns: 1fr 110px 130px 56px 30px; }
.pos-row.head.einzel { padding: 10px 0 8px; }
.ro-head-name { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ro-expand-all { font-size: 11px; letter-spacing: normal; text-transform: none; }
.ro-row { border-bottom: 1px solid var(--surface-soft); }
.ro-row:last-child { border-bottom: 0; }
.ro-row.has-kids:hover { background: var(--surface-soft); cursor: pointer; }
.ro-caret { display: grid; place-items: center; width: 100%; height: 100%; transition: transform var(--dur-fast); }
.ro-caret.open { transform: rotate(90deg); }
.ro-name { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--q-dark); font-size: 13.5px; }
.ro-name-sub { color: var(--q-dark); font-size: 12.5px; }
.ro-sub .ro-name-sub { opacity: 0.9; }
.ro-name-del { color: var(--q-medium); text-decoration: line-through; }
.ro-tag { padding: 2px 8px; border-radius: 999px; background: #eef5dc; color: #557a15; font-size: 10px; font-weight: var(--w-bold); letter-spacing: 0.04em; text-transform: uppercase; }
.ro-subcount { padding: 1px 7px; border-radius: 999px; background: #e4f1f3; color: var(--q-highlight-3); font-size: 10.5px; font-weight: var(--w-bold); }
.ro-sub { background: var(--q-highlight-4); }
.ro-sub-tick { display: inline-block; width: 8px; height: 8px; margin-left: 8px; border-left: 2px solid var(--q-medium); border-bottom: 2px solid var(--q-medium); opacity: 0.6; }
.pos-share { color: var(--q-medium); font-size: 12px; font-weight: var(--w-bold); }
.ro-sub .num.sub { color: var(--q-dark); font-weight: 600; }
.pos-share.sub { opacity: 0.85; }
.pos-row .num { font-family: var(--font-display); font-size: 13px; font-weight: var(--w-bold); color: var(--q-dark); }
.pos-row .num.del { color: var(--q-medium); text-decoration: line-through; }
.pos-chg { padding: 2px 8px; border-radius: 999px; font-size: 10px; font-weight: var(--w-bold); letter-spacing: 0.04em; text-transform: uppercase; }
.pos-chg.add { background: #eef5dc; color: #557a15; }
.pos-chg.mod { background: #fbf1d8; color: #8a6414; }
.pos-chg.del { background: #f8e0e0; color: var(--danger); }
.ro-row.chg-add { background: #f7fbee; }
.ro-row.chg-mod { background: #fdf8ec; }
.ro-row.chg-del { background: #fdf3f3; }
.pe .pos-list { border: 1px solid var(--divider); border-radius: 13px; padding: 4px 14px 6px; background: #fff; }
.pe-actions { display: flex; gap: 10px; margin-top: 10px; }
.plan-total-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 14px; padding: 14px 18px; border-radius: 13px; background: var(--q-highlight-2); color: rgba(255,255,255,0.85); font-size: 12px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.plan-total-row .ptr-val { color: #fff; font-family: var(--font-display); font-size: 20px; letter-spacing: normal; text-transform: none; }
.plan-over-note { margin-top: 12px; padding: 11px 14px; border-radius: 11px; background: #fbf1d8; color: var(--q-dark); }
.plan-detail-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.foot-hint { color: var(--q-medium); font-size: 12.5px; }
.foot-status { display: inline-flex; align-items: center; gap: 8px; color: var(--q-medium); font-size: 13px; font-weight: var(--w-bold); }

/* Freigabeverlauf */
/* Hinweis auf den begrenzten Protokollausschnitt (FAKE-002, BAL-070). */
.hist-hinweis { margin: 8px 0 0; color: var(--q-medium); font-size: 12px; line-height: var(--lh-normal); }
.hist-list { margin: 8px 0 0; padding: 6px 2px; list-style: none; }
.hist-item { position: relative; display: flex; gap: 14px; padding-bottom: 22px; }
.hist-item:last-child { padding-bottom: 4px; }
.hist-item[role="button"] { cursor: pointer; border-radius: 10px; }
.hist-item[role="button"]:hover .hist-action, .hist-item[role="button"]:focus-visible .hist-action { color: var(--q-highlight-2); }
.hist-rail { position: relative; flex-shrink: 0; width: 28px; }
.hist-item:not(:last-child) .hist-rail::after { content: ''; position: absolute; top: 30px; bottom: -4px; left: 13px; width: 2px; background: var(--divider); }
.hist-node { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--q-medium); color: #fff; }
.hist-node .ui_icon { color: #fff; }
.hist-node.act-approved { background: var(--success); }
.hist-node.act-rejected, .hist-node.act-deleted { background: var(--danger); }
.hist-node.act-returned, .hist-node.act-target_set, .hist-node.act-edited { background: var(--q-highlight-2); }
.hist-node.act-submitted, .hist-node.act-created { background: var(--q-highlight-3); }
.hist-action { display: flex; align-items: center; gap: 9px; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.hist-detail { margin-top: 2px; color: var(--q-dark); opacity: 0.85; font-size: 12.5px; }
.hist-round { padding: 2px 8px; border-radius: 999px; background: var(--q-highlight-4); color: var(--q-highlight-2); font-size: 10.5px; }
.hist-note { margin-top: 7px; padding: 11px 14px; border-radius: 11px; background: var(--surface-soft); color: var(--q-dark); font-size: 12.5px; line-height: 1.55; white-space: pre-line; }
.hist-note.act-returned { background: #fbf1d8; }
.hist-note.act-rejected { background: #f8e0e0; }
.hist-note.act-approved { background: #eef5dc; }
.hist-meta { margin-top: 6px; color: var(--q-medium); font-size: 11.5px; }
.hist-dot { margin: 0 6px; }

/* Entscheidungs-/Einreichdialog */
/* Hoehe an den Inhalt anpassen (statt der festen Modal-Hoehe von 640px),
   damit unter dem Anmerkungsfeld kein grosser Leerraum entsteht. */
.decision-modal { max-width: 560px; height: auto; max-height: calc(100vh - 48px); }
/* GEMESSEN bei BAL-178: Der frisch eingebaute Vollbildschalter setzte die
   Klasse, und das Fenster blieb bei 560 px stehen - ein Knopf ohne Wirkung,
   also genau die Art Attrappe, die hier nichts zu suchen hat. Ursache ist
   nicht die Spezifitaet, sondern die EIGENSCHAFT: `.modal_window.fullscreen`
   setzt `width`, gedeckelt wird aber ueber `max-width` - und das hebt keine
   Breitenangabe auf. Dasselbe gilt fuer die Hoehe, die hier `auto` ist. */
.decision-modal.fullscreen {
  max-width: none;
  height: calc(100vh - 28px);
  max-height: calc(100vh - 28px);
}
.dm-context { margin-bottom: 16px; padding: 14px 16px; border: 1px solid var(--divider); border-radius: 13px; background: var(--surface-soft); }
.dm-ctx-title { color: var(--q-dark); font-size: 14px; font-weight: var(--w-bold); }
.dm-ctx-nums { display: flex; flex-wrap: wrap; gap: 22px; margin-top: 9px; }
.dm-ctx-nums > span { display: flex; flex-direction: column; gap: 2px; }
.dm-ctx-k { color: var(--q-medium); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.dm-ctx-v { color: var(--q-dark); font-family: var(--font-display); font-size: 14.5px; font-weight: var(--w-bold); }
.dm-sendchanges { display: flex; align-items: flex-start; gap: 12px; width: 100%; margin-bottom: 16px; padding: 13px 15px; border: 1px solid var(--divider); border-radius: 13px; background: #fff; text-align: left; }
.dm-sendchanges.on { border-color: var(--q-highlight-2); background: #fafbf3; }
.dm-sendchanges .dm-sc-box { flex-shrink: 0; display: grid; place-items: center; width: 22px; height: 22px; border: 2px solid var(--q-medium); border-radius: 7px; }
.dm-sendchanges.on .dm-sc-box { border-color: var(--q-highlight-2); background: var(--q-highlight-2); }
.dm-sendchanges.on .dm-sc-box .ui_icon { color: #fff; }
.dm-sc-title { display: block; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); }
.dm-sc-sub { display: block; margin-top: 3px; color: var(--q-medium); font-size: 12px; line-height: 1.5; }
.dm-label { display: block; margin-bottom: 7px; color: var(--q-medium); font-size: 11px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.dm-note { width: 100%; min-height: 96px; padding: 12px 14px; resize: vertical; }
.dm-hint { margin-top: 7px; color: var(--danger); font-size: 12px; }
.dm-warn { display: flex; align-items: flex-start; gap: 9px; margin-bottom: 16px; padding: 12px 15px; border: 1px solid #e6c98a; border-radius: 12px; background: #fbf3df; color: #7a5a11; font-size: 12.5px; line-height: 1.55; }
.dm-warn b { font-weight: var(--w-bold); }

/* Einzelne Budgetpositionen zur Freigabe (Freigaben-Seite) */
.single-approvals { margin-top: 26px; }
.sa-head { display: flex; align-items: center; gap: 9px; margin-bottom: 11px; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.sa-count { display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 7px; border-radius: 11px; background: var(--q-highlight-2); color: #fff; font-size: 12px; font-weight: var(--w-bold); }
.sa-row { display: flex; align-items: center; gap: 16px; padding: 14px 18px; border-bottom: 1px solid var(--divider); cursor: pointer; }
.sa-row:last-child { border-bottom: none; }
.sa-row:hover { background: var(--surface-soft); }
.sa-title { color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.sa-meta { margin-top: 3px; color: var(--q-medium); font-size: 12px; }
.sa-amt { margin-left: auto; color: var(--q-dark); font-family: var(--font-display); font-size: 14.5px; font-weight: var(--w-bold); white-space: nowrap; }
.sa-acts { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.icon-action-submit .ui_icon { color: var(--q-highlight-2); }
.plan-assign-link { color: var(--q-highlight-2); font-weight: var(--w-bold); cursor: pointer; }
.plan-assign-link:hover { text-decoration: underline; }

/* Anlage / Zielwertvorgabe */
.plan-create-modal { width: min(620px, calc(100vw - 48px)); }
.fmodal-lead { margin: 0 0 18px; color: var(--q-medium); font-size: 13.5px; line-height: 1.55; }
.cpc-static { padding: 11px 14px; border: 1px solid var(--divider); border-radius: 11px; background: var(--surface-soft); color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.cpc-static-sub { display: block; margin-top: 2px; color: var(--q-medium); font-size: 12px; font-weight: var(--w-regular); }
.cpc-anchor { margin-top: 18px; }
.cpc-anchor-label { margin-bottom: 8px; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); }
.cpc-anchor-hint { color: var(--q-medium); font-weight: var(--w-regular); }
.cpc-anchor-empty { margin-top: 8px; color: var(--q-medium); font-size: 12px; }
.cpc-selplan { margin-top: 10px; padding: 12px 15px; border: 1px solid var(--divider); border-radius: 12px; background: var(--surface-soft); font-weight: var(--w-regular); }
.cpc-selplan-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 3px 0; color: var(--q-medium); font-size: 12.5px; }
.cpc-selplan-row b { color: var(--q-dark); font-weight: var(--w-bold); }
.cpc-selplan-note { display: flex; align-items: flex-start; gap: 7px; margin-top: 8px; padding-top: 9px; border-top: 1px dashed var(--divider); color: var(--q-medium); font-size: 12px; line-height: 1.5; }
.cpc-dup { display: flex; align-items: center; gap: 7px; margin-top: 7px; color: var(--danger); font-size: 12px; font-weight: var(--w-regular); }
.cpc-hint-field { display: flex; align-items: flex-start; gap: 8px; color: var(--q-medium); font-size: 12px; line-height: 1.5; }

/* Planungsassistent: Klammer-Bloecke & Zielwert */
.planner-tbar { margin-bottom: 14px; }
.planner-tbar .tbar { margin: 0; }
.kb-block { border-color: #dbe4f0; background: #fbfcfe; }
.kb-tag { flex-shrink: 0; padding: 3px 9px; border-radius: 999px; background: #e3ebf6; color: var(--q-highlight-2); font-size: 10px; font-weight: var(--w-bold); letter-spacing: 0.05em; text-transform: uppercase; }
.year-amt-group.kb-block { padding: 12px 14px; border: 1px solid #dbe4f0; border-radius: 14px; }
.year-amt-group .yag-title { display: flex; align-items: center; gap: 10px; }
.kb-note { padding: 11px 14px; border-radius: 11px; background: #f2f6fb; color: var(--q-dark); }

/* Budgetbaum: abgeleitete Planungszeilen */
.tree-node-plan { background: #fcfdf9; }
.tree-node-plan .t-name::after { content: 'Planung'; margin-left: 9px; padding: 2px 8px; border-radius: 999px; background: var(--q-highlight-4); color: var(--q-highlight-2); font-size: 10px; font-weight: var(--w-bold); letter-spacing: 0.04em; text-transform: uppercase; vertical-align: 1px; }
.pb-managed { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 8px; color: var(--q-medium); }

/* ── Planungsklammern-Leiste (Budget: Zeitraum · Klammer-Filter · Umschalter) ── */
.plan-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; padding: 10px 14px; border: 1px solid var(--divider); border-radius: 14px; background: #fff; position: relative; }
.plan-bar-lead { display: inline-flex; align-items: center; gap: 7px; font-size: 10.5px; letter-spacing: var(--tracking-xwide); text-transform: uppercase; font-weight: var(--w-bold); color: var(--q-medium); }
.plan-bar-lead .ui_icon { opacity: 0.6; }
.pb-seg { display: inline-flex; gap: 2px; padding: 3px; border: 1px solid var(--q-bright); border-radius: 999px; background: #fff; }
/* Der Periodenschalter nimmt unterhalb des Umbruchs die volle Zeile und teilt
   sie unter seinen beiden Segmenten auf (BAL-182, Befund R-05). GEMESSEN bei
   360px Sichtfeld: 339px in einem 315px breiten Behaelter - die beiden
   Beschriftungen "Aktuelle Periode" und "Zeitraum waehlen" tragen
   `white-space: nowrap` und koennen nicht kuerzer werden.

   `display: flex` statt `inline-flex`, damit der Schalter die Zeile ueberhaupt
   ausfuellen kann; die Pillenform bleibt, sie wird nur breiter. Umgebrochen
   wird NICHT - zwei uebereinanderliegende Halbpillen waeren kein
   Segmentschalter mehr; stattdessen schrumpfen die Segmente gleichmaessig.

   Wie bei `.plan-cards` liegt der Block neben der Komponente und nicht im
   grossen 780er-Block: Der steht vor dieser Definition und wuerde
   ueberschrieben. */
@media (max-width: 780px) {
  /* `min-width: 0` ist hier der wirksame Teil, nicht `display: flex`.
     `.pb-seg` sitzt als flex-Element in `.plan-bar` und hatte
     `flex-shrink: 1` laengst - geschrumpft ist es trotzdem nicht, weil sein
     automatisches Mindestmass die Min-Content-Breite seiner beiden
     `nowrap`-Beschriftungen ist. Dieselbe Falle wie bei `.global_search` in
     BAL-181: Nicht der Schrumpffaktor fehlte, sondern die Erlaubnis, unter das
     Mindestmass zu gehen. */
  .pb-seg { display: flex; min-width: 0; }
  .pb-seg-btn { flex: 1 1 0; min-width: 0; padding-left: 10px; padding-right: 10px; overflow: hidden; text-overflow: ellipsis; }
}
.pb-seg-btn { padding: 7px 17px; background: transparent; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); white-space: nowrap; border-radius: 999px; transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.pb-seg-btn:hover { background: var(--surface-soft); }
.pb-seg-btn.on, .pb-seg-btn.on:hover { background: var(--q-highlight-2); color: #fff; }
.pb-dates { display: inline-flex; align-items: center; gap: 7px; }
.pb-dates-lbl { font-size: 12.5px; font-weight: var(--w-bold); color: var(--q-medium); }
.pb-date { padding: 6px 9px; border: 1px solid var(--divider); border-radius: 9px; background: #fff; color: var(--q-dark); font-size: 12.5px; font-family: inherit; }
.pb-date:focus { border-color: var(--q-highlight-3); }

/* Wo die Anwendung den Fokus ueber die RAHMENFARBE kennzeichnet, wird der
   Standardring des Browsers abgeschaltet. Sonst liegen erneut zwei Ringe in
   zwei Farben uebereinander - teal aus dem Entwurf und die schwarze Haarlinie
   des Browsers (gemessen: 0,67px rgb(16,16,16)). Bisher hat das die pauschale
   dunkelblaue Umrandung verdeckt; seit sie Eingabefelder ausnimmt, kommt der
   Standardring zum Vorschein.

   Der Referenzentwurf macht es an seinen Feldern genauso ausdruecklich, etwa
   bei .atg-new input, .pb-date und .confirm-note textarea.

   Die Liste ist die GEMESSENE Menge: alle acht Regeln dieser Datei, die auf
   :focus eine border-color setzen. Wer eine neunte hinzufuegt, nimmt sie hier
   mit auf - sonst traegt genau dieses Feld wieder zwei Ringe (BAL-095). */
.module_list_search:focus, .module_list_select:focus,
.detail-inline-select:focus,
.planner-field > input:focus, .planner-field > select:focus, .ytb-name-input:focus,
.pos-name:focus, .pos-input input:focus, .imp-textarea:focus,
.content_form_input:focus, .finput:focus,
.pay-inp:focus,
.fselect-coded .fselect:focus,
.ai_drawer_input:focus,
.pb-date:focus { outline: none; }
.pb-spacer { flex: 1; min-width: 0; }
.pb-toggle.active { border-color: var(--q-highlight-2); background: var(--surface-soft); }
.pb-note { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 2px 16px; font-size: 12.5px; color: var(--q-medium); }
.pb-note .ui_icon { opacity: 0.5; }
.pb-note strong { color: var(--q-dark); font-weight: var(--w-bold); }
.pb-note-link { font-size: 12.5px; font-weight: var(--w-bold); color: var(--q-highlight-3); text-decoration: underline; text-underline-offset: 2px; }
.pb-note-link:hover { color: var(--q-highlight-2); }

/* Klammer-Auswahl (Popover) */
.pk-list { display: flex; flex-direction: column; gap: 2px; }
.pk-opt { display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: 10px; text-align: left; transition: background var(--dur-fast) var(--ease-std); }
.pk-opt:hover { background: var(--surface-soft); }
.pk-check { width: 18px; height: 18px; display: grid; place-items: center; flex-shrink: 0; border: 1.5px solid var(--q-medium); border-radius: 5px; transition: all var(--dur-fast) var(--ease-std); }
.pk-check .ui_icon { filter: brightness(0) invert(1); }
.pk-opt.on .pk-check { background: var(--q-highlight-2); border-color: var(--q-highlight-2); }
.pk-info { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pk-title { display: flex; align-items: center; gap: 7px; font-size: 13.5px; font-weight: var(--w-bold); color: var(--q-highlight-2); }
.pk-sub { font-size: 11.5px; color: var(--q-medium); }
.pk-now, .tb-badge-now { padding: 1px 7px; border-radius: 999px; background: rgba(198,211,28,0.35); color: var(--q-highlight-2); font-family: var(--font-display); font-size: 9.5px; font-weight: var(--w-bold); letter-spacing: 0.04em; text-transform: uppercase; }
.tb-badge-now { margin-left: 9px; vertical-align: middle; }
.pk-foot { display: flex; gap: 8px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--divider); }
.pk-foot-btn { flex: 1; padding: 8px; border-radius: 9px; color: var(--q-highlight-3); font-size: 12.5px; font-weight: var(--w-bold); text-align: center; transition: background var(--dur-fast) var(--ease-std); }
.pk-foot-btn:hover { background: var(--surface-soft); }

/* Klammer-Kopfzeile im Budget-Baum */
.tree-bracket { display: grid; grid-template-columns: minmax(280px, 1fr) 130px 130px 120px 96px 106px; align-items: center; gap: 14px; min-width: 900px; padding: 12px 16px; border-top: 1px solid var(--divider); border-left: 3px solid var(--q-highlight-1); background: rgba(198,211,28,0.12); cursor: pointer; transition: background var(--dur-fast) var(--ease-std); }
.tree .tree-bracket:first-child { border-top: 0; }
.tree-bracket:hover { background: rgba(198,211,28,0.2); }
.tree-bracket .tb-title { display: flex; align-items: center; gap: 9px; min-width: 0; }
.tree-bracket .tb-ic { display: grid; place-items: center; flex-shrink: 0; color: var(--q-highlight-2); }
.tree-bracket .tb-name { display: flex; align-items: center; font-family: var(--font-display); font-weight: 700; font-size: 15px; line-height: 1.2; color: var(--q-highlight-2); }
.tree-bracket .tb-meta { margin-top: 2px; font-size: 11.5px; color: var(--q-dark); opacity: 0.65; }
.tree-bracket .tb-amt { text-align: right; font-size: 13px; }
.tree-bracket .tb-amt .big { font-family: var(--font-display); font-weight: 700; color: var(--q-dark); }
.tree-bracket .tb-amt .big.danger { color: var(--danger); }
.tree-bracket .tb-amt small { display: block; font-size: 11px; color: var(--q-medium); }
.tb-count { display: inline-flex; align-items: center; justify-content: center; min-width: 30px; padding: 3px 10px; border-radius: 999px; background: var(--q-highlight-2); color: #fff; font-family: var(--font-display); font-size: 12px; font-weight: 700; }

/* Budget-Listenansicht: Betragsspalten, Ausschöpfung, Perioden-Gruppenkopf */
.budget-list-table td.num { font-family: var(--font-display); font-weight: var(--w-bold); color: var(--q-dark); white-space: nowrap; }
.budget-list-table td.num.danger { color: var(--danger); }
.budget-list-table td.r { text-align: right; }
.budget-list-table th.r { text-align: right; }
.budget-list-table .budget-util-cell { min-width: 150px; }
.module_list_table tr.list-group { cursor: default; }
.module_list_table tr.list-group td { padding: 9px 16px; border-left: 3px solid var(--q-highlight-1); background: rgba(198,211,28,0.12); }
.module_list_table tr.list-group:hover td { background: rgba(198,211,28,0.12); }
.module_list_table tr.list-group .tg-name { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-display); font-weight: 700; font-size: 13.5px; color: var(--q-highlight-2); }
.module_list_table tr.list-group .tg-name .ui_icon { opacity: 0.55; }
.module_list_table tr.list-group .tg-meta { margin-left: 12px; font-size: 11.5px; color: var(--q-dark); opacity: 0.6; }

@media (max-width: 900px) {
  .plan-thead { display: none; }
  /* `min-width: 0` nimmt das `min-width: 820px` der Grundregel zurueck
     (BAL-181). Ohne diese Zeile war die Spaltenanpassung daneben WIRKUNGSLOS:
     Die Grundregel `.plan-thead, .plan-trow` setzt 820px, und die blieb hier
     stehen. GEMESSEN bei 390px vor der Berichtigung: `.plan-trow` 820px breit
     in einem 345px breiten Behaelter - die Zeile wurde also weiterhin
     seitlich verschoben, waehrend das CSS daneben so aussah, als sei der
     Bereich versorgt. Befund R-04 der Bestandsaufnahme. */
  .plan-trow { grid-template-columns: 1fr 110px; min-width: 0; }
  .plan-trow .pt-oe, .plan-trow .pt-num { display: none; }
  .pdh-metabar { gap: 16px; }
  .plan-detail-tabs { padding: 0 16px; }
  .pos-row.einzel { grid-template-columns: 28px 1fr 100px; }
  .pos-row.einzel .pos-share { display: none; }
  .tbar-nums { gap: 14px; }
}

/* ── Hierarchischer Positions-Editor (Freigabedialog & Planungsassistent) ── */
.pe-hint-hier { display: flex; align-items: flex-start; gap: 8px; margin-top: 10px; padding: 11px 14px; border-radius: 11px; background: var(--surface-soft); color: var(--q-medium); font-size: 12.5px; line-height: 1.5; }
.pe-hint-hier b { color: var(--q-dark); }
.hpe { display: flex; flex-direction: column; gap: 10px; }
.hpe-block { border: 1px solid var(--divider); border-radius: 14px; background: #fff; transition: border-color var(--dur-fast), background var(--dur-fast); }
.hpe-block.dyn { border-color: #dbe4f0; }
.hpe-block.drop-over { border: 1.5px dashed var(--q-highlight-3); background: #f2fbfc; }
.hpe-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 12px 14px; }
.hpe-idx { flex-shrink: 0; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; background: var(--surface-soft); color: var(--q-medium); font-family: var(--font-display); font-size: 11px; font-weight: var(--w-bold); }
.hpe-name { flex: 1 1 200px; min-width: 140px; padding: 8px 11px; border: 1px solid var(--divider); border-radius: 9px; color: var(--q-dark); font-size: 13.5px; }
.hpe-name-static { flex: 1 1 200px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.hpe-mainbadge { padding: 2px 8px; border-radius: 999px; background: #e3ebf6; color: var(--q-highlight-2); font-size: 10px; font-weight: var(--w-bold); letter-spacing: 0.04em; text-transform: uppercase; }
.ro-topic { padding: 2px 8px; border-radius: 999px; background: var(--q-highlight-4); color: var(--q-highlight-2); font-size: 10.5px; font-weight: var(--w-bold); }
.hpe-topic-sel { flex: 0 0 auto; }
.hpe-topic-sel select { padding: 7px 26px 7px 10px; border: 1px solid var(--divider); border-radius: 9px; color: var(--q-dark); font-size: 12.5px; background-position: right 8px center; }
.hpe-dyn-toggle { flex-shrink: 0; display: inline-flex; align-items: center; gap: 6px; padding: 7px 11px; border: 1px solid var(--divider); border-radius: 9px; background: #fff; color: var(--q-medium); font-size: 12px; font-weight: var(--w-bold); white-space: nowrap; }
.hpe-dyn-toggle:hover { border-color: var(--q-medium); }
.hpe-dyn-toggle.on { border-color: var(--q-highlight-2); background: var(--q-highlight-2); color: #fff; }
.hpe-dyn-toggle.on .ui_icon { color: #fff; }
.hpe-amt { flex-shrink: 0; display: flex; align-items: center; gap: 9px; }
.hpe-amt input { width: 130px; padding: 8px 10px; border: 1px solid var(--divider); border-radius: 9px; text-align: right; font-family: var(--font-display); font-weight: var(--w-bold); }
.hpe-amt.hpe-amt-computed { padding: 7px 12px; border-radius: 9px; background: var(--surface-soft); }
.hpe-computed { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 13.5px; font-weight: var(--w-bold); }
.hpe-prev { color: var(--q-medium); font-size: 12px; white-space: nowrap; }
.hpe-delta { min-width: 40px; color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-bold); text-align: right; }
.hpe-delta.up { color: var(--danger); } .hpe-delta.down { color: var(--success); } .hpe-delta.flat { color: var(--q-medium); }
.hpe-kids { padding: 4px 14px 12px 40px; border-top: 1px solid var(--surface-soft); }
.hpe-krow { display: flex; align-items: center; gap: 9px; padding: 6px 0; }
.hpe-krow.dragging { opacity: 0.4; }
.hpe-krow .hpe-name { flex: 1 1 180px; }
.hpe-krow .hpe-name-static.sub { flex: 1 1 180px; font-size: 12.5px; font-weight: var(--w-regular); }
.hpe-grip { flex-shrink: 0; display: grid; grid-template-columns: repeat(2, 3px); grid-auto-rows: 3px; gap: 2.5px; width: 15px; padding: 6px 4px; cursor: grab; opacity: 0.55; }
.hpe-grip:hover { opacity: 1; }
.hpe-grip span { display: block; border-radius: 50%; background: var(--q-medium); }
.hpe-grip span:nth-child(1) { grid-row: 1 / 4; grid-column: 1; }
.hpe-grip span:nth-child(2) { grid-row: 1 / 4; grid-column: 2; }
.hpe-grip::before, .hpe-grip::after { content: none; }
.hpe-ktick { flex-shrink: 0; display: block; width: 8px; height: 8px; margin: 0 4px; border-radius: 50%; background: var(--q-medium); opacity: 0.5; }
.hpe-kamt { width: 120px; padding: 7px 9px; border: 1px solid var(--divider); border-radius: 8px; text-align: right; font-family: var(--font-display); font-weight: var(--w-bold); }
.hpe-kfoot { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 6px; padding-top: 9px; border-top: 1px dashed var(--divider); }
.hpe-dynrow { display: flex; align-items: center; gap: 10px; }
.hpe-dynsw { position: relative; display: inline-flex; width: 34px; height: 19px; flex: 0 0 auto; border-radius: 999px; background: #d8ddd8; cursor: pointer; transition: background var(--dur-fast) var(--ease-std); }
.hpe-dynsw .knob { position: absolute; top: 2.5px; left: 2.5px; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.22); transition: transform var(--dur-fast) var(--ease-std); }
.hpe-dynsw.on { background: var(--q-highlight-3); }
.hpe-dynsw.on .knob { transform: translateX(15px); }
.hpe-dynlabel { color: var(--q-medium); font-size: 12px; }
.hpe-subtotal { margin-left: auto; color: var(--q-dark); font-family: var(--font-display); font-size: 13.5px; }
.hpe-structnote { color: var(--q-medium); font-size: 12px; }
.yag-sub { margin-left: auto; color: var(--q-medium); font-size: 12.5px; font-weight: var(--w-regular); }

@media (max-width: 900px) {
  .hpe-head { align-items: stretch; }
  .hpe-name, .hpe-name-static { flex-basis: 100%; }
  .hpe-topic-sel, .hpe-dyn-toggle, .hpe-amt { flex-basis: auto; }
  .hpe-kids { padding-left: 20px; }
}

/* ── Planungsassistent: Themenauswahl (kompakte Liste, positionsgenaue Uebernahme) ── */
.themen-intro { margin: 0 0 12px; color: var(--q-medium); font-size: 12.5px; line-height: 1.5; }
.tpick { overflow: hidden; border: 1px solid var(--divider); border-radius: 12px; background: #fff; }
.tpick-item { border-top: 1px solid var(--divider); }
.tpick-item:first-child { border-top: 0; }
.tpick-item.open { background: #fcfdfb; }
.tpick-row { display: flex; align-items: center; gap: 12px; padding: 11px 14px; transition: background var(--dur-fast) var(--ease-std); }
.tpick-row:hover { background: var(--surface-soft); }
.tpick-item.is-sub .tpick-row { padding-left: 34px; position: relative; }
.tpick-item.is-sub .tpick-row::before { content: ""; position: absolute; left: 20px; top: 50%; width: 8px; height: 1px; background: var(--q-medium); opacity: 0.5; }
.tpick-title { flex: 1 1 auto; min-width: 0; background: none; text-align: left; display: flex; flex-direction: column; gap: 1px; }
.tpk-name { display: flex; align-items: baseline; gap: 8px; color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.tpick-item.is-sub .tpk-name { font-size: 13px; font-weight: 600; }
.tpk-parent { color: var(--q-medium); font-size: 10.5px; font-weight: 600; }
.tpk-meta { color: var(--q-medium); font-size: 11.5px; }
.tpk-sum { flex-shrink: 0; min-width: 64px; text-align: right; color: var(--q-medium); font-family: var(--font-display); font-size: 13px; font-weight: var(--w-bold); }
.tpk-sum.on { color: var(--q-highlight-2); }
.tpk-exp { width: 30px; height: 30px; display: grid; place-items: center; flex-shrink: 0; border-radius: 8px; transition: background var(--dur-fast) var(--ease-std), transform var(--dur-fast) var(--ease-std); }
.tpk-exp:hover { background: var(--q-bright); }
.tpk-exp.open { transform: rotate(180deg); }
.tpick-pos { display: flex; flex-direction: column; gap: 2px; padding: 4px 14px 12px 46px; }
.tpick-item.is-sub .tpick-pos { padding-left: 60px; }
.tpk-posrow { display: flex; align-items: center; gap: 11px; width: 100%; padding: 8px 10px; border-radius: 8px; text-align: left; transition: background var(--dur-fast) var(--ease-std); }
.tpk-posrow:hover { background: var(--surface-soft); }
.tpk-posrow.on { background: #f6f8ec; }
.tpk-posname { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; color: var(--q-dark); font-size: 13px; }
.tpk-posamt { flex-shrink: 0; color: var(--q-medium); font-family: var(--font-display); font-size: 12.5px; font-weight: 600; }
.tpk-posrow.on .tpk-posamt { color: var(--q-highlight-2); }
.tc-box.box-none, .tc-box.box-some, .tc-box.box-all { display: grid; place-items: center; width: 20px; height: 20px; padding: 0; flex-shrink: 0; border: 2px solid var(--q-medium); border-radius: 6px; background: #fff; transition: background var(--dur-fast) var(--ease-std), border-color var(--dur-fast) var(--ease-std); }
.tc-box.box-all, .tc-box.box-some { border-color: var(--q-highlight-2); }
.tc-box.box-all { background: var(--q-highlight-2); }
.tc-box.box-all .ui_icon { color: #fff; }
.tc-box.box-some .box-dash { width: 11px; height: 2.5px; border-radius: 2px; background: var(--q-highlight-2); }
.tc-box.small { width: 20px; height: 20px; border-radius: 6px; }
.tp-bound-tag { padding: 1px 6px; border-radius: 999px; background: #e1f1f3; color: var(--q-highlight-3); font-size: 9.5px; font-weight: var(--w-bold); letter-spacing: 0.04em; text-transform: uppercase; }

/* ── Planungsassistent: Einzelbudget (Budgetposition-Schritt) ─────────── */
.single-struct { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--divider); }
.single-struct .ss-head { margin-bottom: 6px; }
.field-warn { display: flex; align-items: center; gap: 6px; margin-top: 7px; color: #9a6b00; font-size: 12px; }
.existing-ref { margin-bottom: 18px; padding: 14px 16px; border: 1px solid var(--divider); border-radius: 12px; background: var(--surface-soft); }
.er-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); }
.er-head .er-count { margin-left: auto; color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-regular); }
.er-list { display: flex; flex-direction: column; gap: 1px; }
.er-row { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: 7px; color: var(--q-dark); font-size: 13px; }
.er-row.sub { padding-left: 18px; }
.er-row.match { background: #fbf3d6; }
.er-name { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; }
.er-row.sub .er-name { color: var(--q-medium); font-size: 12.5px; }
.er-tick { width: 5px; height: 5px; flex-shrink: 0; border-radius: 50%; background: var(--q-medium); }
.er-mainbadge { padding: 1px 6px; border-radius: 999px; background: #e7ecf2; color: var(--q-highlight-2); font-size: 9.5px; font-weight: var(--w-bold); letter-spacing: 0.04em; text-transform: uppercase; }
.er-amt { flex-shrink: 0; color: var(--q-medium); font-family: var(--font-display); font-size: 12.5px; }
.er-foot { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--divider); color: var(--q-medium); font-size: 11.5px; line-height: 1.5; }

/* ── Planungsassistent: Struktur & Beträge (dialoggestützte Positionsliste) ── */
.year-topic-block.topic-group { padding: 0; overflow: hidden; background: #fff; }
.tg-head { display: flex; align-items: center; gap: 12px; padding: 12px 14px; margin: 0; border-bottom: 1px solid var(--divider); background: var(--surface-soft); }
.tg-icon { width: 32px; height: 32px; border-radius: 9px; background: var(--q-highlight-2); display: grid; place-items: center; flex-shrink: 0; color: #fff; }
.tg-icon .ui_icon { background: #fff; }
.tg-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0; }
.tg-eyebrow { font-size: 9.5px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); color: var(--q-medium); }
.tg-main .fsel { width: 100%; }
.tg-main .fsel-trigger { border: 0; background: transparent; padding: 0; height: auto; min-height: 0; }
.tg-main .fsel-trigger .fsel-val { font-family: var(--font-display); font-weight: var(--w-bold); font-size: 16px; color: var(--q-highlight-2); }
.tg-main .fsel-trigger:hover .fsel-val { color: var(--q-highlight-3); }
.tg-main .fsel-trigger .fsel-ph { font-family: var(--font-display); font-weight: var(--w-bold); font-size: 16px; color: var(--q-medium); }
.tg-total { display: flex; flex-direction: column; align-items: flex-end; gap: 0; flex-shrink: 0; }
.tg-total .tg-total-k { font-size: 9.5px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); color: var(--q-medium); }
.tg-total b { font-family: var(--font-display); font-weight: var(--w-bold); font-size: 16px; color: var(--q-dark); }
.tg-remove { width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; flex-shrink: 0; transition: background var(--dur-fast) var(--ease-std); }
.tg-remove:hover { background: var(--q-bright); }
.topic-group .pos-clean { padding: 8px 12px 12px; }
.pos-clean { display: flex; flex-direction: column; gap: 4px; }
.pos-clean-empty { font-size: 12.5px; color: var(--q-medium); padding: 10px 2px 6px; }
.pcl-item { border-radius: 9px; }
.pcl-item.has-kids { background: #fafdfd; border: 1px solid var(--divider); padding: 2px; }
.pcl-row { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 8px; transition: background var(--dur-fast) var(--ease-std); }
.pcl-row:hover { background: var(--surface-soft); }
.pcl-item.has-kids > .pcl-row:first-child:hover { background: transparent; }
.pcl-row.child { padding-left: 22px; }
.pcl-tick { width: 5px; height: 5px; border-radius: 50%; background: var(--q-medium); flex-shrink: 0; }
.pcl-name { flex: 1 1 auto; min-width: 0; font-size: 13.5px; color: var(--q-dark); display: flex; align-items: center; gap: 8px; font-weight: 600; }
.pcl-row.child .pcl-name { font-weight: var(--w-regular); font-size: 13px; }
.pcl-badge { font-size: 10px; font-weight: var(--w-bold); text-transform: uppercase; letter-spacing: .04em; color: var(--q-highlight-2); background: #e7ecf2; padding: 1px 7px; border-radius: 999px; }
.pcl-amt { flex-shrink: 0; font-family: var(--font-display); font-weight: var(--w-bold); font-size: 13.5px; color: var(--q-dark); }
.pcl-row.child .pcl-amt { font-weight: 600; font-size: 12.5px; color: var(--q-medium); }
.pcl-actions { display: flex; gap: 2px; flex-shrink: 0; }
.pcl-btn { width: 28px; height: 28px; border-radius: 7px; display: grid; place-items: center; color: var(--q-medium); transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.pcl-btn:hover { background: var(--q-bright); color: var(--q-highlight-2); }
.pcl-btn .ui_icon { background: currentColor; }
.pcl-add { display: inline-flex; align-items: center; gap: 8px; margin-top: 6px; padding: 9px 12px; border: 1.5px dashed var(--q-medium); border-radius: 9px; color: var(--q-highlight-3); font-size: 13px; font-weight: var(--w-bold); transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std); align-self: flex-start; }
.pcl-add:hover { border-color: var(--q-highlight-3); background: #f3fafb; }
.pcl-add[disabled] { opacity: 0.5; pointer-events: none; }
.pcl-add .ui_icon { background: var(--q-highlight-3); }
.hpe-planmark { width: 6px; height: 6px; border-radius: 50%; background: var(--q-highlight-3); flex-shrink: 0; opacity: 0.75; }
.plan-legend { display: inline-flex; align-items: center; gap: 6px; margin-left: 10px; font-size: 12px; color: var(--q-medium); }
.plan-legend .hpe-planmark { display: inline-block; }
.ytb-namewrap { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ytb-label { display: flex; align-items: center; gap: 8px; font-size: 11px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); color: var(--q-medium); }
.ytb-ctx { text-transform: none; letter-spacing: 0; font-weight: 600; font-size: 11px; color: var(--q-highlight-3); }
.year-topic-block.kb-block .ytb-head { align-items: flex-end; }
.add-topicgroup { margin-top: 6px; }
.atg-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.atg-panel { border: 1px dashed var(--q-medium); border-radius: 12px; padding: 16px; background: var(--surface-soft); }
.atg-field { display: flex; flex-direction: column; gap: 6px; }
.atg-footrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; }
.atg-newlink { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: var(--w-bold); color: var(--q-highlight-3); }
.atg-newlink:hover { color: var(--q-highlight-2); }
.atg-newlink .ui_icon { background: currentColor; }
.atg-empty { font-size: 12.5px; color: var(--q-medium); padding: 10px 0; }
.atg-cancel { margin-top: 0; font-size: 12.5px; color: var(--q-medium); font-weight: 600; }
.atg-cancel:hover { color: var(--q-dark); }

/* ── Planungsassistent: Positionsdialog (Budgetdialog im Planungsmodus) ── */
.planner-posdlg-overlay { z-index: 120; opacity: 1; pointer-events: auto; }
.planner-posdlg { z-index: 121; height: auto; max-height: min(760px, calc(100vh - 48px)); }
/* Dieselbe Falle wie bei .decision-modal, nur fuer die Hoehe: Diese Regel
   steht SPAETER als `.modal_window.fullscreen` und gewinnt bei gleicher
   Spezifitaet - im Vollbild blieb das Fenster 760 px hoch. */
.planner-posdlg.fullscreen { height: calc(100vh - 28px); max-height: calc(100vh - 28px); }
.ppd-context { display: flex; flex-wrap: wrap; gap: 8px 22px; padding: 12px 14px; background: var(--surface-soft); border-radius: 10px; margin-bottom: 18px; font-size: 13px; color: var(--q-dark); }
.ppd-context .ppd-k { display: block; font-size: 10px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: var(--w-bold); color: var(--q-medium); margin-bottom: 1px; }
.ppd-context > span { font-weight: 600; }
.planner-posdlg .ffield .req { color: #d0463b; }

/* Standardwerte (Stammdaten) — Kategorie-Chips und Tabellen */
.md-cats { display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px; }
.md-cat-group { display: flex; align-items: baseline; gap: 12px; }
.md-cat-grouplabel { flex-shrink: 0; width: 96px; font-size: 11px; text-transform: uppercase; letter-spacing: var(--tracking-wide); font-weight: var(--w-bold); color: var(--q-medium); padding-top: 7px; }
.md-cat-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.md-chip { display: inline-flex; align-items: center; gap: 8px; padding: 7px 13px; border-radius: 999px; background: #fff; border: 1px solid var(--divider); font-size: 12.5px; font-weight: var(--w-regular); color: var(--q-dark); cursor: pointer; transition: background .15s, border-color .15s, color .15s; }
.md-chip:hover { border-color: var(--q-medium); }
.md-chip.on { background: var(--q-highlight-2); border-color: var(--q-highlight-2); color: #fff; font-weight: var(--w-bold); }
.md-chip-count { font-size: 11px; font-weight: var(--w-bold); min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; background: var(--surface-soft); color: var(--q-medium); }
.md-chip.on .md-chip-count { background: rgba(255,255,255,0.22); color: #fff; }
.md-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--q-highlight-2); background: var(--surface-soft); padding: 2px 8px; border-radius: 6px; }
.md-table th.r, .md-table td.r { text-align: right; }
.md-table tbody tr { cursor: pointer; }
.fbtn-danger { color: var(--danger); }
.fbtn-danger:hover { background: #f8e0e0; }

/* ── Freigabe-Workflow: destruktiver Fußbereich + Zeilen-/Karten-Aktionen ── */
.plan-detail-foot .pdf-danger-slot { flex: 0 0 auto; display: flex; align-items: center; }
.plan-detail-foot .pdf-danger-slot:empty { display: none; }
.plan-detail-foot .pdf-main { flex: 1 1 auto; display: flex; align-items: center; justify-content: space-between; gap: 12px; min-width: 0; }
.fbtn-quiet { color: var(--q-medium); }
.fbtn-quiet:hover { color: var(--q-highlight-2); background: var(--surface-soft); }
.pt-statuscell { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.pt-statuscell .row-acts { opacity: 0.55; transition: opacity var(--dur-fast) var(--ease-std); }
.plan-trow:hover .pt-statuscell .row-acts, .plan-trow:focus-within .pt-statuscell .row-acts { opacity: 1; }
.pc-top .row-acts { margin-left: auto; opacity: 0.55; transition: opacity var(--dur-fast) var(--ease-std); }
.plan-card:hover .pc-top .row-acts, .plan-card:focus-within .pc-top .row-acts { opacity: 1; }

/* ── Nicht zuordenbare Budgetpositionen in der Auswahlliste ── */
.fsel-opt-disabled { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 12px; cursor: not-allowed; opacity: 0.85; }
.fsel-opt-disabled .fo-label { color: var(--q-medium); }
.fsel-opt-disabled:hover { background: transparent; }
.fsel-opt .fo-note, .fsel-opt-disabled .fo-note { flex-shrink: 0; margin-left: auto; font-size: 10px; font-weight: var(--w-bold); text-transform: uppercase; letter-spacing: 0.04em; color: #b8791c; background: #fbf1de; padding: 2px 7px; border-radius: 999px; }
.budget-warn-badge { display: inline-flex; align-items: center; justify-content: center; margin-left: 6px; width: 17px; height: 17px; border-radius: 50%; background: #fbf1de; color: #b8791c; vertical-align: middle; }
.budget-warn-badge .ui_icon { color: #b8791c; }

/* ── Budget-Lagebild (druckbarer Report, Export aus dem Dashboard) ───────── */
.report-portal { position: fixed; inset: 0; z-index: 1200; display: flex; flex-direction: column; }
.report-scrim { position: absolute; inset: 0; background: rgba(16, 49, 78, 0.42); backdrop-filter: blur(4px); }
.report-toolbar { position: relative; z-index: 2; flex-shrink: 0; display: flex; align-items: center; justify-content: space-between; padding: 12px 20px; background: var(--q-highlight-2); color: #fff; }
.rp-tb-title { display: inline-flex; align-items: center; gap: 9px; font-family: var(--font-display); font-weight: 600; font-size: 15px; }
.rp-tb-title .ui_icon { background-color: #fff; }
.rp-tb-actions { display: flex; gap: 10px; }
.report-toolbar .button_ghost { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.35); color: #fff; }
.report-toolbar .button_ghost:hover { border-color: #fff; }
.report-toolbar .button_primary { background: #fff; color: var(--q-highlight-2); }
.report-toolbar .button_primary:hover { background: #eef1f4; }

.report-scroll { position: relative; z-index: 1; flex: 1; overflow: auto; padding: 28px 20px 60px; display: flex; justify-content: center; }
.report-sheet { width: 210mm; min-height: 297mm; box-sizing: border-box; background: #fff; box-shadow: var(--shadow-elevated); border-radius: 6px; padding: 18mm 16mm; align-self: flex-start; color: var(--q-dark); font-size: 12px; line-height: 1.5; }

.rp-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; padding-bottom: 16px; border-bottom: 2px solid var(--q-highlight-1); margin-bottom: 22px; }
.rp-eyebrow { font-size: 10px; text-transform: uppercase; letter-spacing: 0.10em; color: var(--q-medium); font-weight: var(--w-bold); margin-bottom: 6px; }
.rp-title { font-family: var(--font-display); font-weight: 600; font-size: 26px; color: var(--q-highlight-2); line-height: 1.1; margin: 0 0 6px; }
.rp-sub { font-size: 12px; color: var(--q-dark); max-width: 60ch; }
.rp-brand { display: inline-flex; align-items: center; gap: 9px; white-space: nowrap; }
.rp-brand-mark { width: 46px; height: 46px; display: block; }

.rp-section { margin-bottom: 24px; }
.rp-h2 { font-family: var(--font-display); font-weight: 600; font-size: 15px; color: var(--q-highlight-3); margin: 0 0 12px; }
.rp-avoid-break { break-inside: avoid; }

.rp-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.rp-kpi { border: 1px solid var(--divider); border-left: 4px solid var(--q-highlight-3); border-radius: 4px; padding: 12px 14px; }
.rp-kpi.warn { border-left-color: var(--warning); }
.rp-kpi.over { border-left-color: var(--danger); }
.rp-kpi.ok { border-left-color: #5a8516; }
.rp-kpi-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--q-medium); font-weight: var(--w-bold); }
.rp-kpi-val { font-size: 22px; font-weight: 800; color: var(--q-highlight-2); line-height: 1.2; margin: 4px 0 2px; }
.rp-kpi-sub { font-size: 10.5px; color: var(--q-dark); }

.rp-tbl { width: 100%; border-collapse: collapse; font-size: 11px; }
.rp-tbl th { text-align: left; font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--q-medium); font-weight: var(--w-bold); padding: 6px 8px; border-bottom: 1.5px solid var(--q-bright); }
.rp-tbl td { padding: 6px 8px; border-bottom: 1px solid #eee; vertical-align: middle; }
.rp-tbl .r { text-align: right; }
.rp-mono { font-variant-numeric: tabular-nums; }
.rp-tbl tfoot td { border-top: 1.5px solid var(--q-highlight-2); border-bottom: none; padding-top: 8px; }
.rp-child td:first-child { padding-left: 8px; }
.rp-indent { display: inline-block; padding-left: 16px; position: relative; color: var(--q-dark); }
.rp-indent::before { content: "\2514"; position: absolute; left: 2px; color: var(--q-medium); }
.rp-danger { color: var(--danger); font-weight: var(--w-bold); }

.rp-util { display: inline-flex; align-items: center; gap: 7px; justify-content: flex-end; }
.rp-util-bar { width: 54px; height: 5px; border-radius: 3px; background: var(--q-bright); overflow: hidden; }
.rp-util-fill { display: block; height: 100%; border-radius: 3px; }
.rp-util-fill.u-ok { background: #5a8516; } .rp-util-fill.u-warn { background: #e0a81e; }
.rp-util-fill.u-high { background: #e08a2b; } .rp-util-fill.u-over { background: #b83232; }
.rp-util-pct { font-size: 10.5px; font-weight: var(--w-bold); font-variant-numeric: tabular-nums; min-width: 38px; text-align: right; }
.rp-util-pct.u-ok { color: #5a8516; } .rp-util-pct.u-warn { color: #b0801e; }
.rp-util-pct.u-high { color: #c0721e; } .rp-util-pct.u-over { color: #b83232; }

.rp-attn { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.rp-attn-item { border: 1px solid var(--divider); border-left: 4px solid var(--q-medium); border-radius: 4px; padding: 9px 12px; }
.rp-attn-item.t-danger { border-left-color: #b83232; background: #fcf4f4; }
.rp-attn-item.t-warn { border-left-color: #e0a81e; background: #fdfaf0; }
.rp-attn-cat { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: var(--w-bold); color: var(--q-medium); }
.rp-attn-title { font-size: 12.5px; font-weight: var(--w-bold); color: var(--q-highlight-2); margin: 1px 0; }
.rp-attn-detail { font-size: 10.5px; color: var(--q-dark); }

.rp-empty { font-size: 11.5px; color: var(--q-medium); font-style: italic; }
.rp-foot { display: flex; justify-content: space-between; font-size: 9.5px; color: var(--q-medium); padding-top: 12px; margin-top: 24px; border-top: 1px solid var(--q-bright); }
.rp-reg { font-size: 0.7em; vertical-align: super; }

.rp-tbl .status_badge { font-size: 9.5px; padding: 2px 8px; }

@media print {
  html, body { background: #fff !important; }
  .app_shell { display: none !important; }
  .report-portal { position: static !important; z-index: auto; display: block; }
  .report-scrim, .report-toolbar { display: none !important; }
  .report-scroll { position: static !important; overflow: visible !important; padding: 0 !important; display: block !important; }
  .report-sheet { width: auto !important; min-height: 0 !important; box-shadow: none !important; border-radius: 0 !important; padding: 0 !important; }
  .rp-avoid-break { break-inside: avoid; }
  @page { size: A4; margin: 14mm; }
}

/* ── IAM-Verwaltung: Checkbox-Gruppen in den Einstellungs-Dialogen ── */
.iam-checkgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 4px 14px; margin-top: 4px; }
.iam-check { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; padding: 5px 8px; border-radius: 8px; cursor: pointer; user-select: none; }
.iam-check:hover { background: rgba(0, 0, 0, 0.05); }
.iam-check input { accent-color: var(--q-primary, #16324f); }

/* Meldungsbereich (Befunde FAKE-015, A11Y-001; Gruppe G-15).
   Haengt an <body>, nicht in #app: render() ersetzt dessen Markup, und ein
   Live-Bereich, der neu entsteht, wird von Screenreadern nicht vorgelesen. */
.app_status {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%);
    z-index: 9999;
    max-width: min(560px, calc(100vw - 32px));
    padding: 12px 18px;
    border-radius: 10px;
    border: 1px solid var(--q-border, #d9dde3);
    background: var(--q-surface, #ffffff);
    color: var(--q-text, #1d2430);
    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.18);
    font-size: 14px;
    line-height: 1.45;
}

/* Meldung mit Handlung (BAL-146). Der Live-Bereich bleibt, was er ist; die
   Schaltflaeche liegt darin und fuellt ihn aus - dann trifft ein Klick
   ueberall, wo die Meldung steht, und nicht nur den Text.

   Die Schriftwerte werden ausdruecklich gesetzt: button erbt zwar ueber die
   globale Regel "button, input, textarea, select { font: inherit }", aber
   Ausrichtung und Zeilenhoehe kaemen sonst vom Browser. */
/* Eine Meldung ohne Handlung hat nichts zum Anklicken und darf darunter nichts
   blockieren (BAL-208, Nachtrag). GEMESSEN am 2026-10-04 bei 740 x 360: "Themen
   abgeglichen" lag genau auf "Tour starten" der Bereichshilfe und fing den
   Fingertipp ab; eine Fehlermeldung bliebe dort stehen, bis eine neue kommt. */
.app_status:not(.app_status_klickbar) { pointer-events: none; }
/* Waehrend die Bereichshilfe offen ist, steht die Meldung oben - unten liegen
   die Knoepfe der Karte. Die Klasse setzt bereichshilfeNachziehen(). */
html.bereichshilfe_offen .app_status { top: 12px; bottom: auto; }
.app_status_klickbar { padding: 0; }
.app_status_aktion {
  display: block; width: 100%; margin: 0; padding: 12px 18px;
  border: 0; border-radius: 10px; background: transparent;
  color: inherit; text-align: left;
  font-family: var(--font-sans); font-size: 14px; font-weight: var(--w-regular); line-height: 1.45;
  cursor: pointer;
}
.app_status_aktion:hover { background: rgba(0, 0, 0, 0.04); }
/* Sichtbarer Fokus: Die Meldung ist mit der Tastatur erreichbar, sonst waere
   sie ein Weg, den nur die Maus geht. */
.app_status_aktion:focus-visible { outline: 2px solid var(--q-highlight-2); outline-offset: -3px; }

.app_status_fehler {
    border-color: #c2410c;
    background: #fff5f2;
    color: #7c2d12;
}

.app_status_erfolg {
    border-color: #15803d;
    background: #f2fbf5;
    color: #14532d;
}

/* Seite „Kein Zugriff" (Befund SEC-017, Gruppe G-30, Aufgabe BAL-060).
   Eigenstaendig gestaltet, weil sie ausserhalb der SPA gerendert wird und
   deren Aufbau nicht zur Verfuegung steht. */
.kz_seite {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--color-surface-muted, #f4f5f7);
}
.kz_karte {
  max-width: 34rem;
  padding: 32px;
  border-radius: 12px;
  background: var(--color-surface, #fff);
  box-shadow: 0 2px 16px rgba(16, 24, 40, .08);
}
.kz_titel { margin: 0 0 12px; font-size: 1.375rem; }
.kz_text { margin: 0 0 12px; line-height: 1.55; }
.kz_text_leise { color: var(--color-text-muted, #5c6370); }
.kz_aktionen { margin: 24px 0 0; }

/* Kennzeichnung eines festen fachlichen Stichtags im Lagebericht
   (Befund FAKE-016, Gruppe G-29, Aufgabe BAL-061). Erscheint nur, wenn der
   Stichtag vom heutigen Tag abweicht. */
.rp-stichtag {
  font-weight: 400;
  opacity: .75;
}

/* ── Pagination ──────────────────────────────────────────────────────────────
   Aufgabe BAL-088, Konzept docs/user-experience/pagination.md.
   Klassenreihe: die kurze Reihe (pg-), wie ltb-, fseg-, ak- in dieser Datei.
   Begruendung zu POL-001: Das Bedienelement sitzt unmittelbar an der
   Listen-Toolbar und teilt deren Bausteine (fseg, ltb-facet-label); eine
   Praefixlogik-Komponente daneben haette zwei Schreibweisen in einem
   zusammenhaengenden Bedienbereich erzeugt. */
.pg-leiste { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 2px; padding: 12px 14px; border-top: 1px solid var(--divider); }
.pg-stand { font-size: 12.5px; color: #6d6d6d; }
.pg-seiten { display: flex; align-items: center; gap: 4px; }
.pg-seite, .pg-pfeil { display: grid; place-items: center; min-width: 28px; height: 28px; padding: 0 7px; border-radius: 8px; background: transparent; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.pg-seite:hover:not(.on), .pg-pfeil:hover:not(:disabled) { background: var(--surface-soft); }
.pg-seite.on { background: var(--q-highlight-2); color: #fff; font-weight: var(--w-bold); }
.pg-pfeil:disabled { opacity: 0.32; cursor: default; }
.pg-luecke { min-width: 18px; text-align: center; color: #9a9a9a; font-size: 12.5px; }

/* Anhaengende Modi: Stand und Handlungen untereinander, mittig - hier gibt es
   keine Ortsangabe, an der sich das Auge links ausrichten koennte. */
.pg-leiste-fluss { flex-direction: column; justify-content: center; gap: 10px; }
.pg-fluss-aktionen { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center; }
.pg-laedt { color: #737373; }

/* Die Marke ist der Ausloeser des Modus "Beim Scrollen". Sie traegt bewusst
   eine Hoehe: Ein Element ohne Ausdehnung wird von IntersectionObserver in
   manchen Lagen nie als sichtbar gemeldet. */
.pg-marke { width: 100%; height: 1px; }


.pg-hinweis { margin-top: 8px; font-size: 11.5px; line-height: 1.45; color: #737373; }
/* Vier Schalter passen nicht in eine Zeile des Panels. */
.fseg-wrap { flex-wrap: wrap; }

/* Konzept 7.3: Die Ladeanimation respektiert die Systemeinstellung fuer
   reduzierte Bewegung. Der Ladezustand bleibt sichtbar - nur die Drehung
   entfaellt, sonst waere die Aussage weg statt der Bewegung. */
@media (prefers-reduced-motion: reduce) {
  .meter-seg { transition: none; }
}

/* Modusauswahl als Liste statt als Segmented Control (BAL-088, Nachbesserung).
   GEMESSEN: Das Sortier-Panel bietet 220,7px Innenbreite; die vier
   Beschriftungen brauchen nebeneinander 396,4px. "Beim Scrollen" allein
   braucht 118,6px und bekam 108,2 - der Schalter brach auf zwei Zeilen.
   Die Liste uebernimmt das Muster von .ltb-sort-opt darueber; neu ist nur die
   zweite Zeile je Eintrag.

   Die Zeile setzt Groesse, GEWICHT, Zeilenhoehe und Farbe ausdruecklich:
   .ltb-sort-opt.on setzt font-weight auf bold, was sonst auch den Erklaertext
   fett stellte - dieselbe Vererbungsfalle, die in diesem Projekt schon viermal
   in eine Komponente hineingewirkt hat. */
.pg-modus { align-items: flex-start; padding: 7px 10px; }
.pg-modus-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pg-modus-name { font-size: 13px; line-height: 1.3; }
.pg-modus-sub { font-size: 11.5px; font-weight: var(--w-light); line-height: 1.35; color: #6f6f75; }
.pg-modus.on .pg-modus-sub { color: #5d6b52; }
/* Gesperrt bei Schrittweite "Alle": sichtbar, aber ohne Zeigerreaktion. */
.pg-modus:disabled { opacity: 0.42; cursor: default; }
.pg-modus:disabled:hover { background: transparent; }
.pg-modus-liste { margin-top: 4px; }

/* Tastaturfokus auf Tabellenzeilen: FLAECHE statt Umrandung (BAL-096).
   Beanstandung der Auftraggeberin: Beim Durchschalten sei die markierte Zeile
   kaum zu erkennen - mal nur ein Strich oben, mal oben und unten.

   URSACHE, gemessen: Eine Zeile ist display: table-row und bildet damit kein
   eigenes Malrechteck; die Zellen zeichnen darueber. Eine Umrandung wird von
   den Browsern an solchen Zeilen uneinheitlich und teilweise beschnitten
   gezeichnet - genau die beschriebenen Striche. Die Anwendung fuehrt fuer
   Zeilen ohnehin schon eine Flaechensprache (:hover auf rgb(250,251,250)).

   Die Flaeche sitzt auf den ZELLEN, nicht auf der Zeile: Eine Gruppenzeile
   (.list-group td) hat einen eigenen Zellhintergrund, der einen Zeilen-
   hintergrund verdecken wuerde.

   Farbe: --q-highlight-3 bei 22 Prozent, also derselbe Ton, mit dem seit
   BAL-095 auch Eingabefelder ihren Fokus zeigen. GEMESSEN: rgb(204,235,239),
   1,26 : 1 gegen Weiss und 1,21 : 1 gegen den Hover-Ton - unterscheidbar von
   beidem. AUSGEWIESEN: Kein heller Ton der Palette erreicht die 3 : 1, die
   WCAG 1.4.11 fuer eine Flaechenkennzeichnung ansetzt; ueber eine ganze
   Zeilenhoehe ist die Flaeche aber deutlich besser wahrnehmbar als die
   beschnittene Umrandung, die sie ersetzt. Text darauf bleibt bei 10,63 : 1. */
tr:focus-visible { outline: none; }
tr:focus-visible > td { background: rgba(21, 165, 181, 0.22); }
/* KEINE Abrundung an den Zellen. Erst gerundet (BAL-096), auf Wunsch der
   Auftraggeberin wieder entfernt (BAL-098). GEMESSEN war die Tabellenzeile
   damit die einzige Eintragsart, deren Rundung erst durch den Fokus entstand
   (0px auf 10px); Baumknoten und Freigabezeilen sind ohnehin eckig. Karten und
   Kacheln behalten ihre eigene Rundung (12 bis 16px) - die kommt aus ihrer
   Form und nicht aus der Kennzeichnung, und eine eckige Flaeche wuerde die
   Kartenform zerschneiden. */

/* Einheitliche Kennzeichnung fokussierter LISTENEINTRAEGE (BAL-097).
   Beanstandung der Auftraggeberin: Die Kennzeichnung sei nicht konsequent -
   im Budget wuerden Eintraege anders hervorgehoben, teils noch mit Rahmen, als
   etwa bei Zahlungen oder Rechnungen. Zutreffend: BAL-096 hatte nur
   Tabellenzeilen umgestellt.

   GEMESSENE MENGE ueber elf Ansichten: acht Arten von Listeneintraegen, davon
   sieben noch mit der dunkelblauen Umrandung - Baumknoten im Budget
   (.tree-node), Themenkacheln (.topic-card), Freigabezeilen (.plan-trow),
   Einzelpositionen (.sa-row), Kontingentkarten (.gauge-card),
   Benachrichtigungen (.notif), Wissenskarten (.kb-card). Nur die
   Tabellenzeilen trugen die Flaeche.

   Statt neun Klassen einzeln zu behandeln, greift die Regel am gemeinsamen
   Marker: data-detail traegt sieben der acht Arten, data-plan-open die achte.
   Wer eine neunte Eintragsart baut, bekommt die Kennzeichnung damit
   automatisch - vorausgesetzt, der Eintrag traegt seine Marke.

   ABGRENZUNG: Bedienelemente behalten den Ring. Eine Kennzahlkachel, ein
   Fortschrittsbalken oder ein Navigationseintrag ist kein Datensatz, sondern
   ein Schalter; dort ist der Ring die richtige Sprache und ausserdem der
   kontraststaerkere Indikator (13,36 : 1). */
[data-detail]:focus-visible:not(tr), [data-plan-open]:focus-visible {
  outline: none;
  background: rgba(21, 165, 181, 0.22);
}

/* ── Komponente: meter (gestapelter Balken) ─────────────────────────────────
   Herausgeloest aus .budget-check beim zweiten Verwender (BAL-107): Der
   Balken steht jetzt ausserdem in der Rechnungsuebersicht des Reiters
   "Zahlungen". Struktur und Verhalten sind hier, die BEDEUTUNG der Farben
   bringt der Aufrufer als Modifikatorklasse mit.

   Kurze Klassenreihe (POL-001): Der Balken ist ausschliesslich in dieser
   Reihe entstanden und steht neben .bc-*, .pis-* und .pay-* - eine
   Umstellung auf die lange Reihe haette ihn allein gestellt.

   Die Luecke zwischen den Segmenten ist ein INNERER Schatten, kein gap: Ein
   Flex-Abstand haette die Prozentbreiten verschoben, und bei einem Balken ist
   das Verhaeltnis die ganze Aussage. So trennt er sichtbar, ohne zu verzerren.
   Zugleich ist er die von der Farbpruefung geforderte zweite Kodierung.
   Doku: docs/css/structure/meter.md */
.meter { display: flex; flex-direction: column; gap: 6px; }
.meter-track { position: relative; height: 10px; border-radius: 999px; overflow: hidden; background: #fff; }
/* Ein Pixel Ueberstand, vom overflow der Spur ohnehin abgeschnitten.
   GEMESSEN war das Problem: Das letzte Segment endete 0,02px vor der Kante.
   Auf gerader Strecke unsichtbar - entlang des 5px-Bogens am Ende zieht sich
   dieser Bruchteil aber ueber die ganze Rundung und wird durch die
   Kantenglaettung zu einem sichtbaren Haarstrich in der Spurfarbe.
   Die Verhaeltnisse zwischen den Segmenten bleiben exakt erhalten - alle
   Prozentwerte beziehen sich auf dieselbe, um 1px groessere Breite. */
.meter-segs { position: relative; display: flex; height: 100%; width: calc(100% + 1px); }
.meter-seg { height: 100%; min-width: 2px; transition: width var(--dur-base) var(--ease-std); }
/* Trennlinie nach innen gelegt - sie verschiebt nichts. */
.meter-segs .meter-seg:not(:last-child) { box-shadow: inset -2px 0 0 #fff; }
.meter-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; color: var(--q-dark); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.meter-legend span { display: inline-flex; align-items: center; gap: 5px; }
.meter-chip { width: 8px; height: 8px; flex: 0 0 8px; border-radius: 2px; }

/* Rollen des Budget- und Planungsbalkens (BAL-100 bis BAL-106). */
.meter-seg-gebunden, .meter-chip-gebunden { background: var(--q-highlight-3); }
.meter-seg-neu, .meter-chip-neu { background: var(--q-highlight-5); }
.meter-seg-ueber, .meter-chip-ueber { background: var(--danger); }

/* Rollen des Rechnungsbalkens (BAL-107). Die drei Farben sind die
   Statusfarben der Anwendung - dieselben, aus denen die Statuspillen der
   Rechnungsliste darunter ihre Farbe nehmen (STATUS_LABELS: open/warning,
   paid/success, overdue/danger, gespeist aus dem Serverkatalog
   invoice_status). Eine eigene Skala haette in derselben Ansicht zwei
   Farbsprachen fuer denselben Gegenstand ergeben.
   GEMESSEN mit dem Palettenpruefer: --success und --warning liegen unter
   Protanopie bei einem Abstand von 6,4 - im Bereich 6 bis 8, der nur MIT
   zweiter Kodierung zulaessig ist. Die gibt es hier dreifach: die 2px-Luecken
   zwischen den Segmenten, die beschriftete Legende und die Kennzahlen
   darueber, die jeden Betrag nennen.
   Der Rest traegt bewusst keine Farbe der Skala: Er ist keine Kategorie,
   sondern das, was noch fehlt. */
.meter-seg-bezahlt, .meter-chip-bezahlt { background: var(--success); }
.meter-seg-offen, .meter-chip-offen { background: var(--warning); }
.meter-seg-ueberfaellig, .meter-chip-ueberfaellig { background: var(--danger); }
.meter-seg-rest, .meter-chip-rest { background: #dcdddd; }

.budget-check .meter { margin-top: 8px; }

/* Uebertragung des Wissensbestands in die Wissensbasis (BAL-128). */
.ai-wissen { display: flex; flex-direction: column; gap: 8px; padding: 10px 0 4px; }
.ai-wissen-zeile { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
.ai-wissen-stand { color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-light); }

/* Herkunft und Trefferqualitaet in der Quellenkachel (BAL-130). Ein gefundener
   Treffer traegt seine Guete, ein mitgegebener nicht - er wurde nicht gesucht,
   sondern gesetzt, und eine 0 daneben saehe aus wie ein schlechter Treffer. */
.ai-quelle-mass { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ai-quelle-art { padding: 1px 6px; border-radius: 999px; background: var(--surface-soft); color: var(--q-medium); font-size: 9.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; white-space: nowrap; }
.ai-quelle-art-gefunden { background: rgba(21,165,181,0.16); color: var(--q-highlight-2); }
.ai-quelle-ort { color: var(--q-medium); font-size: 10px; font-weight: var(--w-light); }
.ai-quelle-gefunden { border-color: var(--q-highlight-3); }
/* Der Balken ist die zweite Kodierung neben der Zahl und macht die Kacheln
   nebeneinander vergleichbar - worum es beim Blaettern geht. */
.ai-quelle-balken { display: block; height: 3px; border-radius: 999px; background: var(--divider); overflow: hidden; }
.ai-quelle-balken i { display: block; height: 100%; border-radius: 999px; background: var(--q-highlight-3); }

/* ── Einstellungen › Schnittstellen (BAL-133) ─────────────────────────────────
   Zugaenge zur MCP-Schnittstelle. Die Zeilen der Uebersicht benutzen die
   Bausteine der Kontextuebersicht (.ai-kontext-zeile); eigen ist nur, was es
   dort nicht gibt: die einmalige Anzeige des Geheimnisses, der Endpunkt und
   die Werkzeugauswahl.

   KLASSENREIHE: die kurze (mcp-…), wie ai-…, meter-… und kennz-… daneben.
   Die lange Praefixlogik aus ucs.md gilt fuer die Hauptbausteine der
   Anwendung (app_shell, module_list, ai_drawer); dieser Bereich haengt an
   den bestehenden ai-…-Bausteinen, und ein Wechsel der Reihe mitten in einer
   Zeile waere schwerer zu lesen als die Uneinheitlichkeit im Ganzen
   (POL-001 ist offen; die Wahl ist hier bewusst getroffen). */

.mcp-endpunkt { display: block; margin: 10px 0 0; padding: 10px 12px; border: 1px solid var(--divider); border-radius: 8px; background: var(--q-surface-2, #f6f7f7); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; font-weight: var(--w-regular); color: var(--q-dark); word-break: break-all; }

/* Das Geheimnis: einmalig, deshalb hervorgehoben. Rolle alert im Markup - wer
   mit einem Screenreader arbeitet, darf diese eine Gelegenheit nicht
   verpassen. */
.mcp-geheimnis { margin: 0 0 16px; padding: 16px; border: 1px solid var(--success); border-radius: 12px; background: color-mix(in srgb, var(--success) 8%, transparent); }
.mcp-geheimnis-kopf { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; font-weight: var(--w-regular); line-height: 1.5; color: var(--q-dark); }
.mcp-geheimnis-kopf svg { flex: 0 0 auto; margin-top: 2px; color: var(--success); }
.mcp-geheimnis-wert { display: block; margin: 12px 0; padding: 12px; border: 1px solid var(--divider); border-radius: 8px; background: #fff; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.5; color: var(--q-dark); word-break: break-all; user-select: all; }
.mcp-geheimnis-fuss { display: flex; flex-wrap: wrap; gap: 8px; }

.mcp-praefix { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; font-weight: var(--w-regular); color: var(--q-muted); }
.mcp-zustand-aktiv { color: var(--success); font-weight: var(--w-bold); }
/* Haelt die Spalte frei, wo kein Widerruf steht - sonst ruecken Zustand und
   Text der uebrigen Zeilen gegeneinander. */
.mcp-platzhalter { display: inline-block; width: 92px; }

.mcp-werkzeuge { display: flex; flex-direction: column; gap: 2px; margin-top: 10px; }
.mcp-werkzeug { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border-radius: 8px; cursor: pointer; }
.mcp-werkzeug:hover { background: var(--q-surface-2, #f6f7f7); }
.mcp-werkzeug input { margin-top: 2px; flex: 0 0 auto; }
/* Nachweispflicht an der Zugangszeile (BAL-216): Schalter mit Beschriftung in
   einer Zeile, im Satzbild der Unterzeilen. */
.mcp-nachweis { display: inline-flex; align-items: center; gap: 8px; margin-top: 4px; color: var(--fg-2); font-weight: var(--w-regular); }
.mcp-nachweis .switch { transform: scale(0.85); transform-origin: left center; }
.mcp-werkzeug-name { display: block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; font-weight: var(--w-regular); color: var(--q-dark); }
/* Groesse, Gewicht, Zeilenhoehe und Farbe ausdruecklich: Die globale
   p/li-Grundregel hat sich hier schon viermal hineingemischt. */
.mcp-werkzeug-sub { display: block; margin-top: 2px; font-size: 12px; font-weight: var(--w-regular); line-height: 1.45; color: var(--q-muted); }

@media (max-width: 780px) {
  .mcp-platzhalter { display: none; }
  .mcp-geheimnis-fuss .button { flex: 1 1 auto; }
}

/* ── Einstellungen › Benachrichtigungen (BAL-169) ─────────────────────────────
   Regelkatalog, Schwellen, Geltungsbereiche und das Kanalregister.

   WIEDERVERWENDUNG: Die Zeilen sind .ai-kontext-zeile, wie in
   „Schnittstellen" und in der Kontextuebersicht - Marke, Text, Mass, Aktion
   in genau dieser Aufteilung. Neu ist ausschliesslich, was es dort nicht
   gibt: die Eingabefelder INNERHALB einer Zeile (Schwelle, Geltungsbereich)
   und die Abzeichen an der Ueberschrift.

   KLASSENREIHE: die kurze (nb-…), wie mcp-…, ai-… und meter-… daneben. Die
   lange Praefixlogik aus ucs.md gilt fuer die Hauptbausteine der Anwendung;
   dieser Bereich haengt an den bestehenden ai-…-Bausteinen, und ein Wechsel
   der Reihe mitten in einer Zeile waere schwerer zu lesen als die
   Uneinheitlichkeit im Ganzen (POL-001 ist offen; die Wahl ist hier bewusst
   getroffen - dieselbe Begruendung wie bei mcp-…). */

/* Erklaerungstext unter einer Ueberschrift. Groesse, GEWICHT, Zeilenhoehe,
   Farbe und Abstaende ausdruecklich - die globale p-Grundregel hat sich in
   dieser Anwendung schon viermal in einen Textbaustein hineingemischt, und
   zuletzt war es genau `font-weight`. */
.nb-regel-erklaerung { margin: 0 0 12px; max-width: 72ch; color: var(--fg-2); font-size: 12px; font-weight: var(--w-light); line-height: 1.5; }

/* Abzeichen an der Regelueberschrift. Vordergrund, GRUND und Rahmen alle
   drei - eine nur umgefaerbte Pille stand hier schon einmal weiss auf weiss. */
.nb-marke { display: inline-block; margin-left: 6px; padding: 1px 7px; border: 1px solid var(--divider); border-radius: var(--radius-pill); background: #fff; color: var(--fg-2); font-size: 10.5px; font-weight: var(--w-regular); line-height: 1.6; vertical-align: middle; }
.nb-marke-alle { border-color: color-mix(in srgb, var(--q-highlight-2) 40%, var(--divider)); background: color-mix(in srgb, var(--q-highlight-2) 10%, #fff); color: var(--q-highlight-2); }
.nb-marke-an { border-color: color-mix(in srgb, var(--success) 45%, var(--divider)); background: color-mix(in srgb, var(--success) 12%, #fff); color: color-mix(in srgb, var(--success) 70%, #000); }

/* Die Felder stehen unter dem Beschreibungstext derselben Zeile und brechen
   auf schmalen Breiten um, statt die Zeile zu sprengen. */
.nb-feld { display: flex; flex-direction: column; gap: 3px; }
/* `--fg-2`, nicht `--q-muted`: Letzteres ist in tokens.css NICHT definiert.
   Ein undefiniertes Token macht die Angabe ungueltig, und die Farbe faellt
   auf den geerbten Wert zurueck - unsichtbar falsch. Gemessen am 2026-09-09;
   der Nachbarblock (.mcp-praefix, .mcp-werkzeug-sub) hat denselben Fehler und
   ist als Befund vermerkt, aber nicht Gegenstand dieser Aufgabe. */
.nb-feld-label { color: var(--fg-2); font-size: 10.5px; font-weight: var(--w-regular); line-height: 1.4; text-transform: uppercase; letter-spacing: 0.04em; }
.nb-schwelle { display: flex; align-items: center; gap: 6px; }
/* Eingabefelder bekommen KEINEN zusaetzlichen Fokusring - der Entwurf
   kennzeichnet sie durchgaengig ueber die Randfarbe (siehe Kopf dieser
   Datei); zwei Ringe in zwei Farben waren schon einmal beanstandet. */
.nb-input { width: 84px; padding: 5px 8px; border: 1px solid var(--divider); border-radius: 8px; background: #fff; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); }
.nb-input:focus { border-color: var(--q-highlight-3); outline: none; }
.nb-einheit { color: var(--fg-2); font-size: 11.5px; font-weight: var(--w-regular); }

/* Mehrere Geltungsbereiche je Regel. Bis dahin war es eine einzelne Auswahl;
   die Beanstandung der Auftraggeberin am 2026-09-09 lautete, dass es entweder
   alle oder MEHRERE sein sollen. Der Datenschnitt konnte das immer schon - der
   eindeutige Schluessel steht auf (Person, Regel, Bereichsart, Kennung) -, nur
   der Weg dorthin fehlte.

   Die gewaehlten Bereiche stehen als Marken nebeneinander und brechen um; die
   Auswahl zum Hinzufuegen sitzt in derselben Reihe, damit sie als Fortsetzung
   der Menge gelesen wird und nicht als eigenes Feld. */
.nb-feld-breit { flex: 1 1 100%; }
.nb-bereiche { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
/* Vordergrund, GRUND und Rahmen alle drei - eine nur umgefaerbte Pille stand
   in diesem Projekt schon einmal weiss auf weiss. */
.nb-bereich { display: inline-flex; align-items: center; gap: 4px; padding: 3px 4px 3px 9px; border: 1px solid color-mix(in srgb, var(--q-highlight-2) 35%, var(--divider)); border-radius: var(--radius-pill); background: color-mix(in srgb, var(--q-highlight-2) 8%, #fff); color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.5; }
/* „Alle" ist keine Auswahl, sondern ihre Abwesenheit - deshalb neutral und
   ohne Entfernen-Knopf: Es gibt nichts wegzunehmen. */
.nb-bereich-alle { border-color: var(--divider); background: #fff; color: var(--fg-2); padding: 3px 9px; }
.nb-bereich-weg { width: 17px; height: 17px; display: grid; place-items: center; border-radius: 50%; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); line-height: 1; }
.nb-bereich-weg:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }

/* Der zweite Zugang (BAL-169): Dialog und Detailreiter zu EINEM Datensatz.

   BEWUSST ANDERS GEBAUT als die Zeile der Einstellungen. Dort steht eine Regel
   mit vielen Datensaetzen - eine Handvoll ausfuehrlicher Zeilen. Hier steht ein
   Datensatz mit ACHTZEHN Regeln (gemessen an einem Thema, 720 px Panelbreite),
   und dieselbe ausfuehrliche Form wurde dort zur Wand aus gleich aussehenden
   Bloecken.

   Drei Entscheidungen daraus:
   1. Ein Schiebeschalter (.switch aus den Formularen) statt einer
      Schaltflaeche - er liest sich als Einstellung, nicht als Handlung, und
      spart die rechte Spalte.
   2. Schwelle und Kanaele nur bei den ABONNIERTEN. Bei fuenfzehn
      abgeschalteten Regeln waeren fuenfzehn leere Schwellenfelder reine
      Flaeche.
   3. Was noch nicht geht, steht EINMAL im Kopf - nicht als sechs gesperrte
      Kaestchen in jeder Zeile. Gemessen waren es 42 gesperrte Kaestchen auf
      einem Schirm; die Auskunft ist dieselbe, der Laerm ist es nicht. */

/* GRUND: das Zartgruen der Anwendung, nicht Grau und nicht ein eigener Ton.

   Zwei Runden dahin. ERST weg von Grau (Beanstandung 2026-09-10):
   `--surface-muted` ist `--q-bright` (#e7e7e7) - als Flaeche unter Text wirkt
   das duester. Ersatz war zunaechst ein Hauch Petrol (5 % `--q-highlight-3`
   auf Weiss).

   DANN auf `--surface-active` (Beanstandung derselben Woche): Die Anwendung
   hatte damit ZWEI Toenungsfamilien - das Zartgruen, das ueberall
   "eingeschaltet, ausgewaehlt, hervorgehoben" bedeutet (Formularabschnitte,
   Auswahleintraege, Sortierung, Zahlungsablesung), und daneben ein
   Petrol, das nur hier vorkam. Zwei Familien fuer dieselbe Aussage sind eine
   zu viel; der Abschnitt "Benachrichtigungen" im Formular und die Regelliste
   im Reiter standen unmittelbar nebeneinander und sprachen verschieden.

   Das PETROL bleibt in dieser Komponente, wo es etwas anderes sagt: als
   Schalterfarbe (an) und als Linie unter der Zwischenueberschrift. Flaeche
   heisst "aktiv", Akzent heisst "Marke" - die Trennung ist der Grund, warum
   beide nebeneinander bestehen duerfen.

   Text darauf traegt `--q-dark`, gemessen 8,05 : 1. `--fg-2` faellt hier
   durch (4,19 : 1) - es besteht nur auf reinem Weiss. */
.nb-kopf { margin: 0 0 18px; padding: 12px 14px; border: 1px solid var(--divider-active); border-radius: 12px; background: var(--surface-active); }
.nb-kopf-zahl { color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); line-height: 1.4; }
.nb-kopf-zahl strong { font-size: 15px; font-weight: var(--w-bold); }
/* `--q-dark`, NICHT `--fg-2`. Gemessen am 2026-09-10: `--fg-2` (#767676) auf
   `--surface-muted` ergibt 3,67 : 1 und faellt damit durch. Nachgerechnet
   braucht #767676 einen Grund von praktisch reinem Weiss, um 4,5 : 1 zu
   erreichen - auf JEDEM getoenten Grund ist die Farbe zu hell. Die Abstufung
   traegt hier deshalb Groesse und Gewicht, nicht die Farbe.

   Dieselbe Falle wie bei den Bereichsmarken, und beim zweiten Mal wieder
   hineingelaufen: Die Regel steht in der Strukturdoku - gemessen wurde sie
   trotzdem erst hinterher. */
.nb-kopf-hinweis { margin-top: 4px; color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.5; }

/* JE REGELKLASSE EINE KARTE (Beanstandung 2026-09-10, achte Runde). Aus
   drei Regeln sind 23 geworden; beide Abschnitte in einer Flaeche ergaben
   eine Wand. Die Karte selbst kommt vom Aufrufer, weil die beiden Zugaenge
   auf verschiedenem Grund liegen: In den Einstellungen ist es `.admin-block`
   (weiss auf grauem Seitengrund), in der Detailansicht `.nb-gruppe-karte` -
   dort ist das Panel selbst weiss, eine weitere weisse Flaeche traegt keine
   Trennung. Umriss und Radius wie `.detail-field-card`, dem Kartenmittel
   dieser Umgebung; eine zweite Kartensprache waere die, die beim naechsten
   Anfassen zurueckbliebe. In den Einstellungen setzt
   `.admin-content > * + *` (18 px) den Abstand, hier die eigene Regel. */
.nb-gruppe { margin-bottom: 16px; }
.nb-gruppe:last-child { margin-bottom: 0; }
.nb-gruppe-karte { padding: 14px 16px; border: 1px solid #f1f2f2; border-radius: 12px; background: #fff; }
/* Groesse, GEWICHT, Zeilenhoehe, Farbe und Abstaende ausdruecklich - ein
   blankes h4 traegt die Browservorgabe und passte in keine Liste.

   ABGESETZT IN DEN MARKENFARBEN (Beanstandung 2026-09-10): In --q-dark ging
   die Zwischenueberschrift zwischen den Regelzeilen unter, die dieselbe
   Farbfamilie tragen. Zwei Mittel, beide UNVERMISCHT aus dem Schema:

   - TEXT: --q-highlight-2, das Navy (#10314e). Gemessen 13,36 : 1 auf Weiss.
   - LINIE: --q-highlight-3, das Petrol (#15a5b5), voll und 2 px stark. Eine
     Linie muss keinen Kontrastwert erfuellen - sie darf den reinen Ton
     zeigen, und genau der ist hier gewollt.

   ZWEI ZWISCHENSCHRITTE, die es nicht wurden, damit sie nicht wiederkommen:
   Die Linie stand erst bei 40 % auf Weiss und wirkte blass. Und der Text
   stand eine Runde lang auf einem abgedunkelten Petrol (75 % mit Schwarz,
   #107c88, 4,93 : 1) - lesbar, aber ein Ton, den das Schema so nicht fuehrt.
   Beides ausdruecklich zurueckgenommen: Die Marke traegt hier die Linie, die
   Lesbarkeit der Text, und beide Farben stehen so, wie sie definiert sind.

   PETROL ALS TEXTFARBE bleibt ausgeschlossen: #15a5b5 auf Weiss ergibt
   2,97 : 1, und 13 px fett ist kein Grosstext - selbst dafuer waere es knapp
   gegen die Grenze 3,0.

   BENENNUNG wie in der Ladeanimation weiter oben und im Design-System:
   Lime #c6d31c (Primaerfarbe), Navy #10314e, Petrol #15a5b5. Eine fruehere
   Fassung dieses Kommentars nannte #10314e "Petrol" - falsch, am 2026-09-10
   berichtigt. */
.nb-gruppe-titel { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin: 0 0 10px; padding-bottom: 7px; border-bottom: 2px solid var(--q-highlight-3); color: var(--q-highlight-2); font-family: var(--font-display); font-size: 13px; font-weight: var(--w-bold); line-height: 1.3; }
.nb-gruppe-zusatz { color: var(--fg-2); font-family: var(--font-sans); font-size: 11px; font-weight: var(--w-regular); }
/* Die Zahl je Karte beantwortet am Abschnitt, was die Kopfzeile fuer das
   Ganze sagt - gerechnet mit DERSELBEN Pruefung, hereingereicht statt
   nachgebaut. `margin-left: auto` schiebt sie an die rechte Kante, wo auch
   die Schalter stehen. */
.nb-gruppe-zahl { margin-left: auto; color: var(--fg-2); font-family: var(--font-sans); font-size: 11px; font-weight: var(--w-regular); white-space: nowrap; }

/* Die Zeile: Inhalt links, Schalter RECHTS - wie `.fform-toggle` in den
   Formularen, wo der Schalter seit jeher rechts steht (Beanstandung
   2026-09-10). Vorher stand er am Datensatz links und in den Einstellungen
   war es eine Schaltflaeche: zwei Ausrichtungen fuer dieselbe Entscheidung,
   in einer Anwendung.

   Der Schalter steht im QUELLTEXT hinter dem Inhalt, nicht nur optisch rechts.
   Eine Umkehr per `order` haette Sehen und Vorlesen auseinanderlaufen lassen -
   Hilfsmittel folgen der Dokumentreihenfolge. */
.nb-regel { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 0 18px; padding: 10px 0; border-bottom: 1px solid var(--divider); }
.nb-regel:last-child { border-bottom: 0; }
.nb-regel-haupt { flex: 1 1 auto; min-width: 0; }
.nb-schalter { margin-top: 1px; flex: 0 0 auto; }
/* Gesperrt heisst hier "an, aber nicht von hier aus" - der Schalter bleibt
   sichtbar und abgelesen, nur nicht bedienbar. */
.nb-schalter-fest { cursor: default; opacity: 0.55; }
/* Beschriftung und Text sind ein `label` fuer den Schalter - ein Klick darauf
   schaltet mit. Der Zeigefinger sagt das an; der Einzelheitenkasten steht
   ausserhalb, damit ein Klick in ein Zahlenfeld nicht die Regel abbestellt. */
.nb-regel-beschriftung { display: block; cursor: pointer; }
.nb-regel-titel { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; color: var(--fg-2); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.4; }
/* Abonniert: dunkler und fetter. Der Unterschied traegt die Ablesung, nicht
   der Schalter allein - Farbe ist hier nicht der einzige Traeger, die
   Schalterstellung sagt dasselbe. */
.nb-regel-an .nb-regel-titel { color: var(--q-dark); font-weight: var(--w-bold); }
.nb-regel-text { display: block; margin-top: 2px; max-width: 68ch; color: var(--fg-2); font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.45; }
.nb-regel-mehr { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 10px 22px; margin-top: 8px; padding: 10px 12px; border: 1px solid var(--divider-active); border-radius: 10px; background: var(--surface-active); }
.nb-regel-mehr-fest { display: block; color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.45; }
/* Alles im getoenten Kasten auf --q-dark heben. `.nb-feld-label` und
   `.nb-einheit` stehen ausserhalb auf Weiss und duerfen dort --fg-2 bleiben;
   HIER faellt dieselbe Farbe durch. Eine Farbe ist nicht dieselbe Angabe,
   wenn der Grund ein anderer ist - deshalb wird sie am Ort ueberschrieben
   statt global geaendert.

   ZWEIMAL GEMESSEN, ZWEIMAL BESTAETIGT: auf `--surface-muted` (#e7e7e7)
   ergab --fg-2 3,67 : 1, auf dem viel helleren Ton von heute (5 %
   `--q-highlight-3` auf Weiss) immer noch 4,32 : 1. Nachgerechnet braucht
   #767676 einen Grund von praktisch reinem Weiss - auf JEDEM getoenten Grund
   faellt die Farbe durch, auch auf einem sehr hellen. Die Abstufung traegt
   hier deshalb Groesse und Gewicht. */
.nb-regel-mehr .nb-feld-label,
.nb-regel-mehr .nb-einheit,
.nb-kopf .nb-feld-label { color: var(--q-dark); }

/* Kanalregister als Pillenreihe (Beanstandung 2026-09-10). Vorher standen in
   den Einstellungen sieben volle Zeilen mit Marke, Titel, Erklaerung und
   Zustand - fuer eine Auskunft, die in einen Satz passt: einer traegt, sechs
   sind vorbereitet. Sie nahmen ein Drittel der Seite ein, bevor die erste
   Regel kam.

   Vordergrund, GRUND und Rahmen alle drei gesetzt - eine nur umgefaerbte
   Pille stand in diesem Projekt schon einmal weiss auf weiss. */
.nb-kanalreihe { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.nb-kanalpille { display: inline-block; padding: 2px 9px; border: 1px solid var(--divider); border-radius: var(--radius-pill); background: #fff; color: var(--fg-2); font-size: 11px; font-weight: var(--w-regular); line-height: 1.6; }
/* Der eine Kanal, der wirklich zustellt. */
.nb-kanalpille-an { border-color: color-mix(in srgb, var(--success) 45%, var(--divider)); background: color-mix(in srgb, var(--success) 12%, #fff); color: color-mix(in srgb, var(--success) 70%, #000); font-weight: var(--w-bold); }

/* Kanalwahl je Regel - nur die verfuegbaren. Was noch fehlt, steht im Kopf. */
.nb-kanalwahl { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.nb-kanal { display: inline-flex; align-items: center; gap: 6px; color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.5; cursor: pointer; }
.nb-kanal input { margin: 0; flex: 0 0 auto; }

/* KOPFZEILE des Reiters in der Detailansicht: Erlaeuterung links, der Weg in
   die Einstellungen RECHTS (Beanstandung 2026-09-10). Vorher stand er als
   .nb-reiter-fuss am Fuss der Liste - bei 18 Regelzeilen findet ihn dort nur,
   wer ohnehin bis unten gescrollt hat. Eine Handlung, die aus dem Abschnitt
   hinausfuehrt, gehoert an dieselbe Stelle wie ueberall sonst: neben die
   Ueberschrift, rechts (vgl. .admin-sec-head, .content_card_header).
   `align-items: flex-start`, weil die Erlaeuterung zwei Zeilen hat und der
   Knopf an der ersten stehen soll, nicht in der Mitte dazwischen. */
.nb-reiter-kopf { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 10px 16px; margin-bottom: 14px; }
.nb-reiter-kopf .nb-regel-erklaerung { flex: 1 1 260px; margin: 0; }
.nb-reiter-kopf > .button { flex: 0 0 auto; }

@media (max-width: 780px) {
  /* Die Mehrfachauswahl (.fsel) statt einer nativen Auswahl: BAL-169 hat
     .nb-select abgeloest. Hier bleibt nur, was die Felder schmal macht. */
  .nb-feld { width: 100%; }
}

/* ── Inferenzebenen: Angabe und Erklaerung (BAL-134) ──────────────────────────
   Die Ebene unter einer Antwort war eine Beschriftung und ist jetzt eine
   Schaltflaeche. Sie behaelt das Aussehen der Beschriftung - eine Ebene, die
   ploetzlich wie ein Knopf aussieht, zoege den Blick von der Antwort ab -,
   bekommt aber Zeigefinger, Fokusring und ein Info-Zeichen.

   Der Dialog benutzt die Huelle der Anwendung (.modal_window/.fmodal), wie sie
   auch die Kennzeichnung benutzt: feststehende Titelleiste mit Vollbild- und
   Schliessknopf. GEMESSEN: Ein erster Anlauf setzte auf eine Klasse
   .kennz-dialog, die es gar nicht gibt - der Dialog stand dann mit
   position:static bei y=1241 ausserhalb des Bildes. Eigen sind nur die
   Karten. */

.ai-ebene { cursor: pointer; display: inline-flex; align-items: center; gap: 4px; border: 0; background: none; padding: 0; font: inherit; color: inherit; }
.ai-ebene svg { opacity: .55; }
.ai-ebene:hover { color: var(--q-dark); }
.ai-ebene:hover svg { opacity: 1; }
.ai-ebene:focus-visible { outline: 2px solid var(--q-highlight-2); outline-offset: 2px; border-radius: 3px; }

/* Dieselbe Flaeche in den Einstellungen, dort aber als sichtbare Angabe mit
   Rahmen: Sie steht allein in einer Zeile und braucht eine Kante, sonst liest
   sie sich wie ein Resttext. */
.ai-ebene-feld .ai-ebene-wert { display: flex; justify-content: flex-end; }
.ai-ebene-gross { padding: 8px 14px; border: 1px solid var(--divider); border-radius: 999px; background: #fff; font-size: 13px; font-weight: var(--w-bold); color: var(--q-dark); }
.ai-ebene-gross:hover { border-color: var(--q-highlight-2); }
.ai-ebene-warnung { border-left: 3px solid var(--warning); padding-left: 12px; }

.ebene-dialog .ebene-karten { margin: 0; }
/* Groesse, Gewicht, Zeilenhoehe und Farbe ausdruecklich - die globalen
   p-Regeln haben sich hier schon mehrfach hineingemischt. */
.ebene-vorwort, .ebene-nachwort { margin: 0 0 16px; font-size: 13px; font-weight: var(--w-regular); line-height: 1.55; color: var(--q-medium); }
.ebene-nachwort { margin: 16px 0 0; }
.ebene-karten { display: flex; flex-direction: column; gap: 10px; }
.ebene-karte { padding: 14px 16px; border: 1px solid var(--divider); border-radius: 10px; background: #fff; }
/* Die Ebene, um die es gerade geht. Die Farbe ist NICHT die einzige Kodierung:
   Die Karte traegt zusaetzlich eine Marke mit Text. */
.ebene-karte-aktiv { border-color: var(--q-highlight-2); box-shadow: inset 3px 0 0 var(--q-highlight-2); }
.ebene-karte-kopf { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.ebene-karte-nr { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; flex: 0 0 24px; border-radius: 50%; background: var(--q-surface-2, #f6f7f7); font-size: 12px; font-weight: var(--w-bold); color: var(--q-dark); }
.ebene-karte-aktiv .ebene-karte-nr { background: var(--q-highlight-2); color: #fff; }
.ebene-karte-titel { font-size: 14px; font-weight: var(--w-bold); color: var(--q-dark); }
.ebene-karte-marke { margin-left: auto; padding: 2px 8px; border-radius: 999px; background: var(--q-highlight-2); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: #fff; }
.ebene-karte-lang { margin: 0; font-size: 13px; font-weight: var(--w-regular); line-height: 1.55; color: var(--q-medium); }
.ebene-karte-balance { margin: 8px 0 0; font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.5; color: var(--q-dark); }

@media (max-width: 780px) {
  .ai-ebene-feld .ai-ebene-wert { justify-content: flex-start; }
  .ebene-karte-marke { margin-left: 0; }
  .ebene-karte-kopf { flex-wrap: wrap; }
}

/* ── Rhythmus der Einstellungsbereiche (BAL-136) ──────────────────────────────
   EINE Regel statt einer margin-bottom je Blockklasse.

   GEMESSEN am 2026-09-06: Der Normalabstand zwischen den direkten Kindern
   eines Einstellungsbereichs ist 18 px - er kam aber aus den Einzelregeln
   .admin-sec-head (18), .admin-kpis (18) und .module_list_toolbar (16). Wer
   keine hatte, klebte: .admin-block und .ki_kennzeichnung_bar tragen keine,
   und so sass die Toolbar der Wissensbasis mit 0 px am Block darueber und die
   Kennzahlen der KI-Kennzeichnung mit 0 px an der Leiste.

   Es waren also nicht zwei Ausreisser, sondern eine fehlende Regel: Jede
   kuenftige Blockart haette denselben Fehler geerbt.

   Der Abstand haengt jetzt am CONTAINER und gilt fuer alles, was hier
   hineingezeichnet wird. Die margin-bottom der Kinder werden dabei ausdruecklich
   auf 0 gesetzt - sonst addierten sie sich zu 34 px. NUR HIER: Ausserhalb von
   .admin-content behalten dieselben Klassen ihre Abstaende, und
   .ki_kennzeichnung_bar sitzt auch an der Schublade des Assistenten. */
.admin-content > * { margin-bottom: 0; }
.admin-content > * + * { margin-top: 18px; }

/* ── Trennlinien in den Einstellungsblöcken (BAL-136) ─────────────────────────
   Genau EINE Linie zwischen zwei Dingen.

   GEMESSEN: .ai-feld zog eine Linie unten, .ak-label.ai-conf-gruppe eine oben -
   wo eine Gruppe auf ein Feld folgte, standen beide, 22 px auseinander. Alle
   drei Gruppenwechsel der Assistentenseite waren betroffen.

   Die vorhandene Ausnahme .ai-feld:last-of-type half nicht: :last-of-type
   zaehlt unter ALLEN div-Geschwistern, und der Block enthaelt neben Feldern
   auch Hinweise, Kontextbloecke und den Fuss.

   Jetzt liegt die Linie ZWISCHEN zwei Feldern statt unter jedem. Damit gibt es
   sie nur dort, wo zwei Felder aufeinanderfolgen - und die Gruppengrenze
   gehoert allein der Gruppenueberschrift. */
.ai-feld { border-bottom: 0; }
.ai-feld + .ai-feld { border-top: 1px solid var(--divider); }

/* ── Ladeanimation im entstehenden Text (BAL-136) ─────────────────────────────
   Sie steht jetzt UNTEN beim Fortschrittstext, nicht ueber der Antwort.
   Vorher war sie das erste Kind der Blase; sobald Text eintraf, schaltete
   .ai-wartet auf display:block, und die Punkte standen ueber dem Text, den
   man gerade liest. */
.ai-strom-lage { display: flex; align-items: center; gap: 9px; }
.ai-strom-text:not(:empty) + .ai-strom-lage { margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--divider); }

/* ── Verweise unter „Hier können Sie" (BAL-137) ───────────────────────────────
   Ein Wort im Fließtext, das zu seinem Bedienelement führt. Es sieht aus wie
   Text mit Unterstreichung und nicht wie ein Knopf: Die Zeile ist eine
   Aufzählung von Sätzen, keine Knopfleiste - eine Reihe von Schaltflächen
   zöge den Blick von der Überschrift ab, unter der sie steht.

   WARUM ein <button> und kein <a>: Es gibt kein Ziel, das sich adressieren
   ließe - der Verweis bedient ein Element auf derselben Seite. Ein <a href>
   ohne Adresse wäre für Hilfsmittel ein Link ins Nichts. */
.ph-tun-link { padding: 0; border: 0; background: none; font: inherit; color: inherit; cursor: pointer; text-decoration: underline; text-decoration-color: currentColor; text-decoration-thickness: 1px; text-underline-offset: 3px; }
/* Maus UND Fokus fuehren zum selben Bild (BAL-151): Wer mit der Tastatur
   navigiert, soll dieselbe Hervorhebung sehen und nicht nur einen Ring.

   Der Farbton ist --q-highlight-3 UNVERAENDERT - das Petrol des Schemas, auf
   ausdrueckliche Entscheidung der Auftraggeberin. Gemessen erreicht es auf
   Weiss 2,97; der Sollwert fuer Fliesstext ist 4,5. Ein abgedunkelter Ton
   (74 % der Marke) kaeme auf 5,06 und wurde vorgelegt, aber verworfen.

   Was den Verweis dennoch lesbar haelt: Die UNTERSTREICHUNG bleibt in jedem
   Zustand, die Farbe ist also nicht die einzige Kodierung, und der
   Ruhezustand traegt mit 4,48 die eigentliche Textlesbarkeit. Die
   Hervorhebung kommt zu einem lesbaren Zustand HINZU, sie ersetzt ihn
   nicht. */
.ph-tun-link:hover,
.ph-tun-link:focus-visible { color: var(--q-highlight-3); text-decoration-color: currentColor; }
.ph-tun-link:focus-visible { outline: 2px solid var(--q-highlight-2); outline-offset: 2px; border-radius: 3px; }

/* ── Eine Spaltenbreite für alle Eingaben eines Feldes (BAL-139) ──────────────
   GEMESSEN am 2026-09-06 im Dialog der KI-Kennzeichnung: VIER verschiedene
   Breiten nebeneinander - Auswahlfelder 260 px, Textfelder 150 px, und die
   beiden mehrzeiligen Felder 338 bzw. 365 px. Die letzten beiden waren
   fliessend und damit sogar untereinander verschieden: Sie nahmen, was die
   Beschriftung daneben uebrig liess, und die ist je Feld unterschiedlich lang.
   Das ergibt eine ausgefranste rechte Kante.

   Jetzt eine Zahl an einer Stelle. Sie gilt fuer jedes Bedienelement in einem
   .ai-feld - einzeilig, mehrzeilig, Auswahl - und damit fuer den Dialog der
   Kennzeichnung ebenso wie fuer die Einstellungsseiten, die dieselben
   Bausteine benutzen. */
:root { --ai-feld-spalte: 260px; }
.ai-feld-eingabe { width: var(--ai-feld-spalte); flex: 0 0 var(--ai-feld-spalte); }
.ai-feld .fselect-wrap { width: var(--ai-feld-spalte); flex: 0 0 var(--ai-feld-spalte); }
.ai-feld .kennz-textarea { width: var(--ai-feld-spalte); flex: 0 0 var(--ai-feld-spalte); }

@media (max-width: 720px) {
  /* Unter dem Umbruch steht die Eingabe unter ihrer Beschriftung und nimmt die
     volle Breite - eine feste Spalte waere dort verschenkter Platz. */
  .ai-feld .kennz-textarea { width: 100%; flex: 1 1 auto; }
}

/* ── Organisationseinheiten (BAL-139) ─────────────────────────────────────────
   Die Liste benutzt module_list, der Dialog fmodal - beides vorhanden. Eigen
   sind zwei Dinge: die anklickbare Zeile (wie bei der KI-Kennzeichnung) und
   die Gruppenueberschrift im Dialograster.

   `.ffield-gruppe` ist das Gegenstueck zu `.set-fieldset-label` aus Mission
   Control: Sie gliedert ein Formular in thematische Abschnitte, statt alle
   Felder flach untereinander zu stellen. */
.oe-zeile { cursor: pointer; }
.oe-zeile:hover > td { background: var(--surface-soft); }
.oe-zeile:focus-visible { outline: 2px solid var(--q-highlight-2); outline-offset: -2px; }

/* Groesse, Gewicht, Abstand und Farbe ausdruecklich - die globalen Grundregeln
   haben sich in diesem Projekt schon viermal in eine Komponente gemischt. */
.ffield-gruppe { margin: 6px 0 -4px; font-size: 10.5px; font-weight: var(--w-bold); line-height: 1.4; letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--q-medium); }
.ffield-gruppe:not(:first-child) { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--divider); }

/* ------------------------------------------------------------------
   Kontext im Wortlaut (BAL-142)

   Der Dialog zeigt, WAS der Assistent als Kontext bekommt - die
   Zusammensetzung in den Einstellungen sagt nur, wie viel. Klassenreihe:
   die kurze (POL-001), weil der Dialog neben .ebene-dialog, .fmodal und
   .ai-kontext-* steht, die alle aus dieser Reihe stammen.

   Jeder Textbaustein setzt Groesse, Gewicht, Zeilenhoehe, Farbe und Abstand
   ausdruecklich. Es gibt zwar keine globale p-Regel, aber body vererbt 15px
   und w-light - beides waere hier zu gross und zu duenn.
   ------------------------------------------------------------------ */
.kontext-dialog .modal_window_body { display: flex; flex-direction: column; gap: 14px; }
.kontext-vorwort { margin: 0; color: var(--q-medium); font-size: 13px; font-weight: var(--w-light); line-height: 1.6; }

/* Die Lage in Zahlen, bevor der Wortlaut kommt. */
.kontext-lage { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 16px; padding-bottom: 12px; border-bottom: 1px solid var(--divider); }
.kontext-lage-zahl { color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); }
.kontext-lage-hinweis { color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-light); line-height: 1.4; }

.kontext-block { padding: 14px 16px; border: 1px solid var(--divider); border-radius: 12px; background: #fff; }
/* Ein abgeschalteter Block bleibt sichtbar, tritt aber zurueck: Er gehoert
   zur Aufzaehlung - sonst waere nicht zu sehen, dass es ihn gibt. */
.kontext-block-aus { background: var(--surface-soft); }
.kontext-block-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.kontext-block-titel { color: var(--q-dark); font-size: 13.5px; font-weight: var(--w-bold); }
.kontext-block-mass { color: var(--q-medium); font-size: 11px; font-weight: var(--w-regular); white-space: nowrap; }
.kontext-block-sub { margin: 5px 0 0; color: var(--q-medium); font-size: 12px; font-weight: var(--w-light); line-height: 1.5; }
.kontext-block-leer { margin: 10px 0 0; color: var(--q-medium); font-size: 12px; font-weight: var(--w-light); line-height: 1.5; font-style: italic; }

/* Ein Abschnitt je Dokument, aufklappbar. Offen als Vorgabe: Wer den Dialog
   oeffnet, will den Wortlaut sehen und nicht erst siebenmal klicken. */
.kontext-dok { margin-top: 10px; border: 1px solid var(--divider); border-radius: 10px; background: var(--surface-soft); }
.kontext-dok-kopf { display: flex; align-items: baseline; gap: 10px; padding: 8px 12px; cursor: pointer; list-style: none; }
/* Der eigene Pfeil ersetzt den Marker des Browsers: display:flex entfernt ihn
   in mehreren Browsern ohnehin, und so ist er in allen gleich. */
.kontext-dok-kopf::-webkit-details-marker { display: none; }
.kontext-dok-kopf::before { content: ''; flex: 0 0 auto; width: 6px; height: 6px; border-right: 1.5px solid var(--q-medium); border-bottom: 1.5px solid var(--q-medium); transform: rotate(-45deg); transition: transform var(--dur-fast) var(--ease-std); }
.kontext-dok[open] > .kontext-dok-kopf::before { transform: rotate(45deg); }
.kontext-dok-kopf:focus-visible { outline: 2px solid var(--q-highlight-2); outline-offset: -2px; border-radius: 10px; }
.kontext-dok-titel { flex: 1 1 auto; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-bold); }
.kontext-dok-mass { color: var(--q-medium); font-size: 11px; font-weight: var(--w-regular); white-space: nowrap; }
/* Sans statt der Monospace des Browsers: Der Kontext ist deutscher Fliesstext
   mit Zeilenstruktur, kein Quelltext. pre-wrap haelt die Umbrueche, ohne dass
   lange Zeilen waagrecht scrollen. */
.kontext-dok-text { margin: 0; padding: 0 12px 12px; border-radius: 0 0 10px 10px; background: transparent; color: var(--q-dark); font-family: var(--font-sans); font-size: 12px; font-weight: var(--w-light); line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }

.kontext-stoerung { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; padding: 16px; border: 1px solid var(--danger); border-radius: 12px; background: color-mix(in srgb, var(--danger) 6%, #fff); }
.kontext-stoerung-text { margin: 0; color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); line-height: 1.5; }

/* Der Weg von der Zahl zum Wortlaut, im Fuss der Zusammensetzung. */
.ai-kontext-fuss { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--divider); }
.ai-kontext-fuss .button { display: inline-flex; align-items: center; gap: 7px; }
.ai-kontext-fuss-hinweis { color: var(--q-medium); font-size: 11.5px; font-weight: var(--w-light); line-height: 1.4; }

/* ------------------------------------------------------------------
   Zustand des Assistentensymbols in der Kopfleiste (BAL-144)

   Der Assistent arbeitet weiter, wenn die Schublade zugeht - das tat er
   schon vorher, nur sah es niemand. Zwei Zeichen machen es sichtbar.

   FARBEN: dieselben drei wie die Ladeanimation daneben
   (--q-highlight-1/3/2, siehe .ladeanzeige_punkt) und in derselben
   Reihenfolge. Der Wunsch nannte sie ausdruecklich, und ein vierter Farbklang
   fuer denselben Vorgang waere ohnehin einer zu viel.
   ------------------------------------------------------------------ */

/* ARBEITET: der Ladering QZ-L05 "Neuinterpretation" aus der Entwurfsvorlage
   (docs/design/loading_animations), gelegt um das Symbol - drei konzentrische
   Boegen in den drei Markenfarben, jeder mit eigener Umlaufzeit, der mittlere
   gegenlaeufig. Der erste Entwurf war ein conic-gradient mit Maske; die
   Vorlage gibt es genauer und ohne Maskenabhaengigkeit her.

   Das SVG ragt 3 px ueber den 38-px-Knopf hinaus. Bei 14 px Abstand zwischen
   den Knoepfen der Kopfleiste bleiben 8 px - es stoesst an nichts. */
.ai_symbol_ring {
  position: absolute; inset: -3px; width: auto; height: auto;
  pointer-events: none; overflow: visible;
}
.ai_symbol_bogen {
  /* Ohne transform-box/-origin dreht der Bogen um den Ursprung des
     Koordinatensystems statt um die Mitte - so steht es auch in der Vorlage. */
  transform-box: view-box; transform-origin: 50px 50px;
  animation: ai-symbol-bogen var(--ai-symbol-dauer) linear infinite;
}
/* Aussen nach innen, wie in der Vorlage: Umlaufzeiten 2,4 / 3,0 / 3,6 s, der
   mittlere rueckwaerts. --q-loader-speed steuert das Tempo aller Ladeanzeigen
   der Anwendung mit. */
.ai_symbol_bogen_1 { stroke: var(--q-highlight-3); --ai-symbol-dauer: calc(2.4s / var(--q-loader-speed, 1)); }
.ai_symbol_bogen_2 { stroke: var(--q-highlight-1); --ai-symbol-dauer: calc(3s / var(--q-loader-speed, 1)); animation-direction: reverse; }
.ai_symbol_bogen_3 { stroke: var(--q-highlight-2); --ai-symbol-dauer: calc(3.6s / var(--q-loader-speed, 1)); }
@keyframes ai-symbol-bogen { to { transform: rotate(360deg); } }

/* FERTIG: derselbe Punkt wie bei den Benachrichtigungen, nur in der Marke
   statt in der Warnfarbe - eine wartende Antwort ist keine Stoerung. Ein
   Fehlschlag behaelt das rote Vorgabezeichen von .app_shell_dot. */
.app_shell_dot_ai { background: var(--q-highlight-1); }
/* Einmal aufblenden, damit der Punkt bemerkt wird, wenn er waehrend der
   Arbeit an einer anderen Stelle der Anwendung erscheint. Kein Dauerpulsen:
   Das zoege die Aufmerksamkeit dauerhaft von der Arbeit ab. */
.ai_symbol_fertig .app_shell_dot { animation: ai-symbol-auftauchen var(--dur-base) var(--ease-std) 1; }
@keyframes ai-symbol-auftauchen { from { transform: scale(0.2); opacity: 0; } to { transform: scale(1); opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .ai_symbol_bogen { animation: none; }
  .ai_symbol_fertig .app_shell_dot { animation: none; }
}

/* Kopiersymbol an jeder Antwort (BAL-155). Es steht neben dem Sprechknopf
   und traegt dieselbe Zurueckhaltung: ein Werkzeug am Rand, kein
   Bedienelement, das mit der Antwort um Aufmerksamkeit ringt. */
.ai-kopieren, .ai-sprech {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; border: 0; border-radius: 6px;
  background: transparent; color: var(--q-medium); cursor: pointer;
  transition: color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std);
}
.ai-kopieren:hover, .ai-sprech:hover { color: var(--q-highlight-3); background: var(--surface-soft); }
.ai-kopieren:focus-visible, .ai-sprech:focus-visible { outline: 2px solid var(--q-highlight-2); outline-offset: 1px; }
/* Beide Werkzeuge stehen zusammen am rechten Rand der Herkunftszeile
   (BAL-165). Vorher stand das Kopiersymbol hinter den Kennzahlen und der
   Sprechknopf wurde einzeln ans Ende geschoben - zwei Werkzeuge, die
   dasselbe tun sollen, standen an zwei Stellen. */
.ai-werkzeuge { display: inline-flex; align-items: center; gap: 2px; margin-left: auto; }
/* Die Bestaetigung faerbt sich in die Marke und bleibt kurz stehen - ein
   Klick ohne Rueckmeldung ist von einem wirkungslosen nicht zu
   unterscheiden. */
.ai-kopieren-fertig, .ai-kopieren-fertig:hover { color: var(--success); background: transparent; }

/* Waehrend gesprochen wird: die Marke, aber ohne Fuellung. Das Symbol ist
   schon zu "stop" gewechselt, und Titel wie aria-label sagen den Zustand in
   Worten - Farbe ist hier also nicht die einzige Kodierung.

   STEHT BEWUSST HINTER .ai-kopieren: Beide Selektoren haben dieselbe
   Spezifitaet, also gewinnt der spaetere. Vorher stand diese Regel weiter
   oben und wurde von der geteilten Grundform ueberschrieben - gemessen blieb
   das Symbol beim Sprechen grau. */
.ai-sprech-an, .ai-sprech-an:hover { color: var(--q-highlight-2); background: var(--surface-soft); }

/* ── Kennzahlen an der Antwort (BAL-156) ─────────────────────────────────────
   Die BELEGTHEIT sagt, ob die Aussagen in den Quellen gedeckt sind - nicht,
   ob die Antwort gut ist. Deshalb steht das Wort daneben und nicht nur eine
   Farbe: Eine ehrliche Absage ist eine gute Antwort mit niedriger
   Belegtheit. */
.ai-belegt {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 1px 8px; border-radius: 999px;
  font-size: 11px; font-weight: var(--w-bold);
  letter-spacing: var(--tracking-wide);
  white-space: nowrap;
}
.ai-belegt-ja { background: color-mix(in srgb, var(--success) 14%, #fff); color: color-mix(in srgb, var(--success) 78%, #000); }
.ai-belegt-nein { background: color-mix(in srgb, var(--warning) 16%, #fff); color: color-mix(in srgb, var(--warning) 82%, #000); }
.ai-belegt-wert { font-weight: var(--w-regular); font-variant-numeric: tabular-nums; opacity: .8; }

/* Die Dauer tritt zurueck - sie ist eine Randnotiz, keine Kennzahl, auf die
   jemand seine Arbeit stuetzt. */
.ai-dauer {
  color: var(--q-medium); font-size: 11px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  /* Die Herkunftszeile setzt Grossbuchstaben - bei einer Einheit ist das
     falsch: "5,9 S" ist keine Sekunde. */
  text-transform: none;
}

/* Feinwerte im Aufklappbereich: eine Beschreibungsliste, kein Kachelfeld -
   es sind drei Angaben, keine Uebersicht. */
.ai-kennzahlen {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: 3px 14px; margin: 10px 0 12px; padding: 10px 12px;
  border-radius: 10px; background: var(--surface-soft);
  font-size: 11.5px; line-height: 1.45;
}
.ai-kennzahlen dt { margin: 0; color: var(--q-medium); font-weight: var(--w-bold); white-space: nowrap; }
.ai-kennzahlen dd { margin: 0; color: var(--q-dark); font-weight: var(--w-light); overflow-wrap: anywhere; }

/* ══════════════════════════════════════════════════════════════════════════
   Komponente: sprachassistent — gesprochene Unterhaltung in Echtzeit (BAL-167)
   ──────────────────────────────────────────────────────────────────────────
   Zweite Gestalt desselben Assistenten: dieselbe Auskunftsfähigkeit, aber ohne
   Tastatur und ohne Chatfenster. Eine ruhige Vollbildfläche, auf der gesprochen
   und zugehört wird; sichtbar ist nur, was zum Verstehen des Gesprächs nötig
   ist — Zustand, das Gehörte, die Antwort, die Mitschrift.

   BENENNUNG. Unterstrich-Logik nach ucs.md §2.1 und den Präfixen aus BAL-004
   (app_shell, ai_drawer, ki_kennzeichnung …) — nicht die kurze zweite Reihe
   (ltb-, ak-, fmodal). Begründung steht in docs/css/structure/sprachassistent.md;
   POL-001 verlangt, dass die Wahl benannt wird.

   KEINE NEUEN GESTALTUNGSWERTE. Alle verwendeten Token bestehen bereits in
   tokens.css: --q-highlight-1/2/3/4, --q-dark, --danger, --radius-sm/lg/pill,
   --dur-fast/base, --ease-std, --font-display, --font-mono, --w-light/bold,
   --tracking-wide/xwide, --shadow-elevated. Nachgesehen, nicht vermutet.

   ZWEI ERSCHEINUNGSBILDER über data-erscheinung, nicht über zwei Klassenbäume:
   Die Fläche wechselt nur ihre Farbrollen, nicht ihren Aufbau. Deshalb stehen
   alle Farben als lokale Eigenschaften am Hauptblock und werden in der
   Milchglas-Fassung umdefiniert — eine Stelle statt vierzig.

   DER ZUSTAND STEHT IN data-phase (bereit · verbinden · hoeren · sprechen). Als
   Klassenkette (.p-hoeren) wäre er an fünf Elementen einzeln zu setzen; als
   Attribut am Hauptblock steht er einmal, und jede abhängige Regel liest ihn
   von dort.
   ══════════════════════════════════════════════════════════════════════════ */

/* DAS ATTRIBUT MUSS DIE ANGABE SCHLAGEN. Sieben Elemente dieser Komponente
   werden über `hidden` ein- und ausgeblendet — die beiden Aufklappfelder, die
   Mitschrift, die Antwort, der Pegel, die Beispiele, die Meldungen. Alle tragen
   ein eigenes `display`, und das gewinnt gegen die Vorgabe des Browsers für
   [hidden]. Ohne diese Regel stünden sie dauerhaft offen.

   Mit !important, weil sonst jede künftige display-Angabe in dieser Datei
   dasselbe Loch wieder aufreißt — die Regel soll nicht von ihrer Reihenfolge
   abhängen. */
.sprachassistent [hidden] { display: none !important; }

.sprachassistent {
  /* Dunkles Erscheinungsbild — die Anwendung verschwindet dahinter. */
  --sa-ink: #fff;
  --sa-ink-2: rgba(255, 255, 255, 0.78);
  --sa-ink-3: rgba(255, 255, 255, 0.62);
  --sa-line: rgba(255, 255, 255, 0.24);
  --sa-line-hi: rgba(255, 255, 255, 0.5);
  --sa-fill: rgba(255, 255, 255, 0.07);
  --sa-fill-hi: rgba(255, 255, 255, 0.16);
  --sa-accent: var(--q-highlight-1);
  --sa-panel: rgba(255, 255, 255, 0.06);

  position: fixed;
  inset: 0;
  /* DIE EBENE IST GEWÄHLT, NICHT GERATEN. Gemessen liegen die Ebenen der
     Anwendung in zwei Gruppen: die Einblendungen der Oberfläche bis 95
     (Schublade 70, Klapplisten 90/95) und die Dialoge ab 118 (Kennzeichnung
     118–121, Rückfrage 130/131, Formulardialog 131/132). Dazwischen ist frei.

     110 liegt genau dort — über allem, was die Fläche verdecken soll, und
     unter allem, was über ihr stehen muss. Die Kennzeichnungstafel und die
     Rückfrage „Mitschrift verwerfen" erscheinen deshalb ohne eine einzige
     Sonderregel richtig. In der Nachbaranwendung stand die Fläche auf 2500 und
     verdeckte ihre eigene Kennzeichnung; das war dort ein eigener Fehlerbericht
     (T-183). */
  z-index: 110;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: radial-gradient(120% 90% at 50% 0%, #123a5c 0%, #0d2a44 45%, #081b2c 100%);
  color: var(--sa-ink);
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-base) var(--ease-std), visibility var(--dur-base);
}
.sprachassistent_offen { opacity: 1; visibility: visible; }

/* DER GLOBALE FOKUSRING TRÄGT HIER NICHT. Er steht auf --q-highlight-2 (Navy)
   und ist auf dem dunklen Grund praktisch unsichtbar — genau die Eigenschaft,
   die er nicht haben darf. Innerhalb der Fläche gilt deshalb die Markenfarbe
   der Fläche; auf Milchglas wechselt sie mit. */
.sprachassistent :focus-visible:not(input):not(select):not(textarea) {
  outline: 2px solid var(--sa-accent);
  outline-offset: 2px;
}
.sprachassistent select:focus-visible { outline: 2px solid var(--sa-accent); outline-offset: 1px; }

/* Milchglas — die Anwendung bleibt hinter mattierter Scheibe sichtbar. Nur die
   Farbrollen wechseln; der Aufbau bleibt derselbe. */
.sprachassistent[data-erscheinung="milchglas"] {
  --sa-ink: var(--q-highlight-2);
  --sa-ink-2: rgba(16, 49, 78, 0.82);
  /* 0,72 statt 0,66 — GEMESSEN, nicht geschätzt. Mit 0,66 kamen der
     Hinweistext, die Kennzeichnungsleiste, der leere Mitschrifttext und der
     Tastenhinweis auf 4,47 : 1 gegen den Grund der Anwendung und lagen damit
     drei Hundertstel unter der Schwelle von 4,5. Auf dem dunklen
     Erscheinungsbild trägt derselbe Token 6,74 : 1 — deshalb fiel es dort
     nicht auf, und deshalb gehört jede Farbe in BEIDEN Fassungen gemessen.
     0,72 ergibt 5,25 : 1 auf --surface-soft und 5,58 : 1 auf Weiß; beide
     Untergründe sind möglich, weil die Scheibe durchscheint. */
  --sa-ink-3: rgba(16, 49, 78, 0.72);
  --sa-line: rgba(16, 49, 78, 0.18);
  --sa-line-hi: rgba(16, 49, 78, 0.45);
  --sa-fill: rgba(255, 255, 255, 0.55);
  --sa-fill-hi: rgba(255, 255, 255, 0.85);
  --sa-accent: color-mix(in srgb, var(--q-highlight-3) 42%, var(--q-highlight-2));
  --sa-panel: rgba(255, 255, 255, 0.5);

  background: rgba(241, 242, 242, 0.55);
  backdrop-filter: blur(26px) saturate(1.15);
  -webkit-backdrop-filter: blur(26px) saturate(1.15);
}

/* KEIN FILTER FÜR DIE SYMBOLE. Die Anwendung zeichnet ihre Symbole als Maske
   mit background-color: currentColor (.ui_icon_mask) beziehungsweise als
   stroke="currentColor" — sie folgen der Textfarbe von selbst. Ein
   `filter: brightness(0) invert(1)`, wie er in der Nachbaranwendung nötig war,
   wäre hier eine Umkehrung dessen, was ohnehin stimmt. */
.sprachassistent .ui_icon { color: currentColor; }

/* Langsam wanderndes Farbfeld im Hintergrund. Rein dekorativ und deshalb
   aria-hidden; auf Milchglas entfällt es, weil dort die Anwendung selbst den
   Untergrund bildet. */
.sprachassistent_ambient {
  position: absolute;
  inset: -10%;
  background: linear-gradient(270deg, #10314e, #15a5b5, #c6d31c, #f1f2f2);
  background-size: 800% 800%;
  opacity: 0.1;
  filter: blur(60px);
  animation: sprachassistent-ambient 30s linear infinite;
  pointer-events: none;
}
.sprachassistent[data-erscheinung="milchglas"] .sprachassistent_ambient { display: none; }

@keyframes sprachassistent-ambient {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* ── Kopfbereich ─────────────────────────────────────────────────────────── */

.sprachassistent_header {
  position: relative;
  z-index: 2;
  width: 100%;
  /* Drei Spalten, damit der Titel mittig steht, ohne dass die Schaltfläche ihn
     verschiebt — die äußere Spalte links bleibt leer und hält die Breite der
     rechten. */
  display: grid;
  grid-template-columns: 38px 1fr 38px;
  align-items: center;
  gap: 16px;
  padding: 20px 24px;
}
.sprachassistent_title {
  grid-column: 2;
  text-align: center;
  font-family: var(--font-display);
  font-weight: var(--w-bold);
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--sa-ink-2);
}
.sprachassistent_controls { grid-column: 3; display: flex; justify-content: flex-end; }
.sprachassistent_control {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--sa-line);
  background: var(--sa-fill);
  color: var(--sa-ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-std), border-color var(--dur-fast) var(--ease-std);
}
.sprachassistent_control:hover { background: var(--sa-fill-hi); border-color: var(--sa-line-hi); }

/* ── Hauptbereich ────────────────────────────────────────────────────────── */

.sprachassistent_body {
  position: relative;
  z-index: 2;
  flex: 1;
  min-height: 0;
  width: 100%;
  display: flex;
  align-items: stretch;
}
.sprachassistent_stage {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(12px, 2.2vh, 22px);
  padding: 8px 24px;
  text-align: center;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}

/* Der Orb. Die Zeichenfläche liegt hinter der Mikrofontaste, beide teilen sich
   dieselbe Mitte. aspect-ratio hält ihn rund, auch wenn die Höhe knapp wird. */
.sprachassistent_orb_wrap {
  position: relative;
  width: clamp(132px, 25vh, 280px);
  height: clamp(132px, 25vh, 280px);
  display: grid;
  place-items: center;
  flex: 0 1 auto;
  aspect-ratio: 1;
}
.sprachassistent_orb { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

.sprachassistent_mic {
  position: relative;
  width: clamp(62px, 10vh, 84px);
  height: clamp(62px, 10vh, 84px);
  border-radius: 50%;
  border: 0;
  cursor: pointer;
  display: grid;
  place-items: center;
  color: var(--sa-ink);
  background: var(--sa-fill);
  box-shadow: inset 0 0 0 1.5px var(--sa-line-hi);
  backdrop-filter: blur(10px);
  transition: background var(--dur-fast) var(--ease-std),
              transform var(--dur-fast) var(--ease-std),
              box-shadow var(--dur-fast) var(--ease-std),
              color var(--dur-fast) var(--ease-std);
}
.sprachassistent_mic:hover { background: var(--sa-fill-hi); }
.sprachassistent_mic:active { transform: scale(0.97); }
/* Während zugehört wird, trägt die Taste die Markenfarbe — sie ist dann der
   einzige gefüllte Fleck auf der Fläche. Das Symbol wechselt mit auf das
   Dunkelblau; auf Limette wäre Weiß unlesbar. */
.sprachassistent[data-phase="hoeren"] .sprachassistent_mic {
  background: var(--q-highlight-1);
  color: var(--q-highlight-2);
  box-shadow: 0 0 0 10px rgba(198, 211, 28, 0.16), inset 0 0 0 1.5px rgba(255, 255, 255, 0.4);
}

/* ── Zustandszeile ───────────────────────────────────────────────────────── */

.sprachassistent_status {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  font-size: 11px;
  font-weight: var(--w-bold);
  line-height: var(--lh-normal);
  text-transform: uppercase;
  letter-spacing: var(--tracking-xwide);
  color: var(--sa-accent);
}
.sprachassistent_status_dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.sprachassistent[data-phase="bereit"] .sprachassistent_status_dot { background: var(--sa-ink-3); }
.sprachassistent[data-phase="hoeren"] .sprachassistent_status_dot { animation: sprachassistent-puls 1.6s var(--ease-std) infinite; }
.sprachassistent[data-phase="verbinden"] .sprachassistent_status_dot { animation: sprachassistent-puls 0.8s var(--ease-std) infinite; }

@keyframes sprachassistent-puls {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.75); }
}

/* Pegelanzeige — sie belegt niederschwellig, dass das gewählte Mikrofon
   tatsächlich Signal liefert. Ohne sie ist „es passiert nichts" nicht von „das
   Mikrofon ist stumm" zu unterscheiden. */
.sprachassistent_level { display: inline-flex; align-items: center; gap: 9px; }
.sprachassistent_level_bars { display: inline-flex; align-items: flex-end; gap: 2px; height: 14px; }
.sprachassistent_level_seg {
  width: 3px;
  height: 5px;
  border-radius: 2px;
  background: var(--sa-line);
  transition: height 90ms linear, background 90ms linear;
}
.sprachassistent_level_seg:nth-child(even) { height: 8px; }
.sprachassistent_level_seg_an { height: 14px; background: var(--q-highlight-1); }
.sprachassistent_level_seg_spitze.sprachassistent_level_seg_an { background: var(--q-highlight-3); }
.sprachassistent_level_tag {
  font-size: 9.5px;
  font-weight: var(--w-bold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--sa-ink-3);
}
.sprachassistent_level_tag_aktiv { color: var(--sa-accent); }
.sprachassistent_status .sprachassistent_level {
  margin-left: 4px;
  padding-left: 11px;
  border-left: 1px solid var(--sa-line);
}

/* ── Gesagtes und Antwort ────────────────────────────────────────────────── */

.sprachassistent_said {
  max-width: 34ch;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(19px, 2.6vh, 27px);
  line-height: 1.35;
  color: var(--sa-ink);
  text-wrap: pretty;
}
/* Ohne Gesagtes steht dort der Hinweis, was zu tun ist — leiser und kleiner,
   damit die beiden nicht verwechselt werden. */
.sprachassistent_said_leer {
  font-family: var(--font-sans);
  font-weight: var(--w-light);
  font-size: 15px;
  color: var(--sa-ink-3);
  max-width: 44ch;
}

.sprachassistent_answer { max-width: 60ch; display: flex; flex-direction: column; gap: 14px; align-items: center; }
.sprachassistent_answer_text {
  margin: 0;
  font-size: 15px;
  font-weight: var(--w-light);
  line-height: 1.65;
  color: var(--sa-ink-2);
  white-space: pre-wrap;
  text-align: left;
  text-wrap: pretty;
}

.sprachassistent_note,
.sprachassistent_error {
  max-width: 48ch;
  margin: 0;
  font-size: 13.5px;
  font-weight: var(--w-light);
  line-height: 1.6;
  color: var(--sa-ink-2);
}
/* Ein eigener Rotton für den dunklen Grund: --danger ergibt dort 2,9 : 1 und
   ist damit unter der Schwelle. Auf Milchglas gilt --danger wieder — dort ist
   er richtig. */
.sprachassistent_error { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: #ffd9d9; }
.sprachassistent[data-erscheinung="milchglas"] .sprachassistent_error { color: var(--danger); }

.sprachassistent_examples { display: flex; flex-direction: column; gap: 7px; }
.sprachassistent_example { font-size: 13.5px; font-weight: var(--w-light); line-height: var(--lh-normal); color: var(--sa-ink-3); }

/* ── Mitschrift ──────────────────────────────────────────────────────────── */
/* Sie ist der Beleg der Sitzung: Ton vergeht, eine Auskunft der Verwaltung soll
   das nicht. */

.sprachassistent_transcript {
  width: 340px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
  margin: 0 20px 4px 0;
  background: var(--sa-panel);
  border: 1px solid var(--sa-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  backdrop-filter: blur(10px);
}
.sprachassistent_transcript_header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 16px 14px 20px;
  border-bottom: 1px solid var(--sa-line);
}
.sprachassistent_transcript_title { font-family: var(--font-display); font-weight: var(--w-bold); font-size: 13.5px; color: var(--sa-ink); }
.sprachassistent_transcript_count { font-size: 11px; color: var(--sa-ink-3); margin-right: auto; }
.sprachassistent_transcript_close {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 0;
  color: var(--sa-ink-3);
  background: transparent;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.sprachassistent_transcript_close:hover { background: var(--sa-fill-hi); color: var(--sa-ink); }

.sprachassistent_transcript_body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* Die Blasen bestimmen ihre Seite selbst — der Rumpf darf sie nicht dehnen,
     sonst füllt jede die volle Breite und die Seite verschwindet. */
  align-items: stretch;
}
.sprachassistent_transcript_empty { margin: 0; font-size: 13px; font-weight: var(--w-light); line-height: 1.6; color: var(--sa-ink-3); }

/* Sprechblasen. DIE SEITE TRÄGT DIE UNTERSCHEIDUNG, NICHT DIE FARBE: Sie bleibt
   in beiden Erscheinungsbildern und bei reduziertem Kontrast erhalten, und sie
   ist dieselbe Ordnung, die jeder aus Nachrichtenprogrammen kennt — eigene Rede
   rechts, Gegenüber links. Dieselbe Sprache wie ai_drawer_message_user und
   ai_drawer_message_assistant in der Schublade. */
.sprachassistent_transcript_item {
  display: flex;
  flex-direction: column;
  gap: 5px;
  text-align: left;
  /* Die Blase nimmt nicht die volle Breite: Sonst wäre sie ein Block und keine
     Blase, und die Seite ließe sich nicht ablesen. */
  max-width: 85%;
  align-self: flex-start;
}
.sprachassistent_transcript_item_person { align-self: flex-end; }
.sprachassistent_transcript_item_meta {
  font-size: 10px;
  font-weight: var(--w-bold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--sa-ink-3);
}
.sprachassistent_transcript_item_person .sprachassistent_transcript_item_meta { text-align: right; color: var(--sa-accent); }
/* Der Körper der Blase. Eine Ecke bleibt eng — sie zeigt zur sprechenden Seite
   und macht aus dem Rechteck eine Blase, ohne dass es einen Zipfel bräuchte. */
.sprachassistent_transcript_item_text {
  padding: 9px 13px;
  border-radius: var(--radius-lg);
  border-bottom-left-radius: var(--radius-sm);
  background: var(--sa-fill);
  border: 1px solid var(--sa-line);
  font-size: 13.5px;
  font-weight: var(--w-light);
  line-height: 1.6;
  color: var(--sa-ink-2);
  white-space: pre-wrap;
  text-wrap: pretty;
}
.sprachassistent_transcript_item_person .sprachassistent_transcript_item_text {
  background: rgba(198, 211, 28, 0.16);
  border-color: rgba(198, 211, 28, 0.42);
  border-bottom-left-radius: var(--radius-lg);
  border-bottom-right-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-weight: 400;
  color: var(--sa-ink);
}
.sprachassistent_transcript_footer {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 20px 18px;
  border-top: 1px solid var(--sa-line);
}
.sprachassistent_transcript_clear {
  font: inherit;
  font-size: 12px;
  color: var(--sa-ink-3);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--sa-line);
}
.sprachassistent_transcript_clear:hover:not(:disabled) { color: var(--sa-ink); }
.sprachassistent_transcript_clear:disabled { opacity: 0.4; cursor: default; }

/* ── Fußbereich ──────────────────────────────────────────────────────────── */

.sprachassistent_footer {
  position: relative;
  z-index: 2;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 16px 24px 22px;
}
/* Drei Teile in einer Zeile: Bedienelemente links, Kennzeichnung in der Mitte
   (sie darf wachsen und schrumpfen), Tastenhinweis rechts. GEMESSEN war es
   anders: Die Basiskomponente setzt an der Leiste `flex-shrink: 0`, weshalb sie
   bei 1400 px nicht mitging und den Hinweis in eine zweite Zeile drückte. */
.sprachassistent_footer_controls { display: flex; flex-wrap: wrap; gap: 8px; }
.sprachassistent_kennzeichnung { flex: 1 1 340px; min-width: 0; }

.sprachassistent_chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: inherit;
  font-size: 12.5px;
  color: var(--sa-ink);
  padding: 8px 15px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--sa-line);
  background: var(--sa-fill);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std);
}
.sprachassistent_chip:hover:not(:disabled) { border-color: var(--sa-line-hi); }
.sprachassistent_chip_an { border-color: var(--q-highlight-1); background: rgba(198, 211, 28, 0.16); }
.sprachassistent_chip:disabled { opacity: 0.45; cursor: default; }

/* ── Aufklappfelder der Fußzeile ─────────────────────────────────────────── */

.sprachassistent_popover_wrap { position: relative; }
.sprachassistent_popover {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 0;
  width: 286px;
  padding: 14px 16px 12px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--sa-line);
  background: var(--sa-panel);
  backdrop-filter: blur(18px);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28);
  display: flex;
  flex-direction: column;
  gap: 12px;
  z-index: 5;
}
.sprachassistent[data-erscheinung="milchglas"] .sprachassistent_popover {
  background: rgba(255, 255, 255, 0.9);
  box-shadow: var(--shadow-elevated);
}
.sprachassistent_popover_weit { width: 320px; max-height: min(70vh, 520px); overflow-y: auto; }
.sprachassistent_popover_header { display: flex; align-items: center; gap: 10px; }
.sprachassistent_popover_title { font-family: var(--font-display); font-weight: var(--w-bold); font-size: 13px; color: var(--sa-ink); margin-right: auto; }
.sprachassistent_popover_row { display: flex; flex-direction: column; gap: 6px; text-align: left; }
.sprachassistent_popover_label {
  font-size: 10.5px;
  font-weight: var(--w-bold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--sa-ink-3);
}
.sprachassistent_popover_section {
  font-size: 10px;
  font-weight: var(--w-bold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--sa-ink-3);
  margin-top: 2px;
}
.sprachassistent_popover_footer { border-top: 1px solid var(--sa-line); padding-top: 10px; }
.sprachassistent_popover_hint { font-size: 11px; font-weight: var(--w-light); line-height: 1.45; color: var(--sa-ink-3); }

.sprachassistent_select {
  font: inherit;
  font-size: 13px;
  color: var(--sa-ink);
  background: var(--sa-fill);
  border: 1px solid var(--sa-line);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  cursor: pointer;
  max-width: 100%;
}
/* Die Liste selbst zeichnet das Betriebssystem auf hellem Grund — dort gilt die
   dunkle Schrift, nicht die helle der Fläche. */
.sprachassistent_select option { color: var(--q-dark); background: #fff; }

.sprachassistent_perm {
  font: inherit;
  font-size: 11.5px;
  white-space: nowrap;
  color: var(--sa-ink);
  background: var(--sa-fill);
  border: 1px solid var(--sa-line);
  border-radius: var(--radius-pill);
  padding: 6px 13px;
  cursor: pointer;
  align-self: flex-start;
  margin-top: 2px;
}
.sprachassistent_perm:hover { border-color: var(--q-highlight-1); }

.sprachassistent_radios { display: flex; flex-direction: column; gap: 2px; }
.sprachassistent_radio {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  text-align: left;
  font: inherit;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  padding: 8px 9px;
  cursor: pointer;
  color: var(--sa-ink);
}
.sprachassistent_radio:hover { background: var(--sa-fill); }
.sprachassistent_radio_an { background: var(--sa-fill-hi); }
.sprachassistent_radio_mark {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  margin-top: 2px;
  border-radius: 50%;
  border: 1.5px solid var(--sa-line-hi);
  display: block;
}
.sprachassistent_radio_an .sprachassistent_radio_mark {
  border-color: var(--q-highlight-1);
  box-shadow: inset 0 0 0 3px var(--q-highlight-1);
}
.sprachassistent_radio_text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sprachassistent_radio_label { font-size: 12.5px; font-weight: var(--w-bold); }
.sprachassistent_radio_sub { font-size: 11px; font-weight: var(--w-light); line-height: 1.4; color: var(--sa-ink-3); }

.sprachassistent_hint { font-size: 11px; color: var(--sa-ink-3); white-space: nowrap; }
.sprachassistent_hint kbd {
  font-family: var(--font-mono);
  font-size: 10px;
  padding: 2px 5px;
  border-radius: 4px;
  border: 1px solid var(--sa-line);
  margin: 0 2px;
}

/* ── KI-Kennzeichnung auf dunklem Grund ──────────────────────────────────── */
/* Die Leiste ist die BESTEHENDE Komponente (ki_kennzeichnung_bar) samt Tafel
   und Erläuterungsdialog. Angepasst wird nur, was der dunkle Grund erzwingt:
   Farben. Aufbau, Text und Verhalten bleiben unberührt. */
/* Die Leiste ist in der Schublade ein Band UNTER dem Kopf und trägt deshalb
   `border-bottom` und `flex-shrink: 0`. In einer Fußzeile ist beides falsch:
   der Strich hängt frei, und die Starrheit sprengt die Zeile. Hier wird sie zur
   Pille — dieselbe Form wie die Chips daneben. */
.sprachassistent .ki_kennzeichnung_bar {
  flex-shrink: 1;
  padding: 8px 9px 8px 14px;
  border: 1px solid var(--sa-line);
  border-radius: var(--radius-pill);
  background: var(--sa-fill);
  color: var(--sa-ink-3);
}
.sprachassistent .ki_kennzeichnung_bar_text {
  color: var(--sa-ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* DER FETTE TEIL TRÄGT DIE KATEGORIE. Die Basiskomponente setzt ihn auf
   --q-highlight-2 (Navy); das ist auf hellem Grund richtig und auf dunklem
   gemessen 1,13 : 1. Ausgerechnet die Angabe, um die es bei einer Kennzeichnung
   geht, verschwände im Untergrund. Hier steht deshalb die Akzentfarbe der
   Fläche — dieselbe, die auch der Zustandszeile gilt; sie wechselt mit dem
   Erscheinungsbild und ist in beiden lesbar. */
.sprachassistent .ki_kennzeichnung_bar_text b { color: var(--sa-accent); }
/* GEMESSEN UND BEHOBEN: Der Knopf war weiß auf weiß, Kontrast 1 : 1 — die
   Schrift stand da, unsichtbar. Ursache war eine halbe Übernahme: In der
   Nachbaranwendung ist dieses Bedienelement ein unterstrichener Text, hier ist
   es eine Pille mit eigenem Grund (`background: #fff`). Übernommen war nur die
   Farbregel für den Text; der Grund blieb stehen. Wer nur die Optik einer
   Vorlage übernimmt, baut ihre Umgebung nicht mit — deshalb stehen hier alle
   drei Angaben: Vordergrund, Grund und Rahmen. */
.sprachassistent .ki_kennzeichnung_bar_control {
  color: var(--sa-ink);
  background: var(--sa-fill);
  border-color: var(--sa-line-hi);
}
.sprachassistent .ki_kennzeichnung_bar_control:hover { color: var(--sa-accent); border-color: var(--q-highlight-1); }
.sprachassistent .ki_kennzeichnung_mark { flex-shrink: 0; }

/* ── Schmalere Fenster ───────────────────────────────────────────────────── */
/* Die Umbruchpunkte sind die der Anwendung (1100 / 900 / 780 / 720), nicht neu
   erfundene: 900 nimmt der Mitschrift Breite, 720 stellt sie unter die Bühne. */

@media (max-width: 900px) {
  .sprachassistent_transcript { width: 290px; }
}
@media (max-width: 720px) {
  /* Unter dieser Breite steht die Mitschrift nicht mehr neben der Bühne,
     sondern darunter — nebeneinander bliebe für beides zu wenig. */
  .sprachassistent_body { flex-direction: column; }
  .sprachassistent_transcript { width: auto; margin: 0 16px 4px; max-height: 45%; }
  .sprachassistent_said { font-size: 19px; }
  .sprachassistent_hint { display: none; }
  .sprachassistent_footer { justify-content: center; text-align: center; }
}

/* Bewegungsreduzierung: Das wandernde Farbfeld und der pulsierende Punkt sind
   Zierde und tragen keine Auskunft — der Zustand steht als Text daneben. Der
   Orb selbst prüft prefers-reduced-motion in seiner Zeichenschleife und friert
   dort seine Zeitachse ein; er folgt dann nur noch dem Pegel. */
@media (prefers-reduced-motion: reduce) {
  .sprachassistent_ambient { animation: none; }
  .sprachassistent_status_dot { animation: none; }
}

/* ── Komponente: intro — die Start-Animation (BAL-172) ──────────────────────
   Die Oberflaeche baut sich beim Start einmal auf, statt schlagartig
   dazustehen. Drei Varianten ueber die Klasse `intro_v_a|b|c` auf <html>;
   `--intro-d` ist die Basisdauer, alle Zeiten sind Vielfache davon — damit
   sich das Tempo an EINER Stelle umstellen laesst.

   **Sie ist kein Vorhang, sondern der Aufbau:** Animiert werden die Teile der
   Anwendung selbst (`.app_shell_sidebar`, `.app_shell_topbar`,
   `.app_shell_main`), nicht eine Flaeche darueber. Die einzige Ausnahme ist die
   Flaeche der Variante C, die die Marke zeigt und danach verschwindet; ihr
   Markup steht in `assets/js/quantiz-marken.js`, der Ausloeser in
   `assets/js/intro.js`.

   Uebernommen aus der Nachbaranwendung Mission Control (dort
   css/components/intro.css). Der Unterschied kommt aus dem Aufbau dieser
   Anwendung: Die Shell heisst hier `app_shell_*`, und die Wurzel ist
   `#app.app_mount`.

   Doku: docs/css/structure/intro.md, Blueprint: blueprints/blueprint_intro.html */

html.intro_run { --intro-d: 600ms; }

/* Verhindert, dass vor dem ersten Frame der scharfe Endzustand aufblitzt.
   Gesetzt **schon beim Ausliefern der Seite** (public/index.php) und im
   naechsten Frame nach dem Start entfernt. */
html.intro_arm .app_mount,
html.intro_arm .intro_splash { visibility: hidden; }

/* Zwischen dem Ausliefern und dem Start liegt die Ladezeit. In der Variante C
   folgt danach eine farbige Flaeche — ohne diese Zeilen laege davor der helle
   Grund der Anwendung, und der Auftritt begaenne mit einem Farbsprung. Die
   Flaeche selbst entsteht erst mit dem Lauf; hier steht nur ihre Farbe.

   Gesetzt wird sie am Koerper und nicht an der Wurzel: Der Koerper traegt seinen
   eigenen Grund (--surface-soft), der die Wurzel sonst ueberdeckte. */
html.intro_arm.intro_v_c[data-intro-arm-grund="weiss"]  body { background: var(--surface); }
html.intro_arm.intro_v_c[data-intro-arm-grund="lime"]   body { background: var(--q-highlight-1); }
html.intro_arm.intro_v_c[data-intro-arm-grund="navy"]   body { background: var(--q-highlight-2); }
html.intro_arm.intro_v_c[data-intro-arm-grund="petrol"] body { background: var(--q-highlight-3); }
html.intro_arm.intro_v_c[data-intro-arm-grund="dunkel"] body { background: var(--q-dark); }

/* ── Variante A — Aufbau in Leserichtung ─────────────────────────────────── */

html.intro_run.intro_v_a .app_shell_sidebar {
  animation: intro_von_links calc(var(--intro-d) * 0.62) var(--ease-std) both;
}
html.intro_run.intro_v_a .app_shell_topbar {
  animation: intro_von_oben calc(var(--intro-d) * 0.62) var(--ease-std) both;
  animation-delay: calc(var(--intro-d) * 0.14);
}
/* **Eine Ebene tiefer als der Entwurf es beschreibt.** `.app_shell_main` traegt
   in dieser Anwendung immer GENAU EIN Kind — den Container der Seite
   (`.mission_control`, `.admin_page`, `.list_page` …) —, und darin liegen die
   Bloecke, die gestaffelt erscheinen sollen (Kopf, Kachelreihe, Spalten). Mit
   dem naheliegenden Selektor `.app_shell_main > *` stiege genau ein Element
   auf, und die Staffelung, die die Variante ausmacht, fiele aus.

   Beide Bauformen sind abgedeckt: Fuehrt eine Seite ihre Bloecke einmal
   unmittelbar in `.app_shell_main`, greift die zweite Regel. Ueber `:only-child`
   schliessen sich die beiden gegenseitig aus — kein Element wird doppelt
   animiert. */
html.intro_run.intro_v_a .app_shell_main > *:only-child > *,
html.intro_run.intro_v_a .app_shell_main > *:not(:only-child) {
  animation: intro_aufsteigen calc(var(--intro-d) * 0.7) var(--ease-std) both;
}
html.intro_run.intro_v_a .app_shell_main > *:only-child > *:nth-child(1),
html.intro_run.intro_v_a .app_shell_main > *:not(:only-child):nth-child(1)   { animation-delay: calc(var(--intro-d) * 0.30); }
html.intro_run.intro_v_a .app_shell_main > *:only-child > *:nth-child(2),
html.intro_run.intro_v_a .app_shell_main > *:not(:only-child):nth-child(2)   { animation-delay: calc(var(--intro-d) * 0.40); }
html.intro_run.intro_v_a .app_shell_main > *:only-child > *:nth-child(3),
html.intro_run.intro_v_a .app_shell_main > *:not(:only-child):nth-child(3)   { animation-delay: calc(var(--intro-d) * 0.50); }
html.intro_run.intro_v_a .app_shell_main > *:only-child > *:nth-child(4),
html.intro_run.intro_v_a .app_shell_main > *:not(:only-child):nth-child(4)   { animation-delay: calc(var(--intro-d) * 0.58); }
/* Obergrenze: Ohne sie wartete die zwoelfte Kachel eine Sekunde auf ihren
   Auftritt. Ab dem fuenften Block laufen alle gemeinsam. */
html.intro_run.intro_v_a .app_shell_main > *:only-child > *:nth-child(n+5),
html.intro_run.intro_v_a .app_shell_main > *:not(:only-child):nth-child(n+5) { animation-delay: calc(var(--intro-d) * 0.66); }

/* ── Variante B — aus dem Fokus (nur Unschaerfe, keine Bewegung) ─────────── */

html.intro_run.intro_v_b .app_shell_sidebar,
html.intro_run.intro_v_b .app_shell_topbar,
html.intro_run.intro_v_b .app_shell_main {
  animation: intro_scharfziehen calc(var(--intro-d) * 0.8) var(--ease-std) both;
}
html.intro_run.intro_v_b .app_shell_topbar { animation-delay: calc(var(--intro-d) * 0.2); }
html.intro_run.intro_v_b .app_shell_main   { animation-delay: calc(var(--intro-d) * 0.4); }

/* ── Variante C — Marke zuerst ────────────────────────────────────────────
   Eine Flaeche, auf der die Quantiz-Marke steht. **Welche** Fassung und **auf
   welchem Grund**, sagen zwei Katalogachsen (`introMarke`, `introGrund`). Die
   Fassungen stammen aus dem Referenzentwurf der Ladeanimationen
   (docs/design/loading_animations/, QZ-L01 … QZ-L08); ihr Markup steht in
   assets/js/quantiz-marken.js, die Bewegung hier.

   **Schleife oder Durchgang — die Unterscheidung traegt die Variante.** Eine
   pulsierende oder umlaufende Bewegung darf mitten im Zyklus ausgeblendet
   werden; sie kehrt ohnehin dorthin zurueck, wo sie herkam. Die beiden
   Klecks-Fassungen laufen dagegen EINMAL und bleiben am offenen Faecher stehen:
   Ihr Rueckweg wuerde die Marke wieder einsammeln, unmittelbar bevor die
   Anwendung erscheint.

   Alle Zeiten sind Vielfache von `--intro-d`. Die Flaeche verblasst nach 1,8
   Basisdauern — das ist der Grund fuer das vierte Tempo. */

html.intro_run.intro_v_c .app_mount {
  animation: intro_scharfziehen calc(var(--intro-d) * 0.9) var(--ease-std) both;
  animation-delay: calc(var(--intro-d) * 1.9);
}
/* Beim Grund "Milchglas" steht die Oberflaeche von Anfang an da und wird von der
   Scheibe unscharf gehalten; das Verblassen der Scheibe IST die Enthuellung.
   Ohne diese Zeile laege die Scheibe vor einer Oberflaeche mit `opacity: 0` —
   also vor nichts, und das Ergebnis waere eine weisse Flaeche. */
html.intro_run.intro_v_c.intro_glas .app_mount { animation: none; }
.intro_splash {
  position: fixed; inset: 0;
  /* Ueber jeder Ebene der Anwendung (hoechste ist `.report-portal` mit 1200) und
     unter dem Meldungsbereich (`.app_status`, 9999): Eine Meldung muss lesbar
     bleiben, auch wenn sie in die Startflaeche hineinfaellt. */
  z-index: 1300;
  display: flex; align-items: center; justify-content: center;
  animation: intro_splash_aus calc(var(--intro-d) * 0.6) var(--ease-std) both;
  animation-delay: calc(var(--intro-d) * 1.8);
  /* Vollfarbig ist der Rueckfall der Nutzungsstellen; hier steht nur, was davon
     abweicht — so tragen auch die Kacheln der Einstellungsmaske die richtigen
     Farben, obwohl es dort keine Flaeche gibt. */
  background: var(--surface-soft);
}

/* ── Die sieben Gruende ───────────────────────────────────────────────────
   Alle sieben Flaechen sind Token aus `tokens.css`; kein neuer Farbwert.

   **Auf einem starken Grund behalten die Fluegel ihre Farben und bekommen eine
   weisse Kontur.** Die Lehrbuchantwort waere die einfarbige (negative) Fassung —
   die Regel des Markenhandbuchs, aber die falsche Antwort auf diese Frage: Der
   Faecher IST die Farbe. Die Kontur hebt ihn vom Grund ab, ohne ihm etwas zu
   nehmen, und loest dasselbe Problem: Gemessen deckt sich auf limefarbenem
   Grund das Lime-Blatt (1,00 : 1), auf navyfarbenem das Navy-Blatt, auf
   petrolfarbenem das Petrol-Blatt.

   Der **Schriftzug** folgt dagegen dem Kontrast: Er ist Schrift und muss lesbar
   bleiben, und eine Kontur um graue Buchstaben auf dunklem Grund macht sie nicht
   lesbarer, sondern fetter. Welche Farbe, ist gerechnet und nicht gewaehlt — je
   Grund die kontrastreichere von Weiss und Navy. Die Zahlen stehen im Katalog
   (assets/js/intro.js) und in docs/css/structure/intro.md.

   Auf Petrol gewinnt NAVY (4,51 : 1 gegen 2,97 : 1). Das ist der Punkt, an dem
   die Rechnung die Vermutung widerlegt — Mission Control setzt dort Weiss. */
.intro_splash[data-grund="hell"]  { background: var(--surface-soft); }
.intro_splash[data-grund="weiss"] { background: var(--surface); }

/* **Milchglas deckt nicht.** Die Anwendung steht beim Lauf schon da — sie
   scheint unscharf hindurch, bis die Flaeche verblasst und sie scharf zieht.
   Das ist der Gedanke aus QZ-L11 des Entwurfs, dort eine eigene Variante fuer
   blockierende Vorgaenge; hier ist es ein Grund unter den anderen.

   Ohne `backdrop-filter` bliebe eine halbdurchsichtige weisse Flaeche mit der
   ungeschaerften Anwendung darunter — lesbar, aber unruhig hinter der Marke.
   Der Rueckfall deckt deshalb staerker. */
.intro_splash[data-grund="milchglas"] {
  background: rgba(255, 255, 255, 0.72);
  -webkit-backdrop-filter: blur(20px) saturate(1.1);
  backdrop-filter: blur(20px) saturate(1.1);
}
@supports not (backdrop-filter: blur(1px)) {
  .intro_splash[data-grund="milchglas"] { background: rgba(255, 255, 255, 0.93); }
}
.intro_splash[data-grund="lime"]   { background: var(--q-highlight-1); --marke-wort: var(--q-highlight-2); }
.intro_splash[data-grund="navy"]   { background: var(--q-highlight-2); --marke-wort: var(--q-white); }
.intro_splash[data-grund="petrol"] { background: var(--q-highlight-3); --marke-wort: var(--q-highlight-2); }
.intro_splash[data-grund="dunkel"] { background: var(--q-dark);        --marke-wort: var(--q-white); }

/* ── Zusatz auf der Flaeche: Claimzeile und Verweis (BAL-176) ─────────────
   Zwei frei eingebbare Elemente unter der Marke. Ohne Eingabe steht hier
   nichts und die Flaeche sieht aus wie vorher - deshalb haengt alles am
   Merkmal `data-zusatz`, das die Flaeche nur dann traegt.

   DIE FARBE IST NICHT GEWAEHLT, SONDERN UEBERNOMMEN: `--marke-wort` ist je
   Grund die kontrastreichere von Weiss und Navy, gerechnet und oben im
   Katalog belegt (7,78 : 1 auf Hell bis 13,36 : 1 auf Navy). Derselbe Wert
   traegt den Schriftzug der Marke - Claim und Verweis daneben in einer
   zweiten Farbe waeren zwei Messungen statt einer.

   DER VERWEIS TRAEGT EINE EIGENE FARBE (BAL-177), waehlbar aus sieben Werten
   wie die Gruende; "marke" ist die gerechnete Schriftfarbe und die einzige,
   die auf jedem Grund traegt.

   IM RUHEZUSTAND OHNE UNTERSTREICHUNG (ausdruecklich so gewuenscht), beim
   Ueberfahren und im Tastaturfokus mit. Das ist hier vertretbar und waere es
   in einem Fliesstext nicht: Der Verweis steht ALLEIN auf einer eigenen Zeile
   unter dem Claim, nicht zwischen Woertern - unterschieden wird er durch
   Stellung und Gewicht, nicht allein durch Farbe. Dazu kommen Zeigerform,
   Unterstreichung beim Ueberfahren und der Fokusring.

   GLOBALE REGELN GEGENGEHALTEN: `body` setzt `font-weight: var(--w-light)`
   und `font-size: 15px`, `a` setzt `color: var(--q-highlight-2)` und
   `text-decoration: none`. Beide Blocke setzen deshalb Groesse, Gewicht,
   Zeilenhoehe, Farbe, Abstand und - beim Verweis - Unterstreichung
   ausdruecklich. Navy auf navyfarbenem Grund waere sonst unsichtbar. */
.intro_splash[data-zusatz="1"] {
  flex-direction: column;
  gap: clamp(20px, 5vh, 46px);
}
.intro_splash_zusatz {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  max-width: min(86vw, 560px);
  padding: 0 16px;
  text-align: center;
  color: var(--marke-wort, var(--q-dark));
  /* Nach der Marke, vor dem Ausblenden: Die Marke braucht 0,45 Basisdauern
     fuer ihren Auftritt, das Ausblenden der Flaeche beginnt bei 1,8. */
  animation: intro_zusatz_ein calc(var(--intro-d) * 0.5) var(--ease-std) both;
  animation-delay: calc(var(--intro-d) * 0.9);
}
.intro_splash_claim {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(14px, 2.1vw, 19px);
  font-weight: var(--w-regular);
  line-height: 1.35;
  color: inherit;
  text-wrap: pretty;
}
.intro_splash_link {
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  color: inherit;
  font-family: var(--font-sans);
  font-size: clamp(12.5px, 1.5vw, 15px);
  font-weight: var(--w-bold);
  line-height: 1.4;
  text-decoration: none;
  text-underline-offset: 4px;
  text-decoration-thickness: 2px;
}
.intro_splash_link:hover,
.intro_splash_link:focus-visible { text-decoration: underline; }

/* Die sechs gewaehlten Farben. "marke" hat keine Regel - der Verweis erbt dann
   die gerechnete Schriftfarbe des Claims (color: inherit oben), und das ist
   genau das Verhalten aus BAL-176. Das Merkmal steht an der FLAECHE, nicht am
   Verweis: So sieht eine Regel beide Seiten der Kombination, und die
   Einstellungsmaske kann sie mit denselben zwei Merkmalen nachstellen. */
.intro_splash[data-linkfarbe="lime"]    .intro_splash_link { color: var(--q-highlight-1); }
.intro_splash[data-linkfarbe="navy"]    .intro_splash_link { color: var(--q-highlight-2); }
.intro_splash[data-linkfarbe="petrol"]  .intro_splash_link { color: var(--q-highlight-3); }
.intro_splash[data-linkfarbe="violett"] .intro_splash_link { color: var(--q-highlight-5); }
.intro_splash[data-linkfarbe="weiss"]   .intro_splash_link { color: var(--q-white); }
.intro_splash[data-linkfarbe="dunkel"]  .intro_splash_link { color: var(--q-dark); }
/* DER FOKUSRING FOLGT NICHT DER GEWAEHLTEN FARBE - das waere ein Fehler, den
   BAL-177 erst eingebaut haette: Bei Limette auf hellem Grund traegt sie
   1,47 : 1, und ein Fokusring, den man nicht sieht, ist keiner. Er nimmt
   stattdessen `--marke-wort`, die je Grund gerechnete Schriftfarbe - sie
   traegt auf jedem der sieben Gruende (mindestens 4,51 : 1).

   Und nicht `--focus-ring`: Der ist Petrol und waere auf dem petrolfarbenen
   Grund deckungsgleich mit der Flaeche.

   Die Unterstreichung beim Fokus kommt dazu: zwei Kennzeichen statt einem. */
.intro_splash_link:focus-visible {
  outline: 2px solid var(--marke-wort, var(--q-dark));
  outline-offset: 3px;
}

/* ANHALTEN, solange Zeiger oder Fokus im Zusatz stehen (BAL-176).
   `animation: none` statt `animation-play-state: paused`: Wer den Verweis
   anfaehrt, waehrend die Flaeche schon halb verblasst ist, soll ihn lesen
   koennen - eingefroren bliebe er halbdurchsichtig. */
.intro_splash.intro_splash_haelt {
  animation: none;
  opacity: 1;
  visibility: visible;
}
.intro_splash.intro_splash_haelt .intro_splash_zusatz {
  animation: none;
  opacity: 1;
  transform: none;
}
/* Und beim Verlassen sofort ausblenden, ohne die Vorlaufzeit von vorn. */
.intro_splash.intro_splash_geht {
  animation: intro_splash_aus calc(var(--intro-d) * 0.5) var(--ease-std) both;
  animation-delay: 0s;
}

/* Die Kontur.

   `vector-effect: non-scaling-stroke` ist hier der Kern: Die Fassungen rechnen
   in fuenf verschiedenen Koordinatenfeldern (100, 200, 370, 945, 1024), und eine
   Strichstaerke in Feldeinheiten waere in jeder davon anders dick. So sind es
   ueberall 2,5 Bildschirmpunkte.

   `paint-order: stroke fill` legt den Strich HINTER die Fuellung: Die Kontur
   liegt damit aussen an und frisst nicht die Haelfte ihrer Breite in die Form
   hinein.

   **Nicht in der weichgezeichneten Lage.** Dort laufen die Blaetter durch einen
   Weichzeichner mit Farbmatrix (Metaball); ein weisser Strich wuerde dort
   mitverrechnet und den Klecks aufhellen, statt ihn abzusetzen. */
.intro_splash[data-kontur="1"] .intro_marke [data-blatt],
.intro_splash[data-kontur="1"] .intro_marke [data-blatt] path {
  stroke: var(--q-white);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
  paint-order: stroke fill;
}
.intro_splash[data-kontur="1"] .intro_marke_weich [data-blatt],
.intro_splash[data-kontur="1"] .intro_marke_weich [data-blatt] path { stroke: none; }

/* Ein Bogen IST ein Strich — er laesst sich nicht umranden. Hinter jedem liegt
   deshalb eine breitere weisse Fassung im Markup, die nur hier sichtbar wird. */
.intro_marke_bogen_kontur { display: none; }
.intro_splash[data-kontur="1"] .intro_marke_bogen_kontur {
  display: block;
  stroke: var(--q-white);
}

/* ── Die Marke auf der Flaeche ────────────────────────────────────────────
   Der Rueckfall jeder Farbe steht an der NUTZUNGSSTELLE (`var(--x, var(--y))`)
   und nicht am Container: Dieselbe Zeichnung steht auf der Flaeche, in einer
   Vorschaukachel der Einstellungen und im Blueprint — nur auf der Flaeche gibt
   es einen Container, der Variablen setzen koennte. Eine ungueltige `var()`
   faellt auf den Anfangswert zurueck, nicht auf den geerbten. */

.intro_marke {
  height: auto;
  /* Zwei Fassungen schwenken ihre Fluegel im Lauf weit aus dem Markenfeld heraus
     (der umlaufende Fluegel von "Auffaechern" beschreibt einen Kreis um seinen
     Fuss). Ohne dies wuerden sie am Rand des viewBox abgeschnitten — auf einer
     Flaeche, auf der ohnehin nichts anderes steht. */
  overflow: visible;
  animation: intro_marke_ein calc(var(--intro-d) * 0.45) var(--ease-std) both;
}
/* Zwei Bauformen: das Lockup ist breit, ein Zeichen ist quadratisch. */
.intro_marke[data-form="lockup"]  { width: min(72vw, 520px); }
.intro_marke[data-form="zeichen"] { width: min(46vw, 260px); }

/* **`:not()` ist hier kein Feinschliff, sondern die Berichtigung eines
   Fehlers.** Der Unterstrich ist ein offener Linienzug (zwei Striche, kein
   geschlossener Umriss) und liegt mit in der Schriftgruppe. Ohne den Ausschluss
   trifft ihn `.intro_marke_wort path` — und diese Regel GEWINNT gegen
   `.intro_marke_linie`: Klasse plus Typ schlaegt Klasse allein. Gefuellt wird
   ein offener Linienzug so, als waere er geschlossen, und aus dem Strich wird
   ein Keil, der nach rechts breiter wird. */
.intro_marke_wort path:not(.intro_marke_linie) { fill: var(--marke-wort, var(--q-dark)); }
.intro_marke_linie {
  fill: none; stroke: var(--marke-wort, var(--q-dark));
  stroke-width: 5.5; stroke-linejoin: round; stroke-linecap: round; stroke-miterlimit: 10;
}

/* Die vier Fluegel — gleich, welche Fassung sie zeichnet. */
.intro_marke [data-blatt="a"], .intro_marke [data-blatt="a"] path { fill: var(--marke-a, var(--q-highlight-3)); }
.intro_marke [data-blatt="b"], .intro_marke [data-blatt="b"] path { fill: var(--marke-b, var(--q-highlight-1)); }
.intro_marke [data-blatt="c"], .intro_marke [data-blatt="c"] path { fill: var(--marke-c, var(--q-bright)); }
.intro_marke [data-blatt="d"], .intro_marke [data-blatt="d"] path { fill: var(--marke-d, var(--q-highlight-2)); }
.intro_marke_bogen { fill: none; stroke-linecap: round; }
.intro_marke_bogen[data-bogen="a"] { stroke: var(--marke-a, var(--q-highlight-3)); }
.intro_marke_bogen[data-bogen="b"] { stroke: var(--marke-b, var(--q-highlight-1)); }
.intro_marke_bogen[data-bogen="d"] { stroke: var(--marke-d, var(--q-highlight-2)); }

/* ── Fassung "fliessend" (QZ-L07/L08): ein Durchgang ─────────────────────
   Jedes Blatt dreht um seinen FUSS, nicht um seine Mitte: Nur so laufen die
   vier im zusammengefalteten Zustand zu einem Klecks zusammen. */
.intro_marke_blatt {
  transform-box: fill-box; transform-origin: 50% 100%;
  animation-duration: calc(var(--intro-d) * 1.8);
  animation-timing-function: var(--ease-std);
  animation-fill-mode: both;
}
.intro_marke_blatt[data-blatt="a"] { animation-name: intro_marke_a; }
.intro_marke_blatt[data-blatt="b"] { animation-name: intro_marke_b; }
.intro_marke_blatt[data-blatt="c"] { animation-name: intro_marke_c; }
.intro_marke_blatt[data-blatt="d"] { animation-name: intro_marke_d; }

/* Die beiden Lagen loesen einander ab: Solange die Blaetter beieinander liegen,
   zeigt die weichgezeichnete Lage sie als EINEN Tropfen (Weichzeichner plus
   Farbmatrix = Metaball); sobald sie auseinandergehen, uebernimmt die scharfe. */
.intro_marke_weich  { animation: intro_marke_weich_aus  calc(var(--intro-d) * 1.8) var(--ease-std) both; }
.intro_marke_scharf { animation: intro_marke_scharf_ein calc(var(--intro-d) * 1.8) var(--ease-std) both; }

/* ── Fassung "Fluegelschlag" / "Vollmarke" (QZ-L01/L02): Schleife ───────── */
.intro_marke_fluegel {
  transform-box: fill-box; transform-origin: center;
  animation: intro_marke_puls calc(var(--intro-d) * 0.9) var(--ease-std) infinite;
}
.intro_marke_fluegel[data-blatt="d"] { animation-delay: calc(var(--intro-d) * -0.225); }
.intro_marke_fluegel[data-blatt="c"] { animation-delay: calc(var(--intro-d) * -0.15); }
.intro_marke_fluegel[data-blatt="b"] { animation-delay: calc(var(--intro-d) * -0.075); }

/* ── Fassung "Auffaechern" (QZ-L03): Schleife ueber Basisdauer × 1,8 ────── */
.intro_marke_faecher {
  transform-box: view-box;
  animation-duration: calc(var(--intro-d) * 1.8);
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.intro_marke_faecher[data-blatt="a"] { animation-name: intro_faecher_teal; }
.intro_marke_faecher[data-blatt="b"] { animation-name: intro_faecher_b; }
.intro_marke_faecher[data-blatt="c"] { animation-name: intro_faecher_c; }
.intro_marke_faecher[data-blatt="d"] { animation-name: intro_faecher_d; }

/* ── Fassung "neu geordnet" (QZ-L04) ─────────────────────────────────────
   Zwei geschachtelte Gruppen um denselben Punkt: Die aeussere stellt das Blatt
   auf seinen Platz im 29-Grad-Raster, die innere laesst es umlaufen. Beide
   brauchen `transform-box: view-box`, sonst bezoege sich `transform-origin` auf
   den Umriss des Elements statt auf das Koordinatenfeld. */
.intro_marke_ord_dreh,
.intro_marke_ord { transform-box: view-box; transform-origin: 512px 880px; }
.intro_marke_ord {
  animation-duration: calc(var(--intro-d) * 1.8);
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.intro_marke_ord[data-blatt="a"] { animation-name: intro_ord_teal; }
.intro_marke_ord[data-blatt="b"] { animation-name: intro_ord_b; }
.intro_marke_ord[data-blatt="c"] { animation-name: intro_ord_c; }
.intro_marke_ord[data-blatt="d"] { animation-name: intro_ord_d; }

/* ── Fassung "Neuinterpretation" / "Lockup, animiert" (QZ-L05/L06) ──────
   Drei Boegen, drei Umlaufzeiten im Verhaeltnis 1 : 1,25 : 1,5 wie im Entwurf —
   der mittlere laeuft rueckwaerts, damit keine Nahtstelle entsteht. */
.intro_marke_bogen {
  transform-box: view-box;
  animation: intro_bogen calc(var(--intro-d) * 1.2) linear infinite;
}
.intro_marke_bogen[data-bogen="b"] { animation-duration: calc(var(--intro-d) * 1.5); animation-direction: reverse; }
.intro_marke_bogen[data-bogen="d"] { animation-duration: calc(var(--intro-d) * 1.8); }

/* "Ruhend" traegt keine Bewegung — die Klasse steht trotzdem im Markup, damit
   die Fassung an ihren Teilen erkennbar bleibt. */
.intro_marke_ruhig { animation: none; }

/* ── Bewegungsablaeufe ─────────────────────────────────────────────────── */

@keyframes intro_von_links {
  from { opacity: 0; transform: translateX(-26px); filter: blur(10px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes intro_von_oben {
  from { opacity: 0; transform: translateY(-18px); filter: blur(8px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes intro_aufsteigen {
  from { opacity: 0; transform: translateY(14px); filter: blur(8px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
/* "Bewegt nichts" heisst: kein `translate`. Die 0,8 % Skalierung ist der
   Unterschied zwischen "steht" und "wirkt tot". */
@keyframes intro_scharfziehen {
  from { opacity: 0; filter: blur(14px); transform: scale(1.008); }
  to   { opacity: 1; filter: blur(0); transform: none; }
}
/* Schmal (BAL-208, Nachtrag): von 0,992 statt 1,008 her - eine vergroesserte
   Oberflaeche ragt 1,6 px ueber den Rand, und ein mobiler Browser verbreitert
   dafuer die Seite und zoomt heraus. */
@media (max-width: 780px) {
  @keyframes intro_scharfziehen {
    from { opacity: 0; filter: blur(14px); transform: scale(0.992); }
    to   { opacity: 1; filter: blur(0); transform: none; }
  }
}
@keyframes intro_splash_aus { to { opacity: 0; visibility: hidden; } }
@keyframes intro_zusatz_ein { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* Die Marke erscheint, bevor sich etwas an ihr bewegt. */
@keyframes intro_marke_ein {
  from { opacity: 0; filter: blur(6px); }
  to   { opacity: 1; filter: blur(0); }
}

/* Der Faecher der Klecks-Fassungen (QZ-L07/L08). Jedes Blatt beginnt bei 44° und
   Groesse 0,13 — vier Blaetter uebereinander ergeben dort einen Klecks — und
   dreht auf seinen Platz. Die vier Startzeitpunkte liegen leicht versetzt, wie
   im Entwurf: Dort steht der Versatz als NEGATIVE Verzoegerung, die bei einem
   einzelnen Durchgang mit `fill-mode: both` den Anfang abschneiden wuerde. Hier
   steht er als unterschiedlicher HALTEPUNKT. */
@keyframes intro_marke_a {
  0%, 18%   { transform: rotate(44deg) scale(0.13); }
  85%, 100% { transform: rotate(0deg) scale(1); }
}
@keyframes intro_marke_b {
  0%, 16%   { transform: rotate(44deg) scale(0.13); }
  85%, 100% { transform: rotate(29deg) scale(1); }
}
@keyframes intro_marke_c {
  0%, 14%   { transform: rotate(44deg) scale(0.13); }
  85%, 100% { transform: rotate(58deg) scale(1); }
}
@keyframes intro_marke_d {
  0%, 12%   { transform: rotate(44deg) scale(0.13); }
  85%, 100% { transform: rotate(87deg) scale(1); }
}
@keyframes intro_marke_weich_aus {
  0%, 45%   { opacity: 1; }
  85%, 100% { opacity: 0; }
}
@keyframes intro_marke_scharf_ein {
  0%, 51%   { opacity: 0; }
  85%, 100% { opacity: 1; }
}

/* Fluegelschlag (QZ-L01/L02): die vier Fluegel pulsieren versetzt. */
@keyframes intro_marke_puls {
  0%, 100% { opacity: 0.22; transform: scale(0.9); }
  35%      { opacity: 1;    transform: scale(1); }
}

/* Auffaechern (QZ-L03): Der petrolfarbene Fluegel laeuft einmal um; die drei
   anderen legen sich unterwegs auf ihn und faechern am Ende wieder auf. Sie
   blenden dafuer aus — ihre Formen decken sich nicht vollstaendig. */
@keyframes intro_faecher_teal {
  0%, 12%   { transform: rotate(0deg); animation-timing-function: linear; }
  82%, 100% { transform: rotate(360deg); }
}
@keyframes intro_faecher_b {
  0%, 14.9%   { transform: rotate(0deg) scale(1); opacity: 1; animation-timing-function: var(--ease-std); }
  17.94%      { transform: rotate(0deg) scale(0.92); opacity: 0; animation-timing-function: linear; }
  82%         { transform: rotate(329.46deg) scale(0.92); opacity: 0; animation-timing-function: var(--ease-std); }
  85%         { opacity: 1; }
  88.4%, 100% { transform: rotate(360deg) scale(1); opacity: 1; }
}
@keyframes intro_faecher_c {
  0%, 20.8%  { transform: rotate(0deg) scale(1); opacity: 1; animation-timing-function: var(--ease-std); }
  23.77%     { transform: rotate(0deg) scale(0.92); opacity: 0; animation-timing-function: linear; }
  82%        { transform: rotate(299.48deg) scale(0.92); opacity: 0; animation-timing-function: var(--ease-std); }
  85.5%      { opacity: 1; }
  94%, 100%  { transform: rotate(360deg) scale(1); opacity: 1; }
}
@keyframes intro_faecher_d {
  0%, 25.5%  { transform: rotate(0deg) scale(1); opacity: 1; animation-timing-function: var(--ease-std); }
  28.49%     { transform: rotate(0deg) scale(0.92); opacity: 0; animation-timing-function: linear; }
  82%        { transform: rotate(275.2deg) scale(0.92); opacity: 0; animation-timing-function: var(--ease-std); }
  86%        { opacity: 1; }
  98%, 100%  { transform: rotate(360deg) scale(1); opacity: 1; }
}

/* Neu geordnet (QZ-L04): Vier GLEICHE Fluegel im 29°-Raster decken sich beim
   Einsammeln vollstaendig — deshalb braucht diese Fassung kein Ausblenden. Das
   ist ihr ganzer Unterschied zu QZ-L03, und er liegt in der FORM, nicht in der
   Bewegung. */
@keyframes intro_ord_teal {
  0%, 12%   { transform: rotate(0deg); animation-timing-function: linear; }
  82%, 100% { transform: rotate(360deg); }
}
@keyframes intro_ord_b {
  0%, 17.64% { transform: rotate(0deg); animation-timing-function: linear; }
  82%        { transform: rotate(331deg); animation-timing-function: var(--ease-std); }
  88%, 100%  { transform: rotate(360deg); }
}
@keyframes intro_ord_c {
  0%, 23.28% { transform: rotate(0deg); animation-timing-function: linear; }
  82%        { transform: rotate(302deg); animation-timing-function: var(--ease-std); }
  94%, 100%  { transform: rotate(360deg); }
}
@keyframes intro_ord_d {
  0%, 28.92% { transform: rotate(0deg); animation-timing-function: linear; }
  82%        { transform: rotate(273deg); animation-timing-function: var(--ease-std); }
  99%, 100%  { transform: rotate(360deg); }
}

/* Neuinterpretation (QZ-L05/L06): die Boegen laufen um. */
@keyframes intro_bogen { to { transform: rotate(360deg); } }

/* ── Bewegungsreduzierung ────────────────────────────────────────────────
   Wer im Betriebssystem "Bewegung reduzieren" gewaehlt hat, bekommt die
   Oberflaeche sofort scharf. Der Ausloeser prueft das zusaetzlich und startet
   gar nicht erst — diese Regel ist der Riegel fuer den Fall, dass die
   Einstellung MITTEN im Lauf umgestellt wird. Sie traegt alle Klassen der
   Komponente; wer eine ergaenzt, ergaenzt sie hier mit. */
@media (prefers-reduced-motion: reduce) {
  html.intro_run .app_shell_sidebar,
  html.intro_run .app_shell_topbar,
  html.intro_run .app_shell_main,
  html.intro_run .app_shell_main > *,
  html.intro_run .app_shell_main > * > *,
  html.intro_run .app_mount { animation: none !important; }
  .intro_splash { display: none !important; }
  /* Gehoert zur Flaeche und wird mit ihr nicht gezeichnet — die Regeln stehen
     trotzdem hier, weil die Marke auch ausserhalb der Flaeche verwendet wird
     (Vorschaukacheln der Einstellungen, Blueprint). */
  .intro_marke,
  .intro_marke_blatt,
  .intro_marke_fluegel,
  .intro_marke_faecher,
  .intro_marke_ord,
  .intro_marke_bogen,
  .intro_marke_weich,
  .intro_marke_scharf { animation: none !important; }
}

/* ══ Einstellungen › Darstellung — die Wahl der Fassungen (BAL-172) ════════
   Der Abschnitt liegt im Einstellungsbereich "Darstellung" neben der
   Portionierung und schreibt wie diese bei JEDEM KLICK (siehe
   persistDarstellung in app.js): Der Bereich ist eine Maske ohne
   "Speichern"-Knopf, und ein Bedienelement, das dort auf einen Knopf wartete,
   den es nicht gibt, waere nicht zu bedienen.

   WIEDERVERWENDUNG (ucs.md §25, vor Neubau geprueft):
   - Haeufigkeit und Tempo benutzen `.fseg`/`.fseg-btn` — die Segmentreihe
     dieser Anwendung, unveraendert. Nur die Zusatzangabe des Tempos
     ("600 ms") braucht eine Zeile, die es dort noch nicht gab.
   - Karte, Ueberschrift, Feldbeschriftung und Hinweis sind `.content_card`,
     `.admin-h2`, `.ltb-facet-label` und `.pg-hinweis` aus dem Bestand.
   - Die Ladeanzeige in den Vorschaukacheln ist die ECHTE Komponente
     (renderLadeanzeige), nicht ein Nachbau.
   NEU, mit Begruendung:
   - `.intro_wahl`/`.intro_opt`: eine Kachel mit Vorschau, Namen und
     Erklaerungssatz. `.fseg` ist eine Reihe gleich breiter Segmente fuer kurze
     Beschriftungen — neun Markenfassungen mit Zeichnung und Satz sind damit
     nicht darstellbar.
   - `.intro_grund`: eine umbrechende Pillenreihe mit Farbprobe. `.fseg`
     verteilt sieben Segmente auf eine Zeile gleicher Breite; mit Probe und
     Beschriftung wird das auf schmalen Fenstern unlesbar.
   Klassenreihe: die LANGE Praefixreihe (`intro_*`, ucs.md §25) und nicht die
   kurze (`ltb-`, `fseg-`) — die Komponente ist neu, traegt eigene
   Unterelemente und kommt aus der Nachbaranwendung mit diesen Namen (POL-001
   laesst beide Reihen zu, verlangt aber die Begruendung). */

.intro_wahl { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; margin-top: 4px; }
.intro_opt {
  display: flex; flex-direction: column; gap: 10px; text-align: left;
  padding: 14px;
  border: 2px solid var(--q-bright); border-radius: 18px;
  background: var(--surface); cursor: pointer; font: inherit;
  transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std);
}
.intro_opt:hover { border-color: var(--q-highlight-3); }
.intro_opt:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
/* Der Zustand "ausgewaehlt" traegt die Flaechen dieser Anwendung
   (--surface-active mit --divider-active) und nicht die der Nachbaranwendung:
   Zartgruen bedeutet in Balance durchgaengig "eingeschaltet, ausgewaehlt".
   Text darauf ist --q-dark, gemessen 8,05 : 1 (tokens.css). */
.intro_opt.active { border-color: var(--divider-active); background: var(--surface-active); }
/* Jede vererbbare Eigenschaft ausdruecklich: Die globalen Grundregeln fuer
   Bedienelemente und Absaetze haben hier schon viermal hineingewirkt. */
.intro_opt_name {
  font-family: var(--font-sans);
  font-size: 13.5px; font-weight: var(--w-bold); line-height: 1.35; color: var(--q-dark);
}
.intro_opt_sub {
  font-family: var(--font-sans);
  font-size: 12.5px; font-weight: var(--w-light); line-height: 1.45;
  /* --fg-2 (#767676) statt --q-medium (#bbbbbb): Letzteres ist eine
     Dekorfarbe und traegt auf Weiss nur 1,9 : 1. */
  color: var(--fg-2); text-wrap: pretty;
}
/* **Zwei Farbfassungen heissen zwei Messungen.** Auf Weiss traegt --fg-2
   4,54 : 1 und besteht damit knapp; auf dem Zartgruen der ausgewaehlten Kachel
   nur noch 4,19 : 1 und faellt durch. tokens.css sagt das ausdruecklich
   ("--fg-2 faellt hier durch"), und die Stelle faellt beim Ansehen nicht auf -
   der Unterschied betraegt drei Prozent Helligkeit. Auf der aktiven Kachel
   traegt der Erklaerungssatz deshalb --q-dark (gemessen 8,05 : 1). */
.intro_opt.active .intro_opt_sub { color: var(--q-dark); }

/* Die Miniatur zeigt den Aufbau, den die Variante bewegt: Navigationsleiste,
   Kopfzeile, vier Inhaltsbloecke. */
.intro_mini {
  display: flex; gap: 5px; height: 56px; padding: 5px;
  background: var(--surface-soft); border-radius: 10px;
}
.intro_mini i { display: block; background: var(--q-medium); border-radius: 3px; opacity: 0.55; }
.intro_mini_nav  { width: 14px; flex: none; }
.intro_mini_body { flex: 1; display: flex; flex-direction: column; gap: 5px; }
.intro_mini_bar  { height: 8px; }
.intro_mini_rows { flex: 1; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 5px; }
.intro_opt.active .intro_mini i { background: var(--q-highlight-3); opacity: 0.5; }

/* Beim Ueberfahren **und beim Tastaturfokus** spielt die Miniatur den Ablauf an:
   Eine Vorschau, die nur der Zeiger ausloest, gaebe es fuer die Tastatur nicht. */
.intro_opt:hover .intro_mini i,
.intro_opt:focus-visible .intro_mini i { animation: intro_mini_lauf 1.1s var(--ease-std) both; }
.intro_opt[data-intro-v="a"]:hover .intro_mini_nav,
.intro_opt[data-intro-v="a"]:focus-visible .intro_mini_nav { animation-delay: 0s; }
.intro_opt[data-intro-v="a"]:hover .intro_mini_bar,
.intro_opt[data-intro-v="a"]:focus-visible .intro_mini_bar { animation-delay: 0.10s; }
.intro_opt[data-intro-v="a"]:hover .intro_mini_rows i:nth-child(1),
.intro_opt[data-intro-v="a"]:focus-visible .intro_mini_rows i:nth-child(1) { animation-delay: 0.20s; }
.intro_opt[data-intro-v="a"]:hover .intro_mini_rows i:nth-child(2),
.intro_opt[data-intro-v="a"]:focus-visible .intro_mini_rows i:nth-child(2) { animation-delay: 0.28s; }
.intro_opt[data-intro-v="a"]:hover .intro_mini_rows i:nth-child(3),
.intro_opt[data-intro-v="a"]:focus-visible .intro_mini_rows i:nth-child(3) { animation-delay: 0.36s; }
.intro_opt[data-intro-v="a"]:hover .intro_mini_rows i:nth-child(4),
.intro_opt[data-intro-v="a"]:focus-visible .intro_mini_rows i:nth-child(4) { animation-delay: 0.44s; }
.intro_opt[data-intro-v="b"]:hover .intro_mini_bar,
.intro_opt[data-intro-v="b"]:focus-visible .intro_mini_bar { animation-delay: 0.12s; }
.intro_opt[data-intro-v="b"]:hover .intro_mini_rows i,
.intro_opt[data-intro-v="b"]:focus-visible .intro_mini_rows i { animation-delay: 0.24s; }
.intro_opt[data-intro-v="c"]:hover .intro_mini i,
.intro_opt[data-intro-v="c"]:focus-visible .intro_mini i { animation-delay: 0.45s; }
/* Die Flaeche der Variante C liegt in der Vorgabe auf hellem Grund — dieselbe
   Farbe, die die Miniatur ohnehin hat. Ein Farbwechsel zeigte also nichts mehr.
   Stattdessen liegt die Marke als Andeutung darueber und verschwindet, bevor
   die Bloecke erscheinen. */
.intro_opt[data-intro-v="c"] .intro_mini { position: relative; }
.intro_opt[data-intro-v="c"] .intro_mini::after {
  content: ""; position: absolute; inset: 0; border-radius: 10px;
  background: var(--surface-soft)
    radial-gradient(circle at 50% 50%, var(--q-highlight-1) 0 4px, transparent 4px) no-repeat;
  opacity: 0;
}
.intro_opt[data-intro-v="c"]:hover .intro_mini::after,
.intro_opt[data-intro-v="c"]:focus-visible .intro_mini::after {
  animation: intro_mini_marke 1.1s var(--ease-std) both;
}

@keyframes intro_mini_lauf { from { opacity: 0; filter: blur(4px); } to { opacity: 0.55; filter: blur(0); } }
@keyframes intro_mini_marke {
  0%, 40%   { opacity: 1; }
  70%, 100% { opacity: 0; }
}

/* Die Miniatur ist Beiwerk: Wer Bewegung reduziert, braucht auch hier keine. */
@media (prefers-reduced-motion: reduce) {
  .intro_opt:hover .intro_mini i,
  .intro_opt:focus-visible .intro_mini i,
  .intro_opt:hover .intro_mini::after,
  .intro_opt:focus-visible .intro_mini::after { animation: none !important; opacity: 0; }
}

/* ── Die Marken in der Maske ───────────────────────────────────────────────
   Die Kacheln tragen die ECHTE Marke als Vorschau, nicht eine Andeutung: Das
   Markup gibt es ohnehin, und neun Fassungen nachzubauen hiesse, neun
   Zeichnungen zu pflegen, die mit den Originalen auseinanderlaufen. */

.intro_wahl_marke { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

.intro_marke_vorschau {
  display: grid; place-items: center;
  height: 78px; padding: 8px 12px;
  background: var(--surface-soft); border-radius: 10px;
  /* Auf der aktiven Kachel liegt Zartgruen; ohne eigene Linie waere das
     Kaestchen dort kaum vom Kachelgrund zu unterscheiden. */
  border: 1px solid var(--divider);
}
.intro_marke_vorschau[data-form="lockup"]  .intro_marke { width: 100%; max-width: 190px; }
.intro_marke_vorschau[data-form="zeichen"] .intro_marke { width: 56px; }

/* **Die Vorschau steht still — im ENDZUSTAND, nicht im Ausgangszustand.**
   Ohne Bewegung stuenden die vier Blaetter der Klecks-Fassungen alle auf 44°
   und Groesse 0,13 uebereinander, denn ihre Winkel entstehen erst in der
   Animation. Die Kachel zeigte dann einen Klecks statt einer Marke. Der
   Endzustand einer Animation ist kein Ruhezustand des Markups; wer ihn still
   braucht, schreibt ihn hin. */
.intro_marke_vorschau .intro_marke,
.intro_marke_vorschau .intro_marke_blatt,
.intro_marke_vorschau .intro_marke_fluegel,
.intro_marke_vorschau .intro_marke_faecher,
.intro_marke_vorschau .intro_marke_ord,
.intro_marke_vorschau .intro_marke_bogen,
/* `.intro_marke_scharf` gehoert mit in die Liste, und das faellt nur waehrend
   eines Laufs auf: Ohne `--intro-d` dauert seine Animation 0 s und haelt mit
   `fill-mode: both` den Endzustand - die Kachel sieht richtig aus. Sobald aber
   "Animation ansehen" die Klasse `intro_run` setzt, gilt `--intro-d` fuer das
   GANZE Dokument, und die neun Kacheln blendeten mit auf. Gemessen bei der
   Abnahme von BAL-172, als unter den animierten Zielen ein
   `intro_marke_scharf` auftauchte, das dort nichts zu suchen hatte. */
.intro_marke_vorschau .intro_marke_scharf { animation: none !important; }
/* Die weichgezeichnete Lage wird gar nicht gezeichnet; `display: none` haelt
   auch ihre Animation an. */
.intro_marke_vorschau .intro_marke_weich { display: none; }
.intro_marke_vorschau .intro_marke_blatt[data-blatt="a"] { transform: rotate(0deg); }
.intro_marke_vorschau .intro_marke_blatt[data-blatt="b"] { transform: rotate(29deg); }
.intro_marke_vorschau .intro_marke_blatt[data-blatt="c"] { transform: rotate(58deg); }
.intro_marke_vorschau .intro_marke_blatt[data-blatt="d"] { transform: rotate(87deg); }

/* ── Die Gruende ─────────────────────────────────────────────────────────── */

.intro_gruende { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.intro_grund {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 15px 6px 7px;
  border: 2px solid var(--q-bright); border-radius: var(--radius-pill);
  background: var(--surface); color: var(--q-dark);
  font-family: var(--font-sans); font-size: 13.5px; font-weight: var(--w-light); line-height: 1.35;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std);
}
.intro_grund:hover { border-color: var(--q-highlight-3); }
.intro_grund:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.intro_grund.active { border-color: var(--divider-active); background: var(--surface-active); font-weight: var(--w-bold); }

/* Die Probe zeigt die Flaeche selbst. Ein Rahmen gehoert dazu: Ohne ihn waere
   die helle und die weisse Probe auf weissem Grund nicht zu unterscheiden. */
.intro_grund_probe {
  width: 20px; height: 20px; flex: none;
  border-radius: 50%; border: 1px solid var(--q-bright);
}
.intro_grund_probe[data-grund="hell"]   { background: var(--surface-soft); }
.intro_grund_probe[data-grund="weiss"]  { background: var(--surface); }
/* Die Probe zeigt, was Milchglas ausmacht: Farbe darunter, Weiss darueber. */
.intro_grund_probe[data-grund="milchglas"] {
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.72)),
    linear-gradient(135deg, var(--q-highlight-3) 0 50%, var(--q-highlight-1) 50% 100%);
}
.intro_grund_probe[data-grund="lime"]   { background: var(--q-highlight-1); }
.intro_grund_probe[data-grund="navy"]   { background: var(--q-highlight-2); }
.intro_grund_probe[data-grund="petrol"] { background: var(--q-highlight-3); }
.intro_grund_probe[data-grund="dunkel"] { background: var(--q-dark); }

/* ── Tempo: die Segmentreihe des Bestandes mit einer Zusatzangabe ───────── */
.intro_tempo_seg .fseg-btn em {
  display: block;
  font-style: normal; font-size: 11px; font-weight: var(--w-light);
  color: var(--fg-2);
}
/* Auf dem navyfarbenen aktiven Segment muss die Zusatzangabe mitziehen — sonst
   stuende Grau (#767676) auf Navy, gemessen 1,63 : 1. */
.intro_tempo_seg .fseg-btn.on em { color: var(--q-white); }

/* ── Abschnitt, Hinweis, Wirkungslosigkeit ──────────────────────────────── */

.intro_abschnitt + .intro_abschnitt { margin-top: 18px; }
/* Ist die Animation abgeschaltet — oder gilt eine Achse nur fuer eine andere
   Variante —, bleibt der Abschnitt LESBAR, aber wirkungslos. Ihn zu verstecken
   naehme die Auskunft, was gewaehlt waere. */
.intro_abschnitt[data-aus="1"] { opacity: 0.45; pointer-events: none; }

/* ── Die Freitextfelder der Maske: Claim und Verweis (BAL-176) ────────────
   Drei Eingabefelder im selben Abschnitt wie Marke und Grund, weil sie
   dieselbe Bedingung teilen: Sie wirken nur in der Variante "Marke zuerst".
   Ein Raster statt einer Spalte, damit die kurze Beschriftung und die lange
   Adresse nicht dieselbe Breite bekommen.

   Die Felder selbst bringen ihre Gestaltung aus .content_form_input/.finput
   mit; hier steht nur, was daran haengt. Titel und Hinweis setzen Groesse,
   GEWICHT, Zeilenhoehe und Farbe ausdruecklich: body gibt font-weight 300 und
   15px weiter, und ein Hinweis, der so schwer wiegt wie der Text daneben,
   liest sich als zweite Zeile desselben Satzes. */
/* EINE Spalte ueber die volle Breite der Karte (Beanstandung 2026-09-13): Die
   drei Werte sind Saetze und Adressen, keine kurzen Angaben - nebeneinander
   standen sie in drei schmalen Spalten, und die Adresse passte in keine. */
.intro_zusatz_felder {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-top: 10px;
}
.intro_zusatz_feld { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.intro_zusatz_titel {
  color: var(--q-dark);
  font-size: 11.5px;
  font-weight: var(--w-bold);
  line-height: 1.3;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}
.intro_zusatz_hinweis {
  color: var(--fg-2);
  font-size: 11.5px;
  font-weight: var(--w-light);
  line-height: 1.4;
}
/* ── Die Farbwahl des Verweises und ihr gemessener Kontrast (BAL-177) ─────
   Die Pillenreihe ist die der Gruende (.intro_gruende/.intro_grund) - nur die
   Zuordnung der Farbprobe ist neu. */
.intro_grund_probe[data-linkfarbe="lime"]    { background: var(--q-highlight-1); }
.intro_grund_probe[data-linkfarbe="navy"]    { background: var(--q-highlight-2); }
.intro_grund_probe[data-linkfarbe="petrol"]  { background: var(--q-highlight-3); }
.intro_grund_probe[data-linkfarbe="violett"] { background: var(--q-highlight-5); }
.intro_grund_probe[data-linkfarbe="weiss"]   { background: var(--surface); }
.intro_grund_probe[data-linkfarbe="dunkel"]  { background: var(--q-dark); }
/* Zweifarbig, weil die Farbe hier keine feste ist, sondern aus dem Grund
   folgt - Weiss auf dunklem, Navy auf hellem. */
.intro_grund_probe[data-linkfarbe="marke"] {
  background: linear-gradient(135deg, var(--q-highlight-2) 0 50%, var(--q-white) 50% 100%);
}

/* DAS MESSELEMENT. Es traegt dieselben zwei Merkmale wie die Flaeche und
   dieselben Klassen - damit liefert getComputedStyle den WIRKSAMEN Wert der
   gewaehlten Kombination, nicht einen abgetippten. 49 Paare aus Farbe und
   Grund waeren als Tabelle im Quelltext nach der ersten Tokenaenderung falsch,
   ohne dass es jemandem auffiele.

   Die doppelte Klasse ist noetig, um die Lage der Flaeche (fixed, inset 0,
   z-index 1300) zu ueberschreiben. Nicht display:none: Ein nicht gezeichnetes
   Element hat keine wirksamen Werte zu liefern. */
.intro_splash.intro_kontrast_probe {
  position: absolute;
  inset: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  z-index: auto;
  animation: none;
}
.intro_kontrast_hinweis {
  margin-top: 8px;
  color: var(--fg-2);
  font-size: 11.5px;
  font-weight: var(--w-light);
  line-height: 1.4;
}
/* Unter 4,5 : 1 wird gewarnt, nicht uebersteuert: Die Wahl bleibt, wie sie
   getroffen wurde - aber sie sagt, was sie kostet. */
.intro_kontrast_hinweis[data-warnung="1"] {
  color: var(--danger);
  font-weight: var(--w-regular);
}

/* ── Komponente: ladeanzeige — die waehlbaren Zeichen (BAL-172) ─────────────
   Eine VIERTE ACHSE der Komponente aus BAL-122 (`data-variante`), kein zweiter
   Baustein: Beschriftung, `role="status"`, Bewegungsreduzierung und die drei
   bestehenden Achsen (`lage`, `groesse`, `ton`) gelten unveraendert weiter. Eine
   eigene Komponente je Fassung haette alle vier dreimal gefuehrt.

   Die Zeichnung kommt aus derselben erzeugten Datei wie die Marken der
   Startflaeche (assets/js/quantiz-marken.js), die BEWEGUNG steht getrennt: Dort
   laeuft eine Fassung einmal und bleibt stehen, hier laeuft sie endlos und
   rechnet in einem festen Takt statt in Vielfachen von `--intro-d`.

   Doku: docs/css/structure/ladeanzeige.md */

/* Dieselbe Grundlinie wie die Punktreihe: Der Kasten ist so hoch wie die
   Textzeile daneben (12,5 px × 1,4 = 17,5 px), damit die Fassung die Zeile
   nicht verschiebt. `--ladeanzeige-punkt` bleibt der EINZIGE Groessenwert. */
.ladeanzeige_zeichen {
  display: flex; align-items: center; flex-shrink: 0;
  width: calc(var(--ladeanzeige-punkt) * 2.2);
  height: calc(var(--ladeanzeige-punkt) * 2.2);
}
.ladeanzeige_zeichen_svg { width: 100%; height: 100%; overflow: visible; }

/* Fassung "fluegelschlag" (QZ-L01): die vier Fluegel pulsieren versetzt, im Takt
   der Punkte (1,2 s) und teilbar ueber dieselbe Variable. */
.ladeanzeige_fluegel {
  transform-box: fill-box; transform-origin: center;
  animation: ladeanzeige-fluegel calc(1.2s / var(--q-loader-speed, 1)) var(--ease-std) infinite;
}
.ladeanzeige_fluegel[data-blatt="a"] { fill: var(--q-highlight-3); }
.ladeanzeige_fluegel[data-blatt="b"] { fill: var(--q-highlight-1); animation-delay: calc(0.1s / var(--q-loader-speed, 1)); }
.ladeanzeige_fluegel[data-blatt="c"] { fill: var(--q-bright);      animation-delay: calc(0.2s / var(--q-loader-speed, 1)); }
.ladeanzeige_fluegel[data-blatt="d"] { fill: var(--q-highlight-2); animation-delay: calc(0.3s / var(--q-loader-speed, 1)); }
@keyframes ladeanzeige-fluegel {
  0%, 100% { opacity: 0.25; transform: scale(0.9); }
  40%      { opacity: 1;    transform: scale(1); }
}

/* Fassung "boegen" (QZ-L05): drei konzentrische Boegen, drei Umlaufzeiten im
   Verhaeltnis 1 : 1,25 : 1,5 wie im Entwurf — der mittlere rueckwaerts, damit
   keine Nahtstelle entsteht. */
.ladeanzeige_bogen {
  fill: none; stroke-linecap: round;
  transform-box: view-box; transform-origin: 50px 50px;
  animation: ladeanzeige-bogen calc(1.6s / var(--q-loader-speed, 1)) linear infinite;
}
.ladeanzeige_bogen[data-bogen="a"] { stroke: var(--q-highlight-3); }
.ladeanzeige_bogen[data-bogen="b"] { stroke: var(--q-highlight-1); animation-duration: calc(2s / var(--q-loader-speed, 1)); animation-direction: reverse; }
.ladeanzeige_bogen[data-bogen="d"] { stroke: var(--q-highlight-2); animation-duration: calc(2.4s / var(--q-loader-speed, 1)); }
@keyframes ladeanzeige-bogen { to { transform: rotate(360deg); } }

/* Ohne Bewegung stehen die Zeichen in voller Deckkraft da — dieselbe Regel wie
   fuer die Punkte: Eine unsichtbare Ladeanzeige waere schlechter als eine
   unbewegte. */
@media (prefers-reduced-motion: reduce) {
  .ladeanzeige_fluegel { animation: none; opacity: 1; transform: none; }
  .ladeanzeige_bogen { animation: none; }
}

/* Die Vorschaukacheln der Maske zeigen die Anzeige mittig und gross genug, um
   die Bewegung zu erkennen. Sie LAUFEN OHNE UEBERFAHREN — anders als bei der
   Start-Animation, deren Vorschau einen einmaligen Ablauf zeigt: Eine
   Ladeanzeige IST eine Schleife; sie stillzustellen hiesse, sie zu verstecken. */
.intro_lade_vorschau {
  display: grid; place-items: center;
  height: 56px;
  background: var(--surface-soft); border-radius: 10px;
  border: 1px solid var(--divider);
}
.intro_lade_vorschau .ladeanzeige { --ladeanzeige-punkt: 10px; }

/* ── Extern gefuehrte Themen (BAL-174) ──────────────────────────────────────
   Themen koennen aus der Nachbaranwendung Mission Control stammen. Zwei
   Bausteine: ein Abzeichen an der Themenzeile (woher) und eine Leiste ueber
   der Liste (wie alt, und der Knopf zum Erneuern).

   KLASSENREIHE: Praefixlogik nach ucs.md (`mc_leiste`, `mc_leiste_text`,
   `extern_abzeichen`) und nicht die kurze Reihe (`lc-`, `tc-`, `ffield`). Die
   Wahl ist nach POL-001 zu begruenden: Beide Bausteine sind NEUE, eigenstaendige
   Komponenten mit mehreren Unterelementen und Zustaenden - genau der Fall, fuer
   den ucs.md die Praefixlogik vorsieht. Die kurze Reihe stammt aus dem
   uebernommenen Referenz-Stylesheet und traegt dort bestehende Bausteine; ein
   neuer Baustein soll nicht in eine Reihe wachsen, deren Klaerung noch aussteht.

   Jede Regel setzt Groesse, Gewicht, Farbe und Abstand ausdruecklich. Das ist
   Vorgabe dieses Projekts und hat einen gemessenen Grund: Globale Grundregeln
   haben bereits viermal in eine Komponente hineingewirkt. */

.extern_abzeichen {
  display: inline-flex; align-items: center; gap: 5px;
  margin-left: 8px; padding: 2px 8px;
  border: 1px solid var(--divider); border-radius: var(--radius-pill);
  background: var(--surface-soft);
  /* GEMESSEN, nicht gegriffen: --q-medium ist eine Dekorfarbe (1,9 : 1) und
     scheidet aus. --fg-2 (#767676) traegt auf Weiss 4,54 : 1 - auf diesem
     Grund (--surface-soft, #f1f2f2) aber nur 4,05 : 1, und bei 11 px ist das
     zu wenig. --fg-1 traegt hier 7,78 : 1. Das ist genau der Fall, vor dem die
     Hausregel warnt: Eine Farbe ist gegen den Grund zu messen, der
     tatsaechlich darunter liegt, nicht gegen Weiss. */
  color: var(--fg-1);
  font-family: var(--font-sans); font-size: 11px; font-weight: var(--w-regular);
  line-height: 1.5; letter-spacing: 0; white-space: nowrap; vertical-align: middle;
}
.extern_abzeichen_ampel {
  width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
  background: var(--q-medium);
}
.extern_abzeichen_ampel_success { background: #5a8516; }
.extern_abzeichen_ampel_warning { background: #9b6f16; }
.extern_abzeichen_ampel_danger { background: #b83232; }
.extern_abzeichen_ampel_info { background: #0e7e8b; }
.extern_abzeichen_verwaist {
  border-color: #e8cfcf; background: #f8e0e0; color: #b83232;
  font-weight: var(--w-bold);
}
.extern_abzeichen_verwaist .ui_icon { flex: 0 0 auto; }

.mc_leiste {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  padding: 10px 14px; margin-bottom: 14px;
  border: 1px solid var(--divider); border-radius: var(--radius-md);
  background: var(--surface-soft);
  font-family: var(--font-sans); font-size: 12.5px; font-weight: var(--w-regular);
  line-height: 1.5; color: var(--fg-1);
}
.mc_leiste_quelle {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--q-highlight-2); font-size: 12.5px; font-weight: var(--w-bold);
}
/* --fg-1 aus demselben Grund wie beim Abzeichen: --fg-2 traegt auf
   --surface-soft nur 4,05 : 1. */
.mc_leiste_text { color: var(--fg-1); font-size: 12.5px; font-weight: var(--w-regular); }
.mc_leiste_warnung {
  padding: 2px 9px; border-radius: var(--radius-pill);
  background: #f8e0e0; color: #b83232;
  font-size: 11.5px; font-weight: var(--w-bold);
}
/* Die Fehlermeldung steht IN der Leiste und bleibt dort stehen. Eine Meldung,
   die nach vier Sekunden verschwindet, ist von gar keiner kaum zu
   unterscheiden - und die Leiste ist der Ort, an dem jemand nachsieht, warum
   die Themen nicht aktuell sind. */
.mc_leiste_fehler { border-color: #e8cfcf; background: #fdf4f4; }
.mc_leiste_meldung {
  flex: 1 1 100%; order: 9;
  color: #b83232; font-size: 12px; font-weight: var(--w-regular); line-height: 1.5;
}
.mc_leiste_knopf { margin-left: auto; }
.mc_leiste_knopf[disabled] { opacity: .6; cursor: default; }

.mc_formhinweis {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 11px 13px;
  border: 1px solid var(--divider); border-radius: var(--radius-md);
  background: var(--surface-soft);
  font-family: var(--font-sans); font-size: 12.5px; font-weight: var(--w-regular);
  line-height: 1.55; color: var(--fg-1);
}
.mc_formhinweis .ui_icon { flex: 0 0 auto; margin-top: 2px; color: var(--q-highlight-2); }
.mc_formhinweis strong { font-weight: var(--w-bold); color: var(--fg-1); }

/* Schmale Fenster: Der Knopf rutscht unter den Text, statt ihn zu quetschen.
   Die Umbruchpunkte folgen den bestehenden dieses Stylesheets. */
@media (max-width: 720px) {
  .mc_leiste { align-items: flex-start; }
  .mc_leiste_knopf { margin-left: 0; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Assistent fuer die Ersteinrichtung (BAL-187)

   WIEDERVERWENDUNG VOR NEUBAU. Die Huelle des Assistenten ist vollstaendig
   uebernommen: `.planner-overlay`, `.planner-card`, `.planner-rail`,
   `.planner-steps`, `.planner-step`, `.planner-body`, `.planner-head`,
   `.planner-scroll`, `.planner-foot`, `.planner-form-wide`,
   `.planner-icon-btn` und `.planner-assist` tragen den Import- und den
   Budgetplanungsassistenten und tragen diesen mit. `.setup_wizard` ist die
   dritte fachliche Auspraegung auf derselben Struktur - wie `.import_wizard`
   und `.budget_planner`.

   Ebenso uebernommen sind `.content_card`, `.admin-toggle-row` samt
   `.atr-title`/`.atr-desc`, `.switch`/`.knob`, `.basis-note`, `.fseg`/
   `.fseg-btn`, `.imp-radio`/`.imp-radio-dot`, `.content_form_item`/`.ffield`
   und `.admin-kpi`. Neu ist nur, was es noch nicht gab.

   ZWEI KLASSENREIHEN, EINE ENTSCHEIDUNG (POL-001). Balance fuehrt 163 Klassen
   in der langen Reihe (`app_shell`, `mission_control`, `detail_panel`) und 751
   in einer kurzen (`ltb-btn`, `ps-num`, `ffield`). Diese Komponente waehlt
   die LANGE, ucs-konforme Reihe fuer alles Neue: `setup_wizard` als
   Hauptblock, jedes Unterelement mit demselben Praefix. Die kurze Reihe
   erscheint hier nur dort, wo Bestehendes wiederverwendet wird - dieselbe
   Aufteilung wie bei `.import_wizard`, das ebenfalls als langer Block auf
   kurzem Geruest sitzt.

   FARBEN. Beschreibungstexte tragen `--fg-2` (#767676, 4,54 : 1 auf Weiss)
   und NICHT `--q-medium` (#bbbbbb, 1,9 : 1) - Letzteres ist eine Dekorfarbe.
   Auf `--surface-soft` (#f4f7ee) faellt auch `--fg-2` durch (4,19 : 1); dort
   steht `--q-dark`. Der Referenzentwurf benutzt an diesen Stellen
   durchgehend `--q-medium`; das ist bewusst NICHT uebernommen.

   SCHRIFTGEWICHT. `body` setzt `--w-light` (300), und das vererbt sich bis
   hierher. Jeder Textbaustein dieser Komponente setzt sein Gewicht deshalb
   ausdruecklich - sonst stuende ein Titel duenner da als der Text daneben
   (der Fehler, der in dieser Anwendung viermal aufgetreten ist).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Schiene: Kapitel ueber den Schritten ────────────────────────────────── */

/* Die Schiene wird scrollbar: vierzehn Schritte in vier Kapiteln passen im
   Fenstermodus nicht auf einmal in die 680 px hohe Karte. Marke oben und
   Hinweis unten bleiben stehen, nur die Kapitelliste laeuft. */
.setup_wizard .planner-rail { display: flex; flex-direction: column; }
.setup_wizard_chapters { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 2px; }
.setup_wizard_chapter { margin-bottom: 14px; }
.setup_wizard_chapter:last-child { margin-bottom: 0; }
.setup_wizard_chapter_title {
  display: flex; align-items: center; gap: 7px;
  padding: 0 4px 6px;
  font-family: var(--font-sans); font-size: 10.5px; font-weight: var(--w-bold);
  line-height: 1.4; letter-spacing: var(--tracking-xwide); text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}
.setup_wizard_chapter .planner-steps { margin: 0; }
.setup_wizard_step_tag {
  display: block; margin-top: 2px;
  font-size: 10.5px; font-weight: var(--w-regular); line-height: 1.4;
  color: rgba(255, 255, 255, 0.6);
}

/* ── Fortschritt ─────────────────────────────────────────────────────────── */

.setup_wizard_progress { flex-shrink: 0; height: 3px; background: var(--divider); }
.setup_wizard_progress_bar {
  display: block; height: 100%; background: var(--q-highlight-1);
  transition: width var(--dur-base) var(--ease-std);
}
@media (prefers-reduced-motion: reduce) {
  .setup_wizard_progress_bar { transition: none; }
}

/* ── Empfehlungsleiste ueber dem Schrittinhalt ───────────────────────────── */

.setup_wizard_recommendation {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 18px; padding: 10px 12px 10px 14px;
  border: 1px solid var(--divider); border-radius: var(--radius-md);
  background: var(--surface-soft);
  font-family: var(--font-sans); font-size: 12.5px; font-weight: var(--w-regular);
  line-height: 1.5; color: var(--q-dark);
}
.setup_wizard_recommendation > span { flex: 1 1 auto; min-width: 0; }
.setup_wizard_recommendation > button { flex: 0 0 auto; }

/* Das Abzeichen am empfohlenen Wert. --q-highlight-2 auf --q-highlight-1
   gemessen: 6,1 : 1. */
.setup_wizard_tag {
  display: inline-block; margin-left: 8px; padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--q-highlight-1); color: var(--q-highlight-2);
  font-family: var(--font-sans); font-size: 10px; font-weight: var(--w-bold);
  line-height: 1.6; letter-spacing: var(--tracking-wide); text-transform: uppercase;
  vertical-align: 1px;
}

/* ── Block: ein thematischer Abschnitt im Schritt ────────────────────────── */

.setup_wizard_block { margin-bottom: 14px; padding: 18px 20px; }
.setup_wizard_block:last-child { margin-bottom: 0; }
.setup_wizard_block_header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; margin-bottom: 14px;
}
.setup_wizard_block_title {
  margin: 0;
  font-family: var(--font-display); font-size: 15px; font-weight: var(--w-bold);
  line-height: 1.3; color: var(--q-highlight-2);
}
.setup_wizard_block_description {
  margin: 4px 0 0; max-width: 70ch;
  font-family: var(--font-sans); font-size: 12.5px; font-weight: var(--w-regular);
  line-height: 1.55; color: var(--fg-2); text-wrap: pretty;
}
.setup_wizard_block_controls { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
.setup_wizard_block_body > .admin-toggle-row:first-child { padding-top: 0; }
.setup_wizard_block_body > .admin-toggle-row:last-child { border-bottom: 0; padding-bottom: 0; }

/* ── Auswahl: einander ausschliessende Moeglichkeiten ────────────────────── */

.setup_wizard_options { display: grid; gap: 10px; }
.setup_wizard_option {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 13px 15px; width: 100%;
  border: 1px solid var(--divider); border-radius: var(--radius-md);
  background: var(--surface); text-align: left; cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std);
}
.setup_wizard_option:hover { border-color: var(--q-highlight-3); }
.setup_wizard_option_active { border-color: var(--q-highlight-3); background: var(--surface-active); }
.setup_wizard_option .imp-radio { flex: 0 0 auto; margin-top: 2px; }
.setup_wizard_option_text { min-width: 0; }
.setup_wizard_option_label {
  display: block;
  font-family: var(--font-sans); font-size: 13.5px; font-weight: var(--w-bold);
  line-height: 1.4; color: var(--q-dark);
}
/* Auf der gewaehlten Flaeche liegt --surface-active; dort traegt --fg-2 nur
   4,19 : 1, deshalb --q-dark (8,05 : 1). Auf Weiss bleibt --fg-2. */
.setup_wizard_option_description {
  display: block; margin-top: 3px;
  font-family: var(--font-sans); font-size: 12px; font-weight: var(--w-regular);
  line-height: 1.5; color: var(--fg-2); text-wrap: pretty;
}
.setup_wizard_option_active .setup_wizard_option_description { color: var(--q-dark); }
@media (prefers-reduced-motion: reduce) {
  .setup_wizard_option { transition: none; }
}

/* Die Pillenreihe der Schrittweite. `.fseg`/`.fseg-btn` kommen aus den
   Einstellungen; hier bekommt der Knopf nur Platz fuer das Abzeichen. */
.setup_wizard_segment .fseg-btn { display: inline-flex; align-items: center; }
.setup_wizard_segment .setup_wizard_tag { margin-left: 6px; }

/* ── Schalterzeilen ──────────────────────────────────────────────────────── */

.setup_wizard_toggle .atr-title { display: flex; align-items: center; flex-wrap: wrap; }
.setup_wizard_toggle_gesperrt { opacity: 0.72; }

/* ── Eintraege: Register, Personen, Kanaele, Kennzeichnungen, Pruefliste ─── */

.setup_wizard_items { display: grid; gap: 0; }
.setup_wizard_item {
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 11px 2px;
  border-bottom: 1px solid var(--divider);
  text-align: left;
  font-family: var(--font-sans); font-size: 13.5px; font-weight: var(--w-regular);
  line-height: 1.45; color: var(--q-dark);
}
.setup_wizard_item:last-child { border-bottom: 0; }
.setup_wizard_item_icon {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 24px; height: 24px; border-radius: var(--radius-pill);
  background: #fbeedc; color: #8a5a12;
}
/* Erledigt: Limette gedaempft, Text dunkelgruen - gemessen 7,4 : 1. */
.setup_wizard_item_icon_ok { background: #eaf0cf; color: #4c5600; }
.setup_wizard_item_text { flex: 1 1 auto; min-width: 0; }
.setup_wizard_item_title {
  display: block;
  font-size: 13.5px; font-weight: var(--w-regular); line-height: 1.45; color: var(--q-dark);
}
.setup_wizard_item_description {
  display: block; margin-top: 2px;
  font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.45; color: var(--fg-2);
  text-wrap: pretty;
}
.setup_wizard_item_value {
  flex: 0 0 auto; display: flex; align-items: center; gap: 6px; justify-content: flex-end;
  font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.45; color: var(--fg-2);
}
.setup_wizard_item_ruht .setup_wizard_item_icon { background: var(--surface-soft); color: var(--fg-2); }
.setup_wizard_item_offen .setup_wizard_item_value { color: #8a5a12; font-weight: var(--w-bold); }

/* Die Pruefliste: jede Zeile ist die Schaltflaeche in ihren Schritt. Dasselbe
   Muster wie `.oe-zeile` und `.kennz-zeile`. */
.setup_wizard_check { cursor: pointer; }
.setup_wizard_check:hover .setup_wizard_item_value { color: var(--q-highlight-3); }

/* ── Abweichungsliste in der Pruefliste ──────────────────────────────────── */

.setup_wizard_chips { display: flex; flex-wrap: wrap; gap: 8px; }
.setup_wizard_chip {
  display: inline-flex; align-items: center; padding: 4px 11px;
  border: 1px solid var(--divider); border-radius: var(--radius-pill);
  background: var(--surface-soft);
  font-family: var(--font-sans); font-size: 11.5px; font-weight: var(--w-regular);
  line-height: 1.5; color: var(--q-dark);
}

/* ── Zusammenfassung ─────────────────────────────────────────────────────── */

.setup_wizard_summary { display: grid; gap: 0; }
.setup_wizard_summary_row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 9px 2px; border-bottom: 1px solid var(--divider);
  font-family: var(--font-sans); font-size: 13px; font-weight: var(--w-regular);
  line-height: 1.5; color: var(--fg-2);
}
.setup_wizard_summary_row:last-child { border-bottom: 0; }
.setup_wizard_summary_row strong { font-weight: var(--w-bold); color: var(--q-dark); text-align: right; }

/* ── Hoerprobe ───────────────────────────────────────────────────────────── */

.setup_wizard_preview {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--divider); border-radius: var(--radius-md);
}
.setup_wizard_preview_text {
  flex: 1 1 auto; min-width: 0;
  font-family: var(--font-sans); font-size: 13px; font-weight: var(--w-regular);
  line-height: 1.5; color: var(--q-dark); text-wrap: pretty;
}
.setup_wizard_preview_state {
  flex: 0 0 auto;
  font-family: var(--font-sans); font-size: 11.5px; font-weight: var(--w-regular);
  line-height: 1.45; color: var(--fg-2);
}

/* ── Felder und Rollenblöcke ─────────────────────────────────────────────── */

.setup_wizard_fields { margin: 0; }
.setup_wizard_roles { margin-bottom: 18px; }
.setup_wizard_roles:last-child { margin-bottom: 0; }
.setup_wizard_note { margin-top: 12px; }

/* ── Fussleiste ──────────────────────────────────────────────────────────── */

/* Links die Empfehlungen, rechts der Weg durch den Assistenten. Auf schmalen
   Fenstern untereinander, damit keine der bis zu fuenf Schaltflaechen aus der
   Karte laeuft. */
.setup_wizard_foot { flex-wrap: wrap; gap: 10px; }
.setup_wizard_foot .row { flex-wrap: wrap; }
.setup_wizard_foot .button[disabled] { opacity: 0.4; pointer-events: none; }


/* ── Telefon und Tablet: unterhalb 860 px ─────────────────────────────────
   Nach dem überarbeiteten Referenzentwurf (BAL-198,
   docs/design/application/project, `styles.css` Abschnitt „Assistent —
   Telefon- und Tablet-Ansicht"). Übernommen ist die GESTALTUNG, nicht die
   Klassenreihe des Entwurfs: dort `su-card`, hier `setup_wizard`.

   DER UMBRUCH LIEGT BEI 860 PX und damit über den 780 px der übrigen Dialoge.
   Das ist Absicht: Die Schiene braucht 264 px, und ein Tablet im Hochformat
   (768 – 834 px) behält davon für den Schritt selbst zu wenig übrig. Die
   Schiene wird deshalb schon dort zur Kopfleiste.

   DIE SCHRITTLISTE KLAPPT ZU, statt ihre Höhe zu deckeln. Die vorherige
   Fassung gab ihr 34vh bzw. 26vh — sie nahm damit auch dann Platz, wenn
   niemand navigieren wollte. Jetzt steht in der Kopfleiste eine Pille „n/14",
   und die Liste öffnet auf höchstens 52vh mit eigenem Bildlauf.

   Damit entfallen auch die beiden Notbehelfe der Vorfassung: Die
   Empfehlungsschaltflächen müssen nicht mehr ausgeblendet werden (sie stehen
   gestapelt in voller Breite), und die Vorzeile braucht keine Sonderregel
   mehr — sie steht hier ohnehin auf `white-space: normal`. */

.setup_wizard_hint_mobile { display: none; }
.setup_wizard_nav_toggle { display: none; }

@media (max-width: 860px) {
  /* Randlos über den ganzen Bildschirm. `100dvh` nach `100vh`, damit die
     Leisten mobiler Browser die Karte nicht abschneiden; Browser ohne
     `dvh` behalten den ersten Wert. */
  .planner-card.setup_wizard,
  .planner-card.setup_wizard.fullscreen {
    top: 0; left: 0; transform: none;
    width: 100vw; height: 100vh; height: 100dvh; max-width: none;
    border-radius: 0;
    grid-template-columns: 1fr;
    grid-template-rows: auto minmax(0, 1fr);
  }

  /* Der Vollbildschalter entfällt: Die Karte füllt hier ohnehin den Bildschirm,
     ein Schalter zwischen zwei gleichen Zuständen wäre ohne Wirkung. */
  .setup_wizard_nur_gross { display: none; }

  /* Die Schiene wird zur Kopfleiste. Sie behält Zeichen und Titel — die
     allgemeine Regel ab 780 px blendet `.planner-rail-brand` aus, hier nicht. */
  .setup_wizard .planner-rail { padding: 12px 14px; }
  .setup_wizard .planner-rail-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 0; }
  .setup_wizard .planner-rail-brand img { width: 30px; height: 30px; padding: 4px; border-radius: 8px; }
  .setup_wizard .planner-rail-brand .prb-title { font-size: 14px; }
  .setup_wizard .planner-rail-brand .prb-sub { display: none; }

  .setup_wizard_nav_toggle {
    display: flex; align-items: center; gap: 7px;
    margin-left: auto; min-height: 44px; padding: 0 12px;
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, 0.14); color: var(--q-white);
    font-family: var(--font-sans); font-size: 12.5px; font-weight: var(--w-bold); line-height: 1;
  }
  .setup_wizard_nav_toggle:hover { background: rgba(255, 255, 255, 0.22); }
  /* Es gibt kein Abwärts-Zeichen im Vorrat der Anwendung; `arrowRight` wird
     gedreht — zu und damit nach unten, offen und damit nach oben. */
  .setup_wizard_nav_toggle_zeichen { display: inline-flex; transform: rotate(90deg); transition: transform var(--dur-fast) var(--ease-std); }
  .setup_wizard_nav_toggle[aria-expanded="true"] .setup_wizard_nav_toggle_zeichen { transform: rotate(-90deg); }

  .setup_wizard_chapters {
    flex: 0 0 auto; max-height: 0; overflow: hidden;
    transition: max-height var(--dur-base) var(--ease-std);
  }
  .setup_wizard_chapters_offen { max-height: 52vh; overflow-y: auto; margin-top: 12px; }
  /* Die Schritte bleiben untereinander. Die allgemeine Regel ab 780 px legt
     `.planner-steps` waagrecht — in einer aufklappbaren Liste wäre das ein
     zweiter Bildlauf quer zum ersten. */
  .setup_wizard .planner-steps { flex-direction: column; overflow-x: visible; }
  .setup_wizard .planner-step { width: auto; }

  /* Der Hinweis wandert aus der Schiene über den Schrittinhalt. */
  .setup_wizard .planner-assist { display: none; }
  .setup_wizard_hint_mobile {
    display: flex; align-items: flex-start; gap: 9px;
    margin-bottom: 16px; padding: 10px 12px;
    border-radius: var(--radius-md); background: var(--surface-soft);
    font-family: var(--font-sans); font-size: 12.5px; font-weight: var(--w-regular);
    line-height: 1.5; color: var(--q-dark); text-wrap: pretty;
  }
  .setup_wizard_hint_mobile .ui_icon { flex: 0 0 auto; margin-top: 1px; opacity: 0.7; }

  .setup_wizard .planner-head { padding: 14px 16px 12px; gap: 10px; }
  .setup_wizard .planner-head h2 { margin-top: 4px; font-size: 18px; }
  .setup_wizard .planner-head .eyebrow { white-space: normal; font-size: 10px; line-height: 1.4; }
  .setup_wizard .planner-scroll { padding: 16px; }
  .setup_wizard .planner-icon-btn { width: 44px; height: 44px; }

  /* Die Hauptaktion steht OBEN: `column-reverse` dreht die beiden Reihen, und
     die zweite Reihe (Überspringen · Weiter) liegt damit über den
     Empfehlungswegen — am Daumen und im Blick zuerst. */
  .setup_wizard_foot { flex-direction: column-reverse; align-items: stretch; gap: 8px; padding: 12px 16px; }
  .setup_wizard_foot > .row { flex-direction: row; gap: 8px; }
  .setup_wizard_foot > .row > .button { flex: 1 1 0; }
  .setup_wizard_foot .button { width: 100%; min-height: 46px; justify-content: center; }

  .setup_wizard_block { padding: 15px 16px; }
  .setup_wizard_block_header { flex-direction: column; align-items: stretch; gap: 12px; }
  .setup_wizard_block_controls { width: 100%; }
  .setup_wizard_recommendation { flex-wrap: wrap; }
  .setup_wizard_recommendation .button { width: 100%; min-height: 44px; justify-content: center; }

  /* Trefferflächen auf 44 px — WCAG 2.5.8 verlangt 24 x 24, der Entwurf setzt
     44 und trifft damit auch die AAA-Schwelle 2.5.5. */
  .setup_wizard_option,
  .setup_wizard_check,
  .setup_wizard_chip { min-height: 44px; }

  .setup_wizard_item { flex-wrap: wrap; }
  .setup_wizard_item_value { width: 100%; justify-content: flex-start; padding-left: 36px; }
  .setup_wizard_summary_row { flex-direction: column; gap: 2px; }
  .setup_wizard_summary_row strong { text-align: left; }
  .setup_wizard_preview { flex-wrap: wrap; }
  .setup_wizard_roles + .setup_wizard_roles { margin-top: 14px; }
  .admin-kpis { gap: 22px; }

  /* Die Rückfragen des Assistenten — und nur sie, deshalb die eigene Marke. */
  .confirm-card.setup_wizard_confirm { width: calc(100vw - 24px); }
  .confirm-card.setup_wizard_confirm .confirm-foot { flex-direction: column-reverse; align-items: stretch; gap: 8px; }
  .confirm-card.setup_wizard_confirm .confirm-foot-main { display: contents; }
  .confirm-card.setup_wizard_confirm .confirm-foot .button { width: 100%; min-height: 46px; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .setup_wizard_chapters,
  .setup_wizard_nav_toggle_zeichen { transition: none; }
}
/* ═══════════════════════════════════════════════════════════════════════════
   BEREICHSHILFE — Übersichtskarte und geführte Tour (BAL-199)
   Doku: docs/css/structure/bereichshilfe.md
   Blueprint: blueprints/blueprint_bereichshilfe.html

   Die Ebene liegt auf z-index 125. Die Ebenenkarte der Anwendung steht bei
   `.sprachassistent` (Zeile ~4250): Detail 40/41, Dialoge 60/61, Schublade 70,
   Sprachassistent 110, Kennzeichnung 118–121, Rückfrage 130/131,
   Formulardialog 131/132. 125 liegt über der Kennzeichnung und unter der
   Rückfrage — über allem, was die Hilfe erklären soll, und unter allem, was
   über ihr stehen muss.

   ZWEI KARTEN, EIN BAUSTEIN: `bereichshilfe_karte` trägt Grund, Schatten und
   die Dreiteilung Kopf / Rumpf / Fuß; die Varianten `_uebersicht` und
   `_schritt` unterscheiden nur Lage, Breite, Radius und Innenabstand. Die
   Fußzeile ist in beiden dieselbe — das war die ausdrückliche Vorgabe: zarter
   grauer Grund mit Trennlinie, in jeder Ausprägung gleich.
   ═══════════════════════════════════════════════════════════════════════════ */

.bereichshilfe { position: fixed; inset: 0; z-index: 125; }

/* Die Abdunkelung ist eine echte Schaltfläche: Ein Klick daneben schließt die
   Hilfe, und das soll auch mit Hilfsmitteln erreichbar sein. `tabindex="-1"`
   hält sie aus der Tabreihenfolge heraus — dort steht bereits der
   Schließen-Knopf im Kartenkopf, der dasselbe tut und beschriftet ist. */
.bereichshilfe_scrim { position: absolute; inset: 0; display: block; width: 100%; height: 100%; padding: 0; border: 0; background: rgba(16, 49, 78, 0.5); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); cursor: default; animation: bereichshilfe_ein var(--dur-base) var(--ease-std); }
/* In der Tour übernimmt die Abdunkelung die Maske; die Fläche selbst bleibt
   durchsichtig und dient nur noch als Klickfläche. */
.bereichshilfe_scrim_quiet { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; animation: none; }

@keyframes bereichshilfe_ein { from { opacity: 0; } to { opacity: 1; } }
@keyframes bereichshilfe_karte_ein { from { opacity: 0; transform: translate(-50%, -46%); } to { opacity: 1; transform: translate(-50%, -50%); } }

/* `.layer_no_animation` sitzt auf der Ebene, die Animationen auf ihren
   Kindern — die globale Regel (Zeile 817) griffe deshalb ins Leere. */
.bereichshilfe.layer_no_animation .bereichshilfe_scrim,
.bereichshilfe.layer_no_animation .bereichshilfe_karte { animation: none; }

/* ── Karte: gemeinsamer Baustein ─────────────────────────────────────────── */
.bereichshilfe_karte { display: flex; flex-direction: column; overflow: hidden; background: var(--surface); box-shadow: var(--shadow-elevated); text-align: left; }
.bereichshilfe_karte_uebersicht { position: absolute; top: 50%; left: 50%; width: min(560px, calc(100vw - 40px)); max-height: calc(100vh - 48px); border-radius: var(--radius-lg); transform: translate(-50%, -50%); animation: bereichshilfe_karte_ein var(--dur-base) var(--ease-std); }
.bereichshilfe_karte_schritt { position: fixed; top: 0; left: 0; width: min(360px, calc(100vw - 32px)); max-height: calc(100vh - 32px); border-radius: var(--radius-md); }

.bereichshilfe_karte_header { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; flex-shrink: 0; padding: 24px 26px 0; }
.bereichshilfe_karte_schritt .bereichshilfe_karte_header { padding: 15px 13px 0 20px; }
.bereichshilfe_karte_headings { min-width: 0; }

/* Alle vererbbaren Angaben ausdrücklich: `p` und `h2` bringen Browservorgaben
   für Rand, Größe und Gewicht mit, und die Anwendung setzt zusätzlich eine
   globale `ul`-Regel (siehe .page_header_actions_list). Ein Textbaustein, der
   sich auf Vererbung verlässt, sieht hier anders aus als geplant. */
.bereichshilfe_karte_pretext { margin: 0; color: var(--q-highlight-2); font-size: 11px; font-weight: var(--w-bold); line-height: 1.4; letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.bereichshilfe_karte_title { margin: 5px 0 0; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 26px; font-weight: var(--w-bold); line-height: 1.2; }
.bereichshilfe_karte_schritt .bereichshilfe_karte_title { font-size: 17.5px; margin-top: 4px; }

.bereichshilfe_karte_controls { display: flex; flex-shrink: 0; gap: 4px; }
.bereichshilfe_karte_control { display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--fg-2); transition: background var(--dur-fast) var(--ease-std), color var(--dur-fast) var(--ease-std); }
.bereichshilfe_karte_control:hover { background: var(--surface-muted); color: var(--q-dark); }
.bereichshilfe_karte_schritt .bereichshilfe_karte_control { width: 26px; height: 26px; }

.bereichshilfe_karte_body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 18px 26px 22px; }
.bereichshilfe_karte_schritt .bereichshilfe_karte_body { padding: 10px 20px 16px; }

.bereichshilfe_block_label { margin: 0 0 7px; color: var(--fg-2); font-family: var(--font-sans); font-size: 10.5px; font-weight: var(--w-bold); line-height: 1.4; letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.bereichshilfe_block_label + * + .bereichshilfe_block_label,
.bereichshilfe_items + .bereichshilfe_block_label { margin-top: 20px; }
.bereichshilfe_text { margin: 0; color: var(--fg-1); font-size: 14.5px; font-weight: var(--w-light); line-height: 1.6; text-wrap: pretty; }
.bereichshilfe_karte_schritt .bereichshilfe_text { font-size: 13.5px; }

.bereichshilfe_items { display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; }
.bereichshilfe_item { display: flex; align-items: flex-start; gap: 10px; margin: 0; padding: 0; color: var(--fg-1); font-size: 14px; font-weight: var(--w-light); line-height: 1.5; text-wrap: pretty; }
.bereichshilfe_item_icon { display: grid; place-items: center; flex-shrink: 0; width: 20px; height: 20px; margin-top: 1px; border-radius: 50%; background: var(--q-highlight-1); color: var(--q-highlight-2); }
.bereichshilfe_item_title { min-width: 0; }

/* ── Fußzeile: in beiden Karten gleich ───────────────────────────────────── */
/* Der zarte graue Grund samt Trennlinie ist ausdrückliche Vorgabe der
   Auftraggeberin — „im Sinne der Einheitlichkeit und Konsistenz". Er ist
   derselbe, den `.modal_window_footer` und `.fmodal-foot` tragen. */
.bereichshilfe_footer { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-shrink: 0; padding: 12px 20px 12px 26px; border-top: 1px solid var(--divider); background: var(--surface-soft); }
.bereichshilfe_karte_schritt .bereichshilfe_footer { padding: 10px 14px 10px 20px; }

/* Fortschritt und Tastenhinweis stehen ÜBEREINANDER, nicht nebeneinander: Die
   Punkte gehören zur Tour, die Tasten zur Bedienung. In einer Zeile
   gelesen wirkten sie wie eine Angabe, und bei zwölf Punkten reicht der Platz
   in der schmalen Karte ohnehin nicht. */
.bereichshilfe_footer_status { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.bereichshilfe_progress { display: flex; flex-wrap: wrap; gap: 6px; }
.bereichshilfe_progress_dot { width: 7px; height: 7px; border-radius: 50%; background: var(--divider); transition: background var(--dur-fast) var(--ease-std), transform var(--dur-fast) var(--ease-std); }
.bereichshilfe_progress_dot_done { background: var(--q-medium); }
.bereichshilfe_progress_dot_current { background: var(--q-highlight-1); transform: scale(1.35); }

.bereichshilfe_keys { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0; padding: 0; list-style: none; }
/* --fg-1 und NICHT --fg-2: Der Hinweis steht auf dem grauen Fuß, nicht auf
   Weiß. Gemessen erreicht #767676 dort nur 3,73 : 1 — für 10,5-px-Text zu
   wenig (Sollwert 4,5). #4b4b4b kommt auf 7,71 : 1. Dieselbe Falle wie bei
   .ft-sub, dort am 2026-09-10 gemessen. */
.bereichshilfe_key { display: flex; align-items: center; gap: 4px; margin: 0; padding: 0; color: var(--fg-1); font-size: 10.5px; font-weight: var(--w-light); line-height: 1.4; }
.bereichshilfe_key kbd { min-width: 18px; padding: 2px 5px; border: 1px solid var(--divider); border-radius: 5px; background: var(--surface); color: var(--q-dark); font: inherit; font-size: 10px; text-align: center; }

.bereichshilfe_controls { display: flex; flex-shrink: 0; gap: 8px; }

/* ── Scheinwerfer ────────────────────────────────────────────────────────── */
/* Vier Masken statt eines Ausschnitts: `clip-path` mit einem Loch bräuchte ein
   gemessenes Polygon und verlöre den Eckradius des Ziels. Vier Rechtecke
   liegen auf ganzen Pixeln und lassen den Rahmen mit dem echten Radius des
   hervorgehobenen Elements zeichnen. Alle Maße setzt
   `bereichshilfeNachziehen()` als Inline-Stil. */
.bereichshilfe_maske { position: fixed; pointer-events: none; background: rgba(16, 49, 78, 0.5); }
.bereichshilfe_spot { position: fixed; pointer-events: none; border: 2px solid var(--q-highlight-1); transition: top var(--dur-base) var(--ease-std), left var(--dur-base) var(--ease-std), width var(--dur-base) var(--ease-std), height var(--dur-base) var(--ease-std); }
.bereichshilfe_spot_number { position: absolute; top: -13px; left: -13px; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--q-highlight-1); color: var(--q-highlight-2); font-size: 13px; font-weight: var(--w-bold); box-shadow: var(--shadow-soft); }

/* ── Kurzhilfe in den Erfassungsdialogen ─────────────────────────────────── */
.dialog_kurzhilfe { overflow: hidden; margin-bottom: 18px; border: 1px solid var(--divider); border-radius: var(--radius-sm); }
.dialog_kurzhilfe_header { display: flex; align-items: center; gap: 9px; width: 100%; padding: 9px 12px; border: 0; background: var(--surface-soft); text-align: left; }
.dialog_kurzhilfe_header:hover { background: var(--surface-muted); }
.dialog_kurzhilfe_header_icon { display: inline-flex; flex-shrink: 0; color: var(--fg-2); }
.dialog_kurzhilfe_title { flex: 1; min-width: 0; color: var(--q-highlight-2); font-size: 12.5px; font-weight: var(--w-bold); }
.dialog_kurzhilfe_indicator { display: inline-flex; flex-shrink: 0; color: var(--fg-2); transition: transform var(--dur-fast) var(--ease-std); }
.dialog_kurzhilfe_expanded .dialog_kurzhilfe_indicator { transform: rotate(180deg); }
.dialog_kurzhilfe_body { padding: 14px 14px 15px; border-top: 1px solid var(--divider); }
.dialog_kurzhilfe_text { margin: 0; color: var(--fg-1); font-size: 13px; font-weight: var(--w-light); line-height: 1.6; text-wrap: pretty; }
.dialog_kurzhilfe_items { display: flex; flex-direction: column; gap: 6px; margin: 12px 0 0; padding: 0; list-style: none; }
.dialog_kurzhilfe_item { position: relative; margin: 0; padding: 0 0 0 13px; color: var(--fg-1); font-size: 12.5px; font-weight: var(--w-light); line-height: 1.5; text-wrap: pretty; }
.dialog_kurzhilfe_item::before { content: ""; position: absolute; left: 0; top: 7px; width: 5px; height: 5px; border-radius: 50%; background: var(--q-highlight-1); }
.dialog_kurzhilfe_tip { display: flex; align-items: flex-start; gap: 8px; margin: 13px 0 0; padding-top: 11px; border-top: 1px solid var(--divider); color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-light); line-height: 1.5; text-wrap: pretty; }
.dialog_kurzhilfe_tip_icon { display: inline-flex; flex-shrink: 0; margin-top: 1px; color: var(--q-highlight-3); }

/* ── Telefon und schmales Fenster ────────────────────────────────────────── */
@media (max-width: 780px) {
  .bereichshilfe_karte_uebersicht { width: calc(100vw - 24px); max-height: calc(100vh - 24px); }
  .bereichshilfe_karte_header { padding: 20px 18px 0; }
  .bereichshilfe_karte_body { padding: 16px 18px 20px; }
  .bereichshilfe_footer { flex-direction: column; align-items: stretch; gap: 12px; padding: 12px 18px; }
  /* Kein Tastenhinweis auf dem Telefon: Dort gibt es keine Pfeiltasten und
     keine Esc-Taste, und die Fußzeile ist ohnehin schon gestapelt. */
  .bereichshilfe_keys { display: none; }
  .bereichshilfe_controls .button { flex: 1; justify-content: center; min-height: 44px; }
  /* Trefferfläche nach WCAG 2.5.5 — dieselbe Schwelle wie beim
     Einrichtungsassistenten (BAL-186/BAL-198). */
  .bereichshilfe_karte_control { width: 44px; height: 44px; }
  .dialog_kurzhilfe_header { min-height: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .bereichshilfe_scrim,
  .bereichshilfe_karte { animation: none; }
  .bereichshilfe_spot,
  .bereichshilfe_progress_dot,
  .dialog_kurzhilfe_indicator { transition: none; }
}

/* ══ Arbeitsdialog — Dialog-Standard fuer umfangreiche Dialoge (BAL-207) ══════
   Vorlage: docs/design/application/project/workdialog.css und
   src/WorkDialog.jsx. Aufbau: Kopf · [Abschnittsnavigation | Formular |
   Uebersicht] · Fussleiste. Strukturdoku: docs/css/structure/arbeitsdialog.md,
   Blueprint: blueprints/blueprint_arbeitsdialog.html.

   KEINE NEUE HUELLE: Der Arbeitsdialog ist eine Variante von `.modal_window`
   (`.modal_window_work`) und benutzt dessen Kopf (`modal_window_header`,
   `fmodal-head-l`, `fmodal-chip`, `modal_window_title`, `fmodal-head-actions`)
   und Fuss (`modal_window_footer`, `fmodal-foot-l`/`-r`) unveraendert. Neu ist
   nur, was es vorher nicht gab: Navigation, Abschnitte, 12er-Raster,
   Uebersichtsspalte, Pflichtangaben-Liste.

   Die Regeln stehen mit ZWEI Klassen (`.modal_window.wd`), weil sie gegen die
   einklassige Grundregel `.modal_window` und ihre Umbruchfassungen gewinnen
   muessen - auch dort, wo diese spaeter im Stylesheet stehen.

   TEXTFARBEN: Das Referenzdesign setzt Nebentexte in `--q-medium`. Das ist eine
   Dekorfarbe (1,9 : 1 auf Weiss) und fuer Text nicht zulaessig; hier steht
   `--fg-2` (4,54 : 1 auf Weiss). Auf dem gedaempften Grund der Uebersicht
   (`--surface-soft`) faellt `--fg-2` durch (4,19 : 1) - dort `--q-dark`. */
/* max-width: none, weil Varianten der kompakten Dialoge eine Obergrenze tragen
   (.decision-modal 560 px), die eine Breitenangabe nicht aufhebt (BAL-178). */
.modal_window.wd { display: grid; grid-template-rows: auto minmax(0, 1fr); grid-template-columns: minmax(0, 1fr); width: min(1360px, calc(100vw - 64px)); max-width: none; height: min(920px, calc(100vh - 64px)); max-height: none; }
.modal_window.wd.fullscreen { width: calc(100vw - 24px); height: calc(100vh - 24px); max-height: none; border-radius: 16px; }
.modal_window.wd.wd-md { width: min(1160px, calc(100vw - 64px)); height: min(800px, calc(100vh - 64px)); }
.modal_window.wd.wd-md.fullscreen { width: calc(100vw - 24px); height: calc(100vh - 24px); }
/* Kompakt: Einstellungsformulare und Entscheidungen. Die Hoehe richtet sich nach
   dem Inhalt, zwischen 560 und 800 px - ein festes 800er-Fenster um sechs Felder
   waere eine leere Flaeche. */
.modal_window.wd.wd-kompakt { height: auto; min-height: min(560px, calc(100vh - 64px)); max-height: min(800px, calc(100vh - 64px)); }
.modal_window.wd.wd-kompakt.fullscreen { height: calc(100vh - 24px); max-height: none; }
/* Liegt ueber einem anderen Dialog (Zahlungsplan aus der Beauftragung). */
.modal_window.wd.wd-oben { z-index: 131; }
.modal_window_overlay.wd-oben { z-index: 130; }

.modal_window.wd .modal_window_title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.modal_window.wd .wd-sub { color: var(--fg-2); font-weight: var(--w-light); }
.modal_window.wd .wd-titles { flex: 1; min-width: 0; }
.modal_window.wd .fmodal-head-l > .status_badge { flex-shrink: 0; align-self: flex-end; margin-bottom: 3px; }
.wd-aside-toggle { display: none; }

/* Rahmen um Rumpf und Fuss: bei Formulardialogen das <form>, sonst ein <div>.
   Ein eigener Behaelter, damit das Formular Rumpf UND Fuss umschliesst (der
   Speichern-Knopf ist ein echtes submit) und das Raster trotzdem traegt. */
.modal_window.wd .modal_window_frame { display: grid; grid-template-rows: minmax(0, 1fr) auto; grid-template-columns: minmax(0, 1fr); min-height: 0; flex: none; }
.modal_window.wd .modal_window_body { display: grid; grid-template-columns: 236px minmax(0, 1fr) 372px; min-height: 0; padding: 0; overflow: hidden; position: relative; }
.modal_window.wd.wd-md .modal_window_body { grid-template-columns: 220px minmax(0, 1fr) 340px; }
.modal_window.wd.wd-norail .modal_window_body { grid-template-columns: minmax(0, 1fr) 372px; }
.modal_window.wd.wd-md.wd-norail .modal_window_body { grid-template-columns: minmax(0, 1fr) 340px; }
.modal_window.wd.wd-noaside .modal_window_body { grid-template-columns: 236px minmax(0, 1fr); }
.modal_window.wd.wd-norail.wd-noaside .modal_window_body { grid-template-columns: minmax(0, 1fr); }

/* Navigation (Abschnitte oder Schritte) */
.wd-rail { display: flex; flex-direction: column; gap: 18px; min-height: 0; overflow-y: auto; padding: 22px 14px 18px; border-right: 1px solid var(--divider); }
.wd-rail-label { padding: 0 10px; color: var(--fg-2); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); line-height: 1.4; text-transform: uppercase; }
.wd-nav { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.wd-nav-btn { display: flex; align-items: center; gap: 11px; width: 100%; padding: 9px 10px; border: 0; border-radius: 12px; background: transparent; color: var(--q-dark); font: inherit; font-size: 13.5px; font-weight: var(--w-regular); line-height: 1.3; text-align: left; cursor: pointer; transition: background var(--dur-fast) var(--ease-std); }
.wd-nav-btn:hover { background: var(--surface-soft); }
.wd-nav-btn.wd-nav-btn_active { background: var(--surface-soft); font-weight: var(--w-bold); }
.wd-nav-btn.wd-nav-btn_na { color: var(--fg-2); }
.wd-nav-num { width: 24px; height: 24px; display: grid; place-items: center; flex-shrink: 0; border: 1.5px solid var(--q-bright); border-radius: 50%; background: #fff; color: var(--fg-2); font-size: 11px; font-weight: var(--w-bold); }
.wd-nav-btn.wd-nav-btn_active .wd-nav-num { border-color: var(--q-highlight-2); color: var(--q-highlight-2); }
.wd-nav-btn.wd-nav-btn_done .wd-nav-num { border-color: var(--q-highlight-2); background: var(--q-highlight-2); color: #fff; }
.wd-nav-btn.wd-nav-btn_done .wd-nav-num .ui_icon { filter: brightness(0) invert(1); }
.wd-nav-btn.wd-nav-btn_todo .wd-nav-num { border-color: var(--danger); color: var(--danger); }
.wd-nav-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.wd-nav-sub { overflow: hidden; color: var(--fg-2); font-size: 11px; font-weight: var(--w-light); text-overflow: ellipsis; white-space: nowrap; }
.wd-nav-btn.wd-nav-btn_todo .wd-nav-sub { color: var(--danger); }
.wd-progress { display: flex; flex-direction: column; gap: 8px; margin-top: auto; padding: 14px 10px 2px; border-top: 1px solid var(--divider); }
.wd-progress-row { display: flex; justify-content: space-between; color: var(--q-dark); font-size: 12px; font-weight: var(--w-light); }
.wd-progress-row b { font-weight: var(--w-bold); }
.wd-progress-bar { height: 6px; overflow: hidden; border-radius: 99px; background: var(--q-bright); }
.wd-progress-bar span { display: block; height: 100%; border-radius: 99px; background: var(--q-highlight-1); transition: width var(--dur-base) var(--ease-std); }
/* Assistenzhinweis unter den Schritten (Planungsassistent, Import) */
.wd-assist { display: flex; align-items: flex-start; gap: 10px; margin-top: auto; padding: 14px 12px; border-radius: 14px; background: var(--surface-soft); color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-light); line-height: 1.5; }
.wd-assist-ic { width: 26px; height: 26px; display: grid; place-items: center; flex-shrink: 0; border-radius: 8px; background: var(--q-highlight-2); }
.wd-assist-ic .ui_icon { filter: brightness(0) invert(1); }

/* Formularbereich */
.wd-main { position: relative; min-height: 0; overflow-y: auto; scroll-behavior: smooth; }
.wd-main-inner { max-width: 900px; margin: 0 auto; padding: 8px 44px 56px; }
.modal_window.wd.wd-md .wd-main-inner { max-width: 760px; }
.modal_window.wd.fullscreen .wd-main-inner { max-width: 1180px; }
.modal_window.wd.wd-norail .wd-main-inner { max-width: none; padding-left: 36px; padding-right: 36px; }
.modal_window.wd.wd-breit .wd-main-inner { max-width: none; padding-top: 28px; }
.wd-sec { padding: 30px 0 34px; border-bottom: 1px solid var(--divider); }
.wd-sec:last-child { min-height: 60%; border-bottom: 0; }
.wd-sec.wd-sec-single { padding-top: 28px; border-bottom: 0; min-height: 0; }
.wd-sec-head { display: flex; align-items: baseline; gap: 16px; margin-bottom: 22px; }
.wd-sec-num { min-width: 22px; color: var(--q-highlight-3); font-family: var(--font-display); font-size: 13px; font-weight: var(--w-bold); letter-spacing: 0.04em; }
.wd-sec-title { margin: 0; color: var(--q-dark); font-family: var(--font-display); font-size: 17px; font-weight: var(--w-bold); line-height: 1.25; }
.wd-sec-desc { max-width: 60ch; margin: 5px 0 0; color: var(--fg-2); font-size: 13px; font-weight: var(--w-light); line-height: 1.5; text-wrap: pretty; }
.wd-sec-na { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border: 1px dashed var(--q-bright); border-radius: 14px; color: var(--fg-2); font-size: 13px; font-weight: var(--w-light); line-height: 1.5; }
.wd-sec-na[hidden], .wd-grid[hidden], .wd-col[hidden], .wd-inline-impact[hidden] { display: none; }
.wd-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 18px 20px; }
.wd-col { grid-column: span var(--span, 12); min-width: 0; }
.wd-col > .fform-readout { flex-direction: column; justify-content: center; align-items: flex-start; gap: 2px; min-height: 44px; padding: 9px 12px; }
/* Unter 1240 px steht die Uebersicht nicht mehr neben dem Formular. Was dort an
   Auswirkung zu sehen ist, erscheint dann im Abschnitt selbst - als Abbild des
   Blocks in der Uebersicht, nicht als zweite Rechnung (arbeitsdialog.md). */
.wd-inline-impact { display: none; grid-column: 1 / -1; }

/* Uebersicht */
.wd-aside { display: flex; flex-direction: column; gap: 14px; min-height: 0; overflow-y: auto; padding: 22px 20px 24px; border-left: 1px solid var(--divider); background: var(--surface-soft); }
.wd-aside-head { display: flex; align-items: center; justify-content: space-between; }
.wd-aside-head .wd-rail-label { padding: 0; color: var(--q-dark); }
.wd-aside-close { display: none; }
.wd-card { display: flex; flex-direction: column; gap: 12px; padding: 16px 16px 15px; border: 1px solid var(--q-bright); border-radius: 16px; background: #fff; }
.wd-card-k { color: var(--fg-2); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); line-height: 1.4; text-transform: uppercase; }
.wd-card-title { color: var(--q-dark); font-family: var(--font-display); font-size: 16px; font-weight: var(--w-bold); line-height: 1.3; text-wrap: pretty; overflow-wrap: anywhere; }
.wd-card-title.wd-card-title_empty { color: var(--fg-2); font-weight: var(--w-regular); }
.wd-card-sub { margin-top: -6px; color: var(--fg-2); font-size: 12.5px; font-weight: var(--w-light); line-height: 1.4; overflow-wrap: anywhere; }
.wd-card-text { margin: 0; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-light); line-height: 1.5; text-wrap: pretty; overflow-wrap: anywhere; }
.wd-card-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.wd-card-tag { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 99px; background: var(--surface-soft); color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.4; }
.wd-card-tag.wd-card-tag_critical { background: #fbeae6; color: #8a2a1c; font-weight: var(--w-bold); }
.wd-card-amount { display: flex; flex-direction: column; gap: 2px; padding-top: 12px; border-top: 1px solid var(--divider); }
.wd-card-amount-value { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 26px; font-weight: var(--w-bold); line-height: 1.1; overflow-wrap: anywhere; }
.wd-card-amount-sub { color: var(--fg-2); font-size: 12px; font-weight: var(--w-light); line-height: 1.4; }
.wd-card-facts { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 0; font-size: 12.5px; line-height: 1.4; }
.wd-card-facts dt { margin: 0; color: var(--fg-2); font-weight: var(--w-light); }
.wd-card-facts dd { margin: 0; color: var(--q-dark); font-weight: var(--w-regular); text-align: right; overflow-wrap: anywhere; }
/* Pruefbloecke der Formulare (Budget, Rahmen, Planung, Beauftragung, Kontingent)
   als Karte der Uebersicht - derselbe Block, nur anders gerahmt. */
.wd-aside .budget-check, .wd-inline-impact .budget-check { padding: 15px 15px 14px; border-radius: 16px; }
.wd-aside .budget-check .bc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.wd-aside .budget-check .bc-grid > span:last-child:nth-child(odd) { grid-column: 1 / -1; }
.wd-aside .dialog_kurzhilfe { margin: 0; background: #fff; }
/* Behaelter fuer Karten, die je nach Eingabe entstehen (Rechnung: Beauftragung
   und Kontingent). Leer faellt er weg, damit kein doppelter Abstand bleibt. */
.wd-card-body { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
/* Ein ausgeblendeter Pruefblock muss auch weg sein: .budget-check setzt
   display:flex und hebt damit das hidden-Attribut auf. Im kompakten Dialog
   stand dadurch ein leerer, unsichtbarer Kasten im Formular; in der Uebersicht
   wird daraus eine sichtbare Luecke (BAL-207). */
.budget-check[hidden] { display: none; }
.wd-aside-group { display: flex; flex-direction: column; gap: 14px; }
/* Zielwertbalken (renderTargetBar) als Karte der Uebersicht */
.wd-aside .tbar { margin: 0; padding: 14px; border-radius: 16px; }
.wd-aside .tbar-topbar { flex-wrap: wrap; }
/* Die Zielmarke traegt ihre Beschriftung ueber der Spur; in der schmalen
   Spalte stiess sie an den Prozenttext der Kopfzeile. */
.wd-aside .tbar-head { flex-wrap: wrap; gap: 4px 10px; margin-bottom: 18px; }
.wd-aside .tbar-none { flex-direction: column; align-items: stretch; gap: 12px; }
.wd-aside .tbar-none-r { display: flex; align-items: baseline; justify-content: space-between; padding-top: 10px; border-top: 1px solid var(--divider); }
.wd-aside .tbar-nums { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.wd-inline-impact .tbar { margin: 0 0 14px; }
.wd-hint-fehler { color: var(--danger); }
/* Planungsansicht: links nur die zerstoerende Aktion, rechts die Leiste mit
   Status und Schaltflaechen in ganzer Breite (wie bisher .pdf-main). */
.modal_window.wd.plan-card-detail .fmodal-foot-l { flex: 0 0 auto; }
.modal_window.wd.plan-card-detail .fmodal-foot-l:empty { display: none; }
.modal_window.wd.plan-card-detail .fmodal-foot-r { flex: 1 1 auto; }
.modal_window.wd.plan-card-detail .fmodal-foot-r > .pdf-main { flex: 1 1 auto; display: flex; align-items: center; justify-content: space-between; gap: 12px; min-width: 0; }
.modal_window.wd .plan-detail-inner { max-width: none; padding: 26px 0 20px; }
.modal_window.wd .wd-plan-inner .plan-detail-inner { margin: 0; }
.wd-aside-group:empty { display: none; }
/* Pflichtangaben */
.wd-check { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.wd-check-btn { display: flex; align-items: center; gap: 10px; width: calc(100% + 12px); margin: 0 -6px; padding: 6px; border: 0; border-radius: 8px; background: transparent; color: var(--q-dark); font: inherit; font-size: 13px; font-weight: var(--w-light); line-height: 1.35; text-align: left; cursor: pointer; }
.wd-check-btn:hover { background: var(--surface-soft); }
.wd-check-dot { width: 18px; height: 18px; display: grid; place-items: center; flex-shrink: 0; border: 1.5px solid var(--danger); border-radius: 50%; }
.wd-check-btn.wd-check-btn_ok { color: var(--fg-2); }
.wd-check-btn.wd-check-btn_ok .wd-check-dot { border-color: var(--q-highlight-2); background: var(--q-highlight-2); }
.wd-check-btn.wd-check-btn_ok .wd-check-dot .ui_icon { filter: brightness(0) invert(1); }

/* Fussleiste */
.modal_window.wd .modal_window_footer .fmodal-foot-l { gap: 14px; color: var(--fg-2); font-size: 12.5px; font-weight: var(--w-light); }
.wd-foot-hint { white-space: nowrap; }
.wd-foot-hint .req { margin: 0 2px 0 0; }
.wd-foot-ok { display: inline-flex; align-items: center; gap: 6px; color: var(--q-dark); }
.wd-foot-missing { padding: 0; border: 0; background: transparent; color: var(--danger); font: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.wd-kbd { padding: 2px 6px; border: 1px solid var(--q-bright); border-radius: 5px; background: var(--surface-soft); color: var(--q-dark); font-size: 11px; font-weight: var(--w-regular); }

/* Auswahlkacheln (Planungsassistent: Planungsart, Planungsklammer; Neue
   Planung). Eine Radiogruppe mit grossen Flaechen statt Reitern. */
.wd-opts { display: grid; gap: 12px; }
.wd-opts.wd-opts_c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.wd-opts.wd-opts_c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.wd-opt { position: relative; display: flex; align-items: center; gap: 13px; min-height: 72px; padding: 14px 16px; border: 1.5px solid var(--q-bright); border-radius: 16px; background: #fff; color: var(--q-dark); font: inherit; text-align: left; cursor: pointer; transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std); }
.wd-opt:hover { border-color: var(--q-medium); }
.wd-opt.wd-opt_active { border-color: var(--q-highlight-2); background: var(--surface-active); }
.wd-opt[disabled] { opacity: 0.5; cursor: not-allowed; }
.wd-opt-ic { width: 36px; height: 36px; display: grid; place-items: center; flex-shrink: 0; border-radius: 11px; background: var(--surface-soft); }
.wd-opt.wd-opt_active .wd-opt-ic { background: var(--q-highlight-2); }
.wd-opt.wd-opt_active .wd-opt-ic .ui_icon { filter: brightness(0) invert(1); }
.wd-opt-txt { display: flex; flex: 1; flex-direction: column; gap: 3px; min-width: 0; }
.wd-opt-t { color: var(--q-dark); font-size: 14px; font-weight: var(--w-bold); line-height: 1.3; }
.wd-opt-d { color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-light); line-height: 1.4; text-wrap: pretty; }
.wd-opt-radio { width: 18px; height: 18px; display: grid; place-items: center; flex-shrink: 0; border: 1.5px solid var(--q-medium); border-radius: 50%; background: #fff; }
.wd-opt.wd-opt_active .wd-opt-radio { border-color: var(--q-highlight-2); }
.wd-opt.wd-opt_active .wd-opt-radio::after { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--q-highlight-2); }
.wd-opts.wd-opts_c3 .wd-opt { flex-direction: column; align-items: flex-start; gap: 10px; padding: 16px 16px 15px; }
.wd-opts.wd-opts_c3 .wd-opt-radio { position: absolute; top: 16px; right: 16px; }
.wd-opt-detail { margin-top: 16px; padding: 20px 22px 22px; border: 1px solid var(--divider); border-radius: 16px; background: #fff; }
/* Kennzahlenliste im Formularbereich (Freigaben, Planungsklammer) */
.wd-facts { grid-column: 1 / -1; display: flex; flex-direction: column; margin: 0; padding: 4px 14px; border-radius: 12px; background: var(--surface-soft); }
.wd-fact { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; padding: 9px 0; border-top: 1px solid rgba(0,0,0,0.06); }
.wd-fact:first-child { border-top: 0; }
.wd-fact dt { margin: 0; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-light); }
.wd-fact dd { margin: 0; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); text-align: right; }
.wd-next { display: flex; align-items: center; gap: 9px; padding-top: 18px; border-top: 1px solid var(--divider); color: var(--q-dark); font-size: 13px; font-weight: var(--w-light); }
.wd-next b { font-weight: var(--w-bold); }

/* Assistenten im Arbeitsdialog-Rahmen: breiter Inhalt ohne Lesespalte */
.modal_window.wd.wd-breit .planner-form, .modal_window.wd.wd-breit .planner-form-wide { max-width: none; }

@media (max-width: 1240px) {
  .modal_window.wd .modal_window_body, .modal_window.wd.wd-md .modal_window_body { grid-template-columns: 220px minmax(0, 1fr); }
  .modal_window.wd.wd-norail .modal_window_body, .modal_window.wd.wd-md.wd-norail .modal_window_body { grid-template-columns: minmax(0, 1fr); }
  .modal_window.wd.wd-noaside .modal_window_body { grid-template-columns: 220px minmax(0, 1fr); }
  .wd-aside { position: absolute; top: 0; right: 0; bottom: 0; z-index: 3; width: min(380px, 92%); box-shadow: -12px 0 32px rgba(16,49,78,0.14); transform: translateX(102%); visibility: hidden; transition: transform var(--dur-base) var(--ease-std), visibility 0s linear var(--dur-base); }
  .wd-aside.wd-aside_open { transform: none; visibility: visible; transition: transform var(--dur-base) var(--ease-std), visibility 0s; }
  .wd-aside-toggle, .wd-aside-close { display: inline-flex; }
  .wd-inline-impact { display: block; }
}
@media (max-width: 900px) {
  .modal_window.wd, .modal_window.wd.wd-md { width: calc(100vw - 16px); height: calc(100vh - 16px); border-radius: 16px; }
  .modal_window.wd.wd-kompakt { height: auto; max-height: calc(100vh - 16px); }
  .modal_window.wd .modal_window_body, .modal_window.wd.wd-md .modal_window_body, .modal_window.wd.wd-noaside .modal_window_body { grid-template-columns: minmax(0, 1fr); }
  .modal_window.wd .wd-rail { display: none; }
  .wd-main-inner, .modal_window.wd.wd-norail .wd-main-inner { padding: 4px 20px 40px; }
  .wd-col { grid-column: 1 / -1; }
  .wd-kbd { display: none; }
  .wd-opts.wd-opts_c2, .wd-opts.wd-opts_c3 { grid-template-columns: minmax(0, 1fr); }
  .wd-opts.wd-opts_c3 .wd-opt { flex-direction: row; align-items: center; }
  .wd-opts.wd-opts_c3 .wd-opt-radio { position: static; }
}
@media (max-width: 780px) {
  /* Die Fussleiste stapelt wie in allen Dialogen (A11Y-023): Reihenfolge von
     oben nach unten = Tabulatorfolge. */
  .modal_window.wd .modal_window_footer .fmodal-foot-l { flex-wrap: wrap; }
  .modal_window.wd .modal_window_title { white-space: normal; }
}
@media (max-width: 560px) {
  /* Telefon: Der Kopf traegt nur Titel und Schaltflaechen - das Symbol entfaellt,
     "Uebersicht" steht als Zeichen (Beschriftung bleibt fuer Hilfsmittel). */
  .modal_window.wd .fmodal-chip { display: none; }
  .modal_window.wd .modal_window_header { padding: 14px 14px 14px 18px; gap: 10px; }
  .modal_window.wd .modal_window_title { font-size: 18px; }
  .wd-aside-toggle-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
@media (prefers-reduced-motion: reduce) {
  .wd-main { scroll-behavior: auto; }
  .wd-aside, .wd-progress-bar span { transition: none; }
}

/* ── Assistenten im Arbeitsdialog (BAL-207) ────────────────────────────────
   Planungsassistent und Import benutzen den Arbeitsdialog mit heller
   Schrittnavigation (`wdSchritte`). Der Zielwertbalken und die Gesamtsumme
   stehen in der Uebersicht; im Inhalt nur, solange die Uebersicht eingeklappt
   ist (unter 1240 px) - sonst stuende dieselbe Zahl zweimal nebeneinander. */
@media (min-width: 1241px) {
  .modal_window.wd.budget_planner .wd-main .planner-tbar,
  .modal_window.wd.budget_planner .wd-main .year-grand { display: none; }
}
.wd-plan-grund { display: flex; flex-direction: column; gap: 34px; max-width: 980px; }
.wd-plan-grund-sec .wd-sec-head { margin-bottom: 18px; }
.wd-plan-grund .wd-next { margin: 0; }
/* Vollbild: Themengruppen und Themenauswahl auf mehrere Spalten */
.modal_window.wd.budget_planner.fullscreen .planner-form-wide { display: grid; grid-template-columns: repeat(auto-fill, minmax(440px, 1fr)); gap: 14px; align-items: start; }
.modal_window.wd.budget_planner.fullscreen .planner-form-wide > :not(.year-topic-block) { grid-column: 1 / -1; }
.modal_window.wd.budget_planner.fullscreen .planner-form-wide > .year-topic-block { margin: 0; }
.modal_window.wd.budget_planner.fullscreen .tpick { display: grid; grid-template-columns: repeat(auto-fill, minmax(440px, 1fr)); gap: 0 1px; background: var(--divider); }
.modal_window.wd.budget_planner.fullscreen .tpick-item { border-top: 1px solid var(--divider); background: #fff; }
.modal_window.wd .planner-bound-banner { margin: 0 0 18px; }

/* ── Einrichtungsassistent: helle Schrittnavigation wie im Arbeitsdialog ─────
   Referenzdesign workdialog.css, Abschnitt "Assistenten". Der Assistent
   behaelt seine Karte (`.planner-card`), Groesse, Schiene und Kopf folgen dem
   Arbeitsdialog. Seit BAL-207 ist er die einzige `.planner-card`. */
.planner-card { box-shadow: 0 24px 64px rgba(16,49,78,0.22), 0 0 0 1px rgba(16,49,78,0.04); }
/* Groesse und Spalten nur im Breitlayout - unter 780 px gilt die einspaltige
   Fassung von weiter oben, und die muss gewinnen. */
@media (min-width: 781px) {
  .planner-card { width: min(1360px, calc(100vw - 64px)); height: min(920px, calc(100vh - 64px)); border-radius: 24px; grid-template-columns: 236px minmax(0, 1fr); }
  .planner-card.fullscreen { width: calc(100vw - 24px); height: calc(100vh - 24px); border-radius: 16px; }
}
.planner-rail { padding: 20px 14px 18px; border-right: 1px solid var(--divider); background: #fff; color: var(--q-dark); }
.planner-rail-brand { margin-bottom: 20px; padding: 0 6px; }
.planner-rail-brand img { background: var(--surface-soft); }
.planner-rail-brand .prb-title { color: var(--q-dark); font-size: 14.5px; }
.planner-rail-brand .prb-sub { color: var(--fg-2); }
.planner-steps { gap: 2px; }
.planner-step { gap: 11px; padding: 9px 10px; border-radius: 12px; color: var(--q-dark); }
.planner-step:hover, .planner-step.active { background: var(--surface-soft); }
.planner-step .ps-num { width: 24px; height: 24px; border: 1.5px solid var(--q-bright); background: #fff; color: var(--fg-2); font-family: var(--font-sans); font-size: 11px; }
.planner-step.active .ps-num { border-color: var(--q-highlight-2); background: #fff; color: var(--q-highlight-2); box-shadow: none; }
.planner-step.done .ps-num { border-color: var(--q-highlight-2); background: var(--q-highlight-2); color: #fff; }
.planner-step .ps-label { color: var(--q-dark); font-size: 13.5px; opacity: 1; }
.planner-assist { padding: 14px 12px; background: var(--surface-soft); color: var(--q-dark); }
.planner-assist .pa-badge { width: 26px; height: 26px; background: var(--q-highlight-2); }
.planner-assist .pa-badge .ui_icon { filter: brightness(0) invert(1); }
.planner-assist .pa-text { color: var(--q-dark); opacity: 1; }
.planner-head { align-items: center; padding: 18px 24px 18px 28px; }
.planner-head h2 { margin-top: 4px; font-size: 21px; }
.planner-scroll { padding: 28px 44px 40px; }
.planner-foot { padding: 14px 24px 14px 28px; }
/* Kapitel und Schrittzusatz auf der hellen Schiene: vorher Weiss auf Petrol.
   --fg-2 besteht auf Weiss (4,54 : 1). */
.setup_wizard_chapter_title { color: var(--fg-2); }
.setup_wizard_chapter_title .ui_icon { filter: none; }
.setup_wizard_step_tag { color: var(--fg-2); }
.planner-head .eyebrow { color: var(--q-highlight-3); }

/* ══ Schmale Bildschirme: einzeilige Leisten und Menue "Weitere" (BAL-208) ═══
   Vorlage: docs/design/application/project/responsive.css, src/Responsive.jsx,
   Shell.jsx, Toolbar.jsx. Strukturdoku docs/css/structure/more_menu.md,
   Blueprint blueprints/blueprint_more_menu.html.

   Grundsatz der Auftraggeberin: Kopf- und Listenleiste brechen NICHT um. Was
   keinen Platz hat, wird erst reduziert (Suche schmaler, Beschriftungen weg)
   und wandert dann in ein Menue "Weitere" (drei Punkte). WELCHE Stufe gilt,
   misst kopfleisteEinpassen() / listenleisteEinpassen() am fertigen DOM; das
   CSS hier beschreibt nur, wie jede Stufe aussieht. */

/* ── Menue "Weitere" (gemeinsam fuer Kopf- und Listenleiste) ──
   Optik der Panels und Eintraege ist die von "Neu anlegen"
   (`quick_create_panel`, `quick_create_item`, `quick_create_item_icon`) - die
   Elemente tragen diese Klassen zusaetzlich, statt dass sie hier ein zweites
   Mal stuende. Neu ist nur, was das Schnellanlegen nicht kennt: Zahl,
   Haekchen, Zwischentitel und der Zustand "ausgeblendet". */
.more_menu { position: relative; display: inline-flex; flex-shrink: 0; }
.more_menu[hidden], .more_menu_item[hidden], .more_menu_caption[hidden], .more_menu_button_dot[hidden] { display: none; }
.more_menu_button_dot { position: absolute; top: 6px; right: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 2px #fff; }
.more_menu_panel.quick_create_panel { width: min(280px, calc(100vw - 16px)); max-height: min(70vh, 560px); overflow-x: hidden; overflow-y: auto; }
.more_menu_item { min-height: 42px; font-size: 13.5px; font-weight: var(--w-regular); line-height: 1.3; }
.more_menu_item_title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.more_menu_item_badge { min-width: 20px; height: 20px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; background: var(--q-highlight-2); color: #fff; font-size: 11px; font-weight: var(--w-bold); }
.more_menu_item_active { background: var(--surface-active); color: var(--q-highlight-2); font-weight: var(--w-bold); }
.more_menu_item_check { display: inline-flex; color: var(--q-highlight-2); }
.more_menu_caption { padding: 8px 10px 4px; color: var(--fg-2); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); line-height: 1.4; text-transform: uppercase; }

/* ── Kopfleiste: eine Zeile ── */
.app_shell_topbar { position: relative; flex-wrap: nowrap; min-width: 0; }
.app_shell_breadcrumb { flex: 0 1 auto; min-width: 72px; overflow: hidden; text-overflow: ellipsis; }
.app_shell_topbar_spacer { flex: 1 1 0; min-width: 0; }
.app_shell_topbar > .app_shell_icon_button, .app_shell_topbar > .quick_create, .app_shell_topbar > .notification_center, .app_shell_topbar > .app_shell_topbar_item, .app_shell_topbar > .app_shell_topbar_brand { flex-shrink: 0; }
.app_shell_topbar_item { display: inline-flex; }
/* Das Suchfeld behaelt die Breite seiner Stufe (360 / 220 px). BAL-181 hatte
   es schrumpfen lassen, damit die Leiste bei 820 px nicht ueberlief; das
   uebernimmt jetzt kopfleisteEinpassen(). Duerfte es weiter schrumpfen,
   meldete die Leiste nie einen Ueberlauf - gemessen bei 375 px: Feld auf
   rund 50 px gequetscht, Tastenhinweis ueber dem Plus-Knopf. */
.app_shell_topbar > .global_search { flex-shrink: 0; }
.quick_create { position: relative; }
/* Ausgelagert weicht nur der KNOPF; der Behaelter bleibt, damit sein Panel
   weiter erscheint, wenn es ueber das Menue geoeffnet wird. Er wird dann
   `static`, und das Panel haengt sich an die Kopfleiste. */
.app_shell_topbar_item.app_shell_topbar_item_ueberlauf, .app_shell_topbar_item_ueberlauf > .app_shell_icon_button { display: none; }
/* display: contents statt nur position: static - die Huelle ohne Knopf waere
   ein leeres Flex-Element und braechte trotzdem ihren Abstand (gap) mit; das
   Panel ankert so weiterhin an der Leiste. */
.quick_create.app_shell_topbar_item_ueberlauf, .notification_center.app_shell_topbar_item_ueberlauf { display: contents; }
.app_shell_topbar_item_ueberlauf > .quick_create_panel, .app_shell_topbar_item_ueberlauf > .notification_center_panel { top: calc(100% + 6px); right: 10px; }
/* Suche: schmaler, dann als Knopf, der das Feld ueber die ganze Leiste legt */
.app_shell_topbar_suche_mittel .global_search { width: 220px; }
.app_shell_suche_knopf { display: none; flex-shrink: 0; }
.app_shell_topbar_suche_knopf .app_shell_suche_knopf { display: grid; }
.app_shell_topbar_suche_knopf .global_search { display: none; }
.app_shell_topbar_suche_knopf.app_shell_topbar_suche_offen .global_search { position: absolute; top: 50%; right: 10px; left: 10px; z-index: 90; display: flex; width: auto; padding: 6px 6px 6px 14px; border-color: var(--q-highlight-3); background: #fff; box-shadow: 0 6px 20px rgba(16,49,78,0.12); transform: translateY(-50%); }
.app_shell_topbar_suche_knopf .global_search_hint { display: none; }
.app_shell_topbar_suche_knopf .global_search_input { font-size: 16px; }
.app_shell_topbar_suche_knopf .global_search_panel { left: -10px; right: -10px; width: auto; top: calc(100% + 14px); }
.global_search_schliessen { display: none; flex-shrink: 0; min-height: 32px; padding: 6px 10px; border-radius: 999px; color: var(--q-highlight-2); font-size: 12.5px; font-weight: var(--w-bold); line-height: 1.2; }
.global_search_schliessen:hover { background: var(--surface-soft); }
.app_shell_topbar_suche_knopf .global_search_schliessen { display: inline-flex; align-items: center; }
/* Marke nur als Zeichen (die Kopfleisten-Marke steht erst unter 780 px) */
.app_shell_topbar_marke_zeichen .app_shell_brand_text { display: none; }
.app_shell_topbar_marke_zeichen .app_shell_topbar_brand { --marke-signet: 32px; }

/* ── Listenleiste: eine Zeile ──
   Nur die Leisten mit `data-list-page` (renderToolbar, renderApprovalsToolbar)
   - andere `.module_list_toolbar` haben keinen Einpasser und behalten ihr
   Verhalten. */
.list-toolbar[data-list-page] { flex-wrap: nowrap; gap: 10px; }
.list-toolbar[data-list-page] .ltb-search { flex: 1 1 0; min-width: 220px; }
.list-toolbar[data-list-page] .ltb-actions { flex-wrap: nowrap; flex-shrink: 0; }
.list-toolbar[data-list-page] .ltb-btn, .list-toolbar[data-list-page] .ltb-views { flex-shrink: 0; white-space: nowrap; }
/* Freigaben: Die Status-Schnellfilter stehen IN den Aktionen und scrollen
   seitlich, statt die Zeile zu sprengen - dafuer darf der Aktionsbereich
   dort schrumpfen (gemessen bei 375 px: 318 px Ueberlauf). */
.list-toolbar[data-list-page] .ltb-quickchips { flex: 1 1 auto; min-width: 96px; overflow-x: auto; flex-wrap: nowrap; scrollbar-width: thin; }
.list-toolbar.approvals-toolbar .ltb-actions { flex: 1 1 auto; min-width: 0; }
.list-toolbar.approvals-toolbar .ltb-quickchips > * { flex-shrink: 0; }
/* Beschriftung weg, Name bleibt: nur visuell ausgeblendet, damit Hilfsmittel
   die Schaltflaeche weiter "Filter" nennen. `display: none` nahme den Namen
   mit. */
.ltb_kompakt .ltb-btn-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.ltb_kompakt .ltb-btn, .ltb-btn.ltb-btn_symbol { width: 40px; padding: 0; justify-content: center; gap: 0; }
.ltb_kompakt .ltb-btn .ltb-badge { position: absolute; top: -5px; right: -5px; box-shadow: 0 0 0 2px #fff; }
.ltb_kompakt .ltb-btn { overflow: visible; }
.ltb-pop-wrap.ltb_ueberlauf > .ltb-btn, .ltb-views.ltb_ueberlauf, .ltb-reset.ltb_ueberlauf { display: none; }
/* Wie in der Kopfleiste: ohne Knopf keine Box, kein Abstand. Gemessen an der
   Freigaben-Leiste bei 320 px: zwei leere Huellen kosteten 16 px. */
.ltb-pop-wrap.ltb_ueberlauf { display: contents; }
.ltb-dot { position: absolute; top: 5px; right: 7px; width: 7px; height: 7px; border-radius: 50%; background: var(--q-highlight-2); box-shadow: 0 0 0 2px #fff; }
.ltb-dot[hidden] { display: none; }
.ltb-pop.ltb-pop-mehr { min-width: 0; padding: 6px; }
/* Schmale Leiste: Suchfeld darf kleiner werden, Panels ueber die ganze Breite */
.list-toolbar[data-list-page].ltb_schmal .ltb-search { min-width: 132px; padding: 0 12px; }
/* Freigaben: Suchfeld und Schnellfilter teilen sich die Zeile (320 px). */
.list-toolbar.approvals-toolbar.ltb_schmal .ltb-search { min-width: 112px; }
.list-toolbar.approvals-toolbar.ltb_schmal .ltb-quickchips { min-width: 76px; }
.ltb_schmal .ltb-pop-wrap { position: static; }
.ltb_schmal .ltb-pop { left: 0; right: 0; width: auto; min-width: 0; max-width: none; }
.ltb_schmal .ltb-pop.ltb-pop-mehr { left: auto; width: min(280px, 100%); }

/* ── Initialen-Kreis: bleibt rund ──
   Feste Seitenlaenge, `aspect-ratio` und kein Schrumpfen. In einem engen
   flex-Behaelter darf ihn nichts stauchen - ein gestauchter Kreis ist ein
   Oval (Beanstandung der Auftraggeberin). */
.app_shell_user_avatar, .confirm-card .confirm-avatar { flex: 0 0 auto; aspect-ratio: 1 / 1; }

@media (max-width: 780px) {
  /* Eine Zeile statt drei (ersetzt die Aufteilung aus BAL-190): Zeichen und
     Bereichsname nebeneinander, die Bedienelemente rechts daneben. Der
     Bereichsname traegt dafuer wieder die Schrift der Ueberschrift - als
     einziger Titel der Zeile, nicht mehr als Vorzeile unter der Marke. */
  .app_shell_topbar { flex-wrap: nowrap; height: 58px; padding: 0 10px; gap: 6px; }
  .app_shell_topbar_brand { --marke-signet: 32px; }
  .app_shell_breadcrumb { order: 0; width: auto; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 16px; font-weight: var(--w-bold); letter-spacing: 0; text-transform: none; }
  .global_search { order: 0; width: 360px; }
  .app_shell_topbar_suche_mittel .global_search { width: 220px; }
  /* Die Leiste blieb hier als Spalte gestapelt (`.module_list_toolbar` im
     780er-Block); fuer die eingepassten Leisten gilt wieder die Zeile. */
  .list-toolbar[data-list-page] { flex-direction: row; align-items: center; }
  .list-toolbar[data-list-page] .ltb-search { width: auto; }
  .list-toolbar[data-list-page] .ltb-actions { flex-direction: row; align-items: center; width: auto; }
  .list-toolbar[data-list-page] .ltb-btn { width: auto; }
  .list-toolbar[data-list-page].ltb_kompakt .ltb-btn, .list-toolbar[data-list-page] .ltb-btn.ltb-btn_symbol { width: 44px; min-height: 44px; }
  /* Trefferflaeche 44 px (E-3) und volle Breite fuer die Panels der Kopfleiste */
  .app_shell_topbar .app_shell_icon_button { width: 40px; height: 40px; }
  .more_menu_item { min-height: 44px; }
}
@media (max-width: 560px) {
  .app_shell_topbar .quick_create, .app_shell_topbar .notification_center, .app_shell_topbar .more_menu { position: static; }
  .app_shell_topbar .quick_create_panel, .app_shell_topbar .notification_center_panel { top: calc(100% + 6px); right: 8px; left: 8px; width: auto; max-width: none; }
  .app_shell_topbar .more_menu_panel.quick_create_panel { left: auto; width: min(300px, calc(100% - 16px)); }
  .app_shell_topbar .global_search_footer { display: none; }
  /* Rueckfrage (auch Konto-Dialog, BAL-194): Schaltflaechen ueber die volle
     Breite, die beiden Hauptaktionen teilen sich eine Zeile. Vorher ragte
     "Abmelden" bei 375 px 68 px ueber den Kartenrand. */
  .confirm-card .confirm-foot { flex-wrap: wrap; gap: 8px; padding: 12px 16px; }
  .confirm-card .confirm-foot > .button { flex: 1 1 100%; justify-content: center; min-height: 44px; }
  .confirm-card .confirm-foot-main { flex: 1 1 100%; margin-left: 0; display: flex; align-items: stretch; gap: 8px; }
  .confirm-card .confirm-foot-main .button { flex: 1 1 0; min-width: 0; min-height: 44px; justify-content: center; white-space: normal; text-align: center; line-height: 1.25; }
  .confirm-card .confirm-body { padding: 22px 18px 16px; gap: 13px; }
  .confirm-card .confirm-avatar { width: 44px; height: 44px; font-size: 15px; }
}
/* Telefon: der Rundgang setzt die Karte in voller Breite (bereichshilfeNachziehen) */
.bereichshilfe_hinweis { margin: 10px 0 0; color: var(--q-highlight-2); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.5; text-wrap: pretty; }
.bereichshilfe_hinweis[hidden] { display: none; }
/* Leerraum am Seitenende, solange die Tour laeuft (BAL-208, Nachtrag): So
   laesst sich auch das letzte Ziel einer Seite an den oberen Rand holen, und
   unter ihm bleibt Platz fuer die Karte. Gesetzt von bereichshilfeNachziehen(). */
html.bereichshilfe_tour_laeuft #main-content::after { content: ""; display: block; height: 60vh; }
@media (max-width: 639px) {
  .bereichshilfe_karte_schritt { max-width: none; }
  .bereichshilfe_karte_schritt .bereichshilfe_footer { flex-wrap: wrap; }
}
@media (pointer: coarse) { .global_search_hint { display: none; } }

/* ── Seitenkopf: Einleitung am Telefon zugeklappt (BAL-210) ───────────────────
   Erklaerung, Kennzahl und "Hier koennen Sie" stehen in einem <details>
   (bereichseinleitung() in app.js). Am Schreibtisch ist es immer offen und der
   Schalter unsichtbar - der Kopf sieht aus wie vorher. Unter dem schmalen
   Umbruch (780 px) bleiben Vorzeile, Titel und Kennzahl stehen, der Rest liegt
   hinter "Ueber diesen Bereich".
   GEMESSEN am 2026-10-04 bei 390 x 664: Der Kopf war 310 bis 415 px hoch.
   Vorbild Mission Control (bereichseinleitung.css). Abweichung: Schalter in
   Navy statt Petrol - Petrol erreicht auf Weiss 2,9 : 1, fuer 11-px-Text zu
   wenig. 44 px hoch wie die uebrigen Touch-Ziele (BAL-186/BAL-198).
   Strukturdoku docs/css/structure/seitenkopf_einleitung.md. */
.page_header_mehr_schalter { display: none; }
.page_header_count_schmal { display: none; }
@media (max-width: 780px) {
  .page_header { gap: 12px; margin-bottom: 16px; }
  .page_header_pretext { margin-bottom: 4px; }
  .page_header_title { font-size: 24px; }
  .page_header_count_schmal { display: inline-flex; margin-top: 10px; }
  .page_header_mehr .page_header_count { display: none; }
  .page_header_mehr { margin-top: 4px; }
  .page_header_mehr_schalter {
    display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0;
    cursor: pointer; list-style: none; user-select: none;
    font-family: var(--font-sans); font-size: 11px; font-weight: var(--w-bold); line-height: 1.3;
    letter-spacing: var(--tracking-xwide); text-transform: uppercase; color: var(--q-highlight-2);
  }
  .page_header_mehr_schalter::-webkit-details-marker { display: none; }
  .page_header_mehr_schalter::marker { content: ""; }
  .page_header_mehr_schalter::after {
    content: ""; width: 7px; height: 7px; margin-top: -3px;
    border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
    transform: rotate(45deg); transition: transform var(--dur-fast) var(--ease-std);
  }
  .page_header_mehr[open] > .page_header_mehr_schalter::after { transform: rotate(225deg); margin-top: 3px; }
  .page_header_mehr_schalter:focus-visible { outline: 2px solid var(--q-highlight-3); outline-offset: 2px; border-radius: 4px; }
  .page_header_mehr_inhalt > .page_header_description { margin-top: 0; }
  .page_header_mehr_inhalt { padding-bottom: 4px; }
}
@media (max-width: 780px) and (prefers-reduced-motion: reduce) {
  .page_header_mehr_schalter::after { transition: none; }
}

/* ── Häufige Fragen (BAL-211) ───────────────────────────────────────────────
   Referenzdesign 2026-10-06 (faq.css). Strukturdoku: docs/css/structure/faq.md,
   Blueprint: blueprints/blueprint_faq.html.

   Wiederverwendet: .kb-bar/.sec-title/.sec-sub (Abschnittskopf), .ltb-search
   (Suchfeld der Listenleiste), .md-cat-chips/.md-chip/.md-chip-count
   (Themenpillen der Stammdaten), .content_card (Karte), .fseg/.fseg-btn
   (Reiter), .link-btn (Sprung), .empty_state (Leerzustand).
   Neu ist nur das Akkordeon `faq_list` - Frage und Antwort zum Aufklappen gab
   es in Balance nicht. Klassenreihe: die ucs-Reihe (Unterstrich), wie die
   uebrigen seit BAL-004 neu gebauten Bloecke.

   Jeder Textbaustein setzt Groesse, Gewicht, Zeilenhoehe und Farbe selbst:
   `body` steht auf 300/15 px, und der Browser gibt h3/h4/p eigene Werte. */
.faq { margin: 0 0 34px; }
.faq_header { margin-bottom: 14px; }
.faq_title { margin: 0; }
.faq_description { margin-top: 2px; color: var(--fg-2); }
.faq_search { flex: 0 1 280px; min-width: 0; }
.faq_topics { margin-bottom: 14px; }
.faq_body { padding: 4px 22px; }
.faq_tabs { width: auto; margin-top: 0; }
.faq_tabs .fseg-btn { display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto; padding: 8px 16px; font-size: 13px; white-space: nowrap; }
.faq_tabs_count { font-size: 11px; font-weight: var(--w-bold); opacity: 0.6; }
.faq_tabs .fseg-btn.on .faq_tabs_count { opacity: 0.8; }

.faq_list { display: flex; flex-direction: column; }
.faq_list_item { border-bottom: 1px solid #ececec; }
.faq_list_item:last-child { border-bottom: 0; }
.faq_list_item_heading { margin: 0; font-size: inherit; font-weight: inherit; line-height: inherit; }
.faq_list_item_question { display: flex; align-items: center; justify-content: space-between; gap: 16px; width: 100%; padding: 16px 0; color: var(--q-highlight-2); font-size: 14.5px; font-weight: var(--w-bold); line-height: 1.4; text-align: left; text-wrap: pretty; }
.faq_list_item_question:hover { color: var(--q-highlight-3); }
.faq_list_item_question:focus-visible { outline: 2px solid var(--q-highlight-3); outline-offset: 2px; border-radius: 4px; }
.faq_list_item_icon { display: inline-flex; flex-shrink: 0; opacity: 0.55; transition: transform var(--dur-base) var(--ease-std); }
.faq_list_item_expanded .faq_list_item_icon { transform: rotate(180deg); }
.faq_list_item_answer { padding: 0 36px 18px 0; }
.faq_list_item_answer[hidden] { display: none; }
.faq_list_item_text { max-width: 72ch; margin: 0; color: var(--fg-1); font-size: 13.5px; font-weight: var(--w-regular); line-height: 1.6; text-wrap: pretty; }
.faq_list_item_link { margin-top: 10px; font-size: 13px; }
.faq_list_compact .faq_list_item_question { padding: 11px 0; font-size: 13.5px; }
.faq_list_compact .faq_list_item_answer { padding: 0 28px 12px 0; }
.faq_list_compact .faq_list_item_text { font-size: 13px; }
.faq_empty { padding: 28px 0; }
.faq_footer { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 8px; padding: 14px 0 16px; border-top: 1px solid #ececec; color: var(--fg-2); font-size: 13px; font-weight: var(--w-regular); }
.faq_footer .link-btn { font-size: 13px; }
.bereichshilfe_faq_link { margin-top: 8px; font-size: 13px; }
@media (max-width: 780px) {
  .faq_header { flex-direction: column; align-items: stretch; }
  .faq_search { flex: 1 1 auto; width: 100%; }
  .faq_body { padding: 2px 16px; }
  .faq_tabs { display: flex; width: 100%; }
  .faq_tabs .fseg-btn { flex: 1; justify-content: center; padding: 8px 10px; }
  .faq_list_item_question { min-height: 44px; }
}
@media (prefers-reduced-motion: reduce) { .faq_list_item_icon { transition: none; } }

/* ── Tarif & Abrechnung (BAL-212) ───────────────────────────────────────────
   Referenzdesign 2026-10-06 (billing.css, Praefix bl-). Strukturdoku:
   docs/css/structure/tarif.md, Blueprint: blueprints/blueprint_tarif.html.

   Wiederverwendet: .admin-sec-head/.admin-h2/.sec-sub, .content_card mit
   .content_card_header, .admin-kpis/.admin-kpi/.ak-*, .util/.util-bar,
   .fseg/.fseg-btn (Zeitraum), .switch/.knob (Add-on), .status_badge_*,
   .module_list_table (Vergleich), .field_list_* (Rechnungsdaten),
   .detail-section-label, .info-note/.basis-note, .empty_state,
   Rueckfragedialog der Anwendung. Neu ist der Block `tarif` - Preis- und
   Angebotsdarstellung gab es in Balance nicht.

   Abweichend vom Entwurf: Hinweistexte in --fg-2 statt --q-medium (Dekorfarbe,
   1,9 : 1 auf Weiss). */
.tarif { display: flex; flex-direction: column; gap: 14px; }
.tarif[aria-busy="true"] { cursor: progress; }
.tarif_label { color: var(--fg-2); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); line-height: 1.4; text-transform: uppercase; }
.tarif_hint { color: var(--fg-2); font-size: 12px; font-weight: var(--w-regular); line-height: 1.45; text-wrap: pretty; }
.tarif_section_title { margin: 0 0 10px; }
.content_card_header .tarif_section_title { margin: 0; }
.tarif_code { padding: 3px 8px; border-radius: 6px; background: var(--q-highlight-4); color: var(--q-highlight-2); font-family: var(--font-mono); font-size: 11.5px; font-weight: var(--w-regular); white-space: nowrap; }

.tarif_current { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 18px 28px; align-items: start; }
.tarif_current_main { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.tarif_current_title { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 24px; font-weight: var(--w-bold); line-height: 1.2; }
.tarif_badges { display: flex; flex-wrap: wrap; gap: 6px; }
.tarif_current_next { margin-top: 2px; color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); line-height: 1.45; }
.tarif_current_next b { font-weight: var(--w-bold); }
.tarif_current_side { display: flex; flex-direction: column; gap: 8px; min-width: 240px; }
.tarif_cycle { width: auto; align-self: flex-start; margin-top: 0; }
.tarif_cycle .fseg-btn { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; padding: 7px 14px; font-size: 12.5px; }
.tarif_cycle .fseg-btn:disabled { cursor: default; opacity: 0.7; }
.tarif_cycle_badge { padding: 1px 6px; border-radius: 999px; background: var(--q-highlight-1); color: var(--q-highlight-2); font-size: 10.5px; font-weight: var(--w-bold); }
.tarif_pending { grid-column: 1 / -1; display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding: 10px 14px; border-radius: 12px; background: #fbf1d8; color: #7a5a12; font-size: 13px; font-weight: var(--w-regular); line-height: 1.45; }
.tarif_pending_text { flex: 1; min-width: 200px; }
.tarif_pending b { font-weight: var(--w-bold); }

.tarif_kpis { margin-bottom: 0; }
.tarif_kpi_note { margin-top: 4px; color: var(--fg-2); font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.4; }
.tarif_kpi_util { margin-top: 10px; }
.admin-kpi .ak-num.tarif_kpi_amount { font-size: 22px; }

.tarif_plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(185px, 1fr)); gap: 14px; }
.tarif_plan { display: flex; flex-direction: column; gap: 8px; padding: 18px; border: 1px solid #ececec; border-radius: 18px; background: #fff; }
.tarif_plan_recommended { border-color: var(--q-highlight-1); }
.tarif_plan_current { padding: 17px; border: 2px solid var(--q-highlight-2); background: #fafbfc; }
.tarif_plan_header { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px; }
.tarif_plan_pretext { color: var(--fg-2); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); line-height: 1.3; text-transform: uppercase; }
.tarif_plan_badge { padding: 3px 9px; border-radius: 999px; background: var(--q-highlight-1); color: var(--q-highlight-2); font-size: 11px; font-weight: var(--w-bold); white-space: nowrap; }
.tarif_plan_title { margin: 0; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 18px; font-weight: var(--w-bold); line-height: 1.3; }
.tarif_plan_title span { color: var(--fg-2); font-size: 14px; font-weight: var(--w-regular); }
.tarif_plan_price { display: flex; align-items: baseline; gap: 6px; }
.tarif_plan_price b { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 30px; font-weight: var(--w-bold); line-height: 1.1; }
.tarif_plan_price b.tarif_plan_price_individual { font-size: 22px; }
.tarif_plan_price span { color: var(--fg-2); font-size: 12.5px; font-weight: var(--w-regular); }
.tarif_plan_users { color: var(--q-dark); font-size: 12px; font-weight: var(--w-bold); line-height: 1.4; }
.tarif_plan_description { margin: 2px 0 0; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.5; text-wrap: pretty; }
.tarif_plan_items { display: flex; flex-direction: column; gap: 6px; margin: 2px 0 0; padding: 0; list-style: none; }
.tarif_plan_item { display: flex; align-items: center; gap: 8px; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.4; }
.tarif_plan_item_icon { display: inline-flex; flex-shrink: 0; color: var(--q-highlight-3); }
.tarif_plan_footer { margin-top: auto; padding-top: 10px; }
.tarif_plan_control { width: 100%; justify-content: center; }
.tarif_plan_note { padding: 7px 0; color: var(--q-highlight-2); font-size: 12px; font-weight: var(--w-bold); line-height: 1.4; text-align: center; }
.tarif_plan_note_muted { color: var(--fg-2); font-weight: var(--w-regular); }
.tarif_unlimited { margin: 16px 0 0; }
.tarif_toggle_icon { display: inline-flex; margin-left: 6px; opacity: 0.6; transition: transform var(--dur-base) var(--ease-std); }
.tarif_toggle_icon_expanded { transform: rotate(180deg); }

.tarif_compare { margin-top: 16px; overflow-x: auto; border: 1px solid var(--divider); border-radius: 14px; }
.tarif_compare_table { min-width: 640px; }
.tarif_compare_table tbody tr { cursor: default; }
.tarif_compare_table tbody tr:hover { background: transparent; }
.tarif_compare_table tbody th { position: static; padding: 9px 14px; border-bottom: 1px solid #f1f2f2; background: transparent; color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); letter-spacing: normal; text-align: left; text-transform: none; }
.tarif_compare_table td { padding: 9px 14px; }
.module_list_table.tarif_compare_table th:last-child, .module_list_table.tarif_compare_table td:last-child { text-align: center; }
.tarif_compare_plan { width: 13%; text-align: center; }
.module_list_table th.tarif_compare_plan { text-align: center; }
.tarif_compare_current { background: rgba(16, 49, 78, 0.04); }
.module_list_table th.tarif_compare_current { color: var(--q-highlight-2); }
.tarif_compare_table .tarif_compare_group th { position: static; padding: 7px 14px; background: var(--q-highlight-4); color: var(--q-highlight-2); font-size: 10.5px; font-weight: var(--w-bold); letter-spacing: var(--tracking-wide); text-align: left; text-transform: uppercase; }
.tarif_mark { display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: var(--w-bold); }
.tarif_mark[data-wert="ja"] { width: 20px; height: 20px; border-radius: 50%; background: #eef5dc; color: #5a8516; }
.tarif_mark[data-wert="nein"] { color: var(--fg-2); font-weight: var(--w-regular); }
.tarif_mark[data-wert="addon"] { color: var(--q-highlight-2); font-size: 11px; }
.tarif_mark[data-wert="text"] { color: var(--q-dark); }

.tarif_split { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(280px, 1fr); gap: 14px; align-items: start; }
.tarif_addons { display: flex; flex-direction: column; }
.tarif_addon { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; gap: 14px; align-items: center; padding: 14px 0; border-top: 1px solid var(--divider); }
.tarif_addon:first-child { padding-top: 4px; border-top: 0; }
.tarif_addon_disabled .tarif_addon_main { opacity: 0.65; }
.tarif_addon_icon { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--q-highlight-4); color: var(--q-highlight-2); }
.tarif_addon_title { color: var(--q-highlight-2); font-size: 13.5px; font-weight: var(--w-bold); line-height: 1.35; }
.tarif_addon_description { margin-top: 2px; color: var(--fg-2); font-size: 12px; font-weight: var(--w-regular); line-height: 1.45; text-wrap: pretty; }
.tarif_addon_controls { display: flex; align-items: center; justify-content: flex-end; gap: 12px; }
.tarif_addon_price { color: var(--q-highlight-2); font-family: var(--font-display); font-size: 14px; font-weight: var(--w-bold); white-space: nowrap; }
.tarif_addon_price small { margin-left: 2px; color: var(--fg-2); font-family: var(--font-sans); font-size: 11px; font-weight: var(--w-regular); }
.tarif_stepper { display: inline-flex; align-items: center; border: 2px solid var(--q-bright); }
.tarif_stepper_control { width: 32px; height: 32px; background: #fff; color: var(--q-highlight-2); font-size: 16px; font-weight: var(--w-bold); }
.tarif_stepper_control:disabled { color: var(--q-bright); cursor: default; }
.tarif_stepper_control:focus-visible { outline: 2px solid var(--q-highlight-3); outline-offset: 1px; }
.tarif_stepper_value { min-width: 30px; color: var(--q-dark); font-size: 13px; font-weight: var(--w-bold); text-align: center; }

.tarif_summary { position: sticky; top: 12px; }
.tarif_summary_lines, .tarif_summary_total { display: flex; flex-direction: column; gap: 9px; }
.tarif_summary_total { margin: 12px 0; padding-top: 12px; border-top: 1px solid var(--divider); }
.tarif_summary_line { display: flex; justify-content: space-between; gap: 12px; color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); line-height: 1.4; }
.tarif_summary_line small { display: block; color: var(--fg-2); font-size: 11.5px; }
.tarif_summary_line > span { font-weight: var(--w-bold); white-space: nowrap; }
.tarif_summary_line_discount { color: #4f7613; }
.tarif_summary_line_muted { color: var(--fg-2); }
.tarif_summary_line_total { padding-top: 10px; border-top: 1px solid var(--divider); color: var(--q-highlight-2); font-size: 15px; font-weight: var(--w-bold); }
.tarif_summary_line_total > span { font-family: var(--font-display); font-size: 20px; }

.tarif_entitlements { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 8px; }
.tarif_entitlement { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 10px 12px; border: 1px solid #ececec; border-radius: 12px; }
.tarif_entitlement:not(.tarif_entitlement_active) { background: #fafafa; }
.tarif_entitlement:not(.tarif_entitlement_active) .tarif_entitlement_title { color: var(--fg-2); }
.tarif_entitlement_title { min-width: 0; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.4; overflow-wrap: break-word; hyphens: auto; }
.tarif_entitlements_card .basis-note { margin-top: 12px; }
.tarif_entitlements_card .content_card_header { align-items: flex-start; }
.tarif_entitlements_card .basis-note b { color: var(--q-dark); font-weight: var(--w-bold); }
.tarif_invoices_empty { padding: 26px 10px; color: var(--fg-2); font-size: 13px; }
/* Rechnungsdaten: Die Beschriftungen ("Rechnungsempfaenger", "Kundennummer Quantiz Pay") sind laenger als die 130 px der Detailansicht. Unter 780 px stapelt field_list ohnehin. */
.tarif .field_list_item { grid-template-columns: 210px minmax(0, 1fr); }
@media (max-width: 780px) { .tarif .field_list_item { grid-template-columns: minmax(0, 1fr); gap: 5px; } }
.tarif_terms { padding: 4px 4px 0; color: var(--fg-2); font-size: 12px; font-weight: var(--w-regular); line-height: 1.5; }
.tarif_terms b { color: var(--q-dark); font-weight: var(--w-bold); }
@media (max-width: 900px) {
  .tarif_split, .tarif_current { grid-template-columns: 1fr; }
  .tarif_summary { position: static; }
  .tarif_current_side { min-width: 0; }
}
@media (max-width: 560px) {
  .tarif_addon { grid-template-columns: 36px minmax(0, 1fr); }
  .tarif_addon_controls { grid-column: 2; justify-content: flex-start; }
  .tarif_entitlements { grid-template-columns: 1fr; }
  .tarif_entitlement { grid-template-columns: 1fr auto; }
  .tarif_entitlement .tarif_code:first-child { grid-column: 1 / -1; justify-self: start; }
  .tarif_stepper_control { width: 44px; height: 44px; }
}
@media (prefers-reduced-motion: reduce) { .tarif_toggle_icon { transition: none; } }

/* ── Quantiz Pay in Tarif & Abrechnung (BAL-224) ──────────────────────────
   Erweiterung der Komponente `tarif`: Verbinden, Stand bei Pay, Zahlungsart,
   Rechnungen. Doku: docs/css/structure/tarif.md, Abschnitt Quantiz Pay. */
.tarif_pay { display: flex; flex-direction: column; gap: 12px; }
.tarif_pay .info-note, .tarif_pay .tarif_pending { margin: 0; }
.tarif_pay_text { margin: 0; color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); line-height: 1.55; text-wrap: pretty; }
.tarif_pay_text b { color: var(--q-highlight-2); font-weight: var(--w-bold); }
.tarif_pay_form { grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 4px 0; }
.tarif_pay_form .ffield-full { grid-column: 1 / -1; }
.tarif_pay_controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.tarif_pay_mandate { margin: 12px 0 0; padding: 12px 14px; border: 1px solid var(--divider); border-radius: 11px; background: var(--surface-soft); }
.tarif_pay_mandate p { margin: 6px 0 0; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.55; }
.tarif_pay_consent { display: flex; align-items: flex-start; gap: 10px; margin: 10px 0 12px; color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); line-height: 1.5; cursor: pointer; }
.tarif_pay_consent input { flex-shrink: 0; width: 18px; height: 18px; margin: 1px 0 0; accent-color: var(--q-highlight-2); }
.tarif_pay_consent_error { color: #a83232; }
.tarif_pay_consent_message { display: block; margin-top: 3px; font-size: 12px; }
.tarif .fseg.tarif_cycle + .tarif_pay_text, .tarif .fseg.tarif_cycle + .tarif_pay_mandate, .tarif .fseg.tarif_cycle + .empty_state, .tarif .fseg.tarif_cycle + .info-note { margin-top: 12px; }
.tarif .content_card > .tarif_label { margin: 14px 0 6px; }
.tarif_invoices { min-width: 560px; }
.tarif_invoices td:last-child, .tarif_invoices th:last-child { text-align: right; }
.tarif_invoice_controls { display: flex; align-items: center; justify-content: flex-end; gap: 10px; white-space: nowrap; }
@media (max-width: 780px) { .tarif_pay_form { grid-template-columns: minmax(0, 1fr); } }

/* Fehlerzustand einer Feldeinheit (BAL-224): Meldung im `ffield-hint`, dazu
   `aria-invalid` am Feld. Gab es vorher nicht - Dialoge melden gesammelt.
   Genutzt im Verbindungsschritt zu Quantiz Pay und in der Registrierung der
   oeffentlichen Seiten (dort bis BAL-224 als signup_field_error). */
.content_form_item_error .content_form_input { border-color: var(--danger); }
.content_form_item_error .ffield-hint { color: #a83232; font-weight: var(--w-regular); }

/* Einstellungen › Registrierungen (BAL-221): Karten untereinander, je
   Registrierung eine `content_card` mit `field_list`. */
.registrierungen { display: grid; gap: 14px; }
.registrierungen .content_card { margin: 0; }

/* Gemessene Fussleisten (BAL-226): DOM-/Tab-Reihenfolge bleibt erhalten.
   Diese Regeln ersetzen auch die frueheren mobilen Spalten-/Umbruchregeln. */
.action_footer.action_footer {
  display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;
  gap: 10px; overflow-x: auto;
}
.action_footer.action_footer .footer_action_group.footer_action_group.footer_action_group {
  display: inline-flex; flex-direction: row; flex-wrap: nowrap; align-items: center;
  width: auto; min-width: 0; gap: 10px; overflow: visible; flex: 0 0 auto;
}
.action_footer.action_footer .button {
  flex: 0 0 auto; width: auto; min-width: 44px; min-height: 44px;
  white-space: nowrap;
}
.action_footer .footer_button_label { white-space: nowrap; }
.action_footer .ui_icon { flex-shrink: 0; }
.action_footer.action_footer.footer_compact { gap: 6px; }
.action_footer.action_footer.footer_compact .footer_action_group.footer_action_group { gap: 6px; }
.action_footer.action_footer.footer_compact .button { padding-left: 12px; padding-right: 12px; }
.action_footer.action_footer .button.footer_button_symbol { width: 44px; padding: 9px; gap: 0; }
.action_footer .footer_button_symbol .footer_button_label { display: none; }
.action_footer.footer_compact .wd-kbd { display: none; }
.action_footer.footer_hide_hints :is(.wd-foot-hint, .foot-hint, .foot-status) { display: none; }

/* ══ Organisation und Datenraeume in der Anwendung (BAL-232) ══════════════════
   Vorlage: docs/design/application/project/spaces.css. Strukturdoku
   docs/css/structure/organisation_datenraeume.md, Blueprint
   blueprints/blueprint_organisation_datenraeume.html.

   WIEDERVERWENDET (keine Regel hier): Einstellungshuelle admin-layout /
   admin-nav / admin-nav-item / admin-tabs / admin-content / admin-sec-head /
   admin-kpis; content_card, set-grid / set-card; module_list_table; das Menue
   "Weitere" (more_menu_panel, quick_create_panel, more_menu_item,
   more_menu_caption, more_menu_item_check); Einstellungsdialog
   (renderEinstellungsdialog); Auswahlkarten des Imports (imp-source-seg,
   imp-source-opt, imp-radio); fseg; info-note / basis-note; status_badge;
   avatar-sm; field_list.

   NEU, weil es nichts Vergleichbares gab:
   - space_mark       Raumzeichen (Kuerzel, Farbe nach Sichtbarkeit)
   - space_switch     Wechsler unter der Marke
   - settings_scope   Gruppenkopf der Einstellungsnavigation + Geltungshinweis
   - settings_drill   Telefonliste der Einstellungen
   - entry_list       Zeilenliste fuer Personen, Raeume, Einladungen, Protokoll
   - space_room, space_card, space_rights, space_department, org_overview:
     Anordnungen einzelner Abschnitte aus vorhandenen Bausteinen.
   Farben fuer Text nur --fg-2 (4,54 : 1), nie --q-medium (Dekorfarbe). */

/* ── space_mark ── */
.space_mark { --space-mark: 30px; display: inline-grid; place-items: center; flex-shrink: 0; width: var(--space-mark); height: var(--space-mark); border-radius: 30%; background: var(--q-highlight-2); color: #fff; font-family: var(--font-display); font-size: calc(var(--space-mark) * 0.38); font-weight: var(--w-bold); line-height: 1; letter-spacing: 0; }
.space_mark_organization { background: var(--q-highlight-2); color: #fff; }
.space_mark_restricted { background: var(--q-highlight-3); color: #fff; }
.space_mark_private { background: var(--q-highlight-1); color: var(--q-highlight-2); }
.space_mark_guest { background: #fff; color: var(--q-highlight-2); box-shadow: inset 0 0 0 1.5px var(--q-highlight-2); }
.space_mark_department { background: #fff; box-shadow: inset 0 0 0 1.5px var(--q-medium); }

/* ── space_switch ── */
.space_switch { flex-shrink: 0; margin: 2px 0 8px; }
.space_switch_control { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 10px 7px 7px; border: 1px solid var(--divider); border-radius: 14px; background: #fff; color: var(--q-dark); text-align: left; transition: border-color var(--dur-fast) var(--ease-std), background var(--dur-fast) var(--ease-std); }
.space_switch_control:hover, .space_switch_expanded .space_switch_control { border-color: var(--q-medium); background: var(--surface-soft); }
.space_switch_text { display: flex; flex: 1; flex-direction: column; gap: 1px; min-width: 0; }
.space_switch_title { overflow: hidden; color: var(--q-highlight-2); font-size: 13px; font-weight: var(--w-bold); line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; }
.space_switch_description { overflow: hidden; color: var(--fg-2); font-size: 11px; font-weight: var(--w-regular); line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; }
.space_switch_chevron { display: inline-flex; flex-shrink: 0; color: var(--fg-2); }
.app_shell_sidebar_collapsed .space_switch_control { justify-content: center; padding: 4px; border-color: transparent; background: transparent; }
.app_shell_sidebar_collapsed .space_switch_text, .app_shell_sidebar_collapsed .space_switch_chevron { display: none; }
/* Das Panel ist das des Menues "Weitere", aber FEST positioniert: Die
   Seitenleiste traegt overflow: hidden und wuerde es abschneiden. Lage und
   Breite setzt raumWechslerAusrichten() am Knopf. */
.more_menu_panel.quick_create_panel.space_switch_panel { position: fixed; right: auto; z-index: 95; display: flex; flex-direction: column; overflow: hidden; }
.space_switch_items { min-height: 0; overflow-y: auto; }
.space_switch_group + .space_switch_group { margin-top: 4px; }
.space_switch_group_title { padding: 8px 10px 4px; color: var(--q-dark); font-size: 11.5px; font-weight: var(--w-bold); line-height: 1.4; }
.space_switch_group_title span { color: var(--fg-2); font-weight: var(--w-regular); }
.space_switch_item { gap: 10px; }
.space_switch_item_text { display: flex; flex: 1; flex-direction: column; min-width: 0; }
.space_switch_item_description { color: var(--fg-2); font-size: 11.5px; font-weight: var(--w-regular); line-height: 1.35; }
.space_switch_footer { flex-shrink: 0; margin: 6px -6px -6px; padding: 6px; border-top: 1px solid var(--divider); background: var(--surface-soft); }

/* ── settings_scope ── */
.settings_scope_group { padding: 16px 13px 6px; }
.admin-nav > .settings_scope_group:first-child { padding-top: 2px; }
.settings_scope_group_title { color: var(--fg-2); font-size: 10px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); line-height: 1.4; text-transform: uppercase; }
.settings_scope_group_context { display: flex; align-items: center; gap: 7px; min-width: 0; margin-top: 6px; color: var(--q-highlight-2); font-size: 12px; font-weight: var(--w-bold); line-height: 1.3; }
.settings_scope_group_context > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.settings_scope_group_icon, .settings_scope_note_icon { display: grid; place-items: center; flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%; background: var(--q-highlight-4); color: var(--q-highlight-2); }
.settings_scope_note_icon { background: #fff; }
.settings_scope_note { display: inline-flex; align-items: center; gap: 9px; max-width: 100%; padding: 5px 16px 5px 5px; border-radius: 999px; background: var(--q-highlight-4); color: var(--q-dark); font-size: 12.5px; line-height: 1.4; }
.settings_scope_note_caption { color: var(--fg-2); font-size: 10px; font-weight: var(--w-bold); letter-spacing: var(--tracking-xwide); text-transform: uppercase; }
.settings_scope_note_title { color: var(--q-highlight-2); font-weight: var(--w-bold); }
.settings_scope_note_description { color: var(--fg-2); }
.fseg.settings_scope_switch { width: auto; margin-top: 0; }
.settings_scope_switch .fseg-btn { flex: 0 1 auto; padding: 7px 16px; font-size: 13px; }
.settings_scope_switch + .admin-tabs { margin-top: 14px; }

/* ── settings_drill (Telefon) ── */
.settings_drill { display: flex; flex-direction: column; gap: 18px; margin-top: 4px; }
.settings_drill_group .settings_scope_group { padding: 0 4px 8px; }
.settings_drill_items { overflow: hidden; border: 1px solid #ececec; border-radius: 18px; background: #fff; }
.settings_drill_item { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; padding: 8px 16px; border-bottom: 1px solid #f1f2f2; color: var(--q-dark); font-size: 14.5px; font-weight: var(--w-regular); line-height: 1.3; text-align: left; }
.settings_drill_item:last-child { border-bottom: 0; }
.settings_drill_item:hover, .settings_drill_item:active { background: var(--surface-soft); }
.settings_drill_item_icon { display: grid; place-items: center; flex-shrink: 0; width: 32px; height: 32px; border-radius: 10px; background: var(--q-highlight-4); color: var(--q-highlight-2); }
.settings_drill_item_title { flex: 1; min-width: 0; }
.settings_drill_item_chevron { display: inline-flex; color: var(--fg-2); }
.settings_drill_item_chevron .ui_icon { transform: rotate(-90deg); }
.button.settings_drill_back { display: inline-flex; align-items: center; justify-content: flex-start; align-self: flex-start; gap: 8px; width: auto; min-height: 44px; margin: -6px 0 4px -8px; padding: 0 14px 0 8px; border-color: transparent; background: transparent; color: var(--q-highlight-2); font-weight: var(--w-bold); }
.settings_drill_back_icon { display: inline-flex; }
.settings_drill_back_icon .ui_icon { transform: rotate(90deg); }
/* Geoeffneter Abschnitt: Der Seitenkopf nennt ihn schon - die gleichlautende
   Ueberschrift des Abschnitts entfaellt, Unterzeile und Aktionen bleiben. */
.settings_drill_page .admin-content > .admin-sec-head .admin-h2 { display: none; }

/* ── entry_list ── */
.content_card.entry_list { padding: 0; overflow: hidden; }
.entry_list_header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; padding: 16px 18px; border-bottom: 1px solid #f1f2f2; }
.entry_list_title { margin: 0 0 2px; color: var(--q-dark); font-size: 14px; font-weight: var(--w-bold); line-height: 1.4; }
.entry_list_description { color: var(--fg-2); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.45; }
.entry_list_controls { display: flex; align-items: center; gap: 8px; }
.entry_list_item { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 11px 18px; border-bottom: 1px solid #f1f2f2; }
.entry_list_items > .entry_list_item:last-child { border-bottom: 0; }
.entry_list_item_pending { background: #fffcf5; }
.entry_list_item_group { background: rgba(16, 49, 78, 0.03); }
.entry_list_item_child { padding-left: 44px; }
.entry_list_item[data-level="2"] { padding-left: 70px; }
.entry_list_item[data-level="3"] { padding-left: 96px; }
.entry_list_item_visual { display: inline-flex; flex-shrink: 0; }
.entry_list_item_text { display: flex; flex: 1; flex-direction: column; gap: 1px; min-width: 0; }
.entry_list_item_title { color: var(--q-highlight-2); font-size: 13.5px; font-weight: var(--w-bold); line-height: 1.4; overflow-wrap: anywhere; }
.entry_list_item_description { color: var(--fg-2); font-size: 12px; font-weight: var(--w-regular); line-height: 1.45; overflow-wrap: anywhere; }
.entry_list_item_note { color: var(--fg-2); font-weight: var(--w-regular); }
.entry_list_item_meta { display: flex; align-items: center; flex-shrink: 0; gap: 10px; }
.entry_list_item_role { color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); white-space: nowrap; }
.entry_list_item_select { display: inline-block; min-width: 150px; }
.entry_list_item_select .fselect { min-height: 34px; padding: 6px 32px 6px 10px; font-size: 12.5px; }
.entry_list_item_controls { display: flex; align-items: center; flex-shrink: 0; gap: 4px; }
.entry_list_item_placeholder { display: grid; place-items: center; width: 32px; height: 32px; border: 1.5px dashed var(--q-medium); border-radius: 50%; color: var(--q-dark); }
.entry_list_item_placeholder_filled { border: 0; background: var(--q-highlight-4); color: var(--q-highlight-2); }
.entry_list_footer { padding: 12px 18px; border-top: 1px solid #f1f2f2; background: var(--surface-soft); color: var(--fg-2); font-size: 12px; font-weight: var(--w-regular); line-height: 1.5; }
.entry_list .empty_state { padding: 28px 20px; }

/* ── Abschnitte ── */
.space_room { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 20px; }
.space_room_mark { flex-shrink: 0; }
.space_room > .content_form_item_group { flex: 1; min-width: 240px; }
.space_room_controls { display: flex; flex-basis: 100%; justify-content: flex-end; }
.space_room_static { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; min-height: 42px; color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); line-height: 1.45; }
.space_card { width: 100%; cursor: pointer; }
.space_card_current { border-color: var(--q-highlight-2); }
.space_card_head { display: flex; align-items: center; gap: 12px; min-width: 0; }
.space_card_text { display: flex; flex-direction: column; min-width: 0; }
.space_card_meta { display: inline-flex; align-items: center; gap: 10px; color: var(--q-dark); font-size: 12px; }
.space_card_meta > span:last-child { display: inline-flex; align-items: center; gap: 4px; }
.space_card_role { color: var(--fg-2); font-size: 12px; }
.space_rights .module_list_table tr { cursor: default; }
.space_rights .module_list_table td:not(:first-child), .space_rights .module_list_table th:not(:first-child) { text-align: left; }
.space_rights_yes { display: inline-flex; color: #4e7a26; }
.space_rights_no { color: var(--fg-2); }
.space_department_spaces { display: inline-flex; align-items: center; gap: 4px; }
.space_department_form { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 220px) auto; align-items: center; gap: 10px; }
.org_overview_hero { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; }
.org_overview_hero_main { flex: 1; min-width: 220px; }
.org_overview_hero_title { margin: 4px 0 6px; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 22px; font-weight: var(--w-bold); line-height: 1.2; }
.org_overview_hero_meta { display: flex; flex-wrap: wrap; gap: 4px 18px; color: var(--fg-2); font-size: 12.5px; }
.org_overview_hero_meta b { color: var(--q-dark); font-weight: var(--w-bold); }
.org_overview_columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); align-items: start; gap: 14px; }

/* ── Erweiterungen vorhandener Bausteine ── */
/* Kennzahl als Sprungziel (Organisation > Uebersicht). */
.admin-kpi.admin-kpi_link { width: 100%; text-align: left; cursor: pointer; transition: border-color var(--dur-fast) var(--ease-std); }
.admin-kpi.admin-kpi_link:hover, .admin-kpi.admin-kpi_link:focus-visible { border-color: var(--q-highlight-3); }
/* Zerstoerende Nebenaktion als Textverweis (Entziehen, Sperren). */
.link-btn.link-btn_danger { color: var(--danger); }
.link-btn.link-btn_danger:hover { color: var(--q-highlight-2); }
/* Auswahlkarten des Imports mit echtem Optionsfeld (Einladen, Anlegen):
   das Feld ist unsichtbar, die Karte zeigt Fokus und Sperre. */
.imp-source-opt { position: relative; cursor: pointer; }
.imp-source-opt input { position: absolute; opacity: 0; pointer-events: none; }
.imp-source-opt:has(input:focus-visible) { outline: 2px solid var(--q-highlight-3); outline-offset: 2px; }
.imp-source-opt.on .imp-radio { border-color: var(--q-highlight-2); }
.imp-source-opt.imp-source-opt_disabled { opacity: 0.45; cursor: not-allowed; }

@media (max-width: 780px) {
  /* Waagrechte Leiste: nur das Zeichen, wie bei eingeklappter Seitenleiste. */
  .space_switch { margin: 0 6px 0 0; }
  .space_switch_control { justify-content: center; min-width: 44px; min-height: 44px; padding: 4px; border-color: transparent; background: transparent; }
  .space_switch_text, .space_switch_chevron { display: none; }
  .app_shell_nav_schublade .space_switch { margin: 2px 0 8px; }
  .app_shell_nav_schublade .space_switch_control { justify-content: flex-start; padding: 7px 10px 7px 7px; border-color: var(--divider); background: #fff; }
  .app_shell_nav_schublade .space_switch_text { display: flex; }
  .app_shell_nav_schublade .space_switch_chevron { display: inline-flex; }
  .space_switch_panel .more_menu_item { min-height: 44px; }

  .settings_scope_note { flex-wrap: wrap; row-gap: 2px; border-radius: 16px; }
  .entry_list_header { padding: 14px; }
  .entry_list_item { flex-wrap: wrap; row-gap: 8px; padding: 12px 14px; }
  .entry_list_item_text { flex: 1 1 calc(100% - 50px); }
  .entry_list_item_visual + .entry_list_item_text + .entry_list_item_meta { margin-left: 44px; }
  .entry_list_item_meta { flex-wrap: wrap; }
  .entry_list_item_controls { margin-left: auto; }
  .entry_list_item_controls .planner-icon-btn { width: 44px; height: 44px; }
  .entry_list_item_controls .link-btn { min-height: 40px; }
  .entry_list_item_select .fselect { min-height: 40px; font-size: 16px; }
  .entry_list_item_child { padding-left: 34px; }
  .entry_list_item[data-level="2"] { padding-left: 54px; }
  .space_department_form { grid-template-columns: minmax(0, 1fr); }
  .space_room { flex-direction: column; gap: 14px; }
  .space_room > .content_form_item_group { min-width: 0; width: 100%; }
  .org_overview_hero { gap: 14px; }
  .org_overview_hero_title { font-size: 18px; }
  .org_overview_hero_mark .space_mark { --space-mark: 44px !important; }
  .org_overview_hero_controls { width: 100%; }
  .org_overview_hero_controls .button { justify-content: center; width: 100%; }
  .org_overview_columns { grid-template-columns: minmax(0, 1fr); }
}

/* ── Speicherprofile (BAL-233) ──────────────────────────────────────────────
   Plattform › Speicher & Dateien, Organisation › Speicherort, Profildialog.
   Vorlage: docs/design/application/project/spaces.css (.stg-*). Strukturdoku
   docs/css/structure/speicherprofile.md, Blueprint
   blueprints/blueprint_speicherprofile.html.
   Wiederverwendet und hier NICHT neu definiert: content_card(_header/_title),
   org_overview_columns, set-grid/set-card/sc-*, module_list_table,
   space_rights(_yes/_no), imp-source-*, fseg, fform-grid/fform-toggle,
   util-row, meter, status_badge_*, info-note, detail-section-label.
   Textfarbe fuer Nebenangaben ist --fg-2 (4,54 : 1), nicht --q-medium
   (Dekorfarbe, 1,9 : 1). Jeder Textbaustein setzt Groesse, Gewicht,
   Zeilenhoehe, Farbe und Abstand selbst - body steht auf 15 px / 300. */
.storage_mark { --storage-mark: 36px; display: inline-grid; place-items: center; flex-shrink: 0; width: var(--storage-mark); height: var(--storage-mark); border-radius: 50%; background: var(--q-highlight-4); color: var(--q-highlight-2); }
.storage_mark_s3 { background: rgba(21, 165, 181, 0.12); }
.storage_note { margin: 10px 0 0; color: var(--fg-2); font-size: 12px; font-weight: var(--w-regular); line-height: 1.5; }
.content_card_header .storage_note { margin: 0; }
.storage_check { display: inline-flex; align-items: center; gap: 6px; color: var(--fg-2); font-size: 12px; font-weight: var(--w-regular); line-height: 1.4; }
.storage_check_dot { width: 7px; height: 7px; flex-shrink: 0; border-radius: 50%; background: currentColor; }
.storage_check_ok { color: #4e7a26; }
.storage_check_failed { color: #b83232; }
.storage_check_running .ui_icon { color: var(--q-highlight-3); }
.storage_effective { display: inline-flex; align-items: center; gap: 8px; min-width: 0; color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); line-height: 1.4; text-align: left; }
.storage_effective > span:not(.storage_mark):not(.space_mark) { display: flex; flex-direction: column; min-width: 0; }
.storage_effective_source { color: var(--fg-2); font-size: 11.5px; white-space: nowrap; }
.storage_effective_title { color: var(--q-dark); font-weight: var(--w-regular); white-space: nowrap; }

/* Profilkarte: Variante von set-card */
.storage_card_current { border-color: var(--q-highlight-2); }
/* Grid-Kind darf schmaler werden als sein Inhalt - sonst schiebt der Zielpfad
   (nowrap) oder ein langer Organisationsname die Karte ueber den Rand. */
.set-card.storage_card { min-width: 0; }
.storage_card .sc-head > .storage_note { flex-shrink: 1; margin: 0; text-align: right; }
.storage_card_badges .status_badge { max-width: 100%; white-space: normal; }
.storage_card_head { display: flex; align-items: center; gap: 12px; min-width: 0; }
.storage_card_text { min-width: 0; }
.storage_card_target { overflow: hidden; color: var(--fg-2); font-family: var(--font-mono); font-size: 12px; font-weight: var(--w-regular); line-height: 1.4; text-overflow: ellipsis; white-space: nowrap; }
.storage_card_controls { display: inline-flex; flex-shrink: 0; gap: 2px; }
.storage_card_badges { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.set-card.storage_card .sc-foot { flex-wrap: wrap; }
.storage_table td .storage_card_controls { vertical-align: middle; }

/* Belegung je Profil unter dem Balken */
.storage_overview { align-items: stretch; margin-bottom: 14px; }
.storage_split { display: grid; gap: 8px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--divider); }
.storage_split_item { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.4; }
.storage_split_item .storage_note { margin: 0; }
.storage_split_item_title { color: var(--q-highlight-2); font-weight: var(--w-bold); }

/* Vorgaben fuer Organisationen */
.storage_policy_new { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); gap: 0 20px; align-items: start; }
.storage_orgs .fselect-wrap, .storage_spaces .fselect-wrap { display: inline-block; width: 100%; min-width: 170px; max-width: 260px; }
.storage_orgs td, .storage_spaces td, .storage_orgs th, .storage_spaces th { text-align: left !important; }
.storage_rights { margin: 0 0 18px; }
.storage_rights .module_list_table td:first-child { min-width: 220px; }
.space_rights_depends { color: var(--q-highlight-2); font-size: 12px; font-weight: var(--w-bold); white-space: nowrap; }

/* Vorgabe des Betreibers (Organisationssicht) */
.storage_policy { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 6px 16px; align-items: start; }
.storage_policy_icon { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--q-highlight-4); color: var(--q-highlight-2); }
.storage_policy_caption { display: block; color: var(--fg-2); font-size: 11px; font-weight: var(--w-bold); line-height: 1.4; letter-spacing: 0.1em; text-transform: uppercase; }
.storage_policy_title { margin-top: 3px; color: var(--q-highlight-2); font-family: var(--font-display); font-size: 16px; font-weight: var(--w-bold); line-height: 1.3; }
.storage_policy_description { max-width: 70ch; margin: 4px 0 0; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.5; text-wrap: pretty; }
.storage_policy_side { display: grid; gap: 6px; padding-left: 16px; border-left: 1px solid var(--divider); color: var(--q-dark); font-size: 13px; font-weight: var(--w-regular); }
.storage_policy_side b { color: var(--q-highlight-2); font-weight: var(--w-bold); }
.storage_policy_controls { grid-column: 2 / -1; }

/* Profildialog */
.storage_form_part[hidden] { display: none; }
.storage_form_test { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.storage_form_controls { display: flex; justify-content: flex-end; margin-top: 14px; }

@media (max-width: 780px) {
  .storage_policy_new { grid-template-columns: minmax(0, 1fr); }
  .storage_policy { grid-template-columns: auto minmax(0, 1fr); }
  .storage_policy_side { grid-column: 1 / -1; padding-left: 0; border-left: 0; }
  .storage_policy_controls { grid-column: 1 / -1; }
  .storage_orgs .fselect-wrap, .storage_spaces .fselect-wrap { min-width: 120px; }
}

/* Dateien verschieben (BAL-234) - Teile des Verschiebedialogs. */
.storage_move_route { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.storage_move_arrow { display: inline-grid; place-items: center; color: var(--fg-2); }
.storage_move_progress { display: grid; gap: 8px; }
.storage_move_progress .storage_note { margin: 0; color: var(--q-dark); }
.storage_move_failed { display: grid; gap: 6px; margin: 8px 0 0; padding: 0; list-style: none; }
.storage_move_failed_item { margin: 0; padding: 8px 12px; border: 1px solid var(--divider); border-radius: 10px; color: var(--q-dark); font-size: 12.5px; font-weight: var(--w-regular); line-height: 1.45; }
.storage_move_failed_item b { color: #b83232; font-weight: var(--w-bold); }

/* ── Vollbild-Umschalter auf kleinen Bildschirmen (BAL-239) ───────────────
   Gemessen am 2026-10-09: Unter 900 px nimmt ein Arbeitsdialog bereits
   100vw − 16px ein, seine Vollbildvariante (.modal_window.wd.fullscreen, weiter
   oben, hoehere Spezifitaet) aber 100vw − 24px - "Vollbild" machte das Fenster
   KLEINER. Unter 780 px gilt dasselbe fuer die uebrigen Dialoge (24 gegen 28 px).
   Wo der Dialog die Flaeche ohnehin fuellt, gibt es nichts umzuschalten: Der
   Umschalter entfaellt, und ein am grossen Bildschirm eingeschaltetes Vollbild
   bleibt so gross wie der normale Dialog. Der Browser-Vollbildknopf der
   Kopfleiste (toggle-browser-fullscreen) ist etwas anderes und bleibt. */
@media (max-width: 900px) {
  .modal_window.wd [data-action^="toggle-"][data-action$="-fullscreen"] { display: none; }
  .modal_window.wd.fullscreen, .modal_window.wd.wd-md.fullscreen { width: calc(100vw - 16px); height: calc(100vh - 16px); max-height: none; }
  .modal_window.wd.wd-kompakt.fullscreen { height: auto; max-height: calc(100vh - 16px); }
}
@media (max-width: 780px) {
  [data-action^="toggle-"][data-action$="-fullscreen"]:not([data-action="toggle-browser-fullscreen"]),
  [data-action$="-vollbild"] { display: none; }
  .modal_window.fullscreen:not(.wd), .dedicated-form-modal.fullscreen, .planner-card.fullscreen, .planner-posdlg.fullscreen { width: calc(100vw - 24px); height: calc(100vh - 24px); max-height: calc(100vh - 24px); }
}
