/* AuxData.ai — Komponenten des neuen Designs.
   Quelle: Figma "AuxData.ai — Core (Design System)", Seite 04 · Core.
   Geladen NACH tokens.css. JEDE Regel in dieser Datei steht unter
   [data-design="new"] — eine Regel ohne diesen Selektor faerbt das alte
   Design mit ein und wird vom Unit-Test abgewiesen.

   RESCOPE (2026-09-07, siehe .superpowers/sdd/2026-09-07-designsystem-core-
   components/rescope-report.md): die Basisregeln, die ein nacktes HTML-
   Element restylen (button/a/input[type=text]/select/textarea/input[type=
   date|time|url|search]/hr, inkl. all ihrer :hover/:active/:focus-visible/
   :disabled-Zustaende), stehen jetzt unter ":where([data-design=\"new\"])"
   statt "[data-design=\"new\"]". :where() traegt selbst KEINE Spezifitaet
   bei -- die Regeln landen dadurch wieder bei der Spezifitaet, die ihr
   unscoped Legacy-Gegenstueck in webapp.css hatte (0,0,1 fuer button/a/
   select/textarea/hr; 0,1,1 fuer die type-gebundenen input-Selektoren, weil
   ein Attributselektor selbst schon wie eine Klasse zaehlt). Vier
   Durchgaenge Einzelfall-Restaurierung hatten sich davor an genau der
   Umkehrung abgearbeitet, die der [data-design="new"]-Praefix (0,1,1 bzw.
   0,2,1) auf diesen Basisregeln erzeugt: jede bestehende Zweck-Klasse in
   webapp.css, die den nackten Legacy-button{}/a{}/... bei (0,1,0) oder
   Gleichstand schlug, verlor gegen die praefigierte Basisregel unabhaengig
   von ihrem eigenen Wert. :where() nimmt genau diese eine Spezifitaets-
   Stufe wieder zurueck.

   Wichtig, und Grund, warum unten trotzdem noch viele Einzelfall-Regeln
   stehen: :where() repariert NUR die Spezifitaets-Umkehrung fuer
   Eigenschaften, die die Legacy-Zweck-Klasse SELBST deklariert. Die
   Basisregeln fuehren mehrere Eigenschaften NEU ein, die keine Legacy-
   Klasse je gesetzt hat (v.a. min-height bei button, font-family/-size/
   line-height/font-weight bei a) -- fuer die gibt es keine konkurrierende
   Legacy-Deklaration, gegen die :where() etwas gewinnen koennte; diese
   Werte gelten unabhaengig von jeder Spezifitaet, sobald nichts sie
   zuruecksetzt. Ebenso unveraendert: der :hover/:active/:focus-visible-
   Zustand der Basisregel ist eine EIGENE Spezifitaetsrechnung (Element +
   Pseudoklassen, ohne die Praefix-Klasse jetzt bei (0,2,1) statt (0,3,1))
   -- eine Legacy-Zweck-Klasse, die selbst kein eigenes :hover traegt,
   kollidiert damit weiterhin. Jede verbliebene Einzelfall-Regel unten
   traegt deshalb einen Kommentar, WARUM sie trotz :where() noetig bleibt.

   NACHTRAG (2026-09-08, erste Korrektur, seither UEBERHOLT): "min-height"
   auf der Button-Basisregel wurde zunaechst durch "height" ersetzt, weil
   Legacy-Zweck-Klassen mit eigener Groesse "height" ueberwiegend SELBST
   deklarieren und die Kaskade das dadurch arbitrieren konnte. Das loeste nur
   EINE von sechs unkontestierten Eigenschaften -- "justify-content" bekam
   danach seinen ZWEITEN Einzelfall-Patch (.tool-invocation-toggle,
   .resource-group-header), exakt die Aufzaehlung, die :where() eigentlich
   beenden sollte, jetzt auf einer anderen Eigenschaft.

   FINALE ENTSCHEIDUNG (2026-09-08, siehe rescope-report.md): die Basisregel
   darf NUR NOCH Eigenschaften deklarieren, die das nackte Legacy-"button{}"
   (webapp.css:844) ebenfalls deklariert -- border-radius/padding/display/
   background/color/font-family/font-size/font-weight/border. Jede so
   gesetzte Eigenschaft ist dadurch IMMER kontestiert, unabhaengig davon,
   welche Eigenschaft Figma als naechstes verlangt -- kein siebter Durchgang
   mehr moeglich. "height" ist komplett entfernt (36px kommt jetzt aus
   "padding", das Legacy selbst deklariert und das eine Zweck-Klasse mit
   "padding: 0" deshalb per Kaskade unterlaeuft, statt es nur unwirksam zu
   floor(t)en). "gap"/"align-items"/"justify-content"/"line-height"/
   "transition" (Legacy kennt keins davon) sind ersatzlos entfernt, bis auf
   "align-items"/"justify-content" auf ".button-icon" selbst (echte Klasse,
   quadratische Icon-Zentrierung, kein Leck). Alle ~21 "height: auto"-
   Einzelfall-Resets und die zwei "justify-content: flex-start"-Resets
   sind damit strukturell ueberfluessig und entfernt (rescope-report.md
   listet jede Regel einzeln). Ein neuer Unit-Test erzwingt die Teilmengen-
   Eigenschaft automatisch, siehe tests/unit/components-css.test.js. */

/* Galerie — Entwicklungswerkzeug, kein Anwender-Feature. */
[data-design="new"] .gallery-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ax-space-4);
  padding: var(--ax-space-4);
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-lg);
  margin-bottom: var(--ax-space-6);
  background: var(--ax-bg-surface-1);
}

[data-design="new"] .gallery-tile {
  display: flex;
  flex-direction: column;
  gap: var(--ax-space-2);
  padding: var(--ax-space-3);
  border: 1px solid var(--ax-border-soft);
  border-radius: var(--ax-radius-md);
  min-width: 200px;
}

[data-design="new"] .gallery-tile-label {
  font-size: var(--ax-font-size-label-sm);
  line-height: var(--ax-line-height-label-sm);
  color: var(--ax-text-muted);
}

/* --- Aktionen ------------------------------------------------------------ */

/* Primary. Die nackte button-Regel in webapp.css ist bereits der
   Primary-Button; hier wird sie auf Figmas Geometrie und Tokens gehoben.
   NUR Eigenschaften, die Legacys "button{}" (webapp.css:844) selbst
   deklariert -- border-radius/padding/display/background/color/font-family/
   font-size/font-weight/border -- damit jede hier gesetzte Eigenschaft
   IMMER kontestiert bleibt (rescope-report.md, "Die Entscheidung").
   "height" (36px) ist ersetzt durch "padding": 9px oben/unten + Figmas
   line-height/label-md (18px, ueberwiegend Browser-"normal" nahe genug,
   siehe Report) ergeben 36px, OHNE eine unkontestierte fixe Hoehe zu setzen
   -- eine Zweck-Klasse mit "padding: 0" (0,1,0) gewinnt jetzt direkt gegen
   diese Basisregel (0,0,1), statt nur eine wirkungslose min-Hoehe zu
   unterlaufen. "gap"/"align-items"/"justify-content"/"line-height"/
   "transition" sind ersatzlos entfernt (kein Legacy-Gegenstueck, siehe
   Report fuer die Einzelbegruendung je Eigenschaft). */
:where([data-design="new"]) button {
  border-radius: var(--ax-radius-md);
  padding: 9px var(--ax-space-4);
  display: inline-flex;
  background: var(--ax-action-primary);
  color: var(--ax-action-on-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-md);
  font-weight: 600;
  border: none;
}

:where([data-design="new"]) button:hover:not(:disabled) { background: var(--ax-action-primary-hover); }
:where([data-design="new"]) button:active:not(:disabled) { background: var(--ax-action-primary-pressed); }

:where([data-design="new"]) button:focus-visible {
  box-shadow: var(--ax-focus-ring);
  outline: 2px solid transparent;   /* Versatz sichtbar halten, ohne Outline zu entfernen */
  outline-offset: 2px;
}

:where([data-design="new"]) button:disabled {
  opacity: .5;
  cursor: default;
}

[data-design="new"] button.btn-secondary {
  background: var(--ax-bg-surface-2);
  border: 1px solid var(--ax-border-default);
  color: var(--ax-text-primary);
}
[data-design="new"] button.btn-secondary:hover:not(:disabled) { background: var(--ax-bg-hover); }

[data-design="new"] button.btn-ghost {
  background: none;
  border: none;
  color: var(--ax-text-link);
}
[data-design="new"] button.btn-ghost:hover:not(:disabled) { background: var(--ax-bg-hover); }

/* Icons folgen der Textfarbe, nicht dem Stil. webapp.css:867 erzwingt
   filter: brightness(0) invert(1) (weiss) fuer ALLE Button-Icons. Das ist
   fuer Secondary/Ghost/Icon-Button falsch, sobald deren Flaeche/Umgebung mit
   dem Theme kippt (siehe Tabelle im Task-Report) -- deshalb im Light-Theme
   auf Schwarz umschalten, im Dark-Theme unveraendert lassen. */
[data-design="new"][data-theme="light"] button.btn-secondary img:not(.logo),
[data-design="new"][data-theme="light"] button.btn-ghost img:not(.logo),
[data-design="new"][data-theme="light"] button.button-icon img:not(.logo) {
  filter: brightness(0);
  opacity: 1;
}

/* Primary-Icons weiss halten. webapp.css:444 setzt fuer JEDES Button-Icon im
   Light-Theme -- design-unabhaengig, keine [data-design]-Bindung -- filter:
   brightness(0) (schwarz). Die Primary-Flaeche (--ax-action-primary) ist
   farbig und traegt weissen Labeltext (--ax-action-on-primary, reines Weiss
   in beiden Themes); ein schwarzes Icon stuende dort neben weisser Schrift.
   Deshalb wird es fuer Primary auf Weiss zurueckgedreht.

   HIER STAND EINE AUSSCHLUSSKETTE, UND SIE WAR ZU WEIT. Berichtigt am
   2026-09-17, nachdem der Auftraggeber in der Sichtpruefung zweimal
   unsichtbare Symbole gemeldet hatte ("06 Shell & Nav" Punkt 9, Zurueck-
   Knopf; "07 Chat & AI" Teil B Punkt 1, Composer):

     vorher:  button:not(.btn-secondary):not(.btn-ghost):not(.button-icon)

   Die Kette unterstellte "alles, was nicht Secondary, Ghost oder Icon-Button
   ist, ist Primary". Das ist falsch: im neuen Design ist Primary der NACKTE
   Knopf, und jeder Knopf, der eine eigene Legacy-Flaeche mitbringt, fiel
   ebenfalls in die Regel -- und bekam ein weisses Symbol auf heller Flaeche.
   Gemessen im hellen Theme, neues Design, sichtbare Flaeche gegen Filter:

     chatbot-button                       Flaeche #ffffff   Symbol WEISS
     chatbot-button chatbot-btn-secondary Flaeche #ffffff   Symbol WEISS
     chatbot-button-deactivated …         Flaeche #ffffff   Symbol WEISS
     image                                Flaeche #ffffff   Symbol WEISS
     image-small                          Flaeche #ffffff   Symbol WEISS
     page-action-btn                      Flaeche #f4f3f7   Symbol WEISS

   Sechs Klassen, alle praktisch unsichtbar. Der Auftraggeber hat gemeldet,
   was ihm begegnet ist; die anderen vier standen genauso da.

   DIE RICHTUNG IST JETZT UMGEKEHRT, und das ist eine Entscheidung des
   Auftraggebers vom 2026-09-17: dunkel ist der Grundfall (er kommt ohne
   eigene Regel aus webapp.css:444), weiss bekommt nur, wer nachweislich eine
   farbige Flaeche traegt. Uebersieht jemand kuenftig einen farbigen Knopf,
   steht dort ein dunkles Symbol auf Farbe -- lesbar, nur nicht ideal. Der
   Fehlerfall ist damit harmlos; vorher war er unsichtbar.

   DIE LISTE IST GEMESSEN, NICHT GERATEN. Gemessen wurden #ffffff bzw.
   rgb(0,122,176) als sichtbare Flaeche ueber /designgallery.html,
   /agentmanager.html und /cockpit.html:
     - der NACKTE Knopf: die Basisregel dieses Designs (oben, ":where(…)
       button") faerbt ihn action/primary. "button:not([class])" trifft genau
       ihn.
     - ".voice-control-stop" setzt SELBST keine Flaeche (webapp.css:5917 nur
       Geometrie) und ist damit ebenfalls Primary aus der Basisregel --
       gemessen rgb(0,122,176). Eine Klasse zu tragen heisst hier nicht, eine
       Flaeche zu haben.
     - ".chatbot-button-send" ueberschreibt die transparente Flaeche seines
       ".chatbot-button" auf den Akzent -- gemessen rgb(0,122,176).
     - ".page-action-btn.primary" setzt "background: var(--clr-accent)"
       (components.css:2199). Nicht ueber die Sonde gefunden, weil auf den
       drei Seiten kein primaerer Kopfknopf stand -- aus der Regel gelesen
       und deshalb hier genannt.
   Zugesichert in tests/features/design-knopfsymbole.spec.ts, zweiseitig. */
[data-design="new"][data-theme="light"] button:not([class]) img:not(.logo),
[data-design="new"][data-theme="light"] button.voice-control-stop img:not(.logo),
[data-design="new"][data-theme="light"] button.chatbot-button-send img:not(.logo),
[data-design="new"][data-theme="light"] button.page-action-btn.primary img:not(.logo) {
  filter: brightness(0) invert(1);
  opacity: 1;
}

/* Review-Fund ("Critical 1"), RESCOPE-STAND: acht bestehende Zweck-Buttons
   ueberschnitten sich mit der (vor dem Rescope) praefigierten Basisregel:
   .button-command/-small (webapp.css:1421/1434), .image/-tabwidget/-small
   (webapp.css:3944/3956/3972), .delete (webapp.css:3932), .white
   (webapp.css:3984), .button-action (webapp.css:4652). Alle acht bleiben
   bewusst unreskinnt (Spec §4: nur Primary/Secondary/Ghost/Danger sind
   Achsen-Rollen). Seit :where() auf der Basisregel (Header-Kommentar) reicht
   Legacys eigene Spezifitaet fuer JEDE Eigenschaft, die die jeweilige Klasse
   SELBST deklariert, wieder aus -- die Restaurierung unten ist deshalb pro
   Klasse einzeln darauf reduziert, was WEITERHIN noetig ist:
     - height: seit die Basisregel "height" ueberhaupt nicht mehr setzt
       (finale Entscheidung, Header-Kommentar), gibt es fuer KEINE der acht
       Klassen mehr etwas zu resetten -- die vier vormaligen "height: auto"-
       Eintraege (.button-command/.delete/.white/.button-action) sind
       ersatzlos entfernt.
     - display/padding/border-radius/font-size: .button-command/-small und
       .button-action deklarieren diese SELBST (0,1,0), das reicht nach dem
       Rescope gegen die fixierte Basisregel (0,0,1) -- redundant, aber
       .button-action's "display" faellt auf die UNSCOPED, bare
       "button{display:inline-block}" (webapp.css:844, 0,0,1) zurueck, die
       mit der fixierten Basisregel GLEICHSTAND haelt und die Ladereihenfolge
       (webapp.css zuerst) verliert -- "display" bleibt deshalb fuer
       .button-action bestehen. .delete/.white deklarieren NUR Flaeche/Text/
       Rahmen selbst; display/padding/border-radius/font-size kommen bei
       ihnen ebenfalls aus der TIED bare button{}-Regel -- bleiben deshalb
       fuer beide bestehen.
     - Hover: die Basisregel setzt bei :where() weiterhin eine EIGENE
       Spezifitaetsrechnung fuer ":hover:not(:disabled)" (Element +
       2 Pseudoklassen, (0,2,1)) -- unveraendert von der REST-Faelligkeit.
       .image-small/.delete tragen eigene :hover-Regeln bei GLEICHSTAND
       (0,2,1) mit dieser Basisregel, verlieren die Ladereihenfolge (diese
       Datei laedt nach webapp.css) -- Gegenregel bleibt fuer beide noetig.
   .image und .image-tabwidget (webapp.css:3944/3956) deklarieren
   display/padding/background/border SELBST bei (0,1,1) -- schlagen die
   fixierte Basisregel (0,0,1) jetzt direkt, kein Ruecksprung auf die tied
   bare button{}-Regel noetig. Ihre REST-Zustandsregeln sind deshalb komplett
   entfernt -- nur ihre :hover-Gegenregeln bleiben (eigener Kommentar
   unten). .button-command braucht seit dem Wegfall von "height" auf der
   Basisregel ueberhaupt keine eigene Regel mehr (vormals nur "height: auto"
   -- ersatzlos entfernt). */
/* .button-command-small (webapp.css:1434) und .image-small (webapp.css:
   3972) deklarieren ihre eigene Hoehe SELBST -- brauchten schon vor dieser
   Runde keine Restaurierung (die Basisregel setzt jetzt gar keine Hoehe
   mehr, statt vormals "min-height" bzw. "height"). */
[data-design="new"] button.image-small:hover:not(:disabled) {
  background-color: var(--background-color-button-hover);
}
/* button.image / button.image.page-btn / button.image-tabwidget (REST-
   Zustand) sind entfernt (siehe Block-Kommentar oben) -- webapp.css:3944/
   3938/3956 gewinnen nach dem Rescope allein, unabhaengig von der Lade-
   reihenfolge, fuer alle drei dort deklarierten Eigenschaftsgruppen. Nur
   die :hover-Gegenregeln bleiben, weil die Hover-Spezifitaetsrechnung der
   Basisregel von :where() unberuehrt bleibt (Block-Kommentar oben) und
   button.image:hover/button.image-tabwidget:hover (webapp.css:4253/3968,
   je (0,2,1)) mit ihr GLEICHSTAND halten. */
[data-design="new"] button.image:hover:not(:disabled) {
  background: var(--clr-surface-2);
  color: var(--clr-text-primary);
}
[data-design="new"] button.image-tabwidget:hover:not(:disabled) {
  background: var(--clr-surface-1);
}
/* RESCOPE: .delete (webapp.css:3932, button.delete, (0,1,1)) deklariert
   SELBST nur background/color/border -- die schlagen die fixierte
   Basisregel (0,0,1) jetzt direkt, keine Restaurierung mehr noetig.
   display/border-radius/padding/font-size deklariert .delete NICHT selbst,
   faellt also auf die TIED unscoped button{}-Regel (webapp.css:844, (0,0,1),
   Gleichstand mit der fixierten Basisregel, verliert die Ladereihenfolge)
   zurueck -- bleiben deshalb hier stehen. Kein "height" mehr noetig: die
   Basisregel setzt seit der finalen Entscheidung ueberhaupt keine Hoehe. */
[data-design="new"] button.delete {
  display: inline-block;
  border-radius: 5px;
  padding: 6px 16px;
  font-size: 12px;
}
[data-design="new"] button.delete:hover:not(:disabled) {
  border-color: var(--clr-danger);
  background: transparent;
}
/* .white (webapp.css:3984, button.white, (0,1,1)) deklariert SELBST nur
   background/color -- schlagen die fixierte Basisregel direkt, entfernt.
   display/border-radius/padding/font-size bleiben aus demselben TIED-
   button{}-Grund wie bei .delete oben stehen; .white hat kein eigenes
   :hover (faellt auf die generische, jetzt korrekt niedrig-spezifische
   Hover-Flaeche der Basisregel zurueck -- Token-Wechsel akzeptiert, gleiche
   Einstufung wie beim Help-Widget-Launcher weiter unten). Kein "height"
   mehr noetig, aus demselben Grund wie bei .delete. */
[data-design="new"] button.white {
  display: inline-block;
  border-radius: 5px;
  padding: 6px 16px;
  font-size: 12px;
}
/* .button-action (webapp.css:4652, KLASSE OHNE Element, (0,1,0)) deklariert
   SELBST background-color/color/border/border-radius/padding/font-size --
   schlagen die fixierte Basisregel (0,0,1) direkt, entfernt. NUR "display"
   faellt (wie bei .delete/.white) auf die TIED button{}-Regel zurueck und
   bleibt deshalb stehen; kein "height" mehr noetig. */
[data-design="new"] button.button-action {
  display: inline-block;
}
[data-design="new"] button.button-action:hover:not(:disabled) {
  background-color: var(--background-color-application);
  color: var(--font-color-application);
}

/* .chatbot-button/-deactivated/-send (webapp.css:5624/5646/5666) deklarieren
   border/background/border-radius/padding/display/height SELBST -- die
   Basisregel setzt seit der finalen Entscheidung (Header-Kommentar) KEINE
   dieser Eigenschaften mehr, also gibt es fuer keine von ihnen mehr etwas
   zu resetten -- alle drei REST-Regeln sind komplett entfernt. width/opacity
   waren nie Teil der Basisregel (unveraendert unangetastet, vorbestehende
   Redundanz).

   REGRESSIONSFUND (Sweep-Nachtrag, unveraendert gueltig): ".chatbot-button-
   send" deklarierte zusaetzlich box-shadow (0,1,0) -- das schlug
   ".chatbot-input--focused .chatbot-button-send" (webapp.css:5681, 2
   Klassen, (0,2,0)) permanent, weil die vorherige Restaurierung box-shadow
   bei (0,2,1) hielt (HOEHER als die Fokus-Regel) und den Fokus-Glow der
   Chat-Eingabeleiste dadurch dauerhaft unterdrueckte -- unabhaengig vom
   Fokuszustand. box-shadow ist entfernt (schon in der vorherigen Fassung
   dieses Kommentars); mit der gesamten REST-Regel jetzt komplett entfernt
   entscheidet fuer box-shadow (und border/background) wieder allein Legacys
   eigene Kaskade: ".chatbot-button-send" (0,1,0, box-shadow:0 2px 8px) an
   Ruhe, ".chatbot-input--focused .chatbot-button-send" (0,2,0, box-shadow:
   0 2px 14px, hoehere Spezifitaet) bei fokussierter Eingabeleiste -- exakt
   wie vor diesem gesamten Projekt, der Fokus-Glow verstaerkt sich wieder
   sichtbar.

   sendButton (chatwindowinput.js:106) traegt PRODUKTIV BEIDE Klassen
   zugleich ("chatbot-button chatbot-button-send") -- fuer border/background/
   height entscheidet jetzt wieder allein Legacys eigene Ladereihenfolge in
   webapp.css (chatbot-button-send nach chatbot-button, beide (0,1,0)),
   exakt wie vor diesem gesamten Projekt.

   .chatbot-button-deactivated ist trotz des Namens NICHT :disabled (das
   Element bleibt klickbar) -- die Hover-Spezifitaetsrechnung der Basisregel
   bleibt von :where() unberuehrt (Header-Kommentar), trifft es deshalb auf
   echten Mausover weiterhin und wuerde die Cyan-Flaeche einblenden, wo
   Legacy nur den Cursor auf "help" aendert -- Gegenregel bleibt noetig.

   Mobile (webapp.css:10608-10616, @media max-width:640px): dieselben drei
   Klassen wachsen dort UNSCOPED auf 36x36 (Touch-Ziel), ebenfalls (0,1,0).
   Das eigene @media unten in dieser Datei bleibt unabhaengig davon noetig
   (0,2,1) -- es schlaegt sowohl Legacys REST-Hoehe (0,1,0, 28px) als auch
   Legacys eigene Mobile-Hoehe (0,1,0, 36px) unabhaengig von der jetzt
   geloeschten REST-Restaurierung, war also nie auf sie angewiesen. */
[data-design="new"] button.chatbot-button:hover:not(:disabled) {
  background: rgba(var(--clr-accent-rgb), 0.08);
  border-color: rgba(var(--clr-accent-rgb), 0.3);
}
[data-design="new"] button.chatbot-button-deactivated:hover:not(:disabled) {
  background: transparent;
  border-color: var(--clr-border);
}
[data-design="new"] button.chatbot-button-send:hover:not(:disabled) {
  background: linear-gradient(135deg, var(--clr-accent-btn), var(--clr-accent-btn-hover));
}
@media (max-width: 640px) {
  [data-design="new"] button.chatbot-button,
  [data-design="new"] button.chatbot-button-deactivated,
  [data-design="new"] button.chatbot-button-send {
    width: 36px;
    height: 36px;
    min-width: 36px;
    min-height: 36px;
  }
}

/* RESCOPE: ".copy-button" (webapp.css:746, Teil der Kommaliste ".copy-button,
   pre.mermaid-diagram .download-button", als eigenstaendiger Selektor
   KLASSE OHNE Element, (0,1,0)) deklariert SELBST padding/font-size/border-
   radius/border/background/color/transition -- schlagen die fixierte
   Basisregel (0,0,1) jetzt direkt, alle sieben sind entfernt.
   ".success"/".error" (webapp.css:779/785, je (0,2,0)) brauchen dadurch
   KEINE Gegenregel mehr: die vormals noetige Ausnahme bestand nur, weil die
   Restaurierung selbst border-color/color auf (0,2,1) gesetzt hatte, hoeher
   als ihr (0,2,0) -- ohne diese beiden Eigenschaften in der Restaurierung
   gewinnen ".success"/".error" wieder unmittelbar durch ihre eigene, hoehere
   Spezifitaet gegenueber ".copy-button" selbst (0,2,0 > 0,1,0), wie vor
   diesem gesamten Projekt. Beide Gegenregeln sind deshalb geloescht.

   Kein "height" mehr noetig: weder ".copy-button" noch der zweite
   Kommaglied-Selektor "pre.mermaid-diagram .download-button" (webapp.css:747
   -- derselbe echte Knopf, mermaidrenderer.js:252-257, mit eigenem, nicht
   "copy-button" lautendem Klassennamen, siehe dortiger Kommentar "beide
   Knoepfe wuerden sonst denselben Selektor beantworten") deklariert selbst
   eine Hoehe, aber die Basisregel setzt seit der finalen Entscheidung
   ueberhaupt keine Hoehe mehr, also entfaellt der bisherige Reset ersatzlos.
   Die Hover-Gegenregel bleibt fuer beide noetig: keiner der beiden Selektoren
   traegt ein eigenes Legacy-":hover" fuer "background" (nur ein gemeinsames,
   unbedingtes ":focus-within"/":hover" auf einem VORFAHREN fuer "opacity",
   eine andere Eigenschaft) -- Legacys REST-Flaeche (0,1,0/(0,2,1),
   "background: var(--background-color-input)") verliert waehrend echtem
   Hover gegen die Hover-Spezifitaetsrechnung der Basisregel (0,2,1,
   "background") bei Gleichstand mit ".copy-button" bzw. direkt bei
   ".download-button".

   Defekt (Abschlussreview): dieselbe Hover-Spezifitaetsrechnung (0,4,1)
   schlaegt auch Legacys ".copy-button.success"/".error" (0,2,0) bzw.
   "pre.mermaid-diagram .download-button.success"/".error" (0,3,1) --
   _showFeedback() (mermaidrenderer.js:258/260) haengt diese Klassen an,
   waehrend der Zeiger noch auf dem Knopf steht (Klick => :hover bleibt
   aktiv), die gruene/rote Bestaetigungsfarbe fuer border-color wurde also
   von der eigenen Hover-Regel hier unterdrueckt. ":not(.success):not(.error)"
   nimmt beide Zustaende jetzt strukturell aus der Hover-Regel heraus, statt
   noch eine dritte Restaurierungsebene fuer .success/.error draufzusetzen --
   ohne Treffer gewinnt Legacys eigene .success/.error-Regel wieder
   unbestritten. ".download-button:hover" bekommt zusaetzlich ":not(:disabled)",
   das die Copy-Haelfte schon trug. */
[data-design="new"] button.copy-button:hover:not(:disabled):not(.success):not(.error),
[data-design="new"] pre.mermaid-diagram .download-button:hover:not(:disabled):not(.success):not(.error) {
  background: var(--background-color-input);
  border-color: var(--clr-border);
}

/* Icon Button — Figma "Icon Button", Style=Ghost/Danger, Size=Medium
   (38:12/17 Ghost, 38:52/57 Danger): 36x36, quadratisch, Radius 10, kein
   Innenabstand, Icon 20x20 (--ax-size-icon-md). Eigene Geometrie statt der
   Text-Button-Geometrie oben, deshalb volle Ueberschreibung von
   width/padding/background/border.
   Produktivklasse: atombuttoncommand.js setzt "button-icon" (Ghost-Default).
   Figmas "Style=Filled" (38:32/37) wird bewusst nicht umgesetzt: keine
   Produktivklasse erzeugt diesen Stil heute, siehe designgallerypage.js.
   align-items/justify-content stehen jetzt HIER statt auf der Basisregel
   (die keins von beiden mehr setzt, siehe Header-Kommentar) -- ohne sie
   saesse das einzelne Icon oben-links in der 36x36-Flaeche statt zentriert.
   Legacys eigenes ".button-icon" (webapp.css:1358, class only, (0,1,0))
   deklariert dieselben zwei Werte zufaellig identisch (center/center) und
   wuerde sie mangels Gegenregel ohnehin unkontestiert durchreichen -- die
   Regel hier macht daraus eine bewusste, nicht zufaellige Design-Aussage. */
[data-design="new"] button.button-icon {
  width: var(--ax-size-control-md);
  min-height: var(--ax-size-control-md);
  padding: 0;
  border-radius: var(--ax-radius-md);
  background: none;
  border: none;
  align-items: center;
  justify-content: center;
}
[data-design="new"] button.button-icon img {
  width: var(--ax-size-icon-md);
  height: var(--ax-size-icon-md);
}
[data-design="new"] button.button-icon:hover:not(:disabled) { background: var(--ax-bg-hover); }

/* Danger: atombuttondelete.js setzt "button-icon button-icon--danger".
   Flaeche = Figmas status/danger-bg (38:52/38:57), nicht die solide
   status/danger -- so wie tatsaechlich aus Figma ausgelesen. */
[data-design="new"] button.button-icon--danger {
  background: var(--ax-status-danger-bg);
}
/* Hover: kein Figma-Hover-Wert vorhanden (38:52/38:57 sind nur Default/
   Disabled). Statt der neutralen --ax-bg-hover der Geschwisterstile (die
   den Rotton komplett aufheben wuerde) hier auf die gesaettigtere, solide
   status/danger-Flaeche intensivieren -- bleibt in der Rot-Familie, aendert
   sich sichtbar gegenueber dem Ruhezustand (status/danger-bg). */
[data-design="new"] button.button-icon--danger:hover:not(:disabled) { background: var(--ax-status-danger); }

/* Nachtrag F3 (2026-09-22): die Diktierfunktion entfaellt ueberall (Anwender:
   "Es gibt den Voice Chat, das reicht."), damit auch der Diktier-Button und
   seine Klasse ".dictation-active" -- die Regel dafuer (frueher hier, siehe
   Historie) ist damit Waise und entfernt. */

/* Link — Figma "Link" (110:38 Inline, 110:47 Standalone; beide Style-Varianten
   sind optisch identisch, AtomDisplayLink unterscheidet den Kontext nicht,
   eine Regel fuer <a> genuegt). Textstil "Label/Button": derselbe Inter Semi
   Bold 13/18 wie der Button, keine Unterstreichung im Ruhezustand. */
:where([data-design="new"]) a {
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-md);
  line-height: var(--ax-line-height-label-md);
  font-weight: 600;
  color: var(--ax-text-link);
  text-decoration: none;
  cursor: pointer;
  transition: color 120ms ease-out, box-shadow 120ms ease-out;
}
:where([data-design="new"]) a:hover:not(.disabled) { text-decoration: underline; }

:where([data-design="new"]) a:focus-visible {
  box-shadow: var(--ax-focus-ring);
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: none;
}

/* AtomDisplayLink rendert <a> ohne href (Befehls-Trigger, keine Navigation);
   :disabled existiert fuer <a> nicht. Atom.disable() setzt stattdessen die
   Klasse .disabled (ElementVisibility.disable), deshalb hier statt :disabled.
   ElementVisibility.disable() setzt IMMER beides: element.disabled UND die
   Klasse "disabled" -- letztere kollidiert mit dem UNSCOPED, designunabhaengigen
   webapp.css:1283 (".disabled { color: var(--font-color-disabled); background-
   color: var(--background-color-disabled); }"). Fuer color gewinnt die Basis-
   regel [data-design="new"] a { color: var(--ax-text-link); } bereits per
   Spezifitaet (0,1,1 > 0,1,0) -- aber KEINE Regel hier setzt bislang
   background, also gewinnt webapp.css:1283 dafuer unbestritten: ein Link im
   Disabled-Zustand bekaeme einen grauen Kasten (--clr-surface-3), den Figma
   fuer Links nicht kennt (keine Flaeche in keinem Link-Zustand). Deshalb hier
   explizit auf "none" zurueckgesetzt -- gefunden erst, seit .disable() auf
   dieser Kachel ueberhaupt greift (siehe Fix zu Concern 1, vorige Runde). */
[data-design="new"] a.disabled {
  opacity: .5;
  cursor: default;
  pointer-events: none;
  background: none;
}

@media (prefers-reduced-motion: reduce) {
  :where([data-design="new"]) a { transition: color 120ms ease-out; }
}

/* RESCOPE (vormals "Critical 2"): zehn bestehende Anker-Stellen
   (webapp.css:1110/2277/2287/2649/3271/4686/5005/6129/11805/12807/13262)
   ueberschnitten sich mit der (vor dem Rescope) praefigierten Basisregel.
   AtomDisplayLink (atomdisplaylink.js) rendert ein <a> ohne unterscheidende
   Klasse -- eine Markup-Aenderung ist laut Plan nicht sanktioniert, die
   Restaurierung bleibt darum je Klasse bestehen. Seit :where() (Header-
   Kommentar) reicht Legacys eigene Spezifitaet fuer JEDE Eigenschaft, die
   die jeweilige Klasse SELBST deklariert, wieder aus -- geblieben ist nur,
   was WEITERHIN noetig ist:
     - Typografie (font-family/-size/line-height/font-weight): KEINE der
       zehn Stellen hatte je eine eigene Schriftregel (Ausnahme: .branding-
       preview-card setzt font-size:0.875rem, .dropdown-content-small/
       .navbar2 .dropdown-content setzen font-size:10px/12px direkt selbst
       -- dort jeweils nur "font-family" als Leck geblieben, "font-size" ist
       redundant und entfernt; die uebrigen sieben behalten alle vier
       Eigenschaften). Kein Legacy-Gegenstueck bedeutet: :where() aendert
       nichts (keine Spezifitaet noetig, wenn niemand sonst die Eigenschaft
       setzt) -- bleibt bestehen als "inherit"/literaler Legacy-Wert.
     - Farbe/Unterstreichung: ALLE zehn Klassen deklarieren color SELBST
       direkt auf dem Anker-Selektor (mindestens (0,1,1), teils (0,0,2) bei
       "td a") -- das schlaegt die fixierte Basisregel (0,0,1) jetzt direkt,
       unabhaengig von der Ladereihenfolge. Die vier ":not(:hover)"-Farb-
       Ausnahmen (.cardlist/.dropdown-content(-small)/.navbar2 .dropdown-
       content) sind deshalb komplett entfernt -- ihr einziger Zweck war,
       die vormals (0,2,1)-hoehe Ruhezustands-Restaurierung waehrend des
       Hovers von der jeweiligen Legacy-:hover-Farbregel fernzuhalten; ohne
       diese Ruhezustands-Restaurierung entfaellt der Interessenkonflikt,
       Legacys eigene .KLASSE-a(-Ruhezustand, niedriger) gegen .KLASSE-
       a:hover(hoeher) loest sich unveraendert durch normale Kaskade.
     - "td a" (webapp.css:2287, ZWEI Elemente ohne Klasse, (0,0,2)) schlaegt
       die fixierte Basisregel (0,0,1) fuer color/text-decoration ebenfalls
       direkt (b-Spalte gleich null bei beiden, c-Spalte 2>1) UND verliert
       gegen ".bot-message a"/".msg-bubble-bot a" (je (0,1,1), b-Spalte
       1>0) unveraendert bei einem Link innerhalb einer Tabelle in einer
       Bot-Antwort -- derselbe vereinheitlichte Linkstil wie zuvor, jetzt
       aus Legacys eigener Spezifitaet statt aus zwei komponenten.css-
       Restaurierungen. */
[data-design="new"] .bot-message a {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
}
[data-design="new"] .msg-bubble-bot a {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
}
[data-design="new"] td a {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
}
[data-design="new"] .result-card a {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
}
[data-design="new"] .cardlist a {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
}
[data-design="new"] .notification-markdown a {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
}
[data-design="new"] .function-assistant-explanation a {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
}
[data-design="new"] .branding-preview-card a {
  font-family: inherit;
  line-height: inherit;
  font-weight: inherit;
}
/* Defekt (Abschlussreview): .sourceinfo a (webapp.css:1110) deklariert nur
   color/cursor, KEIN text-decoration -- die Basisregel-Zeile "a { ...
   text-decoration: none }" traf deshalb unbestritten, und die Quellenangaben-
   Links in Chat-Antworten/Ergebniskarten/Wissensdatenbank-Suche verloren im
   Ruhezustand ihre Unterstreichung. Hier explizit wiederhergestellt. */
[data-design="new"] .sourceinfo a {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
  text-decoration: underline;
}
/* Defekt (Core-Spec Abschnitt 14, Punkt 2 -- in Task 6 GEMESSEN und mit
   einer ANDEREN Ursache als der dort genannten): diese Regel trifft auch
   ".navbar2 .dropdown-content a", denn ".dropdown-content a" ist darin
   enthalten. Mit dem rohen Attributpraefix stand sie bei (0,2,1) im
   Spezifitaets-Gleichstand mit Legacys ".navbar2 .dropdown-content a"
   (webapp.css:4994, ebenfalls (0,2,1)) und gewann ihn ueber die
   Ladereihenfolge -- die Eintraege des aufgeklappten Seitennavigations-
   Untermenues verloren damit ihre eigenen 12px und erbten 13,3333px vom
   Dokument. Gemessen im vollen Stapel (1280x720, neues Design, beide
   Themes): 13.3333px mit dieser Regel, 12px nachdem sie per deleteRule
   entfernt war.
   ":where()" traegt keine Spezifitaet bei: die Regel faellt damit auf
   (0,1,1) und
     - schlaegt weiterhin die Basisregel ":where([data-design=new]) a"
       (0,0,1), deren "font-size: var(--ax-font-size-label-md)" sonst
       unbestritten traefe -- ohne diese Regel misst ".dropdown-content a"
       13px statt der geerbten 13.3333px (per deleteRule gemessen),
     - verliert jetzt gegen ".navbar2 .dropdown-content a" (0,2,1) und
       gegen ".wf-step-list-footer .dropdown-content a" (workfloweditor.css
       :459, auch (0,2,1), font-size 12px) -- bei letzterer bisher nur ueber
       die Ladereihenfolge (workfloweditor.css steht in aiprocesseditor.html
       :17 und aiprocessstepeditor.html:17 NACH components.css), jetzt
       unabhaengig davon. */
:where([data-design="new"]) .dropdown-content a {
  font-size: inherit;
}
/* Defekt (Abschlussreview): der vorherige Kommentar hier behauptete, WEDER
   .dropdown-content-small NOCH .navbar2 .dropdown-content deklariere
   font-family selbst -- falsch, beide tun es (webapp.css:6134/4999,
   "font-family: var(--txt)"), genau wie .dropdown-content a oben (webapp.css
   :5010), dessen font-family-Restaurierung deshalb schon vorher korrekt
   geloescht war ("font-family" fehlt in dessen Regel oben). Das hier
   verbliebene "font-family: inherit" ueberschrieb Legacys eigenen Wert also,
   statt ein echtes Leck zu stopfen -- entfernt, zur selben Behandlung wie
   .dropdown-content a. font-size war schon vorher korrekt entfernt (beide
   Klassen deklarieren es SELBST, 10px/12px, webapp.css:6136/5000) -- fuer
   diese beiden Klassen bleibt damit ueberhaupt keine Restaurierung noetig. */

/* --- Formulare -------------------------------------------------------------
   Figma 13:2 (Input Text), 13:26 (Textarea), 13:50 (Select), 234:38
   (Multi-select), 234:2395/234:2447 (Stepper Integer/Decimal), 235:2401
   (Secret). Sollwerte (Spec §6, gegen die eigene Extraktion geprueft):
   Feld 42px (--ax-size-field-md), Radius 10px (--ax-radius-md), Innenabstand
   0/8/0/12 (--ax-space-2/--ax-space-3), Flaeche bg/input, Rahmen 1px
   border/default, Wert text/primary.

   Betrifft laut Task atominputtext.js, atominputtextarea.js,
   atominputselection.js, atominputselectionmulti.js, atominputint.js,
   atominputfloat.js, atominputpasswordsecret.js -- alle rendern entweder ein
   <input type="text">, ein <textarea> oder ein <select> ohne eigene,
   unterscheidende Klasse. atominputint.js/atominputfloat.js (Stepper) und
   atominputpasswordsecret.js (Secret) sind darum zwangslaeufig in der
   input[type="text"]-Regel mitgemeint: es gibt kein Attribut, das sie von
   atominputtext.js trennen wuerde, ohne eine neue Klasse zu erfinden. */
:where([data-design="new"]) input[type="text"] {
  box-sizing: border-box;
  min-height: var(--ax-size-field-md);
  border-radius: var(--ax-radius-md);
  padding: 0 var(--ax-space-2) 0 var(--ax-space-3);
  background: var(--ax-bg-input);
  border: 1px solid var(--ax-border-default);
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-md);
  line-height: var(--ax-line-height-label-md);
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}

:where([data-design="new"]) select {
  box-sizing: border-box;
  min-height: var(--ax-size-field-md);
  border-radius: var(--ax-radius-md);
  padding: 0 var(--ax-space-2) 0 var(--ax-space-3);
  background: var(--ax-bg-input);
  border: 1px solid var(--ax-border-default);
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-md);
  line-height: var(--ax-line-height-label-md);
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}
/* select[multiple] (Input Multi-select, atominputselectionmulti.js) erbt
   dieselbe Regel. Figma 234:38 zeigt ausgewaehlte Werte als entfernbare
   Pillen (Frame "values" mit Chip-Kindern) -- das native Mehrfach-Listenfeld,
   das diese Klasse tatsaechlich rendert, kann das nicht darstellen (Zeilen,
   keine Chips) und bietet dafuer keinen CSS-Haken. Gestylt wird deshalb nur
   die Feldoptik (Rahmen/Radius/Flaeche/Farbe), nicht die Pillen-Darstellung
   -- siehe Report. */

/* RESCOPE: ".multiselect select" (webapp.css:7051, class+element, (0,1,1))
   deklariert min-height SELBST -- schlaegt die fixierte Basisregel (0,0,1)
   jetzt direkt und unabhaengig von der Ladereihenfolge, keine Restaurierung
   mehr noetig. (".multiselect" hat weiterhin keinen Erzeuger im Code --
   vorbestehender toter Code, unveraendert.) */

/* Review-Fund ("Important 6"): input[type="date"|"time"|"url"|"search"]
   (MoleculeLabelDate/Time/Url/Search, 32 Instanzen) werden von keiner Regel
   dieser Datei getroffen, obwohl ihr Label und der ".molecule"-Abstand
   (oben/unten) bereits umgestellt sind -- ein Formular zeigt dadurch
   Figma-Labels neben 5px-radius-Legacy-Feldern. Eigener Regelblock statt
   Erweiterung der input[type="text"]-Kommaliste oben, aus demselben Grund
   wie bei "select": der Unit-Test sucht deren exakten Selektortext. */
:where([data-design="new"]) input[type="date"],
:where([data-design="new"]) input[type="time"],
:where([data-design="new"]) input[type="url"],
:where([data-design="new"]) input[type="search"] {
  box-sizing: border-box;
  min-height: var(--ax-size-field-md);
  border-radius: var(--ax-radius-md);
  padding: 0 var(--ax-space-2) 0 var(--ax-space-3);
  background: var(--ax-bg-input);
  border: 1px solid var(--ax-border-default);
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-md);
  line-height: var(--ax-line-height-label-md);
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}
/* RESCOPE: MoleculeLabelSearch (und organismsllmproviderselector.js)
   wrappen ihr input[type="search"] zusaetzlich in ".search-input-wrapper"
   -- dessen eigene Regel (webapp.css:648, class+element+type-Attribut,
   (0,2,1)) reserviert 32px rechten Innenabstand fuer den nativen
   Clear-Button. Seit :where() auch auf der input[type=...]-Basisregel liegt
   (Header-Kommentar), ist diese jetzt bei (0,1,1) -- ".search-input-wrapper
   input[type=search]" (0,2,1) schlaegt sie direkt, keine Restaurierung mehr
   noetig. */

/* Textarea braucht eine eigene Regel: webapp.css:697-712 zwingt <textarea>
   sonst auf eine feste Hoehe von 200px (min 80px/max 400px). Eine bloss
   ERGAENZTE min-height wuerde daran nichts aendern -- 200px ist groesser und
   gewinnt gegen jede min-height unterhalb von 200px --, darum werden
   height/min-height/max-height hier explizit neu gesetzt statt nur ergaenzt.
   104px ist Figmas gemessene Feldhoehe (Frame 13:28); dafuer existiert kein
   --ax-Token (nur Fuellungen/Rahmen sind in dieser Datei an Variablen
   gebunden, keine Rahmenmasse), deshalb steht hier der literale Messwert --
   genau wie Buttons Hoehe 36px in Task 2. Innenabstand oben ist 12px statt
   0, weil der Wert in Figma mehrzeilig beginnt (padding [12,8,0,12]). */
:where([data-design="new"]) textarea {
  box-sizing: border-box;
  height: auto;
  min-height: 104px;
  max-height: none;
  border-radius: var(--ax-radius-md);
  padding: var(--ax-space-3) var(--ax-space-2) 0 var(--ax-space-3);
  background: var(--ax-bg-input);
  border: 1px solid var(--ax-border-default);
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-md);
  line-height: var(--ax-line-height-label-md);
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}

/* RESCOPE: ".upload-text-view textarea" (webapp.css:4155, class+element,
   (0,1,1)) deklariert min-height/max-height/background/color/border/
   border-radius/padding/font-size/line-height SELBST -- schlagen die
   fixierte Basisregel (0,0,1) jetzt direkt, alle neun sind entfernt.
   Bleiben stehen: "height" und "font-family" -- ".upload-text-view textarea"
   deklariert KEINS von beiden selbst, erbte sie unter Legacy vom UNSCOPED
   "textarea{}" (webapp.css:697, height:200px/font-family:var(--btxt,...),
   (0,0,1)). Diese unscoped Regel TIED jetzt mit der fixierten Basisregel
   (ebenfalls (0,0,1)) -- :where() aendert an einem Gleichstand nichts, und
   die Ladereihenfolge (webapp.css zuerst) verliert dabei fuer beide
   Eigenschaften. "height" explizit auf 200px zurueckgesetzt (kein
   --ax-Token fuer diesen literalen Legacy-Wert), "font-family" auf
   "inherit" (das schreibgeschuetzte Vorschaufeld hatte nie eine eigene
   Schriftregel). */
[data-design="new"] .upload-text-view textarea {
  height: 200px;
  font-family: inherit;
}

:where([data-design="new"]) input[type="text"]:hover:not(:disabled),
:where([data-design="new"]) textarea:hover:not(:disabled),
:where([data-design="new"]) select:hover:not(:disabled),
:where([data-design="new"]) input[type="date"]:hover:not(:disabled),
:where([data-design="new"]) input[type="time"]:hover:not(:disabled),
:where([data-design="new"]) input[type="url"]:hover:not(:disabled),
:where([data-design="new"]) input[type="search"]:hover:not(:disabled) {
  border-color: var(--ax-border-strong);
}

/* Fokus ist doppelt (Spec §5/§6): Rahmenfarbe UND Fokusring, nicht nur eines
   von beiden. Die eigene Extraktion (13:8/13:34/13:58/234:2412/235:2419,
   jeweils strokeWeight 2) bindet die Fokus-Rahmenfarbe an action/primary,
   NICHT an border/accent wie im Taskbrief vorgemessen -- vom Spec-Owner
   bestaetigt (der Knoten selbst bindet an action/primary, obwohl Figmas
   eigene DOC-Tabelle border/accent nennt) -- der Spec wird entsprechend
   korrigiert. border-width wechselt auf 2px, wie tatsaechlich gemessen
   (strokeWeight 2 gegenueber 1 im Ruhezustand). Damit das keine
   Layoutverschiebung ausloest (Spec §5 verbietet das fuer Hover, hier
   konsistent auf Fokus erweitert), tragen alle drei Basisregeln oben
   box-sizing: border-box -- die dickere Umrandung waechst dadurch nach
   INNEN in den Innenabstand, die Aussenmasse (min-height/width) bleiben
   fix. */
:where([data-design="new"]) input[type="text"]:focus-visible,
:where([data-design="new"]) textarea:focus-visible,
:where([data-design="new"]) select:focus-visible,
:where([data-design="new"]) input[type="date"]:focus-visible,
:where([data-design="new"]) input[type="time"]:focus-visible,
:where([data-design="new"]) input[type="url"]:focus-visible,
:where([data-design="new"]) input[type="search"]:focus-visible {
  border-width: 2px;
  border-color: var(--ax-action-primary);
  box-shadow: var(--ax-focus-ring);
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: none;
}

:where([data-design="new"]) input[type="text"]:disabled,
:where([data-design="new"]) textarea:disabled,
:where([data-design="new"]) select:disabled,
:where([data-design="new"]) input[type="date"]:disabled,
:where([data-design="new"]) input[type="time"]:disabled,
:where([data-design="new"]) input[type="url"]:disabled,
:where([data-design="new"]) input[type="search"]:disabled {
  opacity: .5;
  cursor: default;
}

/* AtomInputPasswordSecret (Input Secret) rendert einen Wrapper-Container
   (.password-field) als sein "gerendertes Element", nicht das innere
   <input> selbst (renderUi() ruft setRenderedElement(wrapper) auf) --
   disable() setzt darum .disabled auf dem WRAPPER, nicht :disabled auf dem
   <input>. Gleiches Grundmuster wie a.disabled oben, nur mit anderer
   struktureller Ursache (Wrapper statt fehlendem :disabled auf <a>).
   Dieselbe Kollision wie bei a.disabled: ElementVisibility.disable() haengt
   IMMER auch die Klasse "disabled" an, und das unscoped webapp.css:1283
   (".disabled { color: ...; background-color: var(--clr-surface-3); }")
   traefe den Wrapper -- der selbst KEINE eigene Flaeche/Textfarbe hat (weder
   in webapp.css noch hier), es gibt also keine hoeher-spezifische Regel, die
   dagegenhaelt. Ohne den Reset bekaeme das Secret-Feld im Disabled-Zustand
   einen sichtbaren grauen Kasten hinter Eingabefeld und Buttons, den Figma
   nicht kennt (der Wrapper ist nur Layout, keine Flaeche). color: inherit
   ist defensiv (kein Text sitzt direkt im Wrapper, alle Kinder haben eigene
   Farbregeln), background: none behebt den tatsaechlich sichtbaren Fehler. */
[data-design="new"] .password-field.disabled {
  opacity: .5;
  cursor: default;
  background: none;
  color: inherit;
}

/* Feldlabel (Spec §6: Label text/secondary) -- lebt an <label>
   (AtomDisplayLabel), das nur die MoleculeLabel*-Klassen ueberhaupt
   rendern (MoleculeLabelInput, MoleculeLabelTextArea, MoleculeLabelSelection,
   MoleculeLabelPasswordSecret u.a.); keins der sieben oben gestylten Atome
   rendert selbst ein Label. Jede Molecule-Instanz ohne eigene Klasse
   bekommt automatisch class="molecule" (molecule.js renderUi()), das Label
   ist ihr direktes Kind -- ".molecule > label" trifft deshalb JEDES
   Feldlabel im neuen Design, nicht nur die sieben Formularfelder dieses
   Tasks. Das betrifft auch Checkbox/Radio/Toggle (Task 4), die laut Plan
   denselben Token (text/secondary) fuer ihr Label vorsehen -- diese Regel
   deckt das vorab mit ab, ohne Anspruch, fuer Task 4 vollstaendig zu sein
   (Groesse/Gewicht dort ungeprueft). Werte direkt aus Figma 13:3 gelesen
   (fontSize 12, Inter Medium/500, lineHeight 16px) -- der Knoten traegt
   einen benannten Textstil, daher wurden fontSize/fontName/lineHeight
   gezielt einzeln abgefragt statt aus der Style-Referenz geraten.

   webapp.css:5497 (".molecule > label", UNSCOPED) setzt SECHS Eigenschaften,
   nicht nur die urspruenglich hier uebernommenen vier -- text-transform:
   uppercase und letter-spacing: 0.06em fehlten und liessen jedes Feldlabel
   im neuen Design in Grossbuchstaben mit altem Zeichenabstand rendern,
   obwohl Figma 13:3 weder das eine noch das andere zeigt. Beide jetzt
   explizit zurueckgesetzt.

   :not(.color-picker-molecule) ist noetig, weil webapp.css:11655
   (".molecule.color-picker-molecule > label") mit derselben Spezifitaet
   (0,2,1 wie hier) eine EIGENE, bereits fein abgestimmte Label-Optik traegt
   (0.85rem, text/primary, text-transform:none, eigenes margin) -- bei
   gleicher Spezifitaet gewinnt die Ladereihenfolge (components.css NACH
   webapp.css), meine Regel haette also ihre bewusst andere Gestaltung
   ueberschrieben. Gefunden nicht durch Vermutung, sondern durch Lesen jeder
   ".molecule"-Fundstelle in webapp.css (siehe Report-Tabelle). */
[data-design="new"] .molecule:not(.color-picker-molecule) > label {
  color: var(--ax-text-secondary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-sm);
  line-height: var(--ax-line-height-label-sm);
  font-weight: 500;
  text-transform: none;
  letter-spacing: normal;
}

/* Abstand Label <-> Feld (Spec §6: 8px, --ax-space-2). webapp.css:5490
   (".molecule", UNSCOPED) setzt gap: 5px -- ohne diese Regel bliebe der
   Abstand bei 5px statt der gemessenen 8px. Gleiche Ausnahme wie oben:
   .molecule.color-picker-molecule (webapp.css:11645) ist ein CSS-Grid
   (display: grid, mit dem wichtig-Flag erzwungen) mit eigenen row-gap/column-gap-Werten
   (0.25rem/0.75rem) -- gap ist Kurzform fuer beide zugleich und haette sie
   bei gleicher Spezifitaet (0,2,0 hier wie dort) und spaeterer Ladereihen-
   folge ueberschrieben. */
[data-design="new"] .molecule:not(.color-picker-molecule) {
  gap: var(--ax-space-2);
}

/* Pflichtstern (Spec §6: status/danger) bekommt bewusst KEINE eigene Regel:
   setRequired() (MoleculeLabelInput etc.) haengt "*" per
   setText(this.text + "*") direkt an denselben Textknoten wie das
   Label-Wort an -- es gibt kein eigenes Element, dem CSS eine andere Farbe
   geben koennte. Der Stern erbt deshalb die Label-Farbe (text/secondary),
   nicht status/danger -- dokumentierte Produktionsluecke, siehe Report. */

/* Error (Spec §6: "Label wechselt auf status/danger, Feldrahmen auf
   status/danger") wird hier bewusst NICHT als CSS-Regel umgesetzt:
   AtomInput.setError() -- die Basisklasse aller sieben betroffenen Atome --
   ruft markAsError() auf, die den Rahmen per INLINE style.borderColor =
   'red' faerbt, nicht per Klasse oder Attribut. Es gibt keinen
   CSS-adressierbaren Haken, und keine hier stehende Regel koennte eine
   Inline-Style ueberschreiben, ohne das verbotene "important"-Flag zu
   nutzen. Eine neue Klasse dafuer zu erfinden waere eine Aenderung an einem
   produktiven Validierungspfad und braucht eine eigene Rechtfertigung,
   nicht diesen CSS-Task -- siehe Report. Die Galerie zeigt den Zustand
   trotzdem so weit wie moeglich: sie ruft das echte setError() auf und
   zeigt damit exakt den (roten, nicht token-basierten) Rahmen, den die
   Produktion heute liefert -- fuer AtomInputPasswordSecret sogar sichtbar
   UNWIRKSAM, weil markAsError() dort den Wrapper statt des <input> faerbt
   (derselbe Wrapper-Grund wie beim Disabled-Zustand oben) -- ein
   vorbestehender Produktbug, siehe Report. */

@media (prefers-reduced-motion: reduce) {
  :where([data-design="new"]) input[type="text"],
  :where([data-design="new"]) textarea,
  :where([data-design="new"]) select,
  :where([data-design="new"]) input[type="date"],
  :where([data-design="new"]) input[type="time"],
  :where([data-design="new"]) input[type="url"],
  :where([data-design="new"]) input[type="search"] {
    transition: border-color 120ms ease-out;
  }
}

/* --- Auswahl: Checkbox, Radio, Toggle ---------------------------------
   Figma 17:19/22/26/30 (Checkbox: Unchecked/Checked/Indeterminate/Disabled),
   38:63/66/70 (Radio: Unselected/Selected/Disabled), 17:2/6/10/14 (Toggle:
   On-Default/On-Disabled/Off-Default/Off-Disabled). Box/Track 18x18 (Radius
   6, --ax-radius-sm) bzw. 40x22 (Radius 999, --ax-radius-full).

   AtomInputCheckbox (atominputcheckbox.js) setzt im Konstruktor IMMER
   setCssClass("switch") -- es gibt in der heutigen Produktion KEINEN
   Aufrufer, der diese Klasse wieder entfernt (organismsbulkactiontoolbar.js,
   moleculelabelcheckbox.js und alle uebrigen Fundstellen konstruieren die
   Klasse unveraendert). webapp.css:906-1013 (":not(.switch)" vs. ".switch")
   belegt trotzdem, dass beide Erscheinungsbilder produktiv gemeint sind --
   nur eben ueber verschiedene, teils ungenutzte Codepfade (CheckBoxFactory
   in frontend/js/ui/helper/, fuer neuen Code laut CLAUDE.md tabu, erzeugt
   :not(.switch) direkt). Die Galerie-Kacheln fuer "Checkbox" entfernen die
   Klasse deshalb nach dem Rendern direkt am DOM-Element
   (element.classList.remove("switch")) -- NICHT ueber
   Atom.setCssClass(""), das dabei folgenlos bliebe: setCssClassToElement()
   ueberspringt die Zuweisung genau fuer den leeren String
   (webapp.css-analoger Guard in atom.js, siehe designgallerypage.js-
   Kommentar an setupAuswahlGroup() und Report). AtomButtonToggle
   (atombuttontoggle.js) wird NICHT verwendet: es ist ein Auf-/Zuklapp-Text-
   button ("📄 Label ▸"), keine Ein/Aus-Weiche -- der Name traf zufaellig,
   nicht die Komponente. Siehe Report.

   AtomInputRadio (atominputradio.js) setzt gar keine eigene Klasse und
   erbt darum NICHTS aus webapp.css' ".checkbox-container input[type=
   checkbox]"-System (das ist strikt auf [type=checkbox] verengt) -- jede
   Eigenschaft in der Radio-Regel unten ist deshalb eine Neuanlage, keine
   Ueberschreibung (siehe Report-Tabelle: Radio hat kein Legacy-Gegenstueck,
   nicht einmal -webkit-appearance:none). */

/* Checkbox — :not(.switch). Unchecked/Disabled: Flaeche bg/input, Rahmen
   1px border/strong (siehe eigene Extraktion; Figmas DOC-Tabelle in Spec §5
   nennt fuer Hover denselben Token -- am Ruhezustand deckungsgleich, siehe
   Report). appearance/cursor/position/margin/outline erbt weiterhin aus
   webapp.css:906-920 (unveraendert richtig, keine eigene Regel noetig). */
[data-design="new"] .checkbox-container input[type="checkbox"]:not(.switch) {
  box-sizing: border-box;
  width: 18px;
  height: 18px;
  border-radius: var(--ax-radius-sm);
  background: var(--ax-bg-input);
  border: 1px solid var(--ax-border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 120ms ease-out, border-color 120ms ease-out,
    box-shadow 120ms ease-out, transform 120ms ease-out;
}

/* Checked: Flaeche action/primary, KEIN Rahmen (Figma-Knoten 17:23 liefert
   stroke:null) -- border-color wird auf denselben Ton wie die Flaeche
   gelegt statt auf "none", damit box-sizing:border-box die Aussenmasse
   (18x18) exakt haelt (dieselbe Begruendung wie beim Fokus-Rahmen der
   Formularfelder, Task 3). Der Haken ist Figmas eigener Textknoten "✓"
   (17:24, direkt gelesen statt geschaetzt: Inter Medium 12/16 ==
   --ax-font-size-label-sm/--ax-line-height-label-sm), keine Border-Trick-
   Nachbildung. webapp.css' eigener Border-Trick-Haken (":not(.switch):after",
   width 5px/height 9px/border 2px solid/transform rotate(43deg)) haengt am
   SELBEN Pseudoelement und muss deshalb vollstaendig zurueckgesetzt werden
   (position/width/height/border/transform) -- sonst rendert Legacys
   L-foermiger Rahmen-Haken HINTER meinem Text-Haken durch (siehe
   Report-Tabelle). position:static ersetzt Legacys position:absolute,
   weil hier stattdessen ueber die Flex-Zentrierung der Box zentriert wird. */
[data-design="new"] .checkbox-container input[type="checkbox"]:not(.switch):checked {
  background: var(--ax-action-primary);
  border-color: var(--ax-action-primary);
}
[data-design="new"] .checkbox-container input[type="checkbox"]:not(.switch):checked:after {
  content: "\2713";
  position: static;
  width: auto;
  height: auto;
  border: none;
  transform: none;
  opacity: 1;
  transition: none;
  color: var(--ax-action-on-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-sm);
  line-height: var(--ax-line-height-label-sm);
  font-weight: 500;
}

/* Indeterminate: dieselbe Flaeche wie Checked, aber ein Balken (Figma-
   Rectangle 17:28: 9x2, Radius 1) statt des Hakens -- eigener Zustand,
   kein Legacy-Gegenstueck (webapp.css kennt :indeterminate nirgends,
   siehe Report), dieselben Legacy-Basiseigenschaften am :after (s.o.)
   muessen trotzdem zurueckgesetzt werden, weil sie unbedingt (nicht an
   :checked gebunden) auf JEDES :after dieses Inputs wirken. */
[data-design="new"] .checkbox-container input[type="checkbox"]:not(.switch):indeterminate {
  background: var(--ax-action-primary);
  border-color: var(--ax-action-primary);
}
[data-design="new"] .checkbox-container input[type="checkbox"]:not(.switch):indeterminate:after {
  content: "";
  position: static;
  width: 9px;
  height: 2px;
  border: none;
  border-radius: 1px;
  transform: none;
  opacity: 1;
  transition: none;
  background: var(--ax-action-on-primary);
}

/* Radio — Figma "outer" 18x18, Radius 999 (--ax-radius-full). Unselected/
   Disabled: Flaeche bg/input, Rahmen 1px border/strong -- optisch identisch
   mit Checkbox im Ruhezustand. Selected (38:67): Flaeche BLEIBT bg/input
   (nicht gefuellt!), Rahmen verdoppelt auf 2px action/primary, zusaetzlich
   ein gefuellter Innenpunkt (38:68: Ellipse 8x8, Radius 50%, action/primary).
   Keine Eigenschaft hier ist eine Ueberschreibung -- atominputradio.js setzt
   keine eigene Klasse, webapp.css hat keine [type=radio]-Regel unter
   .checkbox-container (siehe Report), daher volle Neuanlage inkl.
   appearance:none (fehlt bei Radio komplett, anders als bei Checkbox/
   Toggle, die es aus der [type=checkbox]-Basisregel erben). */
[data-design="new"] .checkbox-container input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  box-sizing: border-box;
  width: 18px;
  height: 18px;
  margin: 0;
  cursor: pointer;
  vertical-align: top;
  border-radius: var(--ax-radius-full);
  background: var(--ax-bg-input);
  border: 1px solid var(--ax-border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 120ms ease-out, border-color 120ms ease-out,
    box-shadow 120ms ease-out, transform 120ms ease-out;
}
[data-design="new"] .checkbox-container input[type="radio"]:checked {
  border: 2px solid var(--ax-action-primary);
}
[data-design="new"] .checkbox-container input[type="radio"]:checked:after {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ax-action-primary);
}

/* Toggle — dieselbe Atom-Klasse wie Checkbox (AtomInputCheckbox), aber MIT
   der vom Konstruktor immer gesetzten Klasse "switch" -- der einzige heute
   ueber diesen Atom produktiv erreichbare Zustand (siehe Report). Track
   40x22 (Figma 17:3), Radius 999 (--ax-radius-full), kein Rahmen (stroke:
   null). Aus 17:3 Padding [0,3,0,3]: Knob 16x16 sitzt 3px vom Rand, die
   Verschiebung beim Einschalten ist deshalb 40-16-3-3=18px -- errechnet aus
   Figmas eigenen Massen, nicht geschaetzt. Knob-Farbe text/on-accent
   (17:4/17:8/17:12/17:16, in ALLEN vier Zustaenden identisch). */
[data-design="new"] .checkbox-container input[type="checkbox"].switch {
  box-sizing: border-box;
  width: 40px;
  height: 22px;
  border-radius: var(--ax-radius-full);
  background: var(--ax-text-muted);
  border: none;
  transition: background-color 120ms ease-out, filter 120ms ease-out;
}
[data-design="new"] .checkbox-container input[type="checkbox"].switch:checked {
  background: var(--ax-action-primary);
}
/* Knob. Legacys eigener ".switch:after" (left:2px/top:2px/width:17/height:17/
   background:var(--ab,var(--border))/transform:translateX(var(--x,0))) haengt
   am selben Pseudoelement -- jede hier nicht genannte Eigenschaft (border-
   radius:50%, position:absolute, display:block) bleibt bewusst uebernommen,
   weil sie mit Figma uebereinstimmt; alle Mass- und Farbwerte werden voll
   ersetzt (siehe Report-Tabelle). */
[data-design="new"] .checkbox-container input[type="checkbox"].switch:after {
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  background: var(--ax-text-on-accent);
  transform: translateX(0);
  transition: transform 120ms ease-out;
}
[data-design="new"] .checkbox-container input[type="checkbox"].switch:checked:after {
  transform: translateX(18px);
}
/* webapp.css:1011 daempft den Knob im Zustand disabled+unchecked zusaetzlich
   auf opacity 0.6 (":not(.switch)" im dortigen Selektor bezieht sich auf
   :checked, nicht auf die Eingabe-Klasse) -- das wuerde den Aus-Zustand
   staerker abdunkeln als den An-Zustand, obwohl Figma (17:14 vs. 17:6)
   dafuer keinen Unterschied zeigt (Disabled daempft laut Spec §5 immer das
   GANZE Bauteil einheitlich um 50%, siehe Regel weiter unten). Selbe
   Selektorform wie Legacy, um dessen Spezifitaet sicher zu schlagen. */
[data-design="new"] .checkbox-container input[type="checkbox"].switch:disabled:not(:checked):after {
  opacity: 1;
}

/* Hover: Rahmen -> border/strong (Checkbox/Radio, Spec §5-Tabelle) bzw.
   Track um 6% aufgehellt (Toggle, "hellt 6% auf" -- ein woertlicher
   Filter-Aufhellungswert, kein benannter Hover-Token wie bei Button, siehe
   Report). :not(:checked):not(:indeterminate) ist noetig, weil Checked/
   Indeterminate keinen sichtbaren Rahmen haben (border-color == Flaeche,
   s.o.) -- ein Hover-Rahmen in border/strong waere dort ein Figma-fremder
   Ring. */
[data-design="new"] .checkbox-container input[type="checkbox"]:not(.switch):hover:not(:checked):not(:indeterminate):not(:disabled),
[data-design="new"] .checkbox-container input[type="radio"]:hover:not(:checked):not(:disabled) {
  border-color: var(--ax-border-strong);
}
[data-design="new"] .checkbox-container input[type="checkbox"].switch:hover:not(:disabled) {
  filter: brightness(1.06);
}

/* Pressed: Box/Aussenring skaliert 0,94 (Checkbox/Radio), Knob skaliert 0,92
   (Toggle) -- Transform sitzt auf dem Knob-Pseudoelement, nicht auf dem
   Track selbst, deshalb die eigene :checked-Kombination (translateX UND
   scale zusammen, sonst wuerde die zweite Regel die Verschiebung der
   ersten verwerfen). */
[data-design="new"] .checkbox-container input[type="checkbox"]:not(.switch):active:not(:disabled),
[data-design="new"] .checkbox-container input[type="radio"]:active:not(:disabled) {
  transform: scale(.94);
}
[data-design="new"] .checkbox-container input[type="checkbox"].switch:active:not(:disabled):after {
  transform: translateX(0) scale(.92);
}
[data-design="new"] .checkbox-container input[type="checkbox"].switch:checked:active:not(:disabled):after {
  transform: translateX(18px) scale(.92);
}

/* Fokus auf der Box/dem Track, NICHT auf dem Label (Spec §5: "Focus-Ring
   auf der Box, nicht dem Label" bzw. "auf dem Track") -- <label> ist nicht
   fokussierbar (kein tabindex, kein natives Formularelement), nur das
   <input> selbst kann den Fokus wirklich halten; die Regel unten braucht
   daher keinen Kunstgriff, sie sitzt einfach auf dem <input>, wie jede
   Interaktion es ohnehin erzwingt. Deckt Checkbox, Radio UND Toggle in
   einer Regel ab (dasselbe <input>, ob mit oder ohne .switch).
   webapp.css:959 setzt zusaetzlich ein UNBEDINGTES ".checkbox-container
   input[type=checkbox]:focus { box-shadow: 0 0 0 var(--focus); }" (nicht an
   :focus-visible gebunden) -- ohne Gegenregel bliebe der Ring auch bei
   Maus-Fokus sichtbar, obwiel der Verbindliche-Interaktionsregeln-Tabelle
   (Spec §5) ausdruecklich das Gegenteil verlangt ("damit er beim Mausklick
   ausbleibt"). Deshalb der explizite Reset direkt darunter. */
[data-design="new"] .checkbox-container input[type="checkbox"]:focus-visible,
[data-design="new"] .checkbox-container input[type="radio"]:focus-visible {
  box-shadow: var(--ax-focus-ring);
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: none;
}
[data-design="new"] .checkbox-container input[type="checkbox"]:focus:not(:focus-visible),
[data-design="new"] .checkbox-container input[type="radio"]:focus:not(:focus-visible) {
  box-shadow: none;
}

/* Disabled: Deckkraft 50% fuer das GANZE Bauteil (Box/Track UND Label
   zusammen, Spec §5), nicht nur das <input> -- Box und Label sind
   Geschwister, kein Eltern-Kind-Verhaeltnis, ein opacity nur auf dem
   <input> liesse das Label hell und den Rest dunkel zurueck. :has() traegt
   bereits an anderer Stelle in diesem Codebasis-Zweig (webapp.css:11910,
   ebenfalls im Checkbox-Kontext), kein neues Werkzeug. Das <input> selbst
   bekommt zusaetzlich opacity:1/cursor:default zurueck, weil webapp.css:944
   dafuer bereits opacity:0.9/cursor:not-allowed setzt (unbedingt, jeder
   Deckkraft-Wert dort wuerde sich mit der Container-Deckkraft hier
   MULTIPLIZIEREN und das Element staerker daempfen als Figma zeigt); ebenso
   fuer das Label (webapp.css:953: cursor:not-allowed, nur fuer [type=
   checkbox] -- hier zusaetzlich fuer [type=radio], wo Legacy nichts setzt).

   Eine weitere unscoped Legacy-Regel trifft dieselben Elemente, ist aber
   NICHT ueberschrieben, weil sie bereits wirkungslos ist:
   webapp.css:1278 ("input:disabled { color: var(--font-color-disabled);
   background-color: var(--background-color-disabled); }", ohne jede
   Klassen-/Typ-Einschraenkung -- trifft JEDES disabled <input> im
   Dokument, auch dieses hier). background-color verliert unbedingt gegen
   die obige :not(.switch)/.switch/[type=radio]-Grundregel (background:
   var(--ax-bg-input) bzw. var(--ax-text-muted)/var(--ax-action-primary)),
   die bei jeder Spezifitaet hoeher liegt (mindestens (0,4,1) gegen
   webapp.css:1278s (0,1,1)) -- kein Override noetig, es gibt nichts zu
   gewinnen. color hat auf einem <input type="checkbox"|"radio"> ohne
   Textinhalt keinen sichtbaren Trager: der Haken/Punkt/Balken faerbt sich
   ueber die eigene, explizit gesetzte color-Regel am ::after (siehe oben),
   nicht per Vererbung vom <input>. Aufgenommen, damit diese Tabelle
   vollstaendig bleibt, nicht nur ueberschriebene Regeln zeigt. */
[data-design="new"] .checkbox-container:has(input:disabled) {
  opacity: .5;
  cursor: default;
}
[data-design="new"] .checkbox-container input[type="checkbox"]:disabled,
[data-design="new"] .checkbox-container input[type="radio"]:disabled {
  opacity: 1;
  cursor: default;
}
[data-design="new"] .checkbox-container input[type="checkbox"]:disabled + label,
[data-design="new"] .checkbox-container input[type="radio"]:disabled + label {
  cursor: default;
}

/* Label — Figma-Textknoten der Checkbox/Radio/Toggle-Beispiele direkt
   gelesen (17:21/38:65/17:5: Inter Regular 13/20 == --ax-font-size-body-sm/
   --ax-line-height-body-sm), nicht aus "styled" geraten. ".molecule > label"
   (weiter oben, Task 3) trifft hier NICHT: das Label haengt zwei Ebenen
   unter .molecule (molecule > .checkbox-container > label), nicht direkt
   darunter -- eigene Regel noetig (siehe Report, das war eine falsche
   Annahme im Task-3-Report). webapp.css:971 setzt bereits display:inline-
   block/vertical-align:middle/cursor:pointer/margin-left:4px, aber NUR fuer
   "input[type=checkbox] + label" (Radio bleibt dabei ganz ohne Abstand) --
   display/vertical-align/cursor werden unveraendert uebernommen (stimmen
   bereits), margin-left wird auf Figmas 8px (Checkbox/Radio) bzw. 12px
   (Toggle) korrigiert, fuer beide Eingabetypen. */
[data-design="new"] .checkbox-container input[type="checkbox"] + label,
[data-design="new"] .checkbox-container input[type="radio"] + label {
  margin-left: var(--ax-space-2);
  color: var(--ax-text-secondary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-body-sm);
  line-height: var(--ax-line-height-body-sm);
  font-weight: 400;
}
[data-design="new"] .checkbox-container input[type="checkbox"].switch + label {
  margin-left: var(--ax-space-3);
}

@media (prefers-reduced-motion: reduce) {
  /* Skalierung entfaellt vollstaendig (nicht nur unanimiert) -- Checkbox/
     Radio haben keine semantische Bedeutung in ihrer Groesse, der Press-
     Effekt ist rein dekorativ und faellt komplett weg. */
  [data-design="new"] .checkbox-container input[type="checkbox"]:not(.switch),
  [data-design="new"] .checkbox-container input[type="radio"] {
    transition: background-color 120ms ease-out, border-color 120ms ease-out,
      box-shadow 120ms ease-out;
  }
  [data-design="new"] .checkbox-container input[type="checkbox"]:not(.switch):active:not(:disabled),
  [data-design="new"] .checkbox-container input[type="radio"]:active:not(:disabled) {
    transform: none;
  }
  /* Der Knob-Rutsch (translateX) bleibt -- er traegt den An/Aus-Zustand,
     ist keine blosse Verzierung; nur die Stauchung beim Druecken (scale)
     entfaellt, und der Uebergang wird unanimiert (sofortiger Sprung statt
     Rutschen), was Bewegungsreduktion ebenfalls verlangt. */
  [data-design="new"] .checkbox-container input[type="checkbox"].switch:after {
    transition: none;
  }
  [data-design="new"] .checkbox-container input[type="checkbox"].switch:active:not(:disabled):after {
    transform: translateX(0);
  }
  [data-design="new"] .checkbox-container input[type="checkbox"].switch:checked:active:not(:disabled):after {
    transform: translateX(18px);
  }
}

/* ── Dateien: File Upload, File List, Image Upload ───────────────────────
   Figma 125:75/79/83/92/99 (File Upload, State=Idle/Hover/Uploading/
   Success/Error), 235:2363 (Input / File list), 235:38/52/69 (Input Image
   upload, State=Empty/Filled/Error). Betroffene Klassen: atominputfile.js,
   atominputfilelist.js, atominputfileuploadbuttonlabel.js,
   atominputimageuploadbuttonlabel.js, moleculefiledropzoneselection.js. */

/* File Upload (Dropzone) -- MoleculeFileDropZoneSelection, Markup
   .upload-dropzone > (img.upload-dropzone-icon, h4, p). Nur Idle und Hover
   sind aus dem Produktivcode erreichbar (siehe Report):
   - Hover ist eine ECHTE CSS-Pseudoklasse (webapp.css:4104 setzt bereits
     .upload-dropzone:hover) -- wie bei Formularfeldern/Checkbox (Task 3/4)
     wird sie darum NICHT als eigene Galerie-Kachel gezeigt, sondern live
     per page.hover() gegen die Idle-Kachel geprueft.
   - Uploading (Fortschrittsbalken+Prozentzahl IN der Zone) und Success
     (Dateizeile+Haken IN der Zone) haben in MoleculeFileDropZoneSelection
     keinerlei Entsprechung: es gibt weder Fortschritts- noch
     Erfolgs-Markup im Klassenkoerper. Error ist ebenfalls nicht dauerhaft
     darstellbar -- Groessen-/Anzahlfehler (_showMaxFilesExceeded,
     _filterOversizedFiles) zeigen einen ErrorMsg-Dialog (Overlay), keinen
     anhaltenden CSS-Zustand der Dropzone selbst. Alle drei werden darum
     NICHT gebaut, siehe Report. */
[data-design="new"] .upload-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--ax-space-3);
  padding: var(--ax-space-5);
  border: 1px dashed var(--ax-border-default);
  border-radius: var(--ax-radius-lg);
  background: var(--ax-bg-input);
  cursor: pointer;
  box-sizing: border-box;
  transition: border-color 120ms ease-out, background-color 120ms ease-out;
  text-align: center;
}
/* Hover (Figma 125:79): Rahmen verdoppelt sich auf 2px border/accent,
   Flaeche wechselt auf bg/hover -- box-sizing: border-box (oben) haelt die
   Aussenmasse fest, damit der dickere Rahmen kein Layout verschiebt. */
[data-design="new"] .upload-dropzone:hover {
  border-width: 2px;
  border-color: var(--ax-border-accent);
  background: var(--ax-bg-hover);
}
[data-design="new"] .upload-dropzone h4 {
  margin: 0;
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-body-md);
  line-height: var(--ax-line-height-body-md);
  font-weight: 600;
}
[data-design="new"] .upload-dropzone p {
  margin: 0;
  color: var(--ax-text-muted);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-sm);
  line-height: var(--ax-line-height-label-sm);
  font-weight: 500;
}
/* Kein eigenes Icon-Groessen-Update: Figmas Vektor (125:76) misst 36x26 --
   nicht quadratisch. Das vorhandene upload.svg hat ein quadratisches
   viewBox (0 -960 960 960); es auf 36x26 zu zwingen wuerde es verzerren,
   ein neues, nicht-quadratisches Icon-Asset ist fuer eine reine
   CSS-Aufgabe ausser Reichweite. .upload-dropzone-icon bleibt darum bei
   Legacy-Groesse/-Deckkraft (48x48, opacity .6). */

/* File List -- Figma "Input / File list" (235:2363). Produktivcode hat
   keine eigene Listen-Komponente mit Icon/Groesse/Einzel-Entfernen je
   Datei; die einzige echte "Dateien ausgewaehlt"-Anzeige ist
   MoleculeFileDropZoneSelections eigener .upload-file-list-Bereich (Modus
   "files"), befuellt mit einem <span> je Datei (nur Dateiname, siehe
   addEvents() in moleculefiledropzoneselection.js). Die Flaechen-/Rahmen-/
   Schrifttokens von Figmas Dateizeile (235:2374) werden auf dieses
   tatsaechlich vorhandene <span> uebertragen; Icon, Dateigroesse und
   Einzel-Entfernen-Button existieren im Markup nicht und werden nicht
   nachgebaut. Der umschliessende .upload-file-list bleibt unveraendert
   (Zeilenumbruch-Layout aus mehreren Pillen, 8px Abstand) -- Figmas
   "files"-Stapel-Container (235:2373) hat einen abweichenden Abstand (6px,
   fuer eine EINSPALTIGE Liste), der auf ein umbrechendes Pillen-Layout
   nicht 1:1 uebertragbar ist; eine erfundene Naeherung waere hier
   schlechter als der unveraenderte Legacy-Wert. */
[data-design="new"] .upload-file-list span {
  border-radius: var(--ax-radius-md);
  background: var(--ax-bg-input);
  border: 1px solid var(--ax-border-soft);
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-body-sm);
  line-height: var(--ax-line-height-body-sm);
  font-weight: 400;
  padding: 8px 8px 8px 10px;
}

/* Image Upload -- Figma "Input Image upload" (235:38/52/69). Betroffene
   Klasse atominputimageuploadbuttonlabel.js, produktiv verdrahtet ueber
   MoleculeLabelImageUpload (Label + Ausloeser + Vorschau + Entfernen-
   Button). Figmas Aufbau (ein 42px hohes Feld mit eingebettetem
   28x28-Vorschau-Feld und Dateiname-Text in EINER Zeile) hat keine
   Entsprechung: die Vorschau (.preview-image-container/.preview-image,
   120x120, rund, webapp.css:3176) liegt separat unter dem Ausloeser, zeigt
   kein Dateiname-Text-Element, und wird zusammen mit
   moleculefiledropzoneselections eigener Bild-Vorschau UND jeder anderen
   Verwendung von AtomContainerPreviewImage/AtomDisplayImagePreview geteilt
   (Org-Logo, Marketplace-Bild, Layout-Element-Bild) -- sie auf Figmas 28px
   zu verkleinern waere eine Funktionsregression an unbeteiligten Stellen,
   keine Uebersetzung dieser Aufgabe. .preview-image-container/.preview-image
   bleiben darum unveraendert (Legacy-Optik), siehe Report.

   Restylt wird nur der ECHTE, auf File-/Image-Upload beschraenkte
   Ausloeser (.upload-container label, atominputfileuploadbuttonlabel.js
   UND atominputimageuploadbuttonlabel.js) -- mit Figmas eigenem
   "preview"-Platzhalter-Mass (28x28, Radius 8, Flaeche bg/hover, Knoten
   235:48) als naechstliegender, tatsaechlich vorhandener Entsprechung.
   :not(.chatbot-input .upload-container) grenzt den Chatbot-Anhaengen-
   Button aus (webapp.css:4015-4066, eigene, unveraenderte Optik) --
   dieselbe Klasse "upload-container", aber ein anderer, hier nicht
   betroffener Aufrufkontext (chatwindowinput.js). */
[data-design="new"] .upload-container:not(.chatbot-input .upload-container) label {
  width: var(--ax-size-control-sm);
  height: var(--ax-size-control-sm);
  border-radius: 8px;
  background: var(--ax-bg-hover);
  box-sizing: border-box;
  transition: background-color 120ms ease-out;
}
[data-design="new"] .upload-container:not(.chatbot-input .upload-container) label:hover {
  background: var(--ax-bg-surface-3);
}

/* ── Darstellung: Card, Avatar, Divider, Progress, Accordion ─────────────
   Figma 118:44/62/80 (Card), 118:99/111/121 (Avatar), 112:38/42/46/48
   (Divider), 112:55/58/62/64 (Progress), 115:299/304 (Accordion). */

/* Card -- WICHTIGER BEFUND (siehe Report): atomcontainercard.js, im
   Taskbrief als "Betroffene Klasse" genannt, rendert NICHT Figmas Card. Seine
   Klasse "card-container" ist in webapp.css:3054 der FLEX-WRAP-GRID-Wrapper
   um mehrere Karten (gap 50px, overflow-y auto, max-height calc(100vh-100px)),
   an 12+ Stellen produktiv als Listen-/Grid-Container verwendet
   (Dokumentenlisten, AI-Service-Manager, Modell-Manager, Organisationsliste,
   Marketplace, ...). Die tatsaechliche EINZELKARTE ist ".card"
   (webapp.css:4556, erzeugt ueber ContainerElementFactory.generateCardContainer(),
   produktiv instanziiert durch AtomContainerSingleCard -- atomcontainersinglecard.js,
   14 Aufrufer: Agent-/AI-Service-/Modell-/Organisation-/Marketplace-/Projekt-/
   Dokument-/Nutzungs-Karten u.a.). Diese Regel zielt deshalb auf ".card".

   ".card" ist selbst ebenfalls SEHR breit verwendet (14+ Aufrufer quer durchs
   ganze Produkt) -- Breite/Mindesthoehe (200px/220px) sind fuer diese
   Grid-Layouts tragend und werden deshalb NICHT auf Figmas gemessene 320x116
   umgestellt (Spannung dokumentiert, siehe Report). Nur Flaeche/Rahmen/
   Radius/Schatten/Innenabstand/Abstand werden uebernommen.

   Figma zeigt Default (118:44, kein Schatten, border/soft) und Interactive
   (118:62, Schatten Shadow/Card + border/default) als GETRENNTE Varianten --
   die Produktion kennt aber keine Klasse, die zwischen beiden unterscheidet
   (jede .card-Instanz ist gleich aufgebaut). Deshalb: Default als Ruhezustand,
   Interactive-Optik ueber :hover/:focus-visible (deckt sich mit Spec §5:
   "Hover: Shadow/Card + border/default"). "Selected" (118:80, Rahmen 2px
   border/accent) hat KEIN Markup-Merkmal (keine ".card.selected"-Klasse) --
   nicht gebaut; keine neue Klasse erfunden (die Ausnahmeregel gilt nur fuer
   den Divider).

   Review-Nachtrag -- Survey nach einer ZWEITEN Karten-Klasse: ".result-card"
   (webapp.css:4670, erzeugt in helper/aiserviceresult.js und
   organismschunkcard.js/helper/chunkresultfiller.js) traegt aehnliche Chrome-
   Eigenschaften (Radius 10, Rahmen, Schatten, Innenabstand 20), ist aber
   erwogen und verworfen: sie zeigt gerendertes Markdown-Ergebnismaterial
   (h1-h6, Links, Bilder) auf voller Breite (calc(100% - 80px)) -- inhaltlich
   ein Ergebnis-/Berichtspanel, keine kompakte Info-Kachel wie Figmas Card
   (Titel+Text+Fusszeile, 320x116). Figma misst fuer diese Form keinen
   eigenen Knoten; sie zu uebernehmen hiesse, Typografie fuer h1-h6/Links/
   Bilder zu erfinden statt zu messen -- verstoesst gegen "nie schaetzen".
   Nicht umgesetzt. */
[data-design="new"] .card {
  border-radius: var(--ax-radius-lg);
  background: var(--ax-bg-surface-1);
  border: 1px solid var(--ax-border-soft);
  box-shadow: none;
  color: var(--ax-text-primary);
  padding: var(--ax-space-5);
  gap: var(--ax-space-3);
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}
[data-design="new"] .card:hover {
  border-color: var(--ax-border-default);
  box-shadow: var(--ax-shadow-card);
}
[data-design="new"] .card:focus-visible {
  border-color: var(--ax-border-default);
  box-shadow: var(--ax-focus-ring), var(--ax-shadow-card);
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: none;
}
/* Pressed: 1px nach unten (Spec §5). Der Sprung ist bewusst instant; unter
   reduced-motion entfaellt er trotzdem vollstaendig (siehe unten), weil die
   Regel "jeder Versatz entfaellt" unbedingt gilt, nicht nur fuer animierte.

   HIER STAND "transform: translateY(1px)", UND DAS WAR EIN FEHLER. Gemessen
   und behoben am 2026-09-17, nachdem der Auftraggeber in der Sichtpruefung
   zu "06 Shell & Nav" Punkt 5 gemeldet hatte, er koenne den Agent-Editor
   ueber das Dropdown-Menue nicht mehr oeffnen.

   Ein "transform" auf einem Vorfahren macht diesen Vorfahren zum
   ENTHALTENDEN BLOCK jedes "position: fixed"-Nachfahren. Das Kartenmenue
   (".dropdown-content", webapp.css:4990, "position: fixed; z-index: 9999")
   ist ein Nachfahre der Karte und wurde deshalb in dem Moment, in dem die
   Maustaste herunterging, neu bezogen: gemessen sprang es auf 0/0, verlor
   den Zeiger und ging zu. Das "mouseup" landete auf der Karte statt auf der
   Menuezeile -- und ohne mousedown UND mouseup auf demselben Element
   erzeugt der Browser KEIN Klickereignis. Der Klick "tat nichts".

   Waehrend die Taste unten ist, gemessen auf /agentmanager.html:
     altes Design: transform "none",                Menue 280/251, sichtbar
     mit transform: "matrix(1,0,0,1,0,1)",          Menue   0/0,   display none

   "top" statt "transform" leistet dasselbe, ohne den enthaltenden Block zu
   verschieben: ".card" ist im Bestand bereits "position: relative"
   (webapp.css:4597), ein "top: 1px" versetzt sie also genauso um einen
   Pixel nach unten und laesst das Layout unberuehrt. KEIN "transform" auf
   dieser Klasse -- sie traegt schwebende Menues.

   Reichweite des behobenen Fehlers: JEDES Dropdown innerhalb einer ".card"
   -- Agentenkarten, AI-Service-Karten, Container-Karten und die beiden
   Kartenfabriken. Der Agent-Editor war nur der Weg, auf dem es auffiel.
   Zugesichert in tests/features/design-karten-dropdown.spec.ts, zweiseitig. */
[data-design="new"] .card:active {
  top: 1px;
}
@media (prefers-reduced-motion: reduce) {
  [data-design="new"] .card:active {
    top: auto;
  }
}

/* Review-Fund ("Important 3"): drei Identitaets-Marker kodieren Bedeutung
   ueber border-color + box-shadow bei DERSELBEN Spezifitaet (0,2,0) wie die
   Basisregel oben -- ".card.card-internal" (webapp.css:11048),
   ".card.card-collaboration" (webapp.css:11150), ".agent-card--update .card"
   (webapp.css:11178), alle unscoped. Ohne Gegenregel gewinnt nur die
   Ladereihenfolge und alle drei rendern als gewoehnliche Karte. Restauriert
   hier statt in der Basisregel veraendert (Testselektor). Farben ueber die
   gebrueckten Legacy-Token --clr-accent/--clr-warning (tokens.css bindet sie
   unter [data-design="new"] auf --ax-action-primary/--ax-status-warning
   um, siehe Fundament-Spec) -- --shadow-card selbst ist NICHT gebrueckt,
   deshalb hier durch --ax-shadow-card ersetzt statt woertlich uebernommen. */
[data-design="new"] .card.card-internal,
[data-design="new"] .agent-card--update .card {
  border-color: var(--clr-accent);
  box-shadow: 0 0 0 1px var(--clr-accent), var(--ax-shadow-card);
}
[data-design="new"] .card.card-collaboration {
  border-color: var(--clr-warning);
  box-shadow: 0 0 0 1px var(--clr-warning), var(--ax-shadow-card);
}
/* Residuum ("Befund 7", Spec §14): die drei Identitaetsringe oben liegen bei
   (0,3,0) (Attribut + 2 Klassen) -- GLEICHSTAND mit "[data-design=new]
   .card:focus-visible" weiter oben (Attribut + Klasse + Pseudoklasse,
   ebenfalls (0,3,0)). Die Identitaetsringe stehen im Dokument NACH der
   Fokusregel und gewinnen deshalb bei einem fokussierten Identitaets-Marker
   auf den kontestierten Eigenschaften (border-color/box-shadow) -- der
   Fokusring wuerde unterdrueckt, nicht nur uebermalt. Der urspruengliche
   Bericht behauptete das Gegenteil (Fokus bleibe sichtbar); korrigiert.
   Heute folgenlos: keine ".card"-Instanz traegt "tabindex", :focus-visible
   also unerreichbar (siehe Report) -- restauriert trotzdem nach demselben
   Prinzip wie ".multiselect select" oben (Wert wiederhergestellt, falls
   kuenftig ein fokussierbarer Identitaets-Marker entsteht). Eigene, um die
   Pseudoklasse spezifischere Regel je Marker ((0,4,0) > (0,3,0)) kombiniert
   Fokusring UND Identitaetsfarbe, statt eine der beiden zu verlieren. */
[data-design="new"] .card.card-internal:focus-visible,
[data-design="new"] .agent-card--update .card:focus-visible {
  border-color: var(--clr-accent);
  box-shadow: var(--ax-focus-ring), 0 0 0 1px var(--clr-accent), var(--ax-shadow-card);
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: none;
}
[data-design="new"] .card.card-collaboration:focus-visible {
  border-color: var(--clr-warning);
  box-shadow: var(--ax-focus-ring), 0 0 0 1px var(--clr-warning), var(--ax-shadow-card);
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: none;
}

/* Avatar -- Figma 118:99/111/121 (Initials/Icon/Image, Size=Md): 36x36,
   Radius 999 (--ax-radius-full). AtomContainerAvatar (Klasse
   "chatbot-avatar-container") hat GENAU EINEN Produktivaufrufer
   (chatwindowthinking.js:38), immer mit einem AtomDisplayImage-Kind (Klasse
   "chatbot-avatar") -- die Produktion erzeugt also ausschliesslich Figmas
   "Image"-Variante; Initials und Icon haben keinen Codepfad und werden nicht
   gebaut. Der Status-Punkt (alle drei Figma-Varianten, 9x9, unten rechts an
   der Kante) hat kein Markup-Gegenstueck -- nicht gebaut.

   REVIEW-FUND (korrigiert): ".chatbot-avatar" ist NICHT auf den Avatar
   beschraenkt. chatwindowthinking.js:35-42 vergibt dieselbe Klasse ZWEIMAL --
   einmal an das echte Avatarbild (Kind von .chatbot-avatar-container) UND
   einmal an this.thinkingImageElement, den animierten "... denkt nach"-
   Indikator (chat.gif), der als Kind der Nachrichtenblase (NICHT von
   .chatbot-avatar-container) bei JEDER gestreamten Chat-Antwort erscheint
   (verdrahtet ueber chatbotstreammanager.js:337). Eine unscoped Regel auf
   ".chatbot-avatar" haette also auch diesen Indikator von 50x50 auf 36x36
   verkleinert -- eine Regression auf einer produktiven, hochfrequentierten
   Flaeche, fuer die Figma nichts vorschreibt (kein Denk-Indikator im
   Design-System).

   Entscheidung: die Regel wird ueber den Vorfahren .chatbot-avatar-container
   auf das ECHTE Avatarbild eingegrenzt; thinkingImageElement traegt dieselbe
   Klasse, sitzt aber ausserhalb von .chatbot-avatar-container und bleibt
   deshalb unberuehrt bei Legacy-Groesse (50x50, per fillData() ueber die
   HTML-Attribute width/height=50 gesetzt -- diese verlieren gegen jede
   CSS-width/height-Regel, weshalb ihre Wirkung erst mit der Eingrenzung
   wieder zutrifft). Verifiziert per echter Galerie-Kachel (echte
   OrganismsChatWindowThinking-Instanz, siehe designgallerypage.js) und
   Unit-/E2E-Test.

   Survey nach einer ZWEITEN Avatar-Klasse (Review-Auftrag): gefunden --
   ".msg-bot-avatar"/".msg-greeting-avatar" (webapp.css:2589, 34x34,
   Farbverlauf+Glow) und ".msg-user-avatar" (webapp.css:3002, 30x30,
   bg/surface-3+Rahmen), erzeugt direkt in chatwindowbotmessage.js/
   chatwindowusermessage.js -- der Avatar neben JEDER Chat-Nachricht, weit
   haeufiger sichtbar als der transiente Denk-Indikator oben. Erwogen und
   verworfen: (1) keine wiederverwendbare Avatar-Komponente dahinter -- beide
   sind Ad-hoc-Klassen auf AtomContainerWithClass, kein
   atomcontaineravatar.js-Gegenstueck; (2) sie tragen eine BEABSICHTIGTE
   Bot/User-Unterscheidung (Verlauf+Glow vs. schlichte Flaeche+Rahmen), die
   Figmas EINE generische Avatar-Spezifikation (nur Initials/Icon/Image,
   Size=Md) nicht abbildet; (3) laut Roadmap der Spec (§13) ist "07 · Chat &
   AI" ein SPAETERES Teilprojekt -- Chat-Avatare gehoeren dorthin, nicht in
   "04 · Core". Nicht umgesetzt. */
[data-design="new"] .chatbot-avatar-container {
  width: var(--ax-size-control-md);
  min-width: var(--ax-size-control-md);
  height: var(--ax-size-control-md);
  border-radius: var(--ax-radius-full);
}
[data-design="new"] .chatbot-avatar-container .chatbot-avatar {
  width: var(--ax-size-control-md);
  height: var(--ax-size-control-md);
}

/* Divider -- Figma 112:38 (H-Soft), 112:42 (H-Default), 112:46 (V-Soft),
   112:48 (V-Default). "rule"-Strich 1px, boundTo border/soft bzw.
   border/default, in beiden Achsen gleich gemessen. AtomDisplayHorizontalLine
   kennt Figmas Achsen (Orientation, Emphasis) nicht -- die vom Plan
   sanktionierte Ausnahme (zwei OPTIONALE CSS-Klassen divider-vertical/
   divider-soft) braucht KEINE Code-Aenderung an der Klasse selbst: sie erbt
   Atom.setCssClass() bereits generisch (dieselbe Methode, mit der z.B.
   Task 2 "btn-secondary"/"btn-ghost" vergibt). Bestehende Aufrufer
   (organismsmenubar.js, testresultdetaildialog.js) bleiben unveraendert --
   sie rendern weiterhin ein klassenloses <hr>, treffen also automatisch die
   Default/Horizontal-Basisregel unten.

   organismsmenubar.js' zwei <hr> sitzen in .navbar2 (webapp.css:3463:
   ".navbar2 hr { border:none; border-top:1px solid var(--clr-border);
   margin:6px 14px; width:calc(100% - 28px); }", Spezifitaet (0,1,1),
   IDENTISCH zu "[data-design=new] hr"). Deshalb setzt die Basisregel unten
   NUR border -- margin/width werden bewusst NICHT gesetzt, damit die
   Einrueckung der Nav-Trennlinien (und die von .chatbot-service hr,
   webapp.css:6019, gleiche Werte) erhalten bleibt; nur die Rahmenfarbe wird
   auf den neuen Token gehoben.

   Figmas "label"-Zwischentext (H-Varianten: Linie – Label – Linie) hat kein
   Markup-Gegenstueck (<hr> hat keinen Textinhalt) -- nicht gebaut.

   Survey nach einem DRITTEN <hr>-Erzeuger: cockpitnavigation.js legt an zwei
   Stellen ebenfalls direkt "document.createElement('hr')" mit Klasse
   "rail-divider" an (Icon-Leisten-Trenner im Nav-Rail). Dessen eigene Regel
   ".nav-rail .rail-divider" (webapp.css:3722) hat Spezifitaet (0,2,0) --
   HOEHER als "[data-design=new] hr" (0,1,1) -- und gewinnt deshalb IMMER,
   unabhaengig von der Ladereihenfolge. Die Basisregel unten erreicht diesen
   dritten Trenner also gar nicht; er bleibt vollstaendig Legacy, dieselbe
   bewusste Nicht-Invasivitaet wie bei .navbar2/.chatbot-service oben, hier
   nicht einmal durch eine explizite Ausnahme noetig, sondern strukturell
   bereits gegeben. */
:where([data-design="new"]) hr {
  --divider-color: var(--ax-border-default);
  border: none;
  border-top: 1px solid var(--divider-color);
}
[data-design="new"] hr.divider-soft {
  --divider-color: var(--ax-border-soft);
}
[data-design="new"] hr.divider-vertical {
  border-top: none;
  border-left: 1px solid var(--divider-color);
  width: 0;
  height: 120px;
  margin: 0;
  display: inline-block;
}

/* Progress (Bar) -- Figma 112:55 (Bar, Indeterminate), 112:58 (Bar,
   Determinate). Track 4px, Radius 999, Flaeche bg/hover; Fuellung
   action/primary, Radius 999. VIER (nicht drei) gleich aufgebaute
   Fortschrittsbalken existieren im Bestand (Zweck- statt Achsen-Benennung,
   dieselbe Spannung wie in der Spec §4 beschrieben): .impact-level-track/
   -fill (MoleculeLevelProgress, myimpactpage.js), .aiservice-progress-track/
   -fill (OrganismsAiServiceProgress, templateaiserviceexecution.js),
   .usage-meter-track/-fill (MoleculeUsageMeter, organismspersonalusage.js --
   im Review-Survey nach einer zweiten Klasse derselben Form gefunden; ihr
   eigener CSS-Kommentar in webapp.css erklaert bereits ABSICHTLICH dieselbe
   Geometrie wie .impact-level-* zu tragen ("Farben und Masse folgen den
   Gamification-Balken"), deshalb hier ohne weitere Ruecksprache in dieselbe
   Kommaliste aufgenommen) und .aiservice-wizard-progress-track/-fill
   (MoleculeWizardProgressBar). Die ERSTEN DREI sind Desktop-sichtbar und
   werden hier gemeinsam restylt (comma-Liste, je ein Aufrufer). Der VIERTE
   ist per webapp.css:10376 (".aiservice-wizard-progress { display:none; }",
   unscoped) nur unterhalb des Breakpoints @media (max-width: 640px)
   sichtbar (webapp.css:10378/10664 bestaetigen "Mobile progress bar") --
   ausserhalb der Standard-Testviewport-Reichweite dieser Galerie, deshalb
   NICHT restylt (siehe Report). ".usage-meter-fill-warn"/"-danger" (Warn-/
   Alarmfarbe) haben keine Figma-Entsprechung (Figmas Progress kennt nur eine
   gefuellte Farbe) und bleiben unangetastet -- keine erfundenen Zustaende.

   Bar Indeterminate hat in keinem der drei restylten Balken einen Codepfad
   (alle setzen ihre Fuellbreite ausschliesslich ueber einen echten
   Prozentwert, kein "unbestimmt"-Zustand) -- keine Kachel, keine eigene
   Regel (die Determinate-Regel deckt alle drei Balken vollstaendig ab, da
   "indeterminate" nur eine ANIMATION der Fuellung waere, die hier nicht
   existiert).

   Progress Ring (112:62/64) wird NICHT umgesetzt: die einzigen echten
   Kreis-Spinner-Klassen sind .spinner (webapp.css:4308, 120x120 -- der
   SEITENWEITE Ladebildschirm auf JEDER Seite, ueber das laut CLAUDE.md fuer
   neue UI tabu Helper LoadingScreen) sowie .search-spinner/
   .function-assistant-spinner (14x14/13x13, jeweils in einem grossen,
   service-abhaengigen Organism erzeugt, nicht ohne Backend instanziierbar).
   .spinner auf Figmas 24px-Ring-Mass zu verkleinern waere dieselbe
   Layoutkatastrophe, vor der der Taskbrief fuer Card warnt, nur systemweit
   (jeder Ladebildschirm der Plattform). Nicht umgesetzt, siehe Report. */
[data-design="new"] .impact-level-track,
[data-design="new"] .aiservice-progress-track,
[data-design="new"] .usage-meter-track {
  height: 4px;
  border-radius: var(--ax-radius-full);
  background: var(--ax-bg-hover);
  overflow: hidden;
}
[data-design="new"] .impact-level-fill,
[data-design="new"] .aiservice-progress-fill,
[data-design="new"] .usage-meter-fill:not(.usage-meter-fill-warn):not(.usage-meter-fill-danger) {
  height: 100%;
  border-radius: var(--ax-radius-full);
  background: var(--ax-action-primary);
  animation: none;
}
/* .usage-meter-fill-warn/-danger carry BOTH ".usage-meter-fill" UND ihre
   eigene Modifikatorklasse (siehe MoleculeUsageMeter._fillClass()) -- ohne
   :not() wuerde die obige, hoeher-spezifische neue Regel
   ([data-design=new] .usage-meter-fill, Spezifitaet (0,2,0)) die
   niedriger-spezifische Legacy-Warn-/Alarmfarbe (.usage-meter-fill-warn,
   (0,1,0)) unbeabsichtigt ueberschreiben und action/primary anzeigen, wo
   Rot/Gelb noetig waere. Radius/Hoehe werden trotzdem gebraucht (Figma
   misst nur EINE gefuellte Form) -- deshalb hier separat auf beide
   Modifikatorklassen nachgezogen, nur OHNE die Flaechenfarbe. */
[data-design="new"] .usage-meter-fill-warn,
[data-design="new"] .usage-meter-fill-danger {
  border-radius: var(--ax-radius-full);
}

/* Accordion -- Figma 115:299 (Collapsed), 115:304 (Expanded): umrandetes
   Panel (bg/surface-1, border/soft, Radius 10), Header-Innenabstand
   12/16/12/16, Titel Body/Medium Strong 15/24 (text/primary), Chevron
   text/muted.

   REVIEW-KORREKTUR: eine fruehere Fassung dieses Kommentars behauptete,
   MoleculeSourceInfoAccordion sei "die einzige echte Accordion-Klasse im
   Bestand". Das war falsch -- die Aussage haette schon durch die Suche nach
   "Accordion" im Klassennamen widerlegt werden koennen. Es gibt ZWEI:

   1. OrganismsPartnerAccordion (".partner-accordion"/".accordion-header"/
      ".accordion-name"/".accordion-arrow", webapp.css:10130-10181, EIN
      Aufrufer: platformusagepage.js) -- ein echtes umrandetes Panel mit
      Kopfzeile (Titel + Pfeil) und ausklappbarem Koerper (Kundentabelle),
      per Klick auf den Header umgeschaltet (_toggle()). Strukturell die
      NAEHERE Entsprechung zu Figmas Accordion: Radius 8 (Figma: 10, ueber
      --ax-radius-md sogar exakt), Header-Innenabstand bereits woertlich
      "12px 16px" (Figma: [12,16,12,16], exakte Deckung). Bekommt deshalb
      jetzt die volle Geometrie-Behandlung unten (Panel-Chrome + Header-
      Innenabstand + Titel-Typografie + Chevron-Farbe). Figmas Body-Text
      (Kundentabelle statt Fliesstext) hat keine 1:1-Entsprechung und bleibt
      unberuehrt, ebenso .accordion-badge/.accordion-summary (kein
      Figma-Gegenstueck) und der Hover-Ton auf .accordion-header (keine
      Vorgabe in Spec §5, die Accordion gar nicht auflistet).

   2. MoleculeSourceInfoAccordion (".src-trigger"/".src-body", 2 Aufrufer:
      chatwindowbotmessage.js ueber sourceinfomanager.js,
      organismsresultcard.js) -- eine kompakte, unumrandete Quellenangaben-
      Zeile (10-12px Badges/Zeilen) unter einer Chat-Nachricht bzw. in einer
      Ergebniskarte. Figmas 15px-Titel/umrandetes 16px-Panel wuerde diese
      Einpassung sprengen -- unveraendert erwogen und verworfen (dieselbe
      Spannung wie bei Card), nur die Trigger-Textfarbe wird token-isiert.

   Survey nach WEITEREN Accordion-Klassen: keine gefunden -- die einzigen
   beiden ausklapp-/umschaltbaren Kopfzeile+Koerper-Konstruktionen im
   Bestand sind die zwei oben. */
[data-design="new"] .partner-accordion {
  border-radius: var(--ax-radius-md);
  background: var(--ax-bg-surface-1);
  border: 1px solid var(--ax-border-soft);
}
[data-design="new"] .accordion-header {
  padding: var(--ax-space-3) var(--ax-space-4);
}
[data-design="new"] .accordion-name {
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-body-md);
  line-height: var(--ax-line-height-body-md);
  font-weight: 600;
}
[data-design="new"] .accordion-arrow {
  color: var(--ax-text-muted);
}

/* Die zwei ".src-trigger"-Regeln, die hier standen (Textfarbe
   "--ax-text-muted", Hover "--ax-text-secondary"), sind in
   "07 · Chat & AI" Teil A, Task 5 aufgegangen -- die Vorlage hat sich
   geaendert. Der Absatz 2 oben bleibt woertlich stehen: er ist die
   Begruendung, warum das umrandete Panel AUCH DORT nicht gebaut wird.
   Die neuen Regeln stehen am Ende dieser Datei. */

/* Tooltip -- Figma 110:142/145/148/151 (Placement=Top/Right/Bottom/Left,
   Komponentensatz 110:154). Box: Flaeche bg/elevated, Rahmen 1px
   border/default, Radius 6 (--ax-radius-sm), Innenabstand 4/8/4/8
   (--ax-space-1 / --ax-space-2), Text "Label/Small" = Inter Medium 12/16
   (--ax-font-size-label-sm / --ax-line-height-label-sm), Farbe text/primary.
   Kein Schatten -- keiner der vier Knoten traegt ein effects[]. Figmas
   Pfeil-Kind (10x6-Dreieck, mit 6px Abstand exakt an die Box anschliessend)
   wird NICHT als eigenes Element gebaut (Begruendung unten, Nav-Rail-
   Abschnitt) -- die 6px selbst bleiben als Abstand zum Ausloeser erhalten,
   literal (kein --ax-space-Token trifft genau 6px).

   Heute existiert KEIN Tooltip-Bauteil, sondern nur der lokale Kniff
   ".nav-rail .rail-btn[data-tip]:hover::before" (webapp.css:3574) -- rein
   :hover, verletzt Figmas eigene Regel "Touch has no hover". Diese Regel
   verallgemeinert ihn auf jedes Element mit [data-tip] und behebt den
   Mangel ueber :focus-visible (Tastatur) sowie ein sichtbares Aequivalent
   <= 834px (siehe @media unten).

   SURVEY (siehe Report): der Taskbrief nennt die Nav-Rail-Stelle als
   EINZIGEN bestehenden Tooltip-Kniff. Das ist falsch -- es gibt zwei
   weitere, beide strukturell ANDERS (kein [data-tip]-Attribut) und deshalb
   von der sanktionierten Ausnahme nicht erfasst:
     1. ".button-icon::after" (webapp.css:1396, ungescoped -- gilt in BEIDEM
        Design) liest "attr(title)" und blendet ihn per opacity 0->1 auf
        :hover ein -- KEIN content-Umschalten. Jeder Icon-Button
        (AtomButtonCommand, 18+ CSS-/9+ JS-Stellen) setzt automatisch
        "button.title = ...", bekommt diesen Tooltip also kostenlos.
        Bereits GEOMETRISCH fast identisch mit der Top-Platzierung hier
        (dieselbe bottom/left/transform-Formel) UND, wie sich beim
        Review-Fix dieser Regel herausstellte, auch MECHANISCH identisch
        (opacity-Uebergang statt content-Umschalten) -- diese Regel
        uebernimmt das Muster jetzt bewusst 1:1.
     2. "Atom.setTooltip()" (atom.js:357, Klassen ".tooltip"/".tooltiptext",
        webapp.css:1334) haengt einen <span> an und zeigt ihn ebenfalls rein
        per :hover (visibility) -- 40+ Aufrufer (organismsmodelcard.js,
        chatwindowbotmessage.js, atominput.js-Fehlermeldungen, ...).
   Beide NICHT umgebaut: der Taskbrief und die sanktionierte Ausnahme sind
   wortwoertlich auf "[data-tip]" begrenzt; ein Umbau waere eine ungedeckte
   Ausweitung auf 60+ Aufrufer ausserhalb dieses Tasks (verletzt "Surgical
   Changes"). Deshalb bewusst als Deckungsluecke stehen gelassen, siehe
   Report.

   WICHTIG FUER DIE GALERIE (siehe designgallerypage.js): ein Demo-Trigger
   darf deshalb NICHT die Klasse "button-icon" tragen (AtomButtonCommand) --
   sonst zeigte Hover ZWEI ueberlappende Tooltips gleichzeitig (den
   title-basierten von .button-icon::after UND diesen hier). Die Galerie
   verwendet daher AtomButton OHNE Icon (kein "button-icon", kein
   automatisches title-Attribut, siehe atombutton.js/htmlbuttonelementfactory.js).
   DOKUMENTIERTE LUECKE (kein heutiger Aufrufer, siehe Report): kaeme
   [data-tip] jemals auf einem ".button-icon"-Element zusammen vor, zeigte
   :hover BEIDE Boxen gleichzeitig (::before hier, ::after bei
   .button-icon) -- unterschiedliche Pseudo-Elemente konkurrieren nicht
   ueber Spezifitaet. Zusaetzlich wuerde <= 834px diese Regel HIER
   (Spezifitaet 0,2,1) .button-icon::after (0,1,1) auf den kontestierten
   Eigenschaften content/color/font-size schlagen, OHNE dessen unkontestiertes
   opacity:0/:hover-Gate zu neutralisieren -- die Beschriftung bliebe dadurch
   unsichtbar. Nicht behoben: kein heutiger Aufrufer kombiniert beides,
   eine Absicherung dafuer waere spekulativ (siehe Report).

   Platzierung ueber [data-tip-pos] (kein Figma-Attribut, sondern eine neue,
   fuer die vier Varianten benoetigte Markup-Erweiterung -- die Plattform
   hatte bislang kein Attribut fuer die Ausrichtung). Ohne [data-tip-pos]
   gilt "Top", wie Figmas eigener Standardwert
   (componentPropertyDefinitions.Placement.defaultValue == "Top").

   REVIEW-KORREKTUR (Uebergaenge): die urspruengliche Fassung schaltete die
   Box ueber "content: attr(data-tip)" ausschliesslich auf ":hover"/
   ":focus-visible" um -- ohne Gegenzustand kann das NICHT transitionieren
   (die Pseudo-Box existiert vorher schlicht nicht; es gibt keinen
   Zwischenwert zum Animieren). Das verletzt Spec Paragraph 5 ("120ms
   ease-out auf Farbe und Schatten"), verbindlich fuer JEDE Komponente.
   Behoben: die Box existiert jetzt IMMER (content unbedingt gesetzt),
   Sichtbarkeit laeuft ueber "opacity" mit "transition: opacity 120ms
   ease-out" -- exakt das Muster, das ".button-icon::after" (s.o.) bereits
   nutzt. "transform" bleibt unter prefers-reduced-motion unangetastet: es
   zentriert die Box relativ zum Ausloeser (traegt Position, keine
   Verzierung) und hat ohnehin in KEINEM Zustand einen anderen Wert als in
   jedem anderen -- nichts transitioniert darueber, nichts muesste unter
   reduced-motion entfallen (dieselbe Unterscheidung wie beim Toggle-Knob,
   Task 4). Die <= 834px-Beschriftung unten transitioniert nicht: sie ist
   keine Hover-/Press-Affordanz, sondern eine statische Beschriftung ohne
   Zustandswechsel -- Spec Paragraph 5s Uebergangsregel gilt fuer
   Interaktionszustaende, die diese Beschriftung nicht hat.

   NAV-RAIL-FRAGE (siehe Taskbrief, ausdruecklich zu pruefen): die Box
   (::before) verwendet bewusst dasselbe Pseudo-Element wie die bestehende
   Nav-Rail-Regel. ".nav-rail .rail-btn[data-tip]:hover::before" hat
   Spezifitaet (0,4,1) (2 Klassen + 1 Attribut + 1 Pseudoklasse), diese
   allgemeine Regel nur (0,2,1) fuer den Basiszustand bzw. (0,3,1) fuer den
   Sichtbarkeits-Umschalter -- die Nav-Rail-Regel gewinnt deshalb IMMER auf
   den kontestierten Eigenschaften, unabhaengig von der Ladereihenfolge, und
   die Nav-Rail behaelt ihr Aussehen (Korrektur der Taskbrief-Angabe
   "(0,3,1)" fuer die Nav-Rail-Regel selbst -- 4 nicht 3 Ketten-Glieder,
   siehe Report). Aus demselben Grund traegt die Box HIER keinen eigenen
   Pfeil (zweites Pseudo-Element noetig): ein Pfeil auf ::after wuerde NICHT
   von der Nav-Rail-Regel abgedeckt (die kennt nur ::before) und wuerde als
   pfeilloses, box-loses Dreieck in die Nav-Rail lecken. Der bestehende
   Nav-Rail-Kniff hat ohnehin keinen Pfeil -- ein zweites, pfeilloses
   Erscheinungsbild ist keine Verschlechterung.
   Das <= 834px-Aequivalent (::after) nutzt dagegen ein Pseudo-Element, das
   WEDER die Nav-Rail-::before-Regel NOCH .button-icon::after belegen --
   ABER (Review-Fund, siehe Report "Important 1") NICHT die dritte,
   ebenfalls existierende ::after-Regel auf DERSELBEN Selektor-Familie:
   ".nav-rail .rail-btn.active-*::after" (webapp.css:3554, Spezifitaet
   (0,3,1), der aktive-Tab-Punkt) schlaegt die allgemeine Beschriftungsregel
   (0,2,1) auf "content" -- der Chat-Button ist per
   "cockpitnavigation.js:151" IMMER aktiv beim Laden, das ist also der
   STANDARDFALL, keine Randnotiz. Eigene Ausnahme dafuer siehe unten. */
[data-design="new"] [data-tip] {
  position: relative;
}
[data-design="new"] [data-tip]::before {
  content: attr(data-tip);
  position: absolute;
  z-index: 20;
  white-space: nowrap;
  pointer-events: none;
  background: var(--ax-bg-elevated);
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-sm);
  padding: var(--ax-space-1) var(--ax-space-2);
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-sm);
  line-height: var(--ax-line-height-label-sm);
  font-weight: 500;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
  transition: opacity 120ms ease-out;
}
/* #2004: ":hover" nur auf Geraeten, die schweben koennen -- auf einem
   Beruehrungsgeraet bleibt ":hover" nach dem Antippen haengen und der
   Tooltip laege ueber dem Inhalt. ":focus-visible" (Tastatur) bleibt
   unbedingt. Dasselbe Muster wie die Seitenleisten-Tooltips weiter unten. */
@media (hover: hover) {
  [data-design="new"] [data-tip]:hover::before {
    opacity: 1;
  }
}
[data-design="new"] [data-tip]:focus-visible::before {
  opacity: 1;
}
[data-design="new"] [data-tip-pos="right"]::before {
  bottom: auto;
  left: calc(100% + 6px);
  top: 50%;
  transform: translateY(-50%);
}
[data-design="new"] [data-tip-pos="bottom"]::before {
  bottom: auto;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
}
[data-design="new"] [data-tip-pos="left"]::before {
  bottom: auto;
  left: auto;
  right: calc(100% + 6px);
  top: 50%;
  transform: translateY(-50%);
}

/* Nav-Rail-Ausnahme, Eigenschaft fuer Eigenschaft gegen Legacy geprueft
   (webapp.css:3574): die Box-Basisregel oben hat 19 Eigenschaften (17 wie
   in der ersten Fassung, plus opacity/transition aus der Uebergangs-
   Korrektur oben). 14 davon sind auch bei Legacy gesetzt (content/position/
   z-index/white-space/pointer-events/background/border/border-radius/
   padding/color/font-size/font-weight/left/transform) -- dort gewinnt
   Legacys hoehere Spezifitaet (0,4,1 gegen 0,2,1/0,3,1) unveraendert, die
   Nav-Rail behaelt ihr Aussehen. FUENF Eigenschaften hat Legacy dagegen
   NICHT: font-family, line-height, bottom, opacity, transition.
   font-family/line-height/bottom wuerden ohne Gegenregel UNBEKAEMPFT auch
   in der Nav-Rail durchschlagen -- "bottom" insbesondere kombiniert mit
   Legacys eigenem "top: 50%" und erzwingt eine berechnete Boxhoehe, die die
   Nav-Rail-Tooltip-Box verformt haette (dieselbe Fehlerklasse wie die im
   Taskbrief genannte "unvollstaendige Ueberschreibung"). opacity/transition
   dagegen sind UNOPPOSED, aber HARMLOS: Legacys eigene Aktivierung bleibt
   ueber "content" (hoehere Spezifitaet) an ":hover" gebunden, unveraendert;
   opacity/transition geben der Box lediglich ein 120ms-Einblenden, das sie
   vorher nicht hatte -- Farbe/Form/Position bleiben exakt Legacys eigene.
   Bewusst NICHT neutralisiert (kein Regressionsrisiko, keine erfundene
   Anforderung dagegen), im Report offengelegt.
   Diese Regel spiegelt Legacys eigenen Selektor plus [data-design="new"]
   -- Spezifitaet (0,5,1), zaehlbar HOEHER als Legacy, gewinnt also
   GARANTIERT, nicht nur per Ladereihenfolge. "inherit"/"auto" stellen
   exakt den Zustand her, den diese drei Eigenschaften OHNE die allgemeine
   Regel oben haetten (Pseudo-Elemente erben font-family/line-height vom
   Wirtselement, "bottom" ist initial "auto"). */
[data-design="new"] .nav-rail .rail-btn[data-tip]:hover::before,
[data-design="new"] .nav-rail .rail-btn[data-tip]:focus-visible::before {
  bottom: auto;
  font-family: inherit;
  line-height: inherit;
}

/* DIE HUELLE BESCHNEIDET NICHT MEHR -- sonst ist der Rail-Tooltip im
   EINGEKLAPPTEN Cockpit unlesbar. Gebaut am 2026-09-17 nach der
   Sichtpruefung ("06 Shell & Nav", Punkt 3: "Der Tooltip bei eingeklapptem
   Cockpit Panel ist nicht lesbar. Er wird am Rand abgeschnitten").

   Gemessen am echten Pseudo-Element, 1280px, neues Design:

                   Huelle   Tooltip-Box    davon sichtbar
     ausgeklappt   289      60 ... 154     94 von 94
     eingeklappt    64      60 ... 151      4 von 91

   Die Box selbst ist richtig platziert -- Legacys eigene Regel
   (webapp.css:3600) oeffnet sie mit "left: 48px" nach RECHTS, nicht mittig
   ueber den Knopf. Sie ragt nur aus der eingeklappten Huelle heraus, und
   deren "overflow: hidden" (webapp.css:5499) schneidet sie auf vier Pixel.

   WARUM DAS GEFAHRLOS IST, gemessen und nicht angenommen: die Sidebar
   beschneidet sich SELBST. ".chatbot-service-panel" traegt eigenes
   "overflow: hidden" und ist eingeklappt 0px breit -- ihr Inhalt kann also
   nicht austreten, auch wenn die Huelle es zuliesse. Im ausgeklappten
   Zustand endet der weiteste Nachfahre der Huelle bei 236 von 289; es gibt
   dort nichts zu beschneiden.

   NICHT auf ".panel-collapsed" begrenzt: die Huelle animiert ihre Breite
   (webapp.css:5490, "transition: width 0.2s"), und waehrend des Uebergangs
   traegt sie die Klasse bereits oder noch nicht -- eine zustandsgebundene
   Regel liesse den Tooltip genau dann flackern. Unbedingt ist ruhiger und
   nach der Messung oben ebenso sicher.

   ZWEI EIGENE FEHLSCHLUESSE AUF DEM WEG HIERHER, beide durch Messung
   widerlegt: erst hielt ich es fuer ein z-index-Problem (es ist keins --
   die Box wird beschnitten, nicht ueberdeckt), dann fuer ein reines
   Platzierungsproblem (auch nicht -- ein Stellvertreter mit der GENERISCHEN
   Tooltip-Geometrie ragte links aus dem Fenster, aber die Rail benutzt
   diese Geometrie gar nicht). Wer hier etwas aendert, messe am echten
   Pseudo-Element und in BEIDEN Huellenzustaenden. */
[data-design="new"] .chatbot-service {
  overflow: visible;
}

/* Touch-Aequivalent: <= 834px zeigt der data-tip-Text als sichtbare
   Beschriftung IM Fluss (kein Overlay, kein :hover/:focus-visible-Gate) --
   ::after ist von der Nav-Rail-::before-Box UND von .button-icon::after
   unbelegt, erreicht also grundsaetzlich jedes [data-tip]-Element
   einschliesslich der Nav-Rail-Buttons.

   BEGRENZUNG (Review-Fund "Important 3"): ".rail-btn" ist eine feste
   40x40-Flex-Reihe OHNE flex-wrap und ohne Clipping irgendwo in der
   Kaskade -- ein unbegrenztes Etikett liefe nachweisbar (min-content einer
   Flex-Zeile schrumpft nie unter die Breite ihres laengsten unteilbaren
   Wortes, z.B. "ausblenden" allein bereits > 40px) sichtbar in den
   Nachbarbereich, statt nur "eng, aber vermutlich noch lesbar" zu sein.
   Deshalb bewusst begrenzt statt gehofft:
     - "min-width: 0" hebt die Flex-Item-Voreinstellung "min-width: auto"
       auf (die den Schrumpf unter das intrinsische Minimum sonst
       verhindert) -- ohne dieses Gegenstueck haetten max-width/
       overflow-wrap unten KEINE Wirkung.
     - "max-width: 100%" deckelt die Breite auf die des Ausloesers selbst
       (dessen Content-Box ist bei einem in-flow-::after die umgebende
       Blockbox) -- das Etikett waechst also NIE breiter als sein eigener
       Ausloeser, weder im 40px-Nav-Rail-Fall noch beim breiteren
       Galerie-Button.
     - "overflow-wrap: anywhere" erlaubt Umbruch auch MITTEN in einem Wort,
       falls selbst ein einzelnes Wort die verfuegbare Breite sprengt.
   Ergebnis, deterministisch statt vermutet: das Etikett waechst
   AUSSCHLIESSLICH nach UNTEN (mehrzeilig), nie ueber die Breite seines
   Ausloesers hinaus. In der Nav-Rail bleibt es dabei WEITERHIN im selben
   Flex-Item NEBEN dem Icon (kein flex-wrap auf dem Elternelement, siehe
   oben, das bliebe unveraendert) -- die Zeile bleibt also insgesamt hoeher
   als die feste 40px "rail-btn"-Hoehe, sichtbar ueberstehend nach oben/
   unten (kein overflow:hidden irgendwo in der Kaskade), aber auf wenige,
   durch die Zeilenzahl begrenzte Pixel (Label/Small = 16px Zeilenhoehe je
   Zeile) statt auf eine unbegrenzte horizontale Ausdehnung -- gepruefet
   in tests/features/design-gallery-core.spec.ts.

   REVIEW-KORREKTUR (aktiver Nav-Rail-Button, zweite Runde): eine fruehere
   Fassung dieser Regel liess auf aktiven Rail-Buttons (".active-chat" etc.,
   webapp.css:3554 -- der farbige Aktiv-Tab-Punkt, Spezifitaet (0,3,1)) die
   Beschriftung UEBER eine eigene, hoeher-spezifische Ausnahmeregel
   gewinnen. Das war ein unausgesprochener Tausch, kein Fix: die Beschriftung
   und der Punkt teilen sich dasselbe ::after auf demselben Knoten, es kann
   immer nur EINS gerendert werden -- die Ausnahme hat den Punkt nicht
   ERGAENZT, sondern ERSETZT. Der Chat-Button ist beim Laden IMMER aktiv
   (cockpitnavigation.js:151) und die Nav-Rail ist <= 834px NICHT
   ausgeblendet (webapp.css:10726 haelt sie als kollabierten mobilen
   Standard) -- der Punkt waere also auf einer echten, staendig sichtbaren
   Produktionsflaeche verschwunden, unangekuendigt.

   Untersucht, ob beide koexistieren koennen (Auftrag: einen freien
   Pseudo-Element-Wirt im Teilbaum des Buttons suchen, nicht annehmen, dass
   keiner existiert). ".chip"/".chip svg" (das Icon-Element INNERHALB von
   ".rail-btn") tragen nachweislich KEINE ::before/::after-Regel irgendwo in
   webapp.css (gezielt gegengeprueft) -- ein struktuell freier Wirt
   existiert also. Er ist trotzdem NICHT nutzbar, ohne Markup zu aendern:
   "content: attr(data-tip)" liest das Attribut IMMER vom Element, an dem
   das Pseudo-Element selbst haengt -- CSS hat keinen Mechanismus, das
   Attribut eines VORFAHREN zu lesen (kein Vorfahre-attr(), auch nicht ueber
   vererbte Custom Properties, da attr() nicht in benutzerdefinierte
   Eigenschaften einfliesst, ohne die noch nicht breit unterstuetzte
   erweiterte attr()-Syntax aus CSS Values Level 5). ".chip" traegt selbst
   kein "data-tip" -- nur ".rail-btn" tut das.
   Um ".chip::after" fuer die Beschriftung zu nutzen, muesste
   "cockpitnavigation.js" in "_createRailBtn()" zusaetzlich
   "chip.setAttribute('data-tip', tip)" setzen (dieselbe Zeichenkette, die
   dort bereits fuer "btn.setAttribute('data-tip', tip)" berechnet wird) --
   ein winziger, aber echter Markup-/JS-Eingriff ausserhalb dieses rein
   CSS-Kniff-verallgemeinernden, auf "[data-tip]" begrenzten Tasks, und ohne
   den in der uebergeordneten Spec (Abschnitt 9, "Ausnahmeregel") verlangten
   eigenen Planeintrag nicht zulaessig.

   ENTSCHEIDUNG: Punkt wiederhergestellt, Beschriftung von aktiven
   Rail-Buttons AUSGESCHLOSSEN (Option "b" -- ohne Markup-Aenderung nicht
   erreichbar). Die fuenf ":not(.active-*)"-Ausschluesse unten verhindern
   STRUKTURELL jede Beruehrung dieser Regel mit dem Punkt-Pseudo -- nicht
   nur "content" bliebe unangetastet, sondern auch die uebrigen acht
   Eigenschaften der Beschriftungsregel (u.a. "margin-top", das sonst
   unbekaempft in die Punkt-Positionierung geleckt und ihn sichtbar
   verschoben haette -- derselbe Fehlerklasse wie der bereits behobene
   ::before-Leck, hier VERMIEDEN statt nachtraeglich neutralisiert).
   Ergebnis: auf den fuenf aktiven Farbvarianten bleibt der Punkt exakt
   Legacys eigener, unveraenderter Punkt; die Touch-Beschriftung existiert
   dort schlicht nicht.

   OFFENGELEGTE LUECKE (siehe Report): der Touch-Zugang zur Nav-Rail bleibt
   auf GENAU dem einen Button unvollstaendig, der beim Laden IMMER aktiv
   ist (heute: der Chat-Button; bei jedem Seitenwechsel wechselt auch,
   WELCHER Button aktiv ist). Schliessen wuerde den oben genannten
   Markup-Schritt erfordern (data-tip auf .chip duplizieren, plus Umleiten
   der Beschriftungsregel auf ".rail-btn .chip[data-tip]::after" fuer die
   Nav-Rail) -- ein Fall fuer einen eigenen, sanktionierten Planeintrag,
   nicht fuer diesen Task.

   AUSSERDEM OFFENGELEGT (Review-Fund, siehe Report): ":focus-visible" ist
   auf der Nav-Rail strukturell unerreichbar -- ".rail-btn" sind reine
   <div>s ohne "tabindex" (cockpitnavigation.js, gegengeprueft), koennen
   also gar nicht per Tastatur fokussiert werden. Der Tastatur-Zugang, den
   dieser Task fuer [data-tip] allgemein herstellt, wird auf der Nav-Rail
   folglich nie ausgeloest -- nur die Galerie-Kacheln (echte <button>) UND
   .button-icon-Ausloeser (echte <button>) erreichen ihn. Zu schliessen
   waere ein "tabindex=\"0\"" PLUS eine eigene Tastatur-Aktivierung
   (keydown auf Enter/Space, da ein <div> anders als <button> keinen
   nativen Klick-per-Taste-Mechanismus hat) -- ein echtes Verhaltens-Update
   an cockpitnavigation.js, kein CSS-Kniff, deshalb bewusst ausserhalb
   dieses Tasks belassen. */
/* ":not(.rail-btn)" ERGAENZT AM 2026-09-17 -- die Touch-Beschriftung
   entfaellt in der Nav-Rail.

   Sichtpruefung "06 Shell & Nav", Punkt 2: die Beschriftung ist dort
   unlesbar. Gemessen bei 390px: sie ist "position: static" IM Knopf, also
   auf dessen Inhaltsbreite begrenzt -- 27px, waehrend der Text 117px
   braucht. "overflow-wrap: anywhere" bricht ihn deshalb mitten im Wort,
   ueber viele Zeilen. In einer 64px breiten Leiste ist kein Wortlaut
   unterzubringen.

   Drei Wege standen zur Wahl: herausragen lassen (ueberlagert dauerhaft den
   Chat), kuerzen (eine Beschriftung, die man nicht zu Ende liest), oder
   weglassen. Der Auftraggeber hat am 2026-09-17 das Weglassen entschieden.

   DER PREIS, und er gehoert benannt: unterhalb 834px gibt es keinen Hover,
   und der Tooltip haengt an ":hover". Die Rail-Symbole sind auf einem
   Telefon damit UNBESCHRIFTET. Die im Absatz darueber offengelegte Luecke
   (der jeweils aktive Knopf trug ohnehin keine Beschriftung) ist damit auf
   alle Rail-Knoepfe ausgeweitet -- bewusst, nicht versehentlich.

   AUSDRUECKLICH NUR DIE RAIL: die Regel ist generisch und beschriftet jedes
   "[data-tip]". Galerie-Kacheln und echte ".button-icon"-Ausloeser sind
   breit genug, dort bleibt die Beschriftung und mit ihr der Touch-Zugang.
   ":not(.rail-btn)" steht in DIESEM Selektor statt in einer eigenen
   Gegenregel, weil die generische Regel bei (0,7,1) liegt -- eine
   rail-gescopte Gegenregel muesste diese Zahl erst ueberbieten, statt die
   Ausnahme dort zu nennen, wo sie hingehoert.

   ERWEITERT (Sichtpruefung 2026-09-23): ".cockpit-sidebar-item" ist
   seither ebenso ausgenommen. Der Anwender: "unter 840 wird ploetzlich
   wieder versucht, die Namen der Menuepunkte darzustellen" -- gemessen
   stimmt die Schwelle auf den Pixel, es ist diese Regel.

   WIE DIE EINTRAEGE HIER HINEINGERIETEN: Aufgabe A1 hat den Eintraegen der
   neuen Seitenleiste "data-tip" gegeben (cockpitsidebar.js "_eintrag()"),
   uebernommen vom Muster der alten Symbolleiste, damit ein Symbol im
   eingeklappten Zustand per Tooltip benennbar bleibt. Diese Regel hier ist
   AELTER und generisch -- sie beschriftet jedes "[data-tip]" --, und die
   Ausnahmeliste kannte nur die damals einzige schmale Leiste. Die neuen
   Eintraege wurden also nicht uebersehen, sie sind nachgewachsen.

   DIE BEGRUENDUNG IST WORTGLEICH DIE DER RAIL, eine Handbreit darueber
   aufgeschrieben: die Seitenleiste ist unterhalb 1024px 64px breit (siehe
   den Kompaktblock weiter unten), und "in einer 64px breiten Leiste ist
   kein Wortlaut unterzubringen". "overflow-wrap: anywhere" brach die Namen
   dort mitten im Wort ueber mehrere Zeilen -- das "Versuchen", das der
   Anwender beschreibt.

   DER PREIS GILT HIER GENAUSO und ist dieselbe Entscheidung wie am
   2026-09-17 fuer die Rail: die Symbole der schmalen Seitenleiste sind auf
   einem Telefon unbeschriftet. Am Rechner bleibt der Tooltip (Regel weiter
   unten, ":hover"). */
@media (max-width: 834px) {
  [data-design="new"] [data-tip]:not(.rail-btn):not(.cockpit-sidebar-item):not(.active-chat):not(.active-ai):not(.active-fav):not(.active-res):not(.active-projects)::after {
    content: attr(data-tip);
    display: block;
    font-family: var(--ax-font-sans);
    font-size: var(--ax-font-size-label-sm);
    line-height: var(--ax-line-height-label-sm);
    color: var(--ax-text-primary);
    margin-top: var(--ax-space-1);
    text-align: center;
    min-width: 0;
    max-width: 100%;
    overflow-wrap: anywhere;
  }
}

/* == Vierter Durchgang (13 weitere reale <button>-Elemente) -- RESCOPE-STAND ==
   Dieselbe Grund-Kollision wie "Critical 1" (Header-Kommentar): jede der 13
   Klassen ist bewusst NICHT reskinnt, sondern auf ihr altes Aussehen
   zurueckgesetzt. Seit :where() reicht Legacys eigene Spezifitaet fuer jede
   Eigenschaft, die die jeweilige Klasse SELBST deklariert -- geblieben ist
   pro Klasse nur, was WEITERHIN noetig ist: display (faellt bei manchen
   Klassen auf eine TIED, unscoped Legacy-Regel zurueck), sowie je EINE
   Hover-/Aktiv-Eigenschaft dort, wo die Hover-Spezifitaetsrechnung der
   Basisregel (von :where() unberuehrt, siehe Header-Kommentar) sonst
   durchschlaegt. "height" braucht seit der finalen Entscheidung (Header-
   Kommentar: die Basisregel setzt ueberhaupt keine Hoehe mehr) fuer KEINE
   der 13 Klassen mehr eine Restaurierung -- alle vormaligen "height: auto"-
   Eintraege sind ersatzlos entfernt. Zwei der 13 ("...-readonly-
   restore-btn") brauchen weiterhin KEINE Regel. */

/* .help-widget-launcher (helpwidget.js) -- der schwebende Rund-Button.
   border-radius:50% deklariert die Klasse SELBST (webapp.css:12629, class
   only, (0,1,0)) -- schlaegt die fixierte Basisregel jetzt direkt, entfernt.
   "padding" bleibt: die Klasse setzt es nicht selbst, faellt auf die TIED
   unscoped "button{padding:6px 16px}" zurueck (Gleichstand mit der
   fixierten Basisregel, verliert die Ladereihenfolge) -- ohne den Reset
   waere das Element bei fixer 56x56-Breite/Hoehe kein Kreis mehr, sondern
   ein Stadion. Flaeche/Textfarbe weiterhin bewusst nicht restauriert
   (Token-Wechsel akzeptiert, siehe vorherige Fassung dieses Kommentars).

   AUFGABE L1 (2026-09-23): der Knopf montiert seit einer frueheren Aufgabe
   (railHidden(), page.js) auch auf Cockpit-/Projektseiten im neuen Design,
   weil deren Seitenleiste dort keine eigene Rail mehr baut -- vorher
   uebernahm die alte Rail den Hilfe-Einstieg. Ist-Groesse gemessen:
   56x56px, "bottom: 20px; right: 20px" (webapp.css, unangetastet, gilt
   fuer beide Designs). Auf ".chatbot-input" (webapp.css:5636, Eingabefeld
   des Chat-Composers) steht dessen rechte Kante bei 1280px Fensterbreite
   nur 30px vom rechten Fensterrand entfernt (components.css, Block "07 -
   Chat & AI Teil B", Messung "bei 1280px endet '.chat-window' bei 1250")
   -- der 56px breite, 20px vom Rand entfernte Knopf ueberlappt das Feld
   damit auf voller Hoehe.
   Halbe Groesse (28x28) und 10px naeher an den Rand (20 -> 10) sind die
   vom Anwender genannten Werte. Gerechnet bleiben damit noch 8px
   Ueberlappung (Knopf reicht bis 38px vom Rand, Feldkante liegt bei 30px)
   -- trotzdem hier so umgesetzt, siehe Bericht fuer die Messung und die
   Frage, ob der Wert reicht. "box-sizing: border-box" ist neu dazu-
   gekommen: ohne sie wuerde das bestehende "padding: 6px 16px" bei einer
   28x28-Box das Element wieder zum Stadion machen (dieselbe Ursache wie
   im Absatz darueber, nur bei kleinerer Grundflaeche staerker sichtbar).
   Nur im neuen Design: im alten ist die Rail immer sichtbar, der Knopf
   montiert dort auf Cockpit-/Projektseiten gar nicht (railHidden()
   liefert dort "false"). Andere Seiten ausserhalb des Cockpits (z.B. der
   Agent-Manager) zeigen ihn in beiden Designs weiterhin bei 56x56 --
   dort ist keine Ueberlappung gemeldet, eine ungefragte Groessenaenderung
   dort waere unnoetig (Grundsatz "Surgical Changes").

   NACHBESSERUNG (2026-09-23): die Groesse/Lage oben ist bestaetigt richtig
   -- der Anwender ist damit zufrieden. Das bestehende "padding: 6px 16px"
   blieb aber unveraendert stehen, und das passt nicht mehr zur 28x28-Box:
   das SVG-Icon ist fest 26x26px (webapp.css:12821, unscoped, ".help-
   widget-launcher svg"). Waagerecht will die Box 28px, das Padding allein
   schon 32px (16+16) beanspruchen -- der content-box bleibt rechnerisch 0,
   nicht negativ, weil CSS Breiten/Hoehen nie unter 0 clampt. Senkrecht
   bleiben 28-12=16px fuer ein 26px hohes Icon.
   Das Icon verschwindet dadurch nicht zwingend auf 0px (ein flex-Kind mit
   definierter Groesse und "overflow: visible" schrumpft per Spezifikation
   nicht unter seine automatische Mindestgroesse -- dieselbe Regel, die an
   anderer Stelle in dieser Datei "min-width: 0" fuer Text-Ellipsis in
   Flex-Kindern noetig macht, siehe Kommentar an ".cockpit-sidebar-history
   .container-left-right-spacebetween > li"), sondern bliebe bei 26x26 und
   liefe dabei in den jetzt zu knappen Innenabstand hinein. So oder so ist
   das Padding hier falsch bemessen.
   Das Padding ist fuer die Zentrierung ohnehin nie noetig gewesen: die
   unscoped Basisregel (webapp.css:12799-12816) setzt bereits "display:
   flex; align-items: center; justify-content: center" -- sie zentriert
   das Icon unabhaengig von jedem Innenabstand. Der einzige Grund, warum
   "padding: 6px 16px" hier ueberhaupt steht (siehe Kommentar oben), war
   die Kreisform bei FESTER Breite/Hoehe zu erhalten -- das leistet seit
   dieser Aufgabe "box-sizing: border-box" bereits selbst, unabhaengig vom
   Padding-Wert (die Aussenmasse einer border-box-Box aendern sich durch
   Padding nie). Das Padding ist damit ohne jede verbleibende Aufgabe.
   Entscheidung: Padding auf 0 gesetzt statt es zu verkleinern oder dem
   SVG eine eigene Groesse zu geben -- kleinstmoegliche Aenderung, die den
   tatsaechlich noch aktiven Zweck (Zentrierung) unberuehrt laesst und
   dem 26x26-Icon in der 28x28-Box volle 28x28 content-Flaeche gibt (1px
   Luft auf jeder Seite), ohne eine neue, eigene Groesse fuer das Icon
   einzufuehren, die an keiner anderen Stelle gebraucht wird. */
[data-design="new"] button.help-widget-launcher {
  padding: 0;
  box-sizing: border-box;
  width: 28px;
  height: 28px;
  right: 10px;
}

/* .help-chat-close/.help-chat-maximize (helpchatpanel.js:61-73). Beide
   deklarieren background/padding/font-size/line-height SELBST (webapp.css:
   12703/12716, class only, (0,1,0)) -- schlagen die fixierte Basisregel
   jetzt direkt, alle vier entfernt. Kein "height" mehr noetig (die
   Basisregel setzt keine). Hover-Gegenregel bleibt noetig: Legacy kennt
   fuer beide nur ":hover{opacity:1}" (0,2,0, unkontestiert von "background")
   -- die Hover-Spezifitaetsrechnung der Basisregel (0,2,1) trifft
   "background" trotzdem, Legacys REST-Flaeche "transparent" (0,1,0)
   verliert dagegen waehrend echtem Hover. */
[data-design="new"] button.help-chat-close:hover:not(:disabled) {
  background: transparent;
}
[data-design="new"] button.help-chat-maximize:hover:not(:disabled) {
  background: transparent;
}

/* .mp-tab-btn (marketplacedetailspage.js:111) -- Tab-Selektor, kein CTA.
   Deklariert background/color/border/padding/border-radius/font-size SELBST
   (webapp.css:8555, class only, (0,1,0)) -- schlagen die fixierte Basisregel
   jetzt direkt, alle sechs entfernt. Nur display bleibt (faellt auf die
   TIED unscoped button{}-Regel zurueck) -- kein "height" mehr noetig.
   Hover-Gegenregel bleibt noetig (Legacys ".mp-tab-btn:hover", (0,2,0), TIED
   mit der Hover-Spezifitaetsrechnung der Basisregel (0,2,1) fuer
   "background"), ebenso ":not(.active)" darauf (sonst wuerde die Hover-
   Regel einen aktiven, gehoverten Tab treffen). ".active" (webapp.css:8571,
   (0,2,0)) deklariert color/border-color/font-weight zwar auch selbst
   direkt -- braucht aber TROTZDEM eine eigene "background"-Restaurierung:
   die Hover-Spezifitaetsrechnung der Basisregel (0,2,1) schlaegt Legacys
   ".active" (0,2,0) auf "background", wenn ein aktiver Tab gehovert wird
   (derselbe Mechanismus wie ".page-action-btn.primary" weiter unten) --
   color/border-color/font-weight sind dort unkontestiert und deshalb
   entfernt, nur "background" bleibt. */
[data-design="new"] button.mp-tab-btn {
  display: inline-block;
}
[data-design="new"] button.mp-tab-btn:hover:not(:disabled):not(.active) {
  background: var(--background-color-navigation-hover);
  color: var(--font-color-application);
}
[data-design="new"] button.mp-tab-btn.active {
  background: var(--background-color-button);
}

/* .page-action-btn (command.js:65 "createIconButton()", atombuttonback.js:24
   "back"-Knopf). Deklariert border-radius/padding/border/background/color
   SELBST (webapp.css:8834, class only, (0,1,0)) -- schlagen die fixierte
   Basisregel jetzt direkt; die REST-Regel ist komplett entfernt (die
   Basisregel setzt ohnehin keine Hoehe mehr). Hover-Gegenregel bleibt
   noetig (Legacys ".page-action-btn:hover", (0,2,0), TIED mit der Hover-
   Spezifitaetsrechnung der Basisregel (0,2,1) fuer "background"), mit
   ":not(.primary)". ".primary" (webapp.css:8858, (0,2,0)) braucht dieselbe
   Hover-Ueberlebensregel wie ".mp-tab-btn.active" oben -- NUR "background"
   bleibt (border-color ist unkontestiert waehrend Hover und deshalb
   entfernt); ohne sie wuerde ein gehoverter Primary-Button auf die neutrale
   Hover-Flaeche der Basisregel zurueckfallen, obwohl Legacy fuer
   ".primary:hover" nur "opacity: .85" aendert (Flaeche bleibt Akzent). */
[data-design="new"] button.page-action-btn:hover:not(:disabled):not(.primary) {
  background: var(--clr-surface-2);
}
[data-design="new"] button.page-action-btn.primary {
  background: var(--clr-accent);
}

/* .emoji-picker-cell (atomemojipicker.js:37-40) -- Kachel im Emoji-Gitter.
   Deklariert background/border/border-radius/padding/font-size SELBST
   (webapp.css:11990, class only, (0,1,0)) -- schlagen die fixierte
   Basisregel jetzt direkt, alle fuenf entfernt. Kein "height" mehr noetig,
   also keine eigene Regel mehr fuer die Ruhe-Eigenschaften. Hover-Gegenregel
   bleibt noetig (Legacys ".emoji-picker-cell:hover", (0,2,0), TIED mit der
   Hover-Spezifitaetsrechnung der Basisregel (0,2,1) fuer "background"). */
[data-design="new"] button.emoji-picker-cell:hover:not(:disabled) {
  background: var(--clr-surface-2);
}

/* .icon-picker-toggle-btn (moleculeiconpicker.js:47/51) -- Segmented-
   Control-artiges Paar. Deklariert padding/border/background/color SELBST
   (webapp.css:11996, class only, (0,1,0)) -- schlagen die fixierte
   Basisregel jetzt direkt, alle vier entfernt. Nur display bleibt (TIED
   unscoped button{}-Regel) -- kein "height" mehr noetig. Legacy kennt fuer
   die Klasse selbst KEIN eigenes ":hover" (nur ".active") -- die Hover-
   Spezifitaetsrechnung der Basisregel (0,2,1) traf "background" bisher
   unkontestiert, neutralisierende Hover-Regel auf die Ruhe-Flaeche bleibt
   noetig, mit ":not(.active)". ".active" (webapp.css:11997, (0,2,0)) braucht
   dieselbe Hover-Ueberlebensregel wie ".mp-tab-btn.active" oben -- nur
   "background" bleibt (color ist unkontestiert waehrend Hover). */
[data-design="new"] button.icon-picker-toggle-btn {
  display: inline-block;
}
[data-design="new"] button.icon-picker-toggle-btn:hover:not(:disabled):not(.active) {
  background: var(--clr-base);
}
[data-design="new"] button.icon-picker-toggle-btn.active {
  background: var(--clr-accent);
}

/* .skill-chip-close (skillchiplist.js:84-86) -- das "x" im Skill-Chip.
   Deklariert background/border/color/font-size/line-height/padding SELBST
   (webapp.css:11280, class only, (0,1,0)) -- schlagen die fixierte
   Basisregel jetzt direkt, alle sechs entfernt. Kein "height" mehr noetig,
   also keine eigene Regel mehr fuer die Ruhe-Eigenschaften. Legacy-Hover
   setzt NUR "color" (0,2,0, unkontestiert von der Basisregel, die auf
   :hover nur "background" setzt) -- "color" ist deshalb aus der Hover-
   Restaurierung entfernt (Legacy gewinnt allein, unopposed); "background"
   bleibt (TIED mit der Hover-Spezifitaetsrechnung der Basisregel, sonst
   faerbt sich die Flaeche beim Hover cyan ein). */
[data-design="new"] button.skill-chip-close:hover:not(:disabled) {
  background: transparent;
}

/* .persona-card-list-toolbar-clear (moleculepersonacardlist.js:172-174) --
   als Text-Link gestylter "Auswahl aufheben"-Knopf. Deklariert background/
   padding/font-size/color/text-decoration SELBST (webapp.css:12103, class
   only, (0,1,0)) -- schlagen die fixierte Basisregel jetzt direkt, alle
   fuenf entfernt. Nur display bleibt (TIED unscoped button{}-Regel) -- kein
   "height" mehr noetig. Hover-Gegenregel bleibt noetig (kein eigenes
   Legacy-":hover", die Hover-Spezifitaetsrechnung der Basisregel traf
   "background" bisher unkontestiert). */
[data-design="new"] button.persona-card-list-toolbar-clear {
  display: inline-block;
}
[data-design="new"] button.persona-card-list-toolbar-clear:hover:not(:disabled) {
  background: none;
}

/* .tool-invocation-toggle (organismstoolinvocation.js:94-96) -- aufklappbare
   Tool-Aufruf-Kopfzeile, hoechste Trittfrequenz der 13. Legacy deklariert
   background/padding/text-align/color SELBST, dazu "font: inherit"
   (webapp.css:2834, class only, (0,1,0)) -- alle fuenf schlagen die
   fixierte Basisregel jetzt direkt; "font: inherit" insbesondere loest den
   separat gemeldeten Befund ("fehlendes font: inherit") DURCH DIE
   RESCOPE-KONSTRUKTION, ohne eigene Regel. Nur width bleibt (nie
   kontestiert, siehe Chatbot-Button-Kommentar oben -- unabhaengig von dieser
   Runde). "height" braucht keine Regel mehr (Basisregel setzt keine); und
   "justify-content: flex-start" ist ebenfalls ersatzlos entfernt -- die
   Basisregel selbst setzt seit der finalen Entscheidung kein
   "justify-content" mehr (Header-Kommentar), das Element faellt also auf
   den Flex-Default "flex-start" zurueck, GENAU den Wert, den dieser Patch
   bisher erzwungen hat. Hover-Gegenregel bleibt noetig (kein eigenes
   Legacy-":hover" auf dem Toggle selbst -- nur auf dem Kind
   ".tool-invocation-name" -- die Hover-Spezifitaetsrechnung der Basisregel
   traf "background" bisher unkontestiert). */
[data-design="new"] button.tool-invocation-toggle {
  width: 100%;
}
[data-design="new"] button.tool-invocation-toggle:hover:not(:disabled) {
  background: none;
}

/* .llm-selector-chip (organismsllmproviderselector.js:794-796) -- kompakte
   Filter-Pille. Deklariert padding/font-size/border-radius/background/
   border/color SELBST (webapp.css:7325, class only, (0,1,0)) -- schlagen
   die fixierte Basisregel jetzt direkt, alle sechs entfernt. Kein "height"
   mehr noetig, also keine eigene Regel mehr fuer die Ruhe-Eigenschaften.
   Legacy-Hover setzt NUR "border-color" (0,2,0, unkontestiert von der
   Basisregel) -- deshalb aus der Hover-Restaurierung entfernt; "background"
   bleibt (TIED mit der Hover-Spezifitaetsrechnung der Basisregel), mit
   ":not(.active)". ".active" (webapp.css:7339, (0,2,0)) braucht dieselbe
   Hover-Ueberlebensregel wie ".mp-tab-btn.active" oben -- nur "background"
   bleibt (border-color/color sind unkontestiert waehrend Hover).
   ".llm-selector.compact .llm-selector-chip" (webapp.css:7489, (0,3,0))
   bleibt unabhaengig sicher, keine Ausnahme noetig. */
[data-design="new"] button.llm-selector-chip:hover:not(:disabled):not(.active) {
  /* WERT NACHGEZOGEN in 05 · Data, Teil B — Task 3 (Filterchip). Diese
     Regel haelt die RUHEFLAECHE des Chips gegen die (0,2,1) schwere
     Hover-Rechnung der Basisregel; die Ruheflaeche war "transparent"
     (Legacy) und ist seit Task 3 --ax-bg-surface-1. Beide Werte stehen
     deshalb hier UND in der Ruheregel von Task 3 -- die Begruendung,
     warum der Wert nicht doppelt als eigene Regel weiter unten steht,
     ebenfalls dort. */
  background: var(--ax-bg-surface-1);
}
[data-design="new"] button.llm-selector-chip.active {
  /* WERT NACHGEZOGEN in Task 3, gleiche Rolle wie oben: die Aktivflaeche
     war Legacys --clr-accent und ist seit Task 3 Figmas
     --ax-action-primary.

     BERICHTIGT MIT T1 (2026-09-15), UND DIE ALTE BEGRUENDUNG IST HIER
     WIDERLEGT, NICHT NUR VERALTET. Hier stand: "im DUNKLEN Theme sind
     beide dieselbe cyan/500, im HELLEN NICHT (--clr-accent haengt dort auf
     --ax-text-link = cyan/600) -- ohne diese Zeile bliebe der aktive Chip
     im hellen Theme cyan/600". Die Praemisse gilt nicht mehr: T1 hat
     --ax-action-primary im hellen Theme selbst auf cyan/600 geheilt
     (tokens.css:127). Die zwei Wurzeln sind UNGEBRANDET jetzt in BEIDEN
     Themes wertgleich -- dunkel cyan/500 (tokens.css:69 ueber die Bruecke
     :172), hell cyan/600 (:127 bzw. --ax-text-link :276). Ohne diese Zeile
     bliebe der Chip also in BEIDEN Themes bei dem Wert, den sie setzt.

     WAS DIE ZEILE TROTZDEM TUT, und nur das: sie nimmt dem aktiven Chip die
     ORGANISATIONSFARBE. "--clr-accent" ist brandbar, "--ax-action-primary"
     nicht (brandingapplier.js:6-17 haengt ausschliesslich --clr--Wurzeln
     um). Das ist die bewusste Entscheidung aus Task 3 und der einzige
     verbliebene Unterschied zwischen den beiden Schreibweisen.

     DER SPEZIFITAETSTEIL BLEIBT UNVERAENDERT GUELTIG: diese Regel wiegt
     (0,3,1); eine Aktivregel weiter unten mit (0,3,0) waere gegen sie eine
     tote Deklaration. Genau so eine stand bis T1 als helle Sonderregel im
     Abschnitt "05 Data" -- sie ist entfallen, weil sie nach der Heilung
     viermal wertgleich mass; die Messreihe steht dort. */
  background: var(--ax-action-primary);
}

/* .resource-group-header (organismsaiserviceresources.js:157-159) --
   aufklappbare Gruppenkopfzeile, dieselbe Disclosure-Rolle wie
   ".tool-invocation-toggle" oben. Legacy deklariert min-height:54px/padding/
   background/color/font-weight SELBST (webapp.css:13179, class only,
   (0,1,0)) -- alle fuenf schlagen die fixierte Basisregel jetzt direkt,
   entfernt (min-height EINGESCHLOSSEN -- anders als bei den uebrigen zwoelf
   Klassen deklariert diese Klasse ihre eigene Mindesthoehe SELBST). Keine
   eigene Regel mehr fuer die Ruhe-Eigenschaften: "justify-content: flex-start"
   war der zweite Patch fuer genau die Luecke, die die finale Entscheidung
   strukturell schliesst (Header-Kommentar) -- die Basisregel setzt kein
   "justify-content" mehr, das Element faellt auf den Flex-Default
   "flex-start" zurueck, denselben Wert, den dieser Patch bisher erzwang.
   Hover-Gegenregel bleibt noetig (kein eigenes Legacy-":hover", die Hover-
   Spezifitaetsrechnung der Basisregel traf "background" bisher
   unkontestiert). */
[data-design="new"] button.resource-group-header:hover:not(:disabled) {
  background: var(--clr-surface-2);
}

/* == Fuenfter Durchgang (2026-09-08, Sweep-Nachtrag) ==
   Drei weitere reale <button>-Klassen, die SONST keine Regel brauchen (sie
   deklarieren background/border/padding/etc. SELBST). Alle drei haben keine
   eigene Hoehe -- seit der finalen Entscheidung (Header-Kommentar) setzt die
   Basisregel aber ueberhaupt keine Hoehe mehr, es gibt also fuer keine der
   drei mehr etwas zu resetten. */

/* .satisfaction-answer/.satisfaction-dismiss (moleculesatisfaction.js:76) --
   Feedback-Knoepfe ("zufrieden"/"geht so"/"unzufrieden"/"✕"). Deklarieren
   SELBST padding/font-size/background/border/border-radius/color
   (webapp.css:2135, Kommaliste, class only, (0,1,0)). Hover-Gegenregel
   bleibt noetig (Legacys eigenes ":hover", (0,2,0), setzt nur border-color
   -- "background" bleibt unkontestiert von Legacy und TIED mit der Hover-
   Spezifitaetsrechnung der Basisregel). */
[data-design="new"] button.satisfaction-answer:hover:not(:disabled),
[data-design="new"] button.satisfaction-dismiss:hover:not(:disabled) {
  background: transparent;
}

/* .toggle-btn (atombuttontoggle.js:28, einziger Produktivaufrufer:
   organismsrelationshipcard.js:90, fester Label "Chunks" -- keine dynamische
   Laenge, kein Wachstumsbedarf). Deklariert background/border/border-
   radius/padding/color/font-size/display/align-items/gap/font-family SELBST
   (webapp.css:8336, class only, (0,1,0)). Hover-Gegenregel bleibt noetig
   (Legacys eigenes ":hover", (0,2,0), setzt border-color/color, nicht
   "background" -- TIED mit der Hover-Spezifitaetsrechnung der Basisregel). */
[data-design="new"] button.toggle-btn:hover:not(:disabled) {
  background: var(--clr-surface-2);
}

/* .llm-selector-filter-toggle (organismsllmproviderselector.js:130) --
   Filter-Umschalter im LLM-Auswahl-Dropdown. Deklariert padding/font-size/
   background/border/border-radius/color SELBST (webapp.css:7278, class
   only, (0,1,0)). Hover-Gegenregel bleibt noetig (Legacys eigenes ":hover",
   (0,2,0), setzt nur border-color -- "background" bleibt unkontestiert von
   Legacy und TIED mit der Hover-Spezifitaetsrechnung der Basisregel). */
[data-design="new"] button.llm-selector-filter-toggle:hover:not(:disabled) {
  background: transparent;
}

/* ══ 06 · Shell & Nav — Task 1: Nav-Rail ═════════════════════════
   Figma: Icon Rail 64 breit, Innenabstand 12/0, Abstand 8, Flaeche
   bg/nav, Rahmen border/default. Rail Item 40x40 Radius 10.

   BEWUSSTE ABWEICHUNG (Spec Abschnitt 7): Figmas Rail Item hat genau
   eine Aktivfarbe (action/primary). Die Plattform faerbt pro Bereich
   (Chat/KI/Favoriten/Ergebnisse/Projekte) und diese Farbe ist
   Produktinformation -- sie sagt, in welchem Bereich man steht.
   Uebernommen werden Geometrie und Struktur (Flaeche + 1px Rahmen
   statt des dreifachen box-shadow), nicht die eine Farbe.

   GLEICHSTAND, nur durch Ladereihenfolge entschieden: diese Regel und
   "[data-theme="light"] .nav-rail" (webapp.css:9539) stehen beide bei
   (0,2,0). Legacy setzt dort "background" und "border-right-color"
   (Longhand); diese Regel setzt "background" und "border-right"
   (Shorthand, das "border-right-color" mit umfasst). Fuer die davon
   betroffene Endeigenschaft "border-right-color" ist das nach Expansion
   der Shorthand eine echte Kollision bei gleicher Spezifitaet -- die
   Shorthand-Form verschafft keinen Vorrang, es gewinnt einzig die
   Position in der Kaskade. Diese Regel gewinnt nur, weil components.css
   nach webapp.css laedt; bei vertauschter Ladereihenfolge bliebe die
   Rail auf dem hellen Legacy-Rahmenton haengen. Festgehalten, weil der
   Rest der Datei solche Faelle vermerkt (Nachbesserungsrunde 1,
   Befund 9).

   WARUM HIER "64px" STEHT UND NICHT "var(--ax-size-rail)"
   (Korrekturwelle nach dem Abschlussreview). Das Fundament definiert
   "--ax-size-rail: 64px" (tokens.css:358) mitsamt einer responsiven
   Staffel: bei <=768px will es 56px. Verbraucher hat das Token im ganzen
   "frontend/"-Baum keinen einzigen (nachgeprueft). Es zu benutzen waere
   deshalb keine Aufraeumarbeit, sondern eine Verhaltensaenderung ohne
   Auftrag -- unter 768px schruempfte die Rail auf 56, und die Kollapsregel
   ("width: 64px" unten), die Mobil-Offsets aus diesem Task und die
   Sidebar-Breiten aus Task 2 rechnen alle mit 64. Dasselbe gilt fuer
   "--ax-size-sidebar"/"--ax-size-panel": 64 + 225 = 289 und 64 + 200 = 264
   decken sich heute zufaellig mit den aus Legacy abgeleiteten Werten in
   Task 2, bei <=768px will die Staffel aber 280 (also 344) statt der dort
   umgesetzten 284. Festgehalten als offener Befund in Spec Abschnitt 12;
   ein Umbau gehoert in einen eigenen Task, der die Staffel als Ganzes
   entscheidet. */
[data-design="new"] .nav-rail {
  /* 64 steht hier literal, obwohl "--ax-size-rail" existiert -- siehe die
     Begruendung ueber der Regel. "gap" dagegen am Token: "--ax-space-2"
     ist in allen drei Breakpoint-Stufen von tokens.css 8px (nur
     --ax-space-3 aufwaerts staffeln), die Ersetzung ist also wertgleich
     und breakpointstabil. */
  width: 64px;
  padding: 12px 0;
  gap: var(--ax-space-2);
  background: var(--ax-bg-nav);
  border-right: 1px solid var(--ax-border-default);
  /* Kein universeller box-sizing-Reset in dieser Anwendung (cockpit.html
     laedt genau drei Stylesheets, webapp.css setzt border-box nur lokal).
     Ohne diese Zeile ist .nav-rail content-box und der 1px-Rahmen addiert
     sich auf die width -- gemessen 65 statt 64. Nachbesserungsrunde 1,
     Befund 1 (Blocker). */
  box-sizing: border-box;
}

/* Kein universeller box-sizing-Reset in dieser Anwendung (cockpit.html
   laedt genau drei Stylesheets, webapp.css setzt border-box nur lokal) --
   das ist in dieser Datei jetzt zum dritten Mal aufgetreten (siehe
   ".nav-rail" oben) und wird deshalb hier fuer ".chatbot-service"
   generell nachgezogen, nicht nur fuer den eingeklappten Zustand:
   ".chatbot-service" traegt selbst ein eigenes "border-right/top/bottom:
   1px" (webapp.css:5459-5473, unveraendert Legacy, unabhaengig von
   "panel-collapsed"), ohne border-box addiert sich dieser Rahmen auf
   jede hier gesetzte width -- gemessen 65 statt 64 im eingeklappten
   Zustand (Nachbesserungsrunde 2, dieselbe Fehlerklasse wie Runde-1-
   Befund 1, eine Ebene hoeher). Betrifft auch die 289px, die Task 2 fuer
   den ausgeklappten Zustand setzen wird -- ohne diese Zeile waeren es
   dort 290.

   NEBENWIRKUNG, BEWUSST SO GELASSEN (Nachbesserungsrunde 3, Befund 2 --
   Medium, Ruling des Auftraggebers): "box-sizing" wirkt nicht nur
   eingeklappt, sondern auch im heutigen (noch unveraenderten) AUS-
   geklappten Zustand -- gemessen bei 1400px: Container 320 statt 321,
   Panel 255 statt 256. Kein Versatz, keine Luecke (die Zeile ist Flex-
   Nachbar, schrumpft einfach um 1px mit). Das ist ein bewusst in Kauf
   genommener 1px-Zwischenzustand, bis Task 2 die eigentliche width fuer
   den ausgeklappten Zustand auf 289px setzt -- dort ist die Regel dann
   bereits richtig vorbereitet. Nicht spaeter faelschlich fuer einen Fehler
   halten. */
[data-design="new"] .chatbot-service {
  box-sizing: border-box;
}

/* Eingeklappt bleibt genau die Rail stehen -- die 60 der Legacy-Regel
   waeren jetzt 4px zu wenig und das Cockpit spraenge beim Einklappen.
   Greift ueber alle Breakpoints, in denen "panel-collapsed" gesetzt ist:
   die unbedingte Legacy-Regel (webapp.css:5071, (0,2,0)) UND ihre
   medienabhaengige Verschaerfung bei <=1024px (:6613, setzt dort nur
   min-width -- keine Kollision mit "width") haben beide niedrigere
   Spezifitaet als diese Regel (0,3,0). Bei <=640px (:10726) ist
   "panel-collapsed" laut cockpitnavigation.js:253-255 ohnehin der mobile
   Ausgangszustand, die dortige ungescopte ".chatbot-service"-Regel
   (0,1,0) verliert ebenfalls. Gehoert hierher statt zu Task 2, weil die
   Breitenaenderung hier entsteht -- Task 2 legt diese Regel nicht noch
   einmal an (siehe Plan). Mit "box-sizing: border-box" oben ist "width:
   64px" jetzt die tatsaechliche Aussenbreite, deckungsgleich mit der
   Rail (Nachbesserungsrunde 2, in einem echten Chromium nachgemessen:
   Container 64, Rail 64). */
[data-design="new"] .chatbot-service.panel-collapsed {
  width: 64px;
}

[data-design="new"] .nav-rail .rail-logo {
  width: 30px;
  height: 30px;
  /* "--ax-radius-sm" ist 6px und wird in keinem Breakpoint umdefiniert
     (tokens.css staffelt nur --ax-radius-lg/-xl) -- wertgleich. */
  border-radius: var(--ax-radius-sm);
}

/* "--ax-radius-md" ist 10px und wird in keinem Breakpoint umdefiniert
   (tokens.css staffelt nur --ax-radius-lg/-xl) -- wertgleich zur
   vorherigen literalen 10. Gilt ebenso fuer die drei folgenden Stellen
   (Rail-Dropdown, Sidebar-Zeile, Kopfknopf). */
[data-design="new"] .nav-rail .rail-btn {
  border-radius: var(--ax-radius-md);
}

/* Die Dropdown-Menuepunkte in der Rail (webapp.css:3676-3685, Radius 11)
   sitzen optisch neben den Rail-Buttons und sollen denselben Radius
   tragen wie ".rail-btn" oben -- sonst fallen sie im neuen Design aus
   dem Raster (Nachbesserungsrunde 1, Befund 11). */
[data-design="new"] .nav-rail .dropdown {
  border-radius: var(--ax-radius-md);
}

/* Figmas Rail Item traegt sein Icon direkt; die Plattform schachtelt es
   in einen farbigen Chip. Der Chip ist bereits 22x22 (webapp.css:3593-
   3596) -- bitgleich zu Figmas Zielmass, keine Aenderung noetig. Deshalb
   steht hier bewusst KEINE Regel, nicht einmal eine rein geometrische:
   eine waere ein vollstaendiger No-Op (Nachbesserungsrunde 1, Befund 8).
   Das SVG selbst bleibt bei 13px (webapp.css:3607-3611), sonst sprengt es
   den Chip. Die Strichstaerke 1,75 ist Sache der Icon-Quelle und im CSS
   nicht setzbar.

   KEIN "background" hier -- und ueberhaupt keine Regel. Die Rechnung:
   ein hypothetisches "[data-design="new"] .nav-rail .chip { background:
   ... }" stuende bei (0,3,0) -- ein Attributselektor plus zwei Klassen.
   Die fuenf Bereichs-Chips ".nav-rail .chip-chat" usw. (webapp.css:3614-
   3620) stehen bei (0,2,0) und wuerden verlieren; ihre Flaeche traegt
   aber genau die Bereichsfarbe, die die Rail laut Spec Abschnitt 7
   behalten soll. Die aktiven Fassungen ".nav-rail .rail-btn.active-chat
   .chip-chat" (:3638-3642) stehen bei (0,4,0) und blieben unberuehrt --
   betroffen waeren die fuenf Grundzustaende. Deshalb keine Regel.

   DRITTER GLEICHSTAND derselben Art wie in Befund 9 (Nachbesserungsrunde
   3, Befund 4): "[data-theme="light"] .nav-rail .chip" (webapp.css:9556,
   background rgba(schwarz,0.05)) steht ebenfalls bei (0,3,0) -- exakt wie
   die hypothetische Regel oben. Auch das ein Grund, hier keine Regel
   anzulegen: sie wuerde nicht nur die fuenf Bereichs-Chips ueberfahren,
   sondern zusaetzlich mit Legacys eigener Hell-Fassung nur durch
   Ladereihenfolge gewinnen, statt durch Spezifitaet. */

/* Der Theme-Chip und seine drei Geschwister (Sprache, Design, Kollaps)
   bleiben Chips -- Figmas 80x36-Pille wird nicht gebaut (Spec
   Abschnitt 7). Uebernommen werden nur seine Tokens.

   ".chip-collapse" GEHOERT HIER DAZU (Korrekturwelle nach dem
   Abschlussreview). Er ist der vierte formgleiche Nachbar in derselben
   Rail -- 22x22, Radius 7, kein Bereichs-Chip, keine Produktfarbe -- und
   stand als einziger der vier noch auf Legacys 7-Prozent-Weiss-Waesche.
   Im vollen Stapel gemessen (dunkel, ueber der Rail rgb(18,17,28)
   komponiert): Kollaps-Chip rgb(35,34,44) gegen rgb(26,24,38) bei den
   drei anderen -- im alten Design tragen alle vier bitgleich
   rgba(255,255,255,0.07), der Bruch entstand erst hier. Mit dieser
   Zeile misst er dieselbe opake Flaeche wie seine Nachbarn.
   Die Textfarbe wandert mit: Legacy faerbt ihn slate/0.70 statt
   slate/0.80 wie die anderen drei; gegen die neue Flaeche haelt
   "--ax-text-muted" 4,477 statt bisher 3,733 (dunkel) bzw. 6,713 statt
   3,384 (hell). Beide Werte steigen, kein Tausch.

   GLEICHSTAND, nur durch Ladereihenfolge entschieden: "[data-theme=
   "light"] .nav-rail .chip-theme" (webapp.css:9565) steht ebenfalls bei
   (0,3,0) und setzt dieselben zwei Eigenschaften (background/color);
   fuer ".chip-collapse" gilt dasselbe ueber webapp.css:9563. Gegen die
   dunklen Fassungen (webapp.css:3620/3629, (0,2,0)) gewinnt diese Regel
   dagegen ueber die Spezifitaet. Festgehalten wie oben bei ".nav-rail"
   selbst (Nachbesserungsrunde 1, Befund 9). */
[data-design="new"] .nav-rail .chip-collapse {
  background: var(--ax-bg-surface-2);
  color: var(--ax-text-muted);
}

/* Aktivzustaende: das Legacy-box-shadow-Trio (Ring + 18px-Glow, je
   webapp.css:3533-3552 -- nicht :3566, das ist bereits der Statuspunkt)
   weicht Flaeche + 1px Rahmen. Die Flaeche uebernimmt pro Bereich exakt
   die Legacy-Deckkraft (0.18/0.18/0.18/0.15/0.16) -- nur Struktur
   aendert sich, nicht die Farbe.

   Der Rahmen ist KEINE Uebernahme: 0.45 ist fuer alle fuenf Bereiche
   derselbe Wert, nicht die jeweilige Legacy-Ring-Deckkraft (0.25/0.25/
   0.25/0.2/0.22). Bewusste Entscheidung, nicht verschleiert (Nachbesse-
   rungsrunde 1, Befund 7): der 18px-Glow bei 0.15 faellt mit dem
   box-shadow komplett weg, und ein nackter 1px-Rahmen bei der alten
   Ring-Deckkraft 0.25 waere ohne diesen Glow-Unterbau sichtbar blasser
   als der bisherige Gesamteindruck -- 0.45 gleicht das fuer einen
   vergleichbar praesenten Rahmen aus. Bleibt so (Entscheidung des
   Auftraggebers in Nachbesserungsrunde 1).

   "box-sizing: border-box" ist nicht optional: der Legacy-Knopf ist
   40x40 ohne Rahmen; ein 1px-Rahmen ohne border-box macht daraus 42x42
   und verschiebt die ganze Rail. Die Aussenmasse bleiben zwar 40x40,
   aber die Padding-Kante (= Content-Kante, da kein Padding gesetzt ist)
   ruecken durch den neuen 1px-Rahmen 1px nach innen. Der Statuspunkt
   (::after, right:5px/top:5px) und die Tooltip-Box (::before, left:48px;
   beide webapp.css:3554-3591, unveraendert Legacy) sind als absolut
   positionierte Kinder relativ zu genau dieser Padding-Kante platziert
   und ruecken auf den fuenf aktiven Knoepfen dadurch optisch 1px ein.
   Kosmetisch, nicht behoben (Nachbesserungsrunde 1, Befund 10). */
[data-design="new"] .nav-rail .rail-btn.active-chat {
  background: rgba(var(--clr-accent-rgb), 0.18);
  box-shadow: none;
  border: 1px solid rgba(var(--clr-accent-rgb), 0.45);
  box-sizing: border-box;
}
[data-design="new"] .nav-rail .rail-btn.active-ai {
  background: rgba(var(--clr-violet-rgb), 0.18);
  box-shadow: none;
  border: 1px solid rgba(var(--clr-violet-rgb), 0.45);
  box-sizing: border-box;
}
[data-design="new"] .nav-rail .rail-btn.active-fav {
  background: rgba(var(--clr-amber-rgb), 0.18);
  box-shadow: none;
  border: 1px solid rgba(var(--clr-amber-rgb), 0.45);
  box-sizing: border-box;
}
[data-design="new"] .nav-rail .rail-btn.active-res {
  background: rgba(var(--clr-cyan-rgb), 0.15);
  box-shadow: none;
  border: 1px solid rgba(var(--clr-cyan-rgb), 0.45);
  box-sizing: border-box;
}
[data-design="new"] .nav-rail .rail-btn.active-projects {
  background: rgba(var(--clr-success-rgb), 0.16);
  box-shadow: none;
  border: 1px solid rgba(var(--clr-success-rgb), 0.45);
  box-sizing: border-box;
}

/* Hell-Theme (Nachbesserungsrunde 1, Befund 3 -- Major): Legacy setzt fuer
   DREI der fuenf Bereiche eine eigene, gedecktere Hell-Flaeche (chat/ai/
   projects, webapp.css:9569-9571, Deckkraft 0.12 statt 0.18/0.18/0.16).
   Die Bereichsfarbe selbst (--clr-accent-rgb usw.) ist bereits theme-
   bewusst -- ohne diese Regeln wuerde die Rail also nicht die falsche
   FARBE zeigen, sondern die falsche, fuer Dunkel gedachte DECKKRAFT auf
   der richtigen Farbe durchschlagen. Im vollen Stapel gemessen (nicht aus
   webapp.css abgeschrieben -- tokens.css:150-217/:219-277 haengt
   --clr-accent-rgb unter [data-design="new"] auf cyan/500 um, in BEIDEN
   Themes): ohne diese Regel rgba(0,159,227,0.18) statt der gewollten
   rgba(0,159,227,0.12) fuer den aktiven Chat-Knopf hell (Nachbesserungs-
   runde 3, Befund 1 -- derselbe falsche Kommentarwert 79,70,229 stammte
   aus webapp.css statt aus dem vollen Stapel und ist hiermit korrigiert).
   fav/res haben in Legacy KEINE eigene Hell-Flaeche und bleiben deshalb
   bewusst unangetastet -- ihre themebewusste Grundregel oben reicht.
   Rahmen/box-shadow/box-sizing bleiben von der themenlosen Regel oben,
   hier wird nur die Flaeche nachgezogen. Spezifitaet (0,5,0) schlaegt
   sowohl die eigene themenlose Regel oben (0,4,0) als auch Legacys
   Hell-Fassung (0,4,0, webapp.css:9569-9571) unabhaengig von der
   Ladereihenfolge -- OHNE diese Regel waeren die beiden (0,4,0)
   tatsaechlich gleichauf und components.css gewaenne nur durch
   Ladereihenfolge (derselbe Gleichstand-Mechanismus wie in Befund 9/4
   dokumentiert). */
[data-design="new"][data-theme="light"] .nav-rail .rail-btn.active-chat {
  background: rgba(var(--clr-accent-rgb), 0.12);
}
[data-design="new"][data-theme="light"] .nav-rail .rail-btn.active-ai {
  background: rgba(var(--clr-violet-rgb), 0.12);
}
[data-design="new"][data-theme="light"] .nav-rail .rail-btn.active-projects {
  background: rgba(var(--clr-success-rgb), 0.12);
}

/* Statuspunkt (::after, webapp.css:3554-3572) und Notif-Badge (.notif,
   :3644-3660) tragen einen 1,5px-Ring in var(--clr-base-deep) -- gedacht,
   um mit dem Rail-Untergrund zu verschmelzen (der Ring "schneidet" die
   dahinterliegende Bereichsfarbe optisch frei). Seit die Railflaeche
   oben auf var(--ax-bg-nav) umgestellt ist, muss der Ring nachziehen,
   sonst zeigt er sichtbar den alten dunklen Legacy-Ton (gemessen:
   Rail #12111c, Ring #070608 -- Nachbesserungsrunde 1, Befund 5,
   Medium). Nur "border-color" wird angefasst, Breite/Stil bleiben
   Legacys eigene 1,5px solid. */
[data-design="new"] .nav-rail .rail-btn.active-chat::after,
[data-design="new"] .nav-rail .rail-btn.active-ai::after,
[data-design="new"] .nav-rail .rail-btn.active-fav::after,
[data-design="new"] .nav-rail .rail-btn.active-res::after,
[data-design="new"] .nav-rail .rail-btn.active-projects::after,
[data-design="new"] .nav-rail .notif {
  border-color: var(--ax-bg-nav);
}

/* Mobile Breakpoints (Nachbesserungsrunde 3, Befund 3 -- Medium, in Task 1
   behoben statt in Task 2, aus demselben Grund wie Befund 4: die Rail hat
   die Breite geaendert, sie traegt die Folgen). Vor dieser Aenderung war
   der eingeklappte Container 60px breit und "overflow: hidden" (webapp.css
   :5459-5473) hat die 64px-Rail auf 60px beschnitten -- niemand sah die
   fehlenden 4px. Seit Runde 2 ist der Container echte 64px, die Rail passt
   vollstaendig hinein, aber die Mobilregeln, die um die Rail HERUM Platz
   lassen, rechnen weiter mit 60. Ergebnis: die Rail (z-index:100 bei
   <=1024px, webapp.css:6608) liegt ueber den ersten 4px des Inhalts
   (z-index:5), der bei "left"/"margin-left: 60px" beginnt statt bei 64.

   Fuenf Fundstellen geprueft, EINE weitere durch Volltextsuche nach "60px"
   in webapp.css gefunden und als NICHT betroffen verworfen (".mp-hero"/
   ".mp-pane-datainfo", Marketplace-Detailseite, :8462/:8718 -- kein Bezug
   zur Rail-Geometrie; ebenso :2177, das den 60px-Ausdruck fuer den
   Embed-iframe explizit STILLLEGT, nicht fortschreibt).

   ".chat-container"/".aiservice-container"/".aiservice-execution-
   container" (:10745/:10388/:10396) haben im <=640px-Block eigene
   left/width-Regeln, die es im <=1024px-Block gar nicht gibt (dort nur
   "position: absolute" bzw. "left: 20px") -- 641-1024px ist bei ihnen gar
   nicht betroffen (kein "left: 60px" dort), nur <=640px, wo eingeklappt
   laut cockpitnavigation.js:253-255 der mobile Ausgangszustand ist. Diese
   drei stehen im <=640px-Block weiter unten.

   KORREKTUR Runde 4 zum Block hier: die Fassung aus Runde 3 stand in
   "@media screen and (max-width: 1024px)" und trug den Praefix direkt.
   Beides war falsch; die frueheren Kommentarzeilen dazu behaupteten das
   Gegenteil und haben genau diese Fehlerrunde ausgeloest. Was wirklich
   gilt -- im vollen Stapel (webapp.css -> tokens.css -> components.css)
   mit echtem Chromium nachgemessen, nicht gerechnet:

   1. UNTERHALB von 641px darf hier gar kein Rail-Versatz stehen.
      webapp.css:10382 oeffnet "@media (max-width: 640px)"; darin setzen
      webapp.css:10599 (".chatbot-input", NACKTE Klasse, Spezifitaet
      (0,1,0)) und webapp.css:10708 (".input-container", NACKTE Klasse,
      (0,1,0)) das Layout auf volle Breite zurueck -- die Eingabe klebt
      dort mit 8px bzw. 10px am Rand, weil ".chat-container" und
      ".aiservice-container" selbst schon hinter der Rail beginnen. Ein
      dritter nackter Reset fuer ".chatbot-input" steht in webapp.css:8590.
      Die Runde-3-Fassung stand mit Praefix bei (0,2,0), schlug alle drei
      und addierte den Rail-Versatz ein zweites Mal.
      Gemessen bei 600px, ".chatbot-input": Legacy links 68 / Breite 516 /
      rechts 584 -- Runde-3-Fassung links 128 / Breite 424 / rechts 552.
      Also 64px Loch links und 32px Totraum rechts.

   2. Im Bereich 641-1024px hat der Praefix eine bestehende Schichtung
      UMGEKEHRT. webapp.css:9396 (".aiservice-execution-container
      .input-container", (0,2,0), OHNE Media-Query, gilt also bei jeder
      Breite) setzt bewusst "margin-left: 0" und "width: calc(100% - 45px)":
      Gegen (0,2,0) hilft der Praefix nicht: Gleichstand, und
      components.css laedt spaeter, also gewann die neue Regel.

      ACHTUNG, hier stand eine falsche Begruendung: die Karte sitze in
      einem Container, der bei <=1024px schon auf "left: 20px" stehe
      (webapp.css:6574-6577), ein zweiter Versatz waere doppelt. Das
      traegt nicht -- 20px liegen NICHT hinter der 60/64px-Rail. Der
      Container traegt "z-index: 10" (:2384) gegen "z-index: 100" der
      Rail (:6608); die Karte steckt bei 641-1024px also schon im ALTEN
      Design 15px unter der Rail, im neuen 18px. Ein Legacy-Fehler, den
      diese Runde bewusst wiederherstellt, weil webapp.css unantastbar
      ist -- und genau das ist die tragfaehige Begruendung.
      Gemessen bei 800px: Legacy links 46 / rechts 785 --
      Runde-3-Fassung links 110 / rechts 810, bei Containerkante 820.

   Daraus die zwei Aenderungen: der Block gilt jetzt
   "(min-width: 641px) and (max-width: 1024px)", und der Marker steht in
   ":where()". ":where()" traegt null Spezifitaet bei, die Regel faellt auf
   (0,1,0) zurueck -- genau dorthin, wo webapp.css:6591 und :6629 stehen.
   Die urspruengliche Schichtung ist damit wiederhergestellt statt
   invertiert; dieselbe Technik wie bei den Basisregeln fuer button/a/input
   weiter oben in dieser Datei.

   Die Invariante dazu: eine per ":where()" entschaerfte Regel darf nur
   Eigenschaften setzen, die die Legacy-Regel ebenfalls setzt -- sonst
   greift sie unangefochten, egal wie niedrig ihre Spezifitaet ist. Hier
   sind es "width" und "margin-left", beide stehen auch in
   webapp.css:6591-6594 bzw. :6629-6635.

   Nahtstelle: "max-width: 640px" und "min-width: 641px" lassen ein Fenster
   im Bereich (640px, 641px) frei; dort gilt weiter der Legacy-Versatz 60px
   aus webapp.css:6591. Unter einem Pixel Fensterbreite, hoechstens 4px
   Ueberdeckung -- bewusst in Kauf genommen statt eines Bruchzahl-
   Breakpoints.

   Die width-Differenz bleibt erhalten (60->64 sind +4px, also 80->84 bzw.
   100->104, damit der rechte Abstand exakt gleich bleibt), nicht neu
   erfunden. */
@media screen and (min-width: 641px) and (max-width: 1024px) {
  :where([data-design="new"]) .input-container {
    width: calc(100% - 84px);
    margin-left: 64px;
  }

  /* NACHGEZOGEN VON "07 · Chat & AI" TEIL B, TASK 1: 104 -> 112.

     Die 104 sind eine ABLEITUNG, keine Konstante. Sie halten die rechte
     Aussenkante dort fest, wo Legacy sie hat: der Versatz waechst um 4px
     (60 -> 64), also waechst der Abzug um 4px (100 -> 104) -- gerechnet
     mit Legacys waagerechtem Innenabstand von 2 x 10px. Teil B setzt dort
     Figmas "16 12 12 16", also 28 statt 20 Pixel, und der Kasten ist in
     diesem Band "content-box": der Zuwachs geht nach AUSSEN. Bliebe der
     Abzug bei 104, waere die rechte Kante um genau diese 8px gewandert --
     die Absicht dieser Regel waere gebrochen, nicht bewahrt. 112 = 104 + 8
     stellt sie wieder her.

     Gemessen bei 800px, rechte Kante: Legacy 782, mit 104er-Abzug 790,
     mit 112er-Abzug wieder 782. Der Versatz links bleibt unangetastet bei
     4px (60 -> 64), das Band bleibt 641-1024px, "margin-left" bleibt 64px.

     WARUM NUR HIER UND NICHT AUCH IM BASISFALL: oberhalb von 1024px gibt
     es keine Regel dieses Teilprojekts auf "width", und der Bestand
     (webapp.css:5529, "calc(100% - 100px)") ist unantastbar. Dort wandert
     die rechte Kante deshalb sehr wohl um 8px -- und das ist gemessen eine
     VERBESSERUNG: bei 1280px endet ".chat-window" bei 1250, der Composer
     stand mit 1242 acht Pixel zu kurz und ist jetzt buendig mit der
     Nachrichtenspalte. In diesem Band hier ist er dagegen schon im ALTEN
     Design 12px darueber hinaus (".chat-window" endet bei 770), weshalb
     der Zuwachs ihn nur weiter hinausschoebe. Deshalb hier heilen, dort
     nicht. */
  :where([data-design="new"]) .chatbot-input {
    width: calc(100% - 112px);
    margin-left: 64px;
  }
}

@media (max-width: 640px) {
  [data-design="new"] .aiservice-container {
    left: 64px;
    width: calc(100% - 72px);
  }

  [data-design="new"] .aiservice-execution-container {
    left: 64px;
    width: calc(100% - 72px);
  }

  /* ENTFERNT 2026-09-25 (Sichtpruefung Mobil): hier stand
       "left: 64px; width: calc(100% - 72px)"
     -- eine Handkompensation fuer den Versatz, den die absolute Lage des
     Chatbereichs erzeugte. Seit die Inhaltsbehaelter im neuen Design
     unterhalb 1024px im Fluss stehen (Regel am Dateiende), rechnet das
     Raster den Versatz selbst aus; die Zeilen wuerden ihn ein zweites Mal
     abziehen. */
}

/* ══ 06 · Shell & Nav — Task 2: Sidebar ═══════════════════════════
   Figma: Sidebar 225 breit, Innenabstand 16/12, Abstand 4, Flaeche
   bg/nav, Rahmen border/default.
   Die Breite liegt im Code nicht auf dem Panel (".chatbot-service-panel"
   ist "flex: 1"), sondern auf dem Rahmen ".chatbot-service" --
   64 Rail + 225 Sidebar = 289.

   GEMESSEN, nicht gerechnet (echtes Chromium, voller Stapel webapp.css ->
   tokens.css -> components.css, data-design="new", dunkel, 1400px,
   Transitionen abgeschaltet): der Rahmen ist mit "box-sizing: border-box"
   (Task 1) 289px BREIT EINSCHLIESSLICH seines eigenen 1px-Rahmens rechts.
   Das Panel als Element misst deshalb 289 - 1 - 64 = **224**, nicht 225.
   Die 225 aus Figma sind die sichtbare Sidebar-Breite inklusive ihrer
   rechten Kante -- diese Kante liegt im Code auf dem Elternelement
   ("border-right" von ".chatbot-service"), nicht auf dem Panel. Beide
   Zahlen sind also dieselbe Sidebar; nur die Elementgrenze liegt anders.
   Der Test sichert deshalb 224 zu und nennt den Grund.

   "flex-shrink: 0" ist KEIN Beiwerk, sondern die Bedingung dafuer, dass die
   289 ueberhaupt ankommen (Nachbesserungsrunde 1, Blocker). Die Chatbot-
   Seite haengt ".chat-container" als Flex-Geschwister neben
   ".chatbot-service" (cockpitchatbot.js:43-56); ".chat-container" traegt
   "width: 100%" (webapp.css:2081), oberhalb von 1024px gibt es fuer
   ".chatbot-service" kein "min-width", und ohne Schrumpfschutz verteilt die
   Flex-Rechnung das Defizit anteilig auf beide. Gemessen bei 1280px im
   vollen Seitenbaum: Rahmen 235,92 statt 289, Panel 170,92 statt 224 --
   die Sidebar wurde SCHMALER statt breiter. Legacy schrumpft genauso (256,80
   statt 321) und tat das immer; das ist vorbestehendes Produktverhalten und
   bleibt unangetastet, weil webapp.css unantastbar ist. Figmas Sidebar ist
   eine feste Breite -- der Schrumpfschutz bringt Zahl und Absicht zur
   Deckung. Wirkt auch eingeklappt: dort war der 64px-Rahmen aus Task 1 bei
   1280px auf 61 zusammengedrueckt, waehrend die Rail ihre 64 behielt und
   unter "overflow: hidden" 3px abgeschnitten wurden.

   Der Rahmen (border-right/-top/-bottom) steht bewusst NICHT hier: die
   Bruecke haengt "--clr-border" bereits auf "--ax-border-default" um
   (tokens.css:151), webapp.css:5468-5470 liefert Figmas border/default
   also schon. Eine Wiederholung waere eine tote Zeile (gemessen mit und
   ohne: rgb(36, 34, 51) in Dunkel, rgb(210, 208, 218) in Hell). */
[data-design="new"] .chatbot-service {
  width: 289px;
  flex-shrink: 0;
  background-color: var(--ax-bg-nav);
}

/* "box-sizing: border-box" und ".panel-collapsed { width: 64px }" stehen
   bereits weiter oben (Task 1) -- hier bewusst NICHT wiederholt. */

/* Abschluss-Fixwelle (2026-09-22, H3, Blocker): ".panel-collapsed" (oben,
   Zeile ~2614) ist im neuen Design keine Klasse mehr, die irgendjemand
   setzt -- der Kollaps-Mechanismus ist seit Aufgabe A2
   ".cockpit-sidebar--eingeklappt" auf der SEITENLEISTE selbst, nicht auf
   dieser Huelle. Ohne eigene Regel blieb ".chatbot-service" beim Klick auf
   den Chevron unveraendert 289px breit, waehrend die Leiste darin auf
   64px schrumpfte -- eine ~225px LEERE SPALTE bei Desktop-Breite. Genau
   der Fehler aus Task 7 des Vorgaengerplans (siehe die GEMESSEN-Notiz
   oben), nur an anderer Stelle: eine Spaltenbreite, die fuer einen Inhalt
   bemessen war, den es so nicht mehr gibt. ":has()" koppelt die
   Huellenbreite an den tatsaechlichen Zustand der Leiste, ohne dass die
   Leiste selbst oder ihr Aufrufer davon wissen muessten. Spezifitaet
   (0,3,0), schlaegt die unbedingte 289px-Regel oben (0,2,0) unabhaengig
   von der Ladereihenfolge. Deckungsgleich mit den beiden Medienabfragen
   unten (<=1024px, <=640px), die denselben Zustand ueber die Fensterbreite
   statt ueber die Klasse erreichen -- dort bleibt "min-width" aus
   demselben Grund noetig (siehe deren Begruendung). */
[data-design="new"] .chatbot-service:has(.cockpit-sidebar--eingeklappt) {
  width: 64px;
  min-width: 64px;
}

/* Die zwei Legacy-Verengungen fuer schmale Fenster mitgezogen. Ohne diese
   zwei Bloecke gilt oben stehende 289 bis 0px hinunter, weil
   "[data-design=\"new\"] .chatbot-service" bei (0,2,0) steht und beide
   Legacy-Regeln bei (0,1,0) bzw. (0,2,0) -- Media-Queries tragen KEINE
   Spezifitaet bei, und components.css laedt spaeter. ":where()" hilft hier
   nicht: es faellt auf (0,1,0) zurueck und gewinnt damit trotzdem, weil
   beide Gegenregeln im frueher geladenen webapp.css stehen. Nur das
   Spiegeln in denselben Breakpoints stellt den Legacy-Verlauf her.
   Uebernommen wird jeweils der Legacy-Wert plus die 4px, die die Rail
   breiter geworden ist (60 -> 64) -- dieselbe Rechnung wie bei den
   Mobil-Offsets aus Task 1, damit die Sidebar selbst ihre fuer schmale
   Fenster gedachte Breite behaelt (200 bzw. 220) statt auf Figmas 225
   aufzugehen.

   KEIN "min-width" hier: die Legacy-Regeln setzen es paarweise mit
   "width" (webapp.css:6609 f., :10728 f., :10739 f.), und ein "min-width"
   bei (0,2,0) wuerde den eingeklappten Zustand mit hochziehen -- die
   Kollapsregel aus Task 1 setzt nur "width", die Untergrenze bliebe dann
   auf 264 stehen und das Cockpit koennte nicht mehr einklappen. Mit den
   Legacy-Untergrenzen (260 bzw. 280) bleibt nur ein theoretischer
   Schrumpfweg von 4px unter extremem Flex-Druck; das ist der guenstigere
   Tausch.

   BERICHTIGT (2026-09-22, Sichtpruefung/Task 7): die Rechnung oben ging
   von einer unterhalb 1024px SICHTBAREN Seitenleiste aus, die nur enger
   werden sollte. Tatsaechlich blendet "[data-design=\"new\"]
   .cockpit-sidebar { display: none }" (components.css, Block "@media
   (max-width: 1024px)" weiter unten in dieser Datei) die Seitenleiste in
   genau diesem Fenster unbedingt aus -- unabhaengig vom hier gesetzten
   Wert. Sichtbar bleibt einzig die Symbolleiste (".nav-rail", 64px breit,
   Regel oben in dieser Datei). 264 bzw. 284px bemassten deshalb eine
   Flaeche, die es dort nicht mehr gibt: GEMESSEN (echtes Chromium) eine
   200px leere Spalte bei 900x800 (eingeklappt wie ausgeklappt, da die
   Seitenleiste ohnehin fehlt) und eine 216px leere Spalte bei 500x800 im
   ausgeklappten Zustand (280 statt 284 gemessen -- derselbe Box-Sizing-
   Effekt wie bei ".chatbot-service.panel-collapsed" oben). Genau dieser
   Leerraum war der Anwender-Befund "leeres Panel bei kleinerer Aufloesung"
   (Sichtpruefung, Befund 4). Beide Regeln setzen deshalb jetzt 64px --
   deckungsgleich mit ".chatbot-service.panel-collapsed" (Task 1, oben)
   und mit dem, was in diesem Fenster tatsaechlich noch drinsteht. Der
   urspruengliche Vergleichswert
   (264/284, gerechnet fuer 200/220 Sidebar-Breite) bleibt oben zur
   Nachvollziehbarkeit stehen.

   "KEIN min-width" OBEN GILT NICHT MEHR: das war fuer 264/284 richtig --
   beide lagen ueber der jeweiligen Legacy-Untergrenze (260 bzw. 280,
   siehe Absatz oben), "width" allein reichte. 64px liegt DARUNTER, und
   ohne eigenes "min-width" GEWINNT die Legacy-Untergrenze trotz
   niedrigerer Spezifitaet: "min-width" schlaegt bei der Berechnung der
   tatsaechlichen Breite ein zu kleines "width" IMMER, unabhaengig von der
   Kaskade, die nur bestimmt, welches "width"/"min-width"-Paar ueberhaupt
   gilt (GEMESSEN, echtes Chromium: mit nur "width: 64px" blieb die Spalte
   bei 260px bzw. 280px stehen -- exakt die Legacy-"min-width" aus
   webapp.css:6719/:10897/:10903 -- die 200/216px Luecke von oben blieb
   unveraendert). Beide Regeln setzen deshalb zusaetzlich "min-width:
   64px". */
@media screen and (max-width: 1024px) {
  [data-design="new"] .chatbot-service {
    width: 64px;
    min-width: 64px;
  }
}

@media (max-width: 640px) {
  [data-design="new"] .chatbot-service:not(.panel-collapsed) {
    width: 64px;
    min-width: 64px;
  }
}

/* ENTFERNT (2026-09-22, C2c-2/Task 8 Nachbesserung 2, I-1): hier standen
   sechs weitere Regeln fuer ".chatbot-service-panel" im neuen Design:
   - Grundflaeche/Innenabstand ("background: var(--ax-bg-nav); padding: 16px
     12px; gap: var(--ax-space-1); box-sizing: border-box;")
   - ".container-tab-widget" ("padding: 8px 0 0;")
   - ".container-cockpit-agent" ("padding: 18px 0 10px; width: 100%;")
   - ".container-cockpit-project" ("padding: 18px 0 10px;")
   - ".new-chat-btn" ("margin: 0 0 10px;")
   - ".timesaving-row" ("margin: 0 0 10px;")
   Alle sechs, wie die drei Zeilenregeln oben, setzten einen
   ".chatbot-service-panel"-Vorfahren voraus. Das Panel entfaellt im neuen
   Design ersatzlos (Task 8) -- keiner dieser vier Wirte
   (Reiterleiste/Agentenwahl/Projektwahl/Neuer-Chat-Knopf/Zeitersparnis-Zeile)
   kann dort je wieder darunter haengen. Exakt dieselbe Unerreichbarkeit wie
   bei den drei bereits entfernten Zeilenregeln, nur beim ersten Durchgang
   uebersehen. */

/* ENTFERNT (2026-09-22, C2c-2/Task 8): hier standen drei Regeln fuer
   "[data-design=\"new\"] .chatbot-service-panel :is(#chat-history,
   #project-chat-history, #project-members-list, #service-history,
   #running-services-list, #project-skills-list) .container-left-right-
   spacebetween" (Grundzeile min-height 34/padding 8 12/radius
   var(--ax-radius-md)), ihre aktive Variante (background:
   var(--ax-action-primary-bg)) und deren Icon-Box (background:
   transparent). Alle drei setzten einen ".chatbot-service-panel"-Vorfahren
   voraus. Das Panel entfaellt im neuen Design ersatzlos (Task 8) -- keine
   der sechs Listen kann dort je wieder unter dieser Klasse haengen
   (Chat-/Service-Historie leben in der Seitenleiste mit eigenen Regeln,
   #project-members-list/#project-skills-list nur noch im DialogProject).
   Die drei Regeln waren damit bereits vor dieser Bereinigung unerreichbar,
   sobald das Panel weg ist -- design-shell-frames.spec.ts "Sidebar-Eintrag:
   Figmas Zeilenkasten im neuen Design" maß das nach (dort korrigiert).

   NACHGETRAGEN (2026-09-22, C2c-2 Abschluss, Empfehlung 1): fuer DREI der
   sechs Listen stimmte "keine Ersatzregel" nicht -- #project-members-list
   und #project-skills-list leben seit Task 7 in DialogProject,
   #running-services-list seit Task 6 in DialogLaufendeDienste (beide
   Dialog-Unterklassen, Wurzelklasse ".dialog", siehe dialog.js). Sie fielen
   ohne Regel auf die generische Zeilendarstellung zurueck. Die Grundzeile
   (Aktiv-Variante und Icon-Box waren nie noetig: keiner der drei Aufrufer
   vergibt "chat-history-active", das ist ausschliesslich Chat-/Service-
   Historie vorbehalten, siehe templatecockpitnavigationchatbot.js:852 und
   templateprojectpanel.js:1058/1210) bekommt hier ihren neuen Wirt. */
[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .container-left-right-spacebetween {
  min-height: 34px;
  padding: 8px 12px;
  gap: 12px;
  border-radius: var(--ax-radius-md);
  box-sizing: border-box;
}

/* ══ Dialog "Ai-Services in Arbeit" + Geschwisterlisten: Zeileninhalt
   (Aufgabe D, 2026-09-22) ═════════════════════════════════════════════
   Die Grundzeile oben (min-height/padding/radius) macht die Zeile nur als
   FLAECHE sichtbar -- ihr INHALT blieb ungestaltet. Neun weitere Regeln
   standen in webapp.css nur unter ".chatbot-service-panel
   #running-services-list" (Zeilen 10120, 10129, 10134, 10146, 10160,
   10170, 10176, 10182, 10187 helle Variante); das Panel entfaellt im
   neuen Design, keine davon griff noch. Der Organismus rendert Status und
   Fortschritt sehr wohl (organismsrunningservices.js:125-140, ueber
   "item.setSubtext()" -> "data-time"-Attribut auf dem "<li>"); ohne die
   "li::after"-Regel weiter unten blieb dieser Text unsichtbar -- exakt der
   gemeldete Mangel ("Status, Fortschritt usw." fehlen).

   Dieselbe Kette (MoleculeCommandListItem/MoleculeFeedbackListItem,
   gleiche Klassennamen) traegt auch "#project-members-list" (Rollenlabel
   als Subtext, dialogproject.js:997 -> _fillMembers()) und
   "#project-skills-list" (kein Subtext, aber dasselbe Icon-Feld und
   dieselbe Marker-/Ellipsis-Notwendigkeit der "li"-Regel). Beide
   Geschwisterlisten hatten denselben blinden Fleck wie
   "#running-services-list" -- nur hat es noch niemand gemeldet. Alle drei
   bekommen deshalb dieselben Regeln, wie schon die Grundzeile oben.

   Bewusst NICHT uebernommen: das "!important" auf "border-left"
   (webapp.css:10125/10132) -- in components.css verboten (Unit-Test), und
   kein Vorfahre hier setzt ueberhaupt einen linken Rahmen, den es zu
   unterdruecken gaebe. Die HELLE Variante der Hover-Flaeche
   (webapp.css:10187, eigener "[data-theme=\"light\"]"-Block) bekommt
   ebenfalls KEINE eigene Regel: "--ax-bg-hover" definiert sich fuer
   "[data-design=\"new\"][data-theme=\"light\"]" bereits selbst um
   (tokens.css:96-104) -- eine zweite Regel waere nur eine Kopie des
   Tokenwerts. */
[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .container-left-right-spacebetween:hover {
  background: var(--ax-bg-hover);
}

[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .list-item-icon {
  width: 26px;
  height: 26px;
  border-radius: var(--ax-radius-sm);
  background: var(--ax-bg-surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--ax-text-secondary);
}

[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .container-left-right-spacebetween li {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  font-size: var(--ax-font-size-label-sm);
  color: var(--ax-text-secondary);
  padding-left: 0;
  list-style: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Der eigentliche Befund: ohne dieses "::after" bleibt "data-time" (Status
   + Fortschritt bei "#running-services-list", Rolle bei
   "#project-members-list") im Dokument, aber ohne jede Darstellung --
   "erfinde keine Daten" heisst hier: der Zahlenwert des Servers wird
   ROH als Text gezeigt, keine Fortschrittsleiste. */
[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .container-left-right-spacebetween li::after {
  content: attr(data-time);
  font-size: 10px;
  color: var(--ax-text-muted);
  font-weight: normal;
  display: block;
  white-space: nowrap;
  margin-top: 1px;
}

[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .container-left-right-spacebetween .dropdown {
  flex-shrink: 0;
  margin-left: 4px;
  margin-right: 0;
}

[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .container-left-right-spacebetween .dropdown .settings-icon {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.1s;
}

[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .container-left-right-spacebetween:hover .dropdown .settings-icon,
[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .container-left-right-spacebetween:focus-within .dropdown .settings-icon,
[data-design="new"] .dialog
  :is(#project-members-list, #project-skills-list, #running-services-list)
  .container-left-right-spacebetween .dropdown-trigger[aria-expanded="true"] .settings-icon {
  opacity: 1;
  pointer-events: auto;
}

/* ══ 06 · Shell & Nav — Task 3: Seitenkopf ════════════════════════
   Figma: Hoehe 84, Innenabstand 16/0, Abstand 16, unterer Rahmen
   border/default; Zurueck-Knopf 36x36 Radius 10 auf bg/surface-2 mit 1px
   border/default; Titelblock-Abstand 4; Ueberzeile text/muted.

   Die horizontale Null wird NICHT uebernommen: Figmas Rahmen bekommt den
   seitlichen Abstand vom Elternrahmen, im Code stellt ihn niemand
   (Spec Abschnitt 7). Es bleibt bei 20px seitlich.

   "min-height" statt "height": der Titel darf umbrechen und den Kopf
   wachsen lassen, statt beschnitten zu werden. Dieselbe Lehre wie beim
   Button in 04 - Core.

   GEMESSEN, nicht gerechnet (echtes Chromium, voller Stapel webapp.css ->
   tokens.css -> components.css in der Reihenfolge aus cockpit.html:16-18,
   Baum nach editprofilepage.js:180-191 nachgebaut -- also mit dem echten
   ".chatbot-service"-Geschwister, nicht mit einem Platzhalter --,
   1280x720, Transitionen abgeschaltet). Die Abgrenzung ist hier wichtig,
   weil zwei verschiedene Zahlen umlaufen:

     ohne Ueberzeile                                      65,00px
     ohne DIESE Regel, Ueberzeilenregel unten aktiv       76,39px
     ohne den GANZEN Block (= altes Design)               74,39px

   Die zwei Pixel Unterschied zwischen 76,39 und 74,39 sind die Ueberzeile,
   die unten schon 4px statt 2px traegt. Eine fruehere Fassung dieses
   Kommentars schrieb 76,39 dem Zustand "ohne die Regeln dieses Blocks" zu
   -- gemessen sind das 74,39. Alle drei Werte liegen unter 84; die neue
   Untergrenze greift also wirklich.

   ZWEI RESTATEMENTS, per deleteRule gegengeprueft und bewusst behalten:
   "border-bottom" steht wortgleich in webapp.css:8799, und die Bruecke
   (tokens.css:151/223) haengt "--clr-border" ohnehin auf
   "--ax-border-default" um -- ohne diese Zeile misst der Kopf im neuen
   Design dunkel rgb(36, 34, 51), also denselben Wert. "box-sizing" steht
   in webapp.css:8801, gemessen "border-box" auch ohne die Regel hier.
   Keine der beiden Zeilen aendert heute ein gerechnetes Ergebnis; sie
   stehen hier, damit die Regel ihre Figma-Werte selbst benennt. */
[data-design="new"] .page-header {
  min-height: 84px;
  padding: 16px 20px;
  gap: 16px;
  border-bottom: 1px solid var(--ax-border-default);
  box-sizing: border-box;
}

/* Wiederherstellung der mobilen Zusammenfaltung. webapp.css:10408 setzt
   im Block "@media (max-width: 640px)" (geoeffnet :10382) den Kopf auf
   "padding: 10px 12px" -- mit NACKTER Klasse, also (0,1,0). Eine
   Media-Query addiert keine Spezifitaet, die Regel oben steht bei (0,2,0)
   und schlaegt sie. Ohne den Block hier traegt der Kopf auf dem Telefon
   wieder 16/20 UND zusaetzlich 84px Mindesthoehe.
   Gemessen bei 600x720: Legacy-Kopf 57px hoch, Innenabstand 10/12,
   "min-height: auto". Genau diesen Zustand stellen die zwei Zeilen wieder
   her; "min-height: auto" ist der Ausgangswert, den der Legacy-Kopf dort
   traegt (gemessen, nicht angenommen).
   ":where()" haette hier NICHT geholfen: es senkt die Regel oben auf
   (0,1,0) -- Gleichstand mit webapp.css:10408 --, und da components.css
   spaeter laedt, gewaenne sie trotzdem. Die Schichtung entsteht hier aus
   der Ladereihenfolge, nicht aus der Spezifitaet.
   Die 640er-Grenze uebernimmt bewusst webapp.css' Wert; der zweite
   Legacy-Schalter :10412 (h1 auf 15px) wird von keiner Regel dieses Tasks
   angefasst und braucht deshalb keine Wiederherstellung. */
@media (max-width: 640px) {
  [data-design="new"] .page-header {
    padding: 10px 12px;
    min-height: auto;
  }
}

/* Figmas Abstand 16 im Titelblock links. Legacy: 10px (webapp.css:8808).
   Kein Media-Query-Gegenstueck in webapp.css -- der Wert gilt in jeder
   Breite, wie im Legacy auch. */
[data-design="new"] .page-header-left {
  gap: 16px;
}

/* Ueberzeile. Figma stellt sie auf text/muted; webapp.css:8817 traegt
   "--clr-text-secondary", und die Bruecke haengt das auf
   "--ax-text-secondary" um. Beide Zustaende gemessen:
   dunkel ink/300 rgb(173, 171, 187) -> ink/400 rgb(129, 127, 146),
   hell  ink/600 rgb(53, 50, 74)     -> ink/500 rgb(85, 83, 106).
   Der Titelblock-Abstand 4 loest webapp.css:8818 (2px) ab. */
[data-design="new"] .page-header-agent {
  color: var(--ax-text-muted);
  margin-bottom: 4px;
}

/* Restatement, per deleteRule gegengeprueft: webapp.css:8824 setzt schon
   "--clr-text-primary", und die Bruecke (tokens.css:159/229) haengt das
   auf "--ax-text-primary" um. Ohne diese Regel misst der Titel im neuen
   Design dunkel rgb(232, 230, 238) und hell rgb(18, 17, 28) -- exakt die
   Werte, die sie setzt. Die Zeile benennt nur das Figma-Token direkt. */
[data-design="new"] .page-header-title h1 {
  color: var(--ax-text-primary);
}

/* Zurueck- und Aktionsknoepfe (webapp.css:8834). Figma: 36x36, Radius 10,
   Flaeche bg/surface-2, 1px border/default.
   Wirksam sind "border-radius" (8 -> 10) und "background": webapp.css:8839
   traegt "--clr-surface-1", ueber die Bruecke also ink/900
   rgb(18, 17, 28) dunkel bzw. ink/0 rgb(255, 255, 255) hell -- Figma will
   eine Stufe hoeher, ink/800 rgb(26, 24, 38) bzw. ink/50
   rgb(244, 243, 247). Beide Zustaende gemessen.
   "border" ist auf DIESEM Knopf wertgleich mit webapp.css:8838
   ("--clr-border" ist gebrueckt) -- als Kurzform setzt es aber auch
   "border-color" neu und nimmt damit ".page-action-btn.primary"
   (webapp.css:8860, ebenfalls (0,2,0)) dessen Akzentrahmen. Siehe die
   Schadensbegrenzung 1 unten. "box-sizing" ist dagegen ein reines
   Restatement: <button> traegt border-box aus der UA-Formatvorlage --
   ohne die Zeile misst der Knopf einschliesslich seines 1px-Rahmens
   exakt 36x36 (gemessen).
   "color" ist heute unsichtbar: der Inhalt ist ausschliesslich ein <img>
   (command.js:71, atombuttonback.js:26), und webapp.css:860-868 faerbt
   jedes Knopf-Icon per "filter: brightness(0) invert(1)" weiss, unabhaengig
   von "color". Die Zeile steht fuer kuenftige Textinhalte -- und traegt
   deshalb "--ax-text-primary", nicht "--ax-text-secondary"
   (Korrekturwelle nach dem Abschlussreview). Legacy setzt hier
   "--clr-text-primary" (webapp.css:8840), und die Bruecke haengt genau
   das auf "--ax-text-primary" um: die Zeile ist damit PARITAET mit
   Legacy und keine neue Wahl -- sie ist seither ein reines Restatement,
   per removeProperty("color") gegengeprueft (dunkel rgb(232,230,238),
   hell rgb(18,17,28), mit und ohne die Zeile identisch), genau wie
   ".page-header-title h1" weiter oben.
   Die erste Fassung stand auf "--ax-text-secondary" und war fuer den
   Fall, fuer den sie gedacht ist, die SCHLECHTERE Farbe. Auf der
   ".primary"-Variante gemessen, Text gegen die Akzentflaeche:
     Legacy ("--clr-text-primary"):   dunkel 2,983 | hell 2,543
     erste Fassung (text-secondary):  dunkel 1,318 | hell 2,585
     jetzt (text-primary):            dunkel 2,403 | hell 3,929
   Der dunkle Wert bleibt unter Legacy, und das liegt NICHT an dieser
   Zeile: die Flaeche darunter ist im neuen Design cyan/500 statt Legacys
   blue/500 (components.css:2149), also heller. Das ist derselbe
   systemische Befund wie an der Wizard-Ziffer -- Fundament-Ebene,
   Spec Abschnitt 12. */
[data-design="new"] .page-action-btn {
  border-radius: var(--ax-radius-md);
  background: var(--ax-bg-surface-2);
  border: 1px solid var(--ax-border-default);
  color: var(--ax-text-primary);
  box-sizing: border-box;
}

/* ZWEI SCHADENSBEGRENZUNGEN zur Regel oben, kein Figma-Wunsch. Beide
   betreffen Regeln, die Task 04 - Core fuer denselben Knopf schon
   angelegt hat (components.css:2146 und :2149) -- die Ausgangslage im
   Brief nennt nur webapp.css und uebersieht sie.

   1. RAHMENFARBE des Primary-Knopfes. organismspageheder.js:98 vergibt
      ".primary" an den ersten Aktionsknopf. Dessen FLAECHE ist sicher:
      "[data-design=\"new\"] button.page-action-btn.primary"
      (components.css:2149) steht bei (0,3,1) und schlaegt die Regel oben
      (0,2,0) -- gemessen dunkel rgb(0, 159, 227), hell rgb(0, 122, 176).
      Die RAHMENFARBE ist es nicht: webapp.css:8860 setzt sie bei (0,2,0),
      die Regel oben setzt "border" als Kurzform bei ebenfalls (0,2,0) und
      gewinnt ueber die Ladereihenfolge. Ohne die Zeile hier traegt der
      Primary-Knopf border/default um eine Akzentflaeche.
      Der Wert ist bewusst "--clr-accent" und nicht "--ax-action-primary":
      die Bruecke haengt "--clr-accent" je Theme UNTERSCHIEDLICH um --
      dunkel auf "--ax-action-primary" rgb(0, 159, 227), hell auf
      "--ax-text-link" rgb(0, 122, 176) (tokens.css:153 bzw. 257, dort mit
      WCAG-Begruendung). Die Flaeche daneben kommt aus components.css:2149
      und nennt ebenfalls "--clr-accent"; nur mit demselben Token bleiben
      Flaeche und Rahmen in BEIDEN Themes gleichfarbig. Eine erste Fassung
      dieser Zeile schrieb "--ax-action-primary" und erzeugte im Hell-Theme
      cyan/500-Rahmen um cyan/600-Flaeche.
      BERICHTIGT MIT T1 (2026-09-15, nachgetragen im Abschlussreview):
      DIESER FEHLER KANN SEITHER NICHT MEHR AUFTRETEN. Der Satz oben bleibt
      als Vorgeschichte stehen, aber er beschreibt kein Risiko mehr.
      "--ax-action-primary" steht im hellen Theme seit T1 selbst auf cyan/600
      (tokens.css, heller Semantik-Block); beide Token liefern hell also
      denselben Wert rgb(0, 122, 176), und eine Rueckkehr zu
      "--ax-action-primary" ergaebe hell cyan/600-Rahmen um cyan/600-Flaeche.
      DIE ZEILE BLEIBT TROTZDEM AUF "--clr-accent", und zwar aus dem zweiten,
      unberuehrten Grund: "--clr-accent" ist brandbar, "--ax-action-primary"
      nicht. Mit dem Semantik-Token verloere der Rahmen die
      Organisationsfarbe. Die Begruendung ist damit halbiert, nicht
      entfallen -- wer sie kuerzt, muss die Brandbarkeit stehen lassen.
      (Dieselbe Halbierung steht als GEHEILT-Vermerk an Abweichung 5 und 9
      in docs/manual/entwicklungshandbuch/14-frontend.md.)

   2. HOVER-FLAECHE. Sie ist NICHT kaputt -- "[data-design=\"new\"]
      button.page-action-btn:hover:not(:disabled):not(.primary)"
      (components.css:2146) steht bei (0,5,1) und schlaegt die Regel oben
      muehelos. Sie ist unsichtbar geworden: der Wert dort ist
      "--clr-surface-2", und genau dieses Token haengt die Bruecke NICHT
      um -- es bleibt die color-mix()-Rechnung aus webapp.css:19 bzw.
      :281 und rechnet sich mit den neuen Enden zu rgb(27, 25.5, 39.5)
      (dunkel) bzw. rgb(250.6, 250.2, 251.8) (hell). Solange die
      Ruheflaeche ink/900 rgb(18, 17, 28) war, war das ein sichtbarer
      Schritt; die Regel oben hebt sie auf ink/800 rgb(26, 24, 38) --
      1,5 von 255 Unterschied. Hell entsprechend: Ruhe ink/50
      rgb(244, 243, 247) gegen 6,6 von 255. Beide Zustaende per
      deleteRule (nur das LETZTE Vorkommen dieses Selektors) und
      CSS.forcePseudoState gemessen, nicht gerechnet.
      Diese Regel wiederholt den Selektor aus :2146 mit Figmas eigenem
      Hover-Token und gewinnt ueber die Ladereihenfolge (Gleichstand
      (0,5,1)); dasselbe Token nutzt components.css:142 schon fuer
      "button.btn-secondary:hover". Neue Werte, gemessen: dunkel ink/700
      rgb(36, 34, 51), hell ink/100 rgb(232, 230, 238). */
[data-design="new"] .page-action-btn.primary {
  border-color: var(--clr-accent);
}

[data-design="new"] button.page-action-btn:hover:not(:disabled):not(.primary) {
  background: var(--ax-bg-hover);
}

/* ══ 06 · Shell & Nav — Task 4: Tabs ══════════════════════════════
   ZWEI getrennte Systeme, in einem Block, weil beide "Tab" heissen:
   (1) ".tab-widget"/".tab" (webapp.css:4753-4800) -- das Markup, das
       MoleculeTabContainer erzeugt (tabcontainer.js:48-49).
   (2) "#menubuttons" (webapp.css:6096-6113) -- die zwei Menueknoepfe
       am Fuss der Nav-Rail (templatecockpitnavigationbase.js:99). Kein
       ".tab"-Markup, nur derselbe Name im Sprachgebrauch.

   Figmas Tab Item: 42 hoch, Innenabstand 10/13/0/13, keine Flaeche,
   kein Rahmen -- nur eine 2px-Unterstreichung, die im aktiven Zustand
   auf die volle Beschriftungsbreite waechst. Sie ist ein ":after" mit
   "left/right: 13px", KEIN "border-bottom" -- ein Rahmen waere so breit
   wie der Reiter statt wie die Beschriftung; die Begruendung steht
   ausfuehrlich an der Regel selbst.
   Heute ist ".tab" ein Kasten mit Rahmen auf allen vier Seiten
   (webapp.css:4782-4789). Das ist die groesste rein visuelle Aenderung
   dieses Teilprojekts.

   Spezifitaet: diese Regel steht bei (0,2,0), Legacys ".tab" bei
   (0,1,0) -- sie gewinnt. Die vertikale Fassung ".tab-widget.vertical
   .tab" (webapp.css:7922, (0,3,0)) gewinnt umgekehrt gegen SIE, und
   genau das ist gewollt: die vertikale Fassung ist kein Figma-Tab-Item
   (siehe den eigenen Block weiter unten).

   "box-sizing: border-box" ist Pflicht, nicht Kosmetik: es gibt in
   dieser Anwendung keinen universellen box-sizing-Reset (dritter Fall
   in diesem Teilprojekt, siehe ".nav-rail" und ".chatbot-service"
   oben). Ohne die Zeile bezoege sich "min-height: 42px" auf den
   INHALTSkasten, und der Innenabstand kaeme obendrauf:
   42 + 10 (oben) + 0 (unten) = 52. Genau so gemessen -- die Regel per
   removeProperty("box-sizing") entschaerft und nachgemessen: 52 statt
   42. Die Unterstreichung steuert NICHTS bei: sie ist seit dem
   Abnahme-Nachtrag ein absolut positioniertes ":after" und nicht mehr
   der 2px-"border-bottom", der hier frueher mitgerechnet wurde (die
   Rechnung stand deshalb bis zur Korrekturwelle auf 54). */
[data-design="new"] .tab {
  padding: 10px 13px 0;
  background: transparent;
  color: var(--ax-text-muted);
  border: none;
  min-height: 42px;
  box-sizing: border-box;
  /* Bezugsrahmen fuer die Unterstreichung weiter unten. Unbekaempft --
     Legacys ".tab" deklariert keine "position" --, deshalb nachgeprueft:
     ein waagerechter Reiter hat heute NULL Elementkinder (nur einen
     Textknoten, gemessen), es gibt dort also nichts, was dadurch einen
     neuen Bezugsrahmen bekaeme. Die einzigen absolut positionierten
     Nachfahren, die ein ".tab" ueberhaupt bekommen kann, sind
     ".status-dot" (webapp.css:7882) und ".tab-chevron" (:7978) -- beide
     gibt es nur in der vertikalen Fassung, und die deklariert
     "position: relative" seit jeher selbst (webapp.css:7923). Die zwei
     Aufrufer von showStatusDot() ausserhalb des Agenten-Editors
     (templatecockpitnavigation{chatbot,aiservice}.js) haengen den Punkt
     an einen "button.image-tabwidget" aus
     MoleculeTabContainerNavigation, nicht an ein ".tab". */
  position: relative;
}

/* Ohne diese Zeile ist Figmas 42px-Reiter an vielen Einbauorten NICHT zu
   sehen -- und zwar genau der Teil, der die ganze Aenderung ausmacht.
   Der Mechanismus, im echten Stapel gemessen (Galerie-Kachel, 1280x720):
   ".input-container" (webapp.css:3107) ist eine Spalten-Flexbox mit
   "max-height: calc(100vh - 300px)"; darin liegen die Tabzeile und der
   Tabkoerper, und der Tabkoerper traegt selbst "height: calc(100vh -
   300px)" (webapp.css:4861). Die Kinder wollen zusammen mehr Hoehe als
   der Container hergibt, also schrumpft Flex sie beide anteilig -- die
   Tabzeile von 42 auf 36,09. Der Reiter selbst behaelt seine
   "min-height: 42px" (ein Flexelement darf seinen Container ueberlaufen),
   und ".tab-widget:not(.vertical)" (webapp.css:4764) hat "overflow-y:
   hidden": die unteren 5,91px werden abgeschnitten -- darin die
   vollstaendige 2px-Unterstreichung, die zwischen 40 und 42 liegt.
   Gemessen ohne diese Regel: navClientHeight 36, navScrollHeight 42,
   Reiterunterkante 196,47 gegen Zeilenunterkante 190,56.
   Die Legacy-Fassung faellt nicht auf, weil ihr Reiter keine eigene
   Hoehe hat: er wird auf 36,09 mitgeschrumpft und verliert dort nur
   Zeilenhoehe (auch heute schon -- die 20px-Zeile steckt in 14,09px
   Inhaltshoehe, ein vorbestehender Legacy-Schoenheitsfehler).

   "flex-shrink" deklariert Legacys ".tab-widget" (webapp.css:4753)
   selbst NICHT -- die Eigenschaft ist also unbekaempft und gilt
   unabhaengig von jeder Spezifitaet. Das ist hier gewollt und
   ungefaehrlich: die einzige Legacy-Regel, die "flex-shrink" auf einer
   Tabzeile ueberhaupt setzt, ist ".tab-widget.vertical"
   (webapp.css:7908) -- und die setzt bereits denselben Wert 0. Beide
   stehen bei (0,2,0), Gleichstand mit identischem Wert, kein Konflikt.
   Die Hauptachse ist hier die senkrechte (der Elternteil ist eine
   Spalten-Flexbox), es geht also nur um Hoehe, nicht um Breite; die
   einzige Tabzeile mit einem ZEILEN-Elternteil ist die vertikale in
   ".tab-layout-vertical", und die traegt "flex-shrink: 0" seit jeher.
   Die 6px, die die Zeile jetzt nicht mehr abgibt, verliert der
   Tabkoerper -- der scrollt ohnehin ("overflow-y: auto"). */
[data-design="new"] .tab-widget {
  flex-shrink: 0;
}

/* "background: transparent" steht in beiden Zustandsregeln, aber NICHT
   aus dem Grund, den man vermutet -- nachgemessen, nicht gerechnet:
   ".tab.active" (webapp.css:4791) und ".tab:hover" (:4797) deklarieren
   beide "background", beide stehen aber nur bei (0,2,0) -- im
   Gleichstand mit "[data-design=new] .tab" oben. Loescht man die zwei
   Zeilen hier, bleibt die Flaeche trotzdem transparent, weil
   components.css NACH webapp.css laedt (per deleteRule geprueft: ohne
   die ".tab.active"- bzw. ".tab:hover"-Regel meldet
   getComputedStyle weiterhin "rgba(0, 0, 0, 0)").
   Die zwei Zeilen sind also eine HAERTUNG, kein Nachweis: sie heben die
   Entscheidung von (0,2,0)-Gleichstand-per-Ladereihenfolge auf
   (0,3,0)-per-Spezifitaet. Damit bleibt die Flaeche auch dann weg, wenn
   jemand die Ladereihenfolge der beiden Dateien vertauscht -- ein Fall,
   den diese Datei an ".nav-rail" schon einmal als echtes Risiko notiert
   hat. Ein Test darauf ist ein Waechter, kein Beweis der Regel.

   ABWEICHUNG VOM BRIEF, bewusst und gemessen: die Unterstreichung
   nimmt "--clr-accent", nicht "--ax-action-primary". Beide sind im
   dunklen Theme derselbe Wert (cyan/500, rgb(0,159,227)); im HELLEN
   Theme haengt die Bruecke "--clr-accent" auf "--ax-text-link"
   (tokens.css:257, cyan/600 rgb(0,122,176)), "--ax-action-primary"
   bleibt cyan/500. Drei Gruende fuer "--clr-accent":
   1. KONTRAST. cyan/500 auf hellem "--clr-surface-1" haelt 2,97 --
      unter der 3,0-Schwelle, die tests/features/design-contrast.spec.ts
      fuer das Paar ("--clr-accent", "--clr-surface-1") selbst
      erzwingt. cyan/600 haelt 4,76. Eine 2px-Zustandsanzeige ist eine
      UI-Komponente im Sinne von WCAG 1.4.11.
   2. PRAEZEDENZ. Exakt dieselbe Entscheidung steht schon in dieser
      Datei, siehe den Kommentar an "[data-design=new] .page-action-btn
      .primary" (Task 3): "Eine erste Fassung dieser Zeile schrieb
      --ax-action-primary und erzeugte im Hell-Theme cyan/500-Rahmen um
      cyan/600-Flaeche."
   3. BRANDING. brandingapplier.js:6 setzt "--clr-accent" je
      Organisation. Mit "--ax-action-primary" verloere der aktive Tab
      als einziges Element der Seite die Kundenfarbe.
   Diese Begruendung gilt jetzt fuer die "background"-Zeile an
   ".tab.active::after" weiter unten -- die Unterstreichung ist seit dem
   Abnahme-Nachtrag ein Pseudoelement, kein Rahmen mehr. Sie ist NICHT
   redundant, auch wenn Legacys ".tab.active" dasselbe Token nennt: ohne
   sie hat der aktive Reiter ueberhaupt keine sichtbare Unterstreichung,
   denn Legacys "border-bottom-color" faerbt einen Rahmen, den die
   Grundregel mit "border: none" entfernt hat. Was der gemessene Wert
   NICHT MEHR unterscheiden kann, ist "--clr-accent" gegen
   "--ax-action-primary": seit T1 (2026-09-15, tokens.css:127) sind die
   beiden UNGEBRANDET in BEIDEN Themes wertgleich -- dunkel
   rgb(0,159,227), hell rgb(0,122,176). Vor T1 trennte sie das helle
   Theme; heute trennt sie nur noch das Organisations-Branding. Die
   zweiseitige Messreihe dazu steht an ".tab.active::after" weiter
   unten. */
[data-design="new"] .tab.active {
  background: transparent;
  color: var(--ax-text-primary);
}

[data-design="new"] .tab:hover {
  background: transparent;
  color: var(--ax-text-primary);
}

/* DIE UNTERSTREICHUNG. Nachtrag zur Abnahme des Teilprojekts, und ein
   Befund derselben Klasse wie der abgeschnittene Reiter weiter oben: die
   erste Fassung nahm "border-bottom: 2px" auf ".tab" -- eine korrekte
   Deklaration, die etwas anderes zeigt, als sie soll. Ein Rahmen ist
   zwangslaeufig so breit wie sein Kasten, die Linie lief also ueber die
   volle REITERbreite. Spec Abschnitt 5 verlangt die volle BESCHRIFTUNGS-
   breite; bei "padding: 10px 13px 0" sind das 26px Unterschied je
   Reiter. Kein Test hat es gemerkt, weil "getComputedStyle" brav "2px"
   meldet, egal wie breit die Linie ist.

   WARUM left/right: 13px GENAU DIE BESCHRIFTUNG TRIFFT, nachgemessen
   statt angenommen: der Reiter ist ein Flexelement ohne "flex-grow"
   (gemessen 0/1/auto), seine Breite ist also seine Inhaltsbreite, und
   die Beschriftung fuellt die Inhaltsbox exakt aus -- gemessen an allen
   drei Galerie-Reitern und an zwei weiteren echten
   MoleculeTabContainer-Einbauorten (900px und 150px breit), in beiden
   Themes: Text-x gleich Inhaltsbox-x und Textbreite gleich
   Inhaltsboxbreite, auf zwei Nachkommastellen (61 / 84,2 / 45,06).
   "text-align" ist "start", nichts zentriert.
   EINE AUSNAHME, ebenfalls gemessen: wird ein mehrwortiges Etikett zum
   Umbruch gezwungen (Zeile auf 120px verengt), entstehen zwei Zeilen von
   119,63 und 61,83 in einer 119,63 breiten Inhaltsbox -- die
   Unterstreichung trifft dann die LAENGSTE Zeile. Fuer ein umbrechendes
   Etikett gibt es keine "volle Beschriftungsbreite"; die laengste Zeile
   ist die beste verfuegbare Bedeutung und in jedem Fall naeher dran als
   die volle Reiterbreite.

   NUR die waagerechte Fassung. ".tab-widget.vertical .tab" ist kein
   Figma-Tab-Item (siehe eigener Block weiter unten) und wuerde hier
   besonders falsch liegen: dort ist der Reiter auf 210px gedehnt, die
   Inhaltsbox 186px breit und die Beschriftung 82,11px -- gemessen. Der
   ":not(.vertical)"-Teil haelt das heraus; er wirkt auch in der
   Mobilfassung ab <=720px, in der die Spalte zur Zeile klappt, aber die
   Klasse behaelt.

   KEINE 40px-ANDEUTUNG IM RUHEZUSTAND, obwohl Figma sie zeigt: der
   Ruhezustand hat laut Spec keine Fuellung, und eine durchsichtige Linie
   hat keine sichtbare Breite. Die Andeutung waere ausschliesslich
   waehrend des Wachsens zu sehen -- und Uebergaenge sind in dieser
   Anwendung an dieser Stelle nicht deklariert (und in der Testsuite
   ohnehin abgeschaltet). Eine Geometrie zu bauen, die nichts zeigt,
   waere eine Behauptung ohne Wirkung; wer spaeter einen Uebergang
   einzieht, findet hier den Grund und die Stelle. */
[data-design="new"] .tab-widget:not(.vertical) .tab::after {
  content: "";
  position: absolute;
  left: 13px;
  right: 13px;
  bottom: 0;
  height: 2px;
  background: transparent;
}

/* Die 13px oben und hier muessen dem waagerechten Innenabstand der
   Grundregel folgen -- werden die 13 dort geaendert, gehoeren sie hier
   mitgeaendert.

   ZUR FARBE: "--clr-accent" statt "--ax-action-primary". Von den drei
   Gruenden, die hier standen (Kontrast im hellen Theme, Praezedenz in
   dieser Datei, Organisations-Branding), IST DER ERSTE ENTFALLEN.
   T1 (2026-09-15) hat "--ax-action-primary" im hellen Theme auf cyan/600
   geheilt (tokens.css:127); ungebrandet liefern beide Wurzeln jetzt in
   beiden Themes denselben Wert, die Kontrastzahl stimmt also auch ohne
   diese Wahl. GEBLIEBEN IST DAS BRANDING, und es traegt allein:
   brandingapplier.js haengt ausschliesslich "--clr-"-Wurzeln um (:6-17),
   "--ax-"-Tokens nicht. Mit "--ax-action-primary" verloere die
   Unterstreichung die Kundenfarbe -- in beiden Themes.

   ZWEISEITIG GEMESSEN (T1, Galerie-Kachel "gallery-tabs-default",
   ".tab:nth-child(1)::after", "background-color", Marke #ff5500):
                        mit dieser Regel   ohne sie
     dunkel ungebrandet rgb(0,159,227)     rgba(0,0,0,0)
     dunkel gebrandet   rgb(255,85,0)      rgba(0,0,0,0)
     hell   ungebrandet rgb(0,122,176)     rgba(0,0,0,0)
     hell   gebrandet   rgb(255,85,0)      rgba(0,0,0,0)
   Ohne die Zeile bleibt die Linie durchsichtig -- die Grundregel oben
   setzt "background: transparent", und ohne Fuellung hat eine 2px-Linie
   keine sichtbare Breite. Die Regel ist damit in allen vier
   Konfigurationen tragend, und die Markenspalte ist der Beleg, dass sie
   eine BRANDBARE Wurzel liest. */
[data-design="new"] .tab-widget:not(.vertical) .tab.active::after {
  background: var(--clr-accent);
}

/* Der Ueberlauf-Verlauf am rechten Rand der Tabzeile (webapp.css:4771,
   Klasse wird von MoleculeTabContainer.updateNavOverflowHint() gesetzt)
   endet auf "--clr-surface-1". Solange ".tab" eine Flaeche hatte, war
   das exakt die Farbe, gegen die der Verlauf blendete -- die Tabflaeche
   war ebenfalls "--clr-surface-1" (webapp.css:4785). Ohne Tabflaeche
   blendet er jetzt gegen den Hintergrund des UMGEBENDEN Containers, und
   der ist je Einbauort verschieden. Deshalb steht hier bewusst KEINE
   Korrektur: "--clr-surface-1" haengt unter [data-design="new"] bereits
   auf "--ax-bg-surface-1" (tokens.css:149) -- es IST also schon das
   passende --ax-Token, und ein anderes waere nicht richtiger, sondern
   nur anders falsch. Steht auf der Sichtpruefungsliste fuer Task 7. */

/* Die vertikale Fassung (webapp.css:7902-8000, Agenten-Editor) ist KEIN
   Figma-Tab-Item: sie ist eine Listennavigation mit Statuspunkt und
   Chevron, mit Flaeche im Aktivzustand und einem 2px-Streifen LINKS
   statt einer Unterstreichung. Sie bekommt deshalb bewusst keine
   Unterstreichung -- die Regel oben verliert dort ohnehin:
   ".tab-widget.vertical .tab" steht bei (0,3,0) gegen ihre (0,2,0) und
   setzt "border: none" nach, das "border-bottom" aus der Regel oben
   also auf 0 zurueck. Dasselbe gilt fuer Innenabstand und Flaeche.

   Nicht von selbst zurueckgesetzt wird "min-height": KEINE der Legacy-
   Regeln fuer ".tab" deklariert je eine Hoehe, die 42px aus der Regel
   oben waeren also unbekaempft und wuerden die Eintraege der
   Einstellungsnavigation von 38 auf 42 aufblasen (per deleteRule
   nachgemessen). Der Agenten-Editor haengt sieben solche Eintraege
   untereinander (agentpage.js:358-393), macht 28px mehr Spaltenhoehe --
   die Unter-Eintraege ".tab-sub-item" sind nicht betroffen, sie tragen
   die Klasse ".tab" nicht. Das ist dieselbe Fehlerklasse,
   die den Rescope in 04 · Core ausgeloest hat -- eine Eigenschaft, die
   Legacy nicht kennt, gilt unabhaengig von jeder Spezifitaet, bis sie
   jemand ausdruecklich zuruecknimmt. Genau das tut die Zeile hier.

   Der Radius ist wertgleich zu Legacy (webapp.css:7926 setzt 6px,
   "--ax-radius-sm" IST 6px, tokens.css:352) -- er steht hier, damit die
   Liste am Radiusraster des Designs haengt statt an einer
   Uebereinstimmung aus Zufall, und ist als Zusicherung ein Waechter,
   kein Nachweis. Die FARBE kommt bereits aus der Regel ganz oben
   (Ruhezustand "--ax-text-muted", (0,2,0) schlaegt Legacys ".tab" bei
   (0,1,0), und die vertikale Legacy-Regel deklariert selbst keine
   "color"); Aktiv- und Hoverfarbe stellt die Bruecke ueber
   "--clr-text-primary" -> "--ax-text-primary". Deshalb steht auch hier
   keine eigene "color"-Zeile.

   KEIN "border-left" und KEIN "border-bottom" in diesem Block: bei
   <=720px klappt die Spalte in eine Zeile (webapp.css:8025-8033) und
   tauscht dort genau diese beiden Kanten. Eine Zeile hier stuende bei
   (0,4,0) und schluege diese Media-Query-Regel bei (0,3,0) -- der
   linke Streifen bliebe in der mobilen Zeile stehen. */
[data-design="new"] .tab-widget.vertical .tab {
  min-height: auto;
  border-radius: var(--ax-radius-sm);
}

/* VERMERK (2026-09-22, Sichtpruefung/Task 3 Nachbesserung 2, NICHT geloescht
   -- fremde Regeln eines frueheren Vorhabens): "#menubuttons" baut seit
   "Alles Persoenliche im Avatar-Menue" im neuen Design gar nicht mehr
   (templatecockpitnavigationbase.js "addMenus()"). Die beiden Regeln unten
   (dieser Block und der "gap"-Block bei "System 2", weiter unten in dieser
   Datei) treffen dort seither nichts mehr -- toter, aber unschaedlicher
   Quelltext. Nicht Teil dieser Nachbesserung, nur vermerkt.
   System 2: die Menueknoepfe am Fuss der Nav-Rail. "#menubuttons" ist
   eine ID und wiegt (1,0,0) -- eine Regel ohne die ID (etwa
   "[data-design=new] .nav-rail .button-container", (0,3,0)) verloere
   gegen sie. Deshalb steht die ID im Selektor.

   BEFUND AUS DER BESTANDSAUFNAHME, den der Brief nicht kennen konnte:
   von den vier Deklarationen in "#menubuttons .container-left-right"
   (webapp.css:6103) ist im ausgelieferten Cockpit nur noch der Radius
   wirksam. ".nav-rail .container-left-right" (webapp.css:3692) setzt
   "padding: 0 !important" und "width: 100% !important" -- "!important"
   schlaegt jede Spezifitaet, die 8px Innenabstand und "width: auto"
   sind seit der Einfuehrung der Rail tot (im echten Stapel gemessen:
   padding 0px, Breite 63px = 100%). Sie sind hier deshalb NICHT
   nachgezogen; das waere ohne "!important" nicht erreichbar, und
   "!important" ist in dieser Datei per Unit-Test verboten.

   Was bleibt, ist der Radius: 5px stammt aus der alten ".navbar2"-
   Navigation, aus der "#menubuttons" uebernommen wurde. Die Rail-
   Elemente daneben stehen im neuen Design alle auf 10px (".rail-btn"
   und ".dropdown", beide weiter oben in dieser Datei) -- diese Zeile
   holt die Zeile in dasselbe Raster.
   Die zweite Zeile des Selektors wiederholt den Hover-Zustand: Legacys
   "#menubuttons .container-left-right:hover" (webapp.css:6110) setzt
   den Radius dort erneut auf 5px und stuende bei (1,2,0), also im
   Gleichstand mit der ersten Zeile hier -- entschieden nur durch die
   Ladereihenfolge. (1,3,0) entscheidet es durch Spezifitaet.

   KORREKTUR (Nachbesserungsrunde 1): hier stand, die Aenderung sei
   unsichtbar, weil die Zeile "weder Flaeche noch Rahmen" trage und
   ".nav-rail .container-left-right:hover" (webapp.css:3702) sie
   "ausdruecklich auf transparent" setze. Das ist FALSCH -- diese
   Legacy-Regel VERLIERT. ".chatbot-service .container-left-right:hover"
   (webapp.css:5987) steht bei derselben Spezifitaet (0,3,0) und SPAETER
   in der Datei, und "#menubuttons" liegt unter ".chatbot-service"
   (templatecockpitnavigationbase.js:51). Es gibt dort also sehr wohl eine
   Flaeche, und dieser Radius rundet sie -- von 5px auf 10px.
   ZAHLEN DAZU, mit Zeitpunkt, weil sie sonst in die Irre fuehren: DAMALS,
   also vor der Regel am Ende dieser Datei, mass man im Hover dunkel
   rgb(22,27,34) im alten und rgb(18,17,28) im neuen Design -- und genau
   das war der Ausfall, denn rgb(18,17,28) ist auch die Farbe der Rail.
   HEUTE, mit dieser Regel, misst man dort rgb(36,34,51) (dunkel) bzw.
   rgb(232,230,238) (hell); das alte Design ist unveraendert. */
[data-design="new"] #menubuttons .container-left-right,
[data-design="new"] #menubuttons .container-left-right:hover {
  border-radius: var(--ax-radius-md);
}

/* FEHLERBEHEBUNG (Nachbesserungsrunde 1, Ruling des Auftraggebers). Die
   Hoverflaeche der zwei Menueknoepfe am Fuss der Rail ist im neuen Design
   unsichtbar -- dunkel UND hell, jede Fensterbreite, und das neue Design
   ist der Standard (designbootstrap.js).

   Der Weg dorthin: die Flaeche kommt aus ".chatbot-service
   .container-left-right:hover" (webapp.css:5987) mit
   "background-color: var(--clr-surface-1)". Die Bruecke haengt
   "--clr-surface-1" auf "--ax-bg-surface-1" = "--ax-ink-900"
   (tokens.css:149/50), und die Rail selbst steht seit Task 1 auf
   "--ax-bg-nav" = ebenfalls "--ax-ink-900" (tokens.css:54). Gleiche Farbe
   auf gleicher Farbe. Im hellen Theme dasselbe Bild mit "--ax-ink-0".
   Gemessen (Zeiger auf dem Knopf, voller Stapel):
     alt  dunkel  Flaeche rgb(22,27,34)  auf Rail rgb(6,8,16)    -> sichtbar
     neu  dunkel  Flaeche rgb(18,17,28)  auf Rail rgb(18,17,28)  -> UNSICHTBAR
     neu  hell    Flaeche rgb(255,255,255) auf Rail rgb(255,255,255) -> UNSICHTBAR
   Erschwerend: die Zeile ist deckend und verdeckt damit auch die
   "rgba(255,255,255,.06)"-Toenung, die ".nav-rail .dropdown:hover"
   (webapp.css:3688) auf den Knopf darunter legt -- ohne diese Regel
   bleibt also GAR keine Rueckmeldung uebrig.

   Spezifitaet, nachgezaehlt: dieser Selektor steht bei (0,5,0)
   -- ein Attributselektor, drei Klassen, eine Pseudoklasse -- gegen die
   (0,3,0) von webapp.css:5987. Kein Gleichstand, keine Abhaengigkeit von
   der Ladereihenfolge. ".chatbot-service" steht bewusst mit im Selektor,
   obwohl schon "[data-design=new] .nav-rail ..." (0,4,0) gereicht haette:
   es benennt genau die Regel, die hier geschlagen wird.

   Warum "--ax-bg-hover" und nicht eine der Flaechen aus Task 1: das ist
   das Token, das diese Datei fuer Hoverflaechen ohnehin schon benutzt
   (".btn-secondary:hover", ".button-icon:hover", ".page-action-btn:hover").
   Es loest zu "--ax-ink-700" (dunkel) bzw. "--ax-ink-100" (hell) auf und
   hebt sich damit in beiden Themes von der Rail ab. */
/* NACHTRAG 2026-09-20: C1 hat die Zeile UMGEZOGEN, und damit war der oben
   behobene Ausfall zurueck. "#menubuttons" haengt im neuen Design nicht mehr
   unter ".nav-rail", sondern unter ".cockpit-sidebar" (gemessene Ahnenkette:
   .container-left-right < #user-menucontent < #user-container < #menubuttons
   < .cockpit-sidebar-footer < .cockpit-sidebar < .chatbot-service). Der
   Selektor unten verlangte ".nav-rail" und griff deshalb oberhalb von 1024px
   gar nicht mehr -- gemessen wurde wieder rgb(18,17,28) auf rgb(18,17,28),
   exakt der Zustand, den die Regel verhindern soll.
   Beide Huellen stehen jetzt im Selektor: die Leiste gilt unterhalb der
   Umbruchbreite weiter, die Seitenleiste darueber. Die zweite Zeile hat
   dieselbe Spezifitaet (0,5,0) wie die erste und schlaegt die (0,3,0) von
   webapp.css:5987 genauso ohne Ladereihenfolge. */
[data-design="new"] .chatbot-service .nav-rail .container-left-right:hover,
[data-design="new"] .chatbot-service .cockpit-sidebar .container-left-right:hover {
  background-color: var(--ax-bg-hover);
}

/* Der Rhythmus der zwei Menueknoepfe gegen den der fuenf Rail-Knoepfe
   darueber. Der Bruch entsteht in Task 1 (Rail von gap 6 auf 8), sichtbar
   wird er durch die Hoverflaeche eine Regel weiter oben -- solange die
   Knoepfe gar keine Flaeche zeigten, war der Unterschied Theorie.

   "#menubuttons" wiegt (1,0,0), diese Regel braucht die ID also mit:
   ".nav-rail .button-container" (webapp.css:3667) steht bei (0,2,0) und
   verliert. Gemessen ist "#menubuttons" UEBRIGENS DASSELBE ELEMENT wie
   ".nav-rail .button-container" -- es gibt in der Rail nur einen
   ".button-container" (templatecockpitnavigationbase.js:99). Die dortigen
   "gap: 4px" sind also kein zweiter Container mit einem dritten Rhythmus,
   sondern eine seit der Rail tote Deklaration auf demselben Knoten.

   WARUM 4 UND NICHT 8, obwohl die Rail auf 8 steht -- das ist der Punkt,
   an dem die naheliegende Zeile das Gegenteil bewirkt haette. Zwischen
   den beiden Knoepfen liegt nicht nur der "gap": jeder Knopf steckt in
   einem "div.molecule" (moleculemenu.js:55 ueber Molecule.renderUi()), und
   ".chatbot-service .molecule" (webapp.css:5484) gibt dem 4px
   "margin-bottom". Der sichtbare Abstand ist deshalb gap + 4.
   Gemessen (Unterkante Chip 1 bis Oberkante Chip 2, voller Stapel):
     alt   Rail-Knoepfe 6   Menueknoepfe 10  (gap 6 + 4)
     neu   Rail-Knoepfe 8   Menueknoepfe 10  (gap 6 + 4)  -> 2px daneben
     mit dieser Regel        Menueknoepfe  8  (gap 4 + 4)  -> deckungsgleich
   Ein "gap: 8px" haette daraus 12 gemacht und den Unterschied von 2 auf 4
   VERDOPPELT. "--ax-space-1" ist 4px (tokens.css:347, ueber alle
   Breakpoints stabil) und ergibt zusammen mit dem 4px-Aussenabstand des
   Molekuels genau die "--ax-space-2" = 8px, auf denen die Rail steht.
   Nebenbei bekommt die tote "gap: 4px" von webapp.css:3671 damit im neuen
   Design endlich ihren Wert -- der Legacy-Autor wollte dort dasselbe.

   Der Container ist ueberdies 30px hoch (".button-container",
   webapp.css:1523) bei 68px Inhalt und laesst ihn mittig ueberlaufen; die
   2px weniger Abstand ruecken den unteren Knopf von 4 auf 5px Abstand zur
   Rail-Unterkante. Beides gemessen, beides vorbestehend, hier nur nicht
   verschlimmert. */
[data-design="new"] #menubuttons {
  gap: var(--ax-space-1);
}

/* System 3: die Wizard-Bar -- Figmas "Breadcrumb". Es gibt EINE Klasse und
   nicht drei Auspraegungen: ".aiservice-wizard-bar" (webapp.css:8885) traegt
   in der Produktion fuenf Einbauorte, nachgezaehlt statt geschaetzt:
     OrganismsAiServiceWizardBar, gebaut von templateaiserviceexecution.js
       -- feste ID "wizard-bar", ohne eigene ID-Regel
     MoleculeWizardContainer, DREIMAL: registerpage.js ("register-wizard"),
       dialogsavechatasdocument.js ("saveChatWizard") und
       aiservicetemplategenerator.js ("aiservice-input-steps"); die Molekuel-
       Klasse haengt "-bar" an, daher die drei IDs unten
     parametereditor.js, ein blanker AtomContainerWithClass mit der ID
       "schema-breadcrumb-bar"
   Dazu die Galerie-Kachel als sechste, reine Entwicklerinstanz.

   VIER ID-SPEZIALISIERUNGEN, und eine ID wiegt (1,0,0): keine der Regeln
   hier bei (0,2,0)/(0,3,0) schlaegt sie. Nachgezaehlt, welche Eigenschaften
   sie ueberhaupt setzen -- und keine einzige davon kommt unten vor:
     #register-wizard-bar / #saveChatWizard-bar (webapp.css:8931/:8939):
       margin, border-radius, width, box-sizing
     #aiservice-input-steps-bar (:8947): margin-left/right/bottom, width,
       box-sizing
     #schema-breadcrumb-bar (:5378): margin, padding, border, border-radius
   Nur die letzte beruehrt eine Eigenschaft von unten, naemlich ueber die
   "border"-Kurzform auch "border-bottom-color". Sie setzt dort
   "var(--clr-border)", und die Bruecke haengt genau dieses Token auf
   "--ax-border-default" (tokens.css:151/223) -- der Wert ist also in beiden
   Themes IDENTISCH mit dem, was die Regel unten schreibt (dunkel
   rgb(36,34,51), hell rgb(210,208,218), im vollen Stapel gemessen). Eine
   Regel mit der ID waere deshalb reine Zeremonie und steht bewusst NICHT
   hier.

   KEIN "display" in diesem Block, nirgends: ab <= 640px blendet
   webapp.css:10641 die Leiste aus (".aiservice-wizard-bar { display: none }",
   (0,1,0)) und holt genau eine zurueck -- den Eingabe-Stepper innerhalb
   ".aiservice-container" (:10650). Eine "display"-Zeile hier stuende bei
   (0,2,0) und liesse die Leiste auf Mobilgeraeten ueberall wieder
   erscheinen, neben dem Fortschrittsbalken, der sie dort ersetzt. Bei 600px
   Fensterbreite gegengemessen: alle fuenf Auspraegungen melden in beiden
   Designs weiterhin "display: none". */

/* Flaeche und Trennkante der Leiste.

   Die Flaeche ist die eigentliche Aenderung und behebt nebenbei einen
   Legacy-Schoenheitsfehler: "--clr-shell" ist "color-mix(--clr-base 70%,
   --clr-surface-1)" (webapp.css:15). Unter der Bruecke sind das ink-950 und
   ink-900 -- zwei benachbarte Sprossen derselben Rampe. Gemessen im vollen
   Stapel, neues Design, VOR dieser Regel: Leiste rgb(13,12,22) auf einem
   Seitengrund von rgb(11,10,20) (dunkel) bzw. rgb(239,238,243) auf
   rgb(244,243,247) (hell) -- in beiden Themes praktisch dieselbe Farbe.
   "--ax-bg-surface-1" macht daraus rgb(18,17,28) bzw. rgb(255,255,255) und
   hebt die Leiste damit ueberhaupt erst vom Grund ab.

   "border-bottom-color" ist dagegen eine HAERTUNG, kein Nachweis: Legacys
   "border-bottom: 1px solid var(--clr-border)" liefert ueber die Bruecke
   bereits denselben Wert. Die Zeile haelt die Kante am --ax-Token fest,
   falls die Bruecke "--clr-border" eines Tages nicht mehr umhaengt. Nur die
   FARBE steht hier, nicht die Kurzform: "border-bottom: 1px ..." wuerde auch
   die Breite neu setzen, und die 1px sind Legacys eigener Wert.

   Nicht ueberschrieben und im Report als "bleibt" begruendet: display,
   align-items, padding, margin-top/right/left, flex-shrink, die zwei oberen
   Eckradien und die Rahmenbreite -- alles Geometrie, die Figma an dieser
   Stelle nicht neu vorgibt. */
[data-design="new"] .aiservice-wizard-bar {
  background: var(--ax-bg-surface-1);
  border-bottom-color: var(--ax-border-default);
}

/* Die Beschriftung eines Schritts.

   WARUM DIE ZWEI ZUSTANDSREGELN NICHT WEGGELASSEN WERDEN DUERFEN, obwohl
   sie denselben Wert schreiben, den die Bruecke ohnehin liefert: die
   Grundregel hier steht bei (0,2,0) -- ein Attributselektor plus eine
   Klasse. Legacys ".aiservice-wizard-step.active" (webapp.css:8906) und
   ".aiservice-wizard-step.done" (:8907) stehen bei EBENFALLS (0,2,0), also
   im Gleichstand, und components.css laedt NACH webapp.css. Ohne die zwei
   Regeln unten faerbte die Grundregel den aktiven und den erledigten
   Schritt mit ein -- beide waeren grau statt hell bzw. gruen. Per
   deleteRule gegengeprueft.
   Die Aktivregel setzt bewusst KEIN "font-weight": die 600 aus
   webapp.css:8906 sind unbestritten, weil hier niemand "font-weight"
   deklariert. */
[data-design="new"] .aiservice-wizard-step {
  color: var(--ax-text-muted);
}

[data-design="new"] .aiservice-wizard-step.active {
  color: var(--ax-text-primary);
}

[data-design="new"] .aiservice-wizard-step.done {
  color: var(--ax-status-success);
}

/* Die Schrittnummer -- der gefuellte Kreis.

   Geometrie bleibt vollstaendig Legacy (22x22, Radius 50%, 1.5px Rahmen,
   Schrift 0.65rem/700, "flex-shrink: 0", "user-select: none").
   Insbesondere steht hier KEIN "box-sizing": Legacy deklariert es nicht,
   eine Zeile hier waere also unbekaempft und schruempfte den Kreis von
   aussen gemessen von 24 auf 22 -- eine Geometrieaenderung, die dieser
   Task nicht beauftragt hat. Der Kreis misst deshalb weiterhin 22px Inhalt
   plus 2x1px Rahmen (1.5px deklariert; bei Geraetepixelverhaeltnis 1
   meldet Chromium als benutzten Wert 1px).

   Geaendert sind nur die Flaechen- und Textfarben:
     Ruhe: "--clr-surface-3" -> "--ax-bg-surface-2" (dunkel rgb(36,34,51)
       -> rgb(26,24,38), hell rgb(232,230,238) -> rgb(244,243,247)). Im
       DUNKLEN Theme loest sich der Kreis damit von seinem eigenen Rahmen:
       "--ax-bg-surface-3" und "--ax-border-default" sind dort beide
       ink-700, die Flaeche lag also exakt auf der Rahmenfarbe. Im hellen
       Theme lagen sie schon vorher auseinander (ink-100 gegen ink-200);
       dort ist der Wechsel eine Angleichung an das Raster, kein Fund.
     Text: "--clr-text-muted" -> "--ax-text-muted". "--clr-text-muted" ist
       das einzige der hier benutzten Legacy-Tokens, das die Bruecke NICHT
       umhaengt; es rechnet sich als color-mix aus "--clr-text-secondary"
       (webapp.css:79/341) und landet damit knapp neben Figmas Wert.
       Gemessen dunkel rgb(138,137,150) -> rgb(129,127,146); hell
       rgb(134,132,146) -> rgb(85,83,106). Im hellen Theme ist das der
       spuerbare Sprung: gegen "--ax-bg-surface-1" haelt der Text danach
       7,42 statt 3,67.
   "border-color" ist wie an der Leiste eine HAERTUNG: "--clr-border" haengt
   bereits auf "--ax-border-default". Nur die Farbe, nicht die Kurzform --
   sonst gingen die 1.5px verloren. */
[data-design="new"] .aiservice-wizard-step-num {
  background: var(--ax-bg-surface-2);
  border-color: var(--ax-border-default);
  color: var(--ax-text-muted);
}

/* Aktiv. Dieselbe Gleichstands-Falle wie bei der Beschriftung: Legacys
   ".aiservice-wizard-step-num.active" (webapp.css:8919) steht bei (0,2,0)
   und verloere den Gleichstand gegen die Grundregel darueber ueber die
   Ladereihenfolge -- der aktive Kreis waere dann grau. Diese Regel bei
   (0,3,0) stellt ihn wieder her.

   Alle drei Werte sind wertgleich zu dem, was die Bruecke aus Legacys
   Tokens ohnehin macht ("--clr-accent-btn" -> "--ax-action-primary",
   "--clr-white" -> "--ax-ink-0" = "--ax-text-on-accent") -- MIT EINER
   AUSNAHME, und die ist Absicht: Legacys "border-color: var(--clr-accent)"
   liefert im HELLEN Theme cyan/600 (die Bruecke haengt "--clr-accent" dort
   auf "--ax-text-link", tokens.css:257), hier steht cyan/500. Der Ring
   verschwindet im hellen Theme also in der Flaeche, statt sie dunkler zu
   umranden -- genau der gefuellte Kreis, den Figma zeigt. Das ist NICHT
   der Fall aus Ruling 11 (Tab-Unterstreichung): dort war die 2px-Linie
   selbst die Zustandsanzeige und musste 3,0 gegen die Flaeche dahinter
   halten.

   KORREKTUR (Review): hier stand, die Zustandsanzeige sei die 22px-Flaeche
   und der Ring trage keine eigene Bedeutung, ein Wechsel auf
   "--ax-action-primary" sei deshalb vertretbar. Das Argument traegt nur
   halb. Die FLAECHE war schon vorher cyan/500 und haelt gegen die weisse
   Leiste ebenfalls nur 2,971; getragen hat den Kreis bisher genau der
   DUNKLERE RING mit 4,761. Beide auf cyan/500 zu setzen laesst den ganzen
   aktiven Kreis im hellen Theme unter die 3,0 fuer grafische Objekte
   fallen -- und kehrt damit das Ruling aus Task 4 um, wo fuer denselben
   Konflikt "--clr-accent" gewaehlt wurde.

   Deshalb traegt der Ring "--clr-accent": dunkel wertgleich cyan/500,
   hell cyan/600 mit 4,761. Die Flaeche bleibt "--ax-action-primary".

   ZWEITE KORREKTUR (Korrekturwelle nach dem Abschlussreview): hier stand,
   die Flaeche habe "ihren Kontrast ohnehin nie" gehabt. Das gilt fuer
   Flaeche gegen LEISTE. Die ZIFFER AUF DER FLAECHE hatte ihn sehr wohl
   und hat ihn verloren -- an der echten Galerie-Kachel gemessen, Ziffer
   gegen Kreisflaeche:
     altes Design:  dunkel 6,702 (weiss auf blue/700)
                    hell   7,903 (weiss auf indigo/700)
     neues Design:  dunkel 2,971 | hell 2,971 (weiss auf cyan/500)
   VERURSACHT IST DAS NICHT HIER: mit "deleteRule" auf diese Regel UND
   auf die Grundregel darueber misst dieselbe Stelle in beiden Themes
   exakt 2,971 weiter -- der Wert kommt aus der Fundament-Bruecke
   ("--clr-accent-btn" -> "--ax-action-primary", "--clr-white" ->
   "--ax-text-on-accent"). Genau diese Paarung sieht Figma fuer JEDEN
   Primaerknopf der Anwendung vor; sie hier allein umzufaerben machte den
   Kreis inkonsistent mit allen anderen und verdeckte, dass der Befund
   systemisch ist. Deshalb bewusst nicht geaendert, sondern als offener
   Befund auf Fundament-Ebene in Spec Abschnitt 12 und auf die
   Sichtpruefungsliste (Ruling des Auftraggebers).

   DRITTE FORTSCHREIBUNG (T1, 2026-09-15) -- DER ERSTE GRUND IST
   ENTFALLEN, DER ZWEITE TRAEGT ALLEIN. Der Ring stand hier mit ZWEI
   Gruenden: Kontrast (hell hielt "--ax-action-primary" nur 2,971, der
   dunklere Ring ueber "--clr-accent" 4,761) und Organisations-Branding.
   T1 hat "--ax-action-primary" im hellen Theme auf cyan/600 geheilt
   (tokens.css:127). Damit haelt die FLAECHE des Kreises selbst 4,761
   gegen die weisse Leiste, und die Ziffer darauf ebenfalls 4,761 statt
   2,971: der oben als systemisch gemeldete Befund ist fuer das HELLE
   Theme erledigt, fuer das DUNKLE steht er weiter (weiss auf cyan/500,
   2,971 -- Regressionssperre in design-contrast.spec.ts). Ungebrandet
   sind Ring und Flaeche im hellen Theme seither wertgleich; der Ring
   zeichnet sich dort nur noch unter der Marke ab.

   GEBLIEBEN IST DAS BRANDING, und dafuer steht die Zeile noch.
   Zweiseitig gemessen (Galerie-Kachel "gallery-wizardbar-default",
   ".aiservice-wizard-step-num.active", "border-top-color", Marke
   #ff5500):
                        mit "border-color"  ohne sie
     dunkel ungebrandet rgb(0,159,227)      rgb(36,34,51)
     dunkel gebrandet   rgb(255,85,0)       rgb(36,34,51)
     hell   ungebrandet rgb(0,122,176)      rgb(210,208,218)
     hell   gebrandet   rgb(255,85,0)       rgb(210,208,218)
   Ohne die Zeile faellt der Ring auf "--ax-border-default" der Grundregel
   zurueck (:3783-3787), und die Organisationsfarbe ist in beiden Themes
   weg. Wer sie auf "--ax-action-primary" umstellt, weil die Kontrastzahl
   jetzt stimmt, nimmt dem Kreis die Kundenfarbe. */
[data-design="new"] .aiservice-wizard-step-num.active {
  background: var(--ax-action-primary);
  border-color: var(--clr-accent);
  color: var(--ax-text-on-accent);
}

/* Erledigt.

   ABWEICHUNG VOM BRIEF, bewusst und nachgerechnet: der Haken nimmt
   "--ax-text-inverse", nicht "--ax-text-on-accent". Der Brief verlangte
   Flaeche UND Rahmen "--ax-status-success" (uebernommen, siehe unten) und
   den Haken auf "--ax-text-on-accent". "--ax-text-on-accent" ist in BEIDEN
   Themes "--ax-ink-0", also Weiss -- und "--ax-status-success" ist im
   dunklen Theme green/400 (#4ade80), ein HELLES Gruen. Weiss auf #4ade80
   haelt 1,74:1. Der Haken waere im dunklen Theme praktisch unsichtbar,
   waehrend "getComputedStyle" brav "rgb(255,255,255)" meldet -- dieselbe
   Fehlerklasse wie die abgeschnittene Tab-Unterstreichung aus Task 4.
   Zum Vergleich, jeweils Haken gegen die Flaeche darunter:
     heute (Legacy-Token "--clr-success-deep"): dunkel  7,12 | hell 3,30
     Brief woertlich (weiss auf status/success): dunkel  1,74 | hell 3,30
     hier ("--ax-text-inverse"):                 dunkel 11,51 | hell 3,30
   "--ax-text-inverse" ist auch semantisch das richtige Token: es ist
   ink-1000 im dunklen und ink-0 im hellen Theme (tokens.css:66/114) --
   also genau "Text auf einer Flaeche, deren Helligkeit dem Theme
   entgegenlaeuft". Und ein gesaettigtes green/400 IST im dunklen Theme
   eine helle Flaeche. Das helle Theme aendert sich dadurch nicht: dort ist
   "--ax-text-inverse" Weiss, also derselbe Wert wie heute.

   Die FLAECHE folgt dem Brief: "--clr-success-deep" (webapp.css:102,
   "color-mix(--clr-success 45%, black)") ist ein Legacy-Einzelstueck, das
   die Bruecke nicht kennt und das im hellen Theme ohnehin schon zu 100%
   "--clr-success" ist (webapp.css:363) -- der Wechsel auf
   "--ax-status-success" macht aus dem dunklen Sonderfall denselben Wert
   wie im hellen Theme und bindet den erledigten Schritt an dasselbe Token
   wie seine Beschriftung und seine Linie. */
[data-design="new"] .aiservice-wizard-step-num.done {
  background: var(--ax-status-success);
  border-color: var(--ax-status-success);
  color: var(--ax-text-inverse);
}

/* Die Verbindungslinie. Beide Zeilen sind HAERTUNGEN, keine Nachweise:
   "--clr-border" und "--clr-success" haengen ueber die Bruecke bereits auf
   "--ax-border-default" bzw. "--ax-status-success", die gerechneten Werte
   aendern sich also um kein Bit. Sie stehen hier, damit die Linie am
   --ax-Token haengt statt an einer Umhaengung, die jemand spaeter loesen
   koennte -- und die ".done"-Regel zusaetzlich, weil die Grundregel sonst
   Legacys ".aiservice-wizard-line.done" (webapp.css:8928, ebenfalls
   (0,2,0)) ueber die Ladereihenfolge schluege und die erledigte Linie grau
   faerbte.

   WO DIESE ZWEI ZEILEN NICHTS ZU SEHEN GEBEN: die Linie ist "flex: 1" mit
   Flex-Basis 0. In einer Leiste, die ihre Breite aus dem Inhalt zieht,
   bleibt fuer sie nichts uebrig -- in der Galerie-Kachel gemessen 0x1px,
   in BEIDEN Designs. Sichtbar wird sie nur dort, wo die Leiste eine Breite
   vorgegeben bekommt: "#register-wizard-bar", "#saveChatWizard-bar" und
   "#aiservice-input-steps-bar" setzen "width: 100%", und auf der
   Ausfuehrungsseite ist die Leiste ein Flex-Element von
   ".aiservice-execution-container" mit "align-items: stretch". */
[data-design="new"] .aiservice-wizard-line {
  background: var(--ax-border-default);
}

[data-design="new"] .aiservice-wizard-line.done {
  background: var(--ax-status-success);
}

/* System 4: Menue / Flyout -- Figma "Menu / Flyout" (Knoten 45:143 auf der
   Seite "06 Shell & Nav"). Ausgelesen, nicht geschaetzt: Flaeche
   "--clr-bg-elevated" #1a1826 (hier "--ax-bg-elevated", tokens.css:53),
   Rahmen "--clr-border" #242233 ("--ax-border-default", :59), Radius
   "--radius-md" 10 ("--ax-radius-md", :352).

   DREI AUSPRAEGUNGEN im Bestand, und sie sind NICHT dasselbe Bauteil:
     ".dropdown-content"        (webapp.css:4964) -- das schwebende Popover.
     ".dropdown-content-small"  (:6116)           -- dessen kleine Fassung.
     ".navbar2 .dropdown-content" (:4950)         -- das INLINE aufgeklappte
       Untermenue der alten Seitennavigation. Es schwebt nicht, sondern sitzt
       buendig in der 220px-Spalte; Legacy setzt dort ausdruecklich
       "border: none" und "border-radius: 0". Figmas Flyout ist es nicht,
       und es bekommt seine Werte unten ausdruecklich zurueck.

   WAS FIGMA SONST NOCH SAGT UND HIER BEWUSST NICHT UMGESETZT WIRD:
   Figmas Menueeintrag ist "Body/Small" (Inter Regular 13/20) in
   "text/secondary", 36px hoch, Innenabstand 16 links, Abstand Icon/Text 12.
   Die Typografie bleibt unangetastet -- die Core-Spec Abschnitt 14 fuehrt
   unter den Punkten 1 und 2 genau das GEGENTEIL als Defekt: dass die
   Eintraege des kleinen und des navbar2-Menues ihre eigenen 10px bzw. 12px
   verloren und auf rund 13,3px wuchsen. Eine Schriftgroessen-Aussage hier
   traefe alle drei Auspraegungen gleich und brachte den behobenen Defekt
   zurueck. Geometrie (Zeilenhoehe, Innenabstand) bleibt aus demselben Grund
   Legacy: sie steht an den <a>-Regeln je Auspraegung unterschiedlich.

   BEWEIS, DASS DIE FLAECHE EINE ECHTE AENDERUNG IST, nicht Zeremonie:
   Legacys "--background-color-navigation" ist "--clr-shell"
   (webapp.css:174/15), also "color-mix(--clr-base 70%, --clr-surface-1)".
   Unter der Bruecke sind das zwei benachbarte Sprossen derselben Rampe --
   im vollen Stapel gemessen "color(srgb 0.0513726 0.047451 0.0878431)",
   rund rgb(13,12,22), auf einem Seitengrund von rgb(11,10,20). Das Menue
   war vom Grund praktisch nicht zu unterscheiden. "--ax-bg-elevated" ist
   ink-800, rgb(26,24,38).

   KEINE "border"-Kurzform: Legacy setzt "1px solid var(--clr-border)", und
   1px ist bereits Figmas Wert. Nur die Farbe wird gehaertet -- und die ist
   wertgleich, weil die Bruecke "--clr-border" ohnehin auf
   "--ax-border-default" haengt (tokens.css:151/223; gemessen dunkel
   rgb(36,34,51), hell rgb(210,208,218), vor wie nach dieser Regel). Sie
   steht hier, damit die Aussage am --ax-Token haengt statt an einer
   Umhaengung.

   KEINE KOLLISION MIT DEM WORKFLOW-EDITOR: ".wf-step-list-footer
   .dropdown-content" (workfloweditor.css:452) steht bei (0,2,0) im
   Gleichstand mit der Regel hier und deklariert background/border/
   border-radius selbst. Entschieden wird der Gleichstand ueber die
   Ladereihenfolge, und workfloweditor.css steht in aiprocesseditor.html:17
   und aiprocessstepeditor.html:17 NACH components.css -- das Add-Step-Menue
   behaelt seine eigene Optik. Nachgemessen, siehe Report.
   Und media.css:190 (dieselbe Klasse, Marketing-Seiten) trifft nie
   zusammen mit dieser Datei: gdpr/imprint/index.html laden weder
   components.css noch tokens.css. */
[data-design="new"] .dropdown-content {
  background-color: var(--ax-bg-elevated);
  border-color: var(--ax-border-default);
  border-radius: var(--ax-radius-md);
}

/* Das Untermenue der alten Seitennavigation bekommt zurueck, was die Regel
   darueber ihm sonst genommen haette. Beide Selektoren wiegen (0,2,0); die
   Regel oben steht spaeter in derselben Datei und gewinnt den Gleichstand,
   ohne dass irgendjemand das gewollt haette.
     background-color: die Spalte selbst traegt "--clr-shell"
       (".navbar2", webapp.css:3478) -- das Untermenue soll darin
       verschwinden, nicht als Karte darauf liegen.
     border-radius: Legacys eigene 0. Eine 10px-Ecke an einem buendig in
       einer 220px-Spalte sitzenden Block ist keine Figma-Aussage.
   KEIN "border-color" noetig: Legacys "border: none" (:4957) setzt
   border-style auf "none", die Rahmenbreite ist damit 0 und die von der
   Regel oben gewonnene Farbe wird nirgends gezeichnet. Eine Zeile hier
   waere tot. */
[data-design="new"] .navbar2 .dropdown-content {
  background-color: var(--background-color-navigation);
  border-radius: 0;
}

/* Die kleine Fassung. Sie hat als einzige der drei GAR KEINEN Legacy-Rahmen
   (webapp.css:6116-6127 deklariert "border" nicht) -- deshalb hier die
   Kurzform, die keinen Legacy-Wert ueberschreibt, sondern Figmas 1px erst
   anlegt. Folge: 2px mehr Aussenmass in jeder Richtung, in der sich das
   Menue am Inhalt orientiert. In der Galerie-Kachel steht es "static" und
   nimmt seine Breite vom Container -- dort GEMESSEN 90 -> 92px Hoehe bei
   unveraenderten 200px Aussenbreite, der Eintrag darin faellt von 200 auf
   198. In der Produktion ist es "position: absolute" und schrumpft auf
   den Inhalt, dort waechst auch die Breite um 2. Das ist bei einem
   Popover mit "min-width: 100px" folgenlos; die Verankerung
   ("left: -80px") bleibt unberuehrt.
   Der Legacy-Schatten ("box-shadow: var(--box-shadow)", :6123) bleibt --
   Figmas "Shadow/Dialog" ist eine andere Groesse und gehoerte, wenn
   ueberhaupt, in einem eigenen Schritt an ALLE drei Auspraegungen.

   "overflow-y: auto" IST DER RADIUS, NICHT DAS SCROLLEN. Ohne diese Zeile
   steht das Menue auf "overflow: visible" und beschneidet seine Nachfahren
   nicht -- die Hoverflaeche des ersten und des letzten Eintrags (eigener
   Radius 5, webapp.css:6137) ragt dann ueber die 10px-Kontur hinaus und
   uebermalt am 45-Grad-Punkt den eigenen 1px-Rahmen. Gemessen bei
   deviceScaleFactor 4, erste Ecke, 24x24 CSS-px-Ausschnitt:
     ohne diese Zeile   94 (dunkel) / 98 (hell) Geraetepixel ausserhalb der
                        Kontur, groesster Ueberstand 0,835 CSS-px
     mit dieser Zeile   45 / 53 Geraetepixel, groesster Ueberstand
                        0,285 / 0,297 CSS-px
   Die 45/53 sind der RAUSCHBODEN der Messung und kein Rest: dieselbe
   Zaehlung an derselben Ecke OHNE jede Hoverflaeche liefert exakt
   dieselben Zahlen -- es ist die eigene, kantengeglaettete Rundung des
   Rahmens. Der Ueberstand ist damit vollstaendig weg.

   WARUM "overflow-y: auto" UND NICHT "overflow: hidden": das grosse
   Geschwister ".dropdown-content" (webapp.css:4981) traegt genau diese
   Deklaration und zeigt den Ueberstand deshalb seit jeher nicht -- die
   kleine Fassung bekommt hier dasselbe, nicht etwas Neues. Vor allem aber
   traegt ".mol-dropdownlist" (webapp.css:13001, von
   MoleculeButtonDropDownList in addEvents() auf DASSELBE Element gelegt)
   "max-height: 320px" MIT "overflow-y: auto". Ein "overflow: hidden" hier
   wiegt (0,2,0) und schluege das (0,1,0) -- gemessen an einer Liste mit 30
   Zeilen (clientHeight 328, scrollHeight 968): nach einem echten
   Wheel-Ereignis bleibt "scrollTop" dann bei 0, waehrend er mit
   "overflow-y: auto" auf 500 geht. Die Sitzungshistorie waere ab der
   ~10. Zeile fuer einen Menschen unerreichbar gewesen. (Ein
   scriptgesetztes "scrollTop" funktioniert bei "hidden" weiterhin -- wer
   nur das prueft, sieht den Fehler nicht.) Mit "overflow-y: auto" ist der
   Wert dort wertgleich mit dem, was die Klasse selbst deklariert: fuer
   ".mol-dropdownlist" aendert sich nichts.
   Ein Fokusring wird dadurch nirgends abgeschnitten: die Eintraege sind
   <a> OHNE href (AtomDisplayLink) und nehmen keinen Fokus an --
   nachgemessen, "el.focus()" laesst "document.activeElement" auf <body>
   stehen, ":focus-visible" kann also nie greifen. Andere Nachfahren gibt
   es nicht: alle drei Erzeuger legen ausschliesslich flache Listen an,
   keiner setzt "data-tip", und im gerenderten Menue steht kein einziges
   Element mit "position: absolute" oder eigenem "box-shadow". */
[data-design="new"] .dropdown-content-small {
  background-color: var(--ax-bg-elevated);
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-md);
  /* 2026-09-22 (C2c-2/Task 7): erster Ort, an dem eine Zeile mit
     ".dropdown-content-small"-Menue (portaled nach <body>, siehe
     atomcontainerdropdowncontentsmall.js) INNERHALB eines geoeffneten
     Dialogs steht -- der Projekt-Dialog traegt jetzt die Skills-/
     Mitglieder-Listen. dialog.js (unantastbar) setzt "zIndex: 60000"
     inline auf ".dialog"; die Basisregel hier (webapp.css:6228) traegt
     nur 999. Ohne Anhebung liegt das Menue als Geschwister von ".dialog"
     unter ihr und ist unklickbar -- gemessen: Playwright meldete
     "#project-tabs ... intercepts pointer events" bei einem Klick auf
     einen Menuepunkt.

     REICHWEITE (Nachbesserung N-1, Pruefer-Hinweis): diese Anhebung gilt
     GLOBAL im neuen Design, nicht nur innerhalb eines Dialogs -- praktisch
     folgenlos ausserhalb, weil dieses Menue ausschliesslich hover-getrieben
     entsteht (MoleculeMenuDropDownSmall, ".settings-icon"-Hover) und daher
     nie stehenbleibt, waehrend gleichzeitig ETWAS ANDERES darueber liegen
     muesste: sein "display" schaltet auf "none", sobald die Maus die Zeile
     verlaesst, ein Dialog kann in der Zwischenzeit also nie ueber ihm
     erscheinen und von ihm verdeckt werden. */
  z-index: 60001;
  /* ZWEITE ACHSE, nicht bloss Beifang: "overflow-y: auto" bei
     "overflow-x: visible" zwingt die x-Achse per CSS-Koerzierung
     ebenfalls auf "auto" -- der Container meldet gemessen
     "overflowX: auto". Und genau das ist noetig: der Eckenueberstand
     ist ein DIAGONALES Problem, eine rein senkrechte Beschneidung
     wuerde ihn nicht beheben. Waagerecht schneidet sie nichts ab
     (gemessen auch mit einem 790px langen unbrechbaren Wort in einem
     150px-Wirt: scrollWidth == clientWidth, in beiden Designs). */
  overflow-y: auto;
}

/* OHNE DIESE ZEILE WAERE DIE FLAECHE DARUEBER UNSICHTBAR. Anders als bei
   den beiden anderen Auspraegungen traegt hier der EINTRAG eine eigene
   deckende Flaeche ("background-color: var(--background-color-navigation)",
   webapp.css:6135) und ist "display: block" -- er fuellt den Container
   restlos aus. Im vollen Stapel gemessen: der Container meldete
   "--ax-bg-elevated", zu sehen war ausschliesslich die Eintragsflaeche.
   "transparent" statt einer zweiten Kopie des Flaechentokens: Figmas
   Eintragsrahmen hat keine Fuellung, die Flaeche liegt am Flyout. */
[data-design="new"] .dropdown-content-small a {
  background-color: transparent;
}

/* Der Hover der Menueeintraege. Zwei getrennte Gruende, beide gemessen:

   1. background-color. Legacys Hoverflaeche ist
      "--background-color-navigation-hover" alias "--clr-surface-1"
      (webapp.css:175/5020) -- unter der Bruecke ink-900 im dunklen und
      ink-0 (WEISS) im hellen Theme. Gegen die neue Flyout-Flaeche
      "--ax-bg-elevated" (ink-800 dunkel, ink-0 hell) bedeutet das: im
      dunklen Theme kehrt sich die Richtung um (der Hover wuerde
      ABDUNKELN), im hellen Theme sind beide Werte BITGLEICH und der Hover
      verschwaende vollstaendig. Die Flaechenaenderung eine Regel weiter
      oben haette also eine funktionierende Affordanz zerstoert.
      "--ax-bg-hover" ist ink-700 (dunkel) bzw. ink-100 (hell) und hebt
      sich in beiden Themes ab. Fuer ".dropdown-content-small" ist der Wert
      ueberdies wertgleich mit Legacys "--clr-surface-3" (:6141) -- dort
      aendert sich nichts, die Zeile ist nur noetig, weil die
      "transparent"-Regel darueber bei (0,2,1) im Gleichstand mit Legacys
      ":hover" (ebenfalls (0,2,1)) stuende und ihn ueber die
      Ladereihenfolge gewaenne.
      Diese Regel wiegt (0,3,1) und wuerde damit auch Legacys
      ".navbar2 .dropdown-content a:hover" (:5013, ebenfalls (0,3,1)) ueber
      die Ladereihenfolge schlagen. Das ist NICHT gewollt und wird eine
      Regel weiter unten zurueckgenommen -- Begruendung dort.

   2. text-decoration. ":where([data-design=new]) a:hover:not(.disabled)"
      unterstreicht jeden Anker; Legacys drei ":hover"-Regeln fuer
      Menueeintraege deklarieren "text-decoration" nicht, die Basisregel
      traf also unbestritten. Gemessen im vollen Stapel, neues Design:
      alle drei Menues meldeten beim Ueberfahren "underline", das alte
      Design "none". Figmas Menueeintrag hat keine Unterstreichung, und
      Legacy loescht sie fuer die Nachbarzeile derselben Spalte
      ausdruecklich (".navbar2 .buttonrow:hover", webapp.css:3341). Das ist
      dieselbe Familie wie Punkt 3 der Core-Spec Abschnitt 14 (der Hover
      darf die Typografie des Eintrags nicht veraendern) und wird hier mit
      geschlossen. */
/* DIE HOVERFLAECHE GEHOERT DER ZEILE, NICHT DEM LINK. Berichtigt am
   2026-09-17 nach der Sichtpruefung ("06 Shell & Nav", Punkt 7: "der
   Hovereffekt im Menue im light Modus hat sobald man ueber den Text geht
   eine andere Farbe, das ist unsauber").

   Vorher stand hier EINE Regel fuer beide Menuearten:
     [data-design="new"] .dropdown-content a:hover,
     [data-design="new"] .dropdown-content-small a:hover
     { background-color: var(--ax-bg-hover); text-decoration: none; }

   Das ist fuer ".dropdown-content-small" richtig und fuer
   ".dropdown-content" falsch, und der Unterschied liegt im Markup: im
   kleinen Menue IST der Link die Zeile ("display: block", eigene deckende
   Flaeche, webapp.css:6135). Im grossen sitzt der Link in einer
   ".buttonrow" (commandfactory.js) und ist SCHMALER als sie. Gemessen an
   einer Agentenkarte, beide Themes:

     Zeile  x=295  Breite 200
     Link   x=305  Breite 156   -- 44px schmaler, 10 links, 34 rechts

   Folge waren ZWEI GESTAPELTE FLAECHEN in einer Zeile. Legacys
   ".buttonrow:hover" (webapp.css:2557, (0,2,0)) faerbt die ganze Zeile,
   und der Link legte seine eigene, dunklere darauf. Gemessen, helles
   Theme, vor der Aenderung:

     Ruhe             Zeile rgba(0,0,0,0)      Link rgba(0,0,0,0)
     neben dem Text   Zeile rgb(255,255,255)   Link rgba(0,0,0,0)
     ueber dem Text   Zeile rgb(255,255,255)   Link rgb(232,230,238)

   Dunkel dasselbe Muster: rgb(18,17,28) gegen rgb(36,34,51). Wer den
   Zeiger waagerecht ueber die Zeile zieht, sieht die Farbe an der
   Linkkante wechseln -- genau die Klage.

   (Eine fruehere Fassung dieses Kommentars behauptete, neben dem Text
   passiere gar nichts. Das war ein Lesefehler in der eigenen Messung: die
   Zeile faerbt sich sehr wohl, nur eben anders als der Link.)

   Die 6px Radius sind nicht neu gewaehlt: Legacys ".dropdown-content
   a:hover" (webapp.css:5049) zeichnet dieselbe Flaeche mit "border-radius:
   6px", und "--ax-radius-sm" ist genau 6px. Die Ecke wandert also mit der
   Flaeche mit, statt sich zu aendern. */
[data-design="new"] .dropdown-content .buttonrow:hover {
  background-color: var(--ax-bg-hover);
  border-radius: var(--ax-radius-sm);
}
/* Und der Link gibt seine Flaeche ab -- sonst laegen zwei uebereinander und
   der Text bekaeme eine zweite, dunklere Stufe. Legacys Regel steht bei
   (0,2,1), diese bei (0,3,1) und gewinnt. */
[data-design="new"] .dropdown-content a:hover {
  background-color: transparent;
  text-decoration: none;
}
/* Das kleine Menue bleibt, wie es war: dort traegt der Link die Zeile. */
[data-design="new"] .dropdown-content-small a:hover {
  background-color: var(--ax-bg-hover);
  text-decoration: none;
}
/* GEGENREGEL FUER DAS NAVBAR2-UNTERMENUE, und sie ist noetig, nicht
   vorsorglich. "06 Shell & Nav" hat dessen Hoverflaeche ausdruecklich bei
   Legacy belassen (Abweichung 10) -- sie kommt aus der generischen
   ".buttonrow:hover" (webapp.css:2557, "--background-color-navigation-
   hover"), waehrend ".navbar2 .dropdown-content .buttonrow:hover"
   (webapp.css:5010) nur den 2px-Streifen links ergaenzt. Die Zeilenregel
   oben steht bei (0,4,0) und schlaegt die generische (0,2,0) -- ohne diese
   Gegenregel bekaeme das Untermenue also den neuen Ton.

   BERICHTIGT NOCH VOR DEM COMMIT: hier stand zuerst "transparent". Das war
   falsch und der rote Lauf hat es gezeigt -- es haette der Zeile den Hover
   GENOMMEN, den Legacy ihr gibt. "Legacy bleibt Legacy" heisst nicht "keine
   Flaeche", sondern "dieselbe Flaeche wie ohne das neue Design". */
[data-design="new"] .navbar2 .dropdown-content .buttonrow:hover {
  background-color: var(--background-color-navigation-hover);
}

/* Vierte Gegenregel: die Hoverflaeche des navbar2-Untermenues bleibt Legacy.
   Die Regel darueber trifft ".navbar2 .dropdown-content a:hover" mit und
   stuende bei (0,3,1) im Gleichstand mit Legacys eigener Regel
   (webapp.css:5013); diese hier wiegt (0,4,1) und entscheidet die Sache
   ueber die Spezifitaet statt ueber die Ladereihenfolge.

   WARUM BEWAHREN UND NICHT VEREINHEITLICHEN -- zwei gemessene Gruende:

   1. "--ax-bg-hover" ist im HELLEN Theme der SCHWAECHERE Wert. Gegen die
      Spaltenflaeche "--clr-shell" gerechnet (WCAG 2.x, aus den im vollen
      Stapel gemessenen RGB-Tripeln):
        dunkel  Legacy rgb(18,17,28)    1,037  |  --ax-bg-hover rgb(36,34,51)    1,249
        hell    Legacy rgb(255,255,255) 1,155  |  --ax-bg-hover rgb(232,230,238) 1,071
      Im hellen Theme faellt der Unterschied zur Spalte also, statt zu
      steigen. Eine erste Fassung dieses Blocks behauptete das Gegenteil
      fuer beide Themes; das war fuer "hell" schlicht falsch.
   2. Die Elternzeile ".navbar2 .buttonrow:hover" (webapp.css:3342) traegt
      dieselbe "--clr-surface-1". Sie ist von keiner Regel hier bestritten
      und bliebe auf Legacy stehen -- in derselben 220px-Spalte stuenden
      dann ZWEI verschiedene Hoverflaechen fuer Zeilen, die heute gleich
      aussehen. Das tauscht nur eine Konsistenz gegen eine andere, und
      zwar in genau dem Bauteil, fuer das dieser Task sonst bewahrt.

   "var(--clr-surface-1)" und nicht "var(--background-color-navigation-hover)":
   beide ergeben denselben Wert (webapp.css:175 ist ein reiner Alias, im
   vollen Stapel in beiden Themes als identisch nachgemessen), aber
   "--clr-surface-1" ist der WOERTLICHE Wert der beiden Regeln, um die es
   geht -- Legacys ":5014" und der Elternzeile ":3342". Der Alias gehoert
   ".dropdown-content a:hover" (:5020), also dem SCHWEBENDEN Flyout; ihn
   ausgerechnet hier zu verwenden wuerde die Zuordnung verwischen, die diese
   Gegenregel gerade festhaelt.

   NUR "background-color": das "text-decoration: none" der Regel darueber
   bleibt bewusst auch fuer das navbar2-Untermenue gueltig. Legacy loescht
   die Unterstreichung fuer die Elternzeile derselben Spalte ausdruecklich
   (".navbar2 .buttonrow:hover", webapp.css:3341) -- hier wird also
   dieselbe Aussage fortgesetzt, nicht eine neue getroffen. */
[data-design="new"] .navbar2 .dropdown-content a:hover {
  background-color: var(--clr-surface-1);
}

/* ══ 05 · Data — Task 2: Tabellen-Grundgeruest ════════════════════
   ELEMENT-BASISREGELN. Sie tragen ":where([data-design=new])", damit die
   Spezifitaet bei der Legacy-Stufe bleibt ((0,0,1) bzw. (0,1,1)) -- ein
   Praefix mit Klassengewicht wuerde die vorhandene Schichtung umkehren und
   jede Zweckklasse lautlos schlagen. Und sie setzen ausschliesslich
   Eigenschaften, die Legacy fuer dasselbe Element kennt (Subset-Invariante,
   seit Task 1 maschinell erzwungen).

   Legacy-Eigenschaftsmengen, mit dem Waechter aus Task 1 ueber die GANZE
   webapp.css gezaehlt (Hell-Theme-Block und Media-Queries eingeschlossen):
   table 10 · th 23 · td 16 · tr 3 (background, cursor, opacity) ·
   thead 0 · tbody 0.

   NICHT ANGEFASST: "table" selbst. Zwei seiner zehn Eigenschaften
   ("display", "overflow-x") stammen ausschliesslich aus
   "@media screen and (max-width: 1024px)" (webapp.css:6519) und waeren
   oberhalb 1024px unangefochten -- den Medienbereich kann der Waechter
   nicht sehen. Figma verlangt am Tabellenrahmen nichts, was die
   Legacy-Regel nicht schon setzt; der sichtbare Rahmen ist
   ".molecule-table-wrap" und gehoert Task 3.

   KEIN "thead"/"tbody", aus zwei unabhaengigen Gruenden: beide haben eine
   LEERE Legacy-Menge (eine Basisregel darauf laesst den Waechter an seiner
   Nichtleer-Zusicherung abbrechen) -- und MoleculeTable erzeugt sie gar
   nicht. renderUi() baut das <table> per document.createElement() und
   AtomDisplayTableRow haengt die <tr> direkt hinein; ein per DOM erzeugtes
   <table> bekommt KEIN automatisches <tbody> (anders als geparstes HTML).
   Die Kopfzeile ist deshalb "tr:nth-child(1)" und die erste DATENZEILE
   "tr:nth-child(2)" -- wer hier "tbody tr" selektiert, trifft nichts. */

/* Table / Header — Figma-Knoten 40:39, 38px hoch, Innenabstand 12/16.
   Knoten und Code-Selektor nebeneinander gelesen: Figmas fuenf "cell"-
   Frames sind die <th> aus AtomDisplayTableColumnHeader, ihre
   Beschriftungen ("ID", "NAME", "BESCHREIBUNG", "PROJEKTFREIGABE",
   "AKTIONEN") stehen 1:1 in MoleculeTable.displayHeaders -- dasselbe
   Bauteil, kein Namensgleichklang.

   "background" und nicht "background-color": Legacy setzt hier einen
   GRADIENTEN ("--th-gradient", webapp.css:3817). Im vollen Stapel gemessen
   ist die Kopfzelle heute in BEIDEN Designs "background-color:
   rgba(0, 0, 0, 0)" mit einem "linear-gradient(...)" im background-image --
   ein "background-color" allein liesse den Verlauf darueber stehen. Nur die
   Kurzform setzt background-image auf "none".

   DIE VERSALIEN BLEIBEN, und sie stehen hier ausdruecklich statt sich auf
   Legacys "th" zu verlassen. Der Knoten laesst daran keinen Zweifel: sein
   Textstil "Label/Caps" traegt letterSpacing 10 % (= 1,1px bei 11px), und
   get_design_context gibt die Beschriftung als "uppercase" mit
   "tracking-[1.1px]" aus. Legacy: 10px / 700 / 1px -- Figma: 11px / 600 /
   1,1px; alle drei Werte aendern sich, also gehoert die ganze
   Kopftypografie an EINE Stelle. Der Tokenname "--ax-font-size-label-caps"
   bestaetigt die Lesart, er begruendet sie nicht.

   INNENABSTAND 12/16 -- Figmas eigene Werte. Der Kopf ist damit 44,5px
   hoch (12 + 20 + 12, dazu der Rahmen) und nicht Figmas 38: die Zelle erbt
   "line-height: 20px" (webapp.css:533, an "body"), Figma rechnet mit einem
   14px-Zeilenkasten. BEIDES zugleich ginge nur ueber "line-height", und das
   ist verboten -- es steht in KEINER der 23 Legacy-Eigenschaften von "th"
   und waere ein unbekaempftes Leck (mit "scroll-margin" am Waechter scharf
   gestellt und bestaetigt).

   Entscheidend ist nicht die absolute Hoehe, sondern die ORDNUNG zur
   Datenzeile: Figma zeichnet den Kopf FLACHER als die Zeile (38 zu 50,
   Verhaeltnis 0,76). Eine erste Fassung dieses Tasks traf mit 9px zwar die
   38 -- und kippte dabei genau diese Ordnung, weil die Datenzeile bei
   Legacys 10px Innenabstand nur 41 hoch blieb (Verhaeltnis 0,94, der Kopf
   also optisch gleich hoch wie die Zeile). Die Datenzelle traegt darum
   jetzt 15px (siehe dort); gemessen 44,5 zu 51, Verhaeltnis 0,87. Die
   Ordnung stimmt wieder, das Verhaeltnis bleibt eine dokumentierte
   Abweichung -- dieselbe Ursache, der 20px-Zeilenkasten.

   WAAGERECHT LITERAL, nicht "var(--ax-space-4)": das Token schrumpft ab
   768px (tokens.css:401) von 16 auf 12px. Kopf und Datenzelle muessen
   denselben waagerechten Abstand tragen, sonst stehen die Beschriftungen
   nicht mehr ueber ihren Zellen -- literal in beiden Regeln haelt das
   ueber alle Breiten.

   "position: sticky" und "top: 0" bleiben Legacy: Figma sagt dazu nichts,
   und sie tragen eine Funktion, keine Gestaltung. */
:where([data-design="new"]) th {
  background: var(--ax-bg-table-header);
  color: var(--ax-accent-knowledge);
  font-size: var(--ax-font-size-label-caps);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--ax-border-default);
}

/* GEGENREGEL ZUR REGEL DARUEBER: <th> heisst in dieser Anwendung nicht
   zwangslaeufig "Spaltenkopf einer Oberflaechentabelle". Jede Markdown-
   Tabelle in einem FLIESSTEXT rendert ihre erste Zeile ebenfalls als <th> --
   und dort ist der Text INHALT, keine Beschriftung. Ein Spaltenkopf-Look
   macht daraus 11px grosse, tuerkise VERSALIEN mitten in einer Antwort.

   BETROFFEN SIND SIEBEN Fliesstext-Behaelter, gemessen, nicht geschaetzt:
   ".notification-markdown", ".reference-content", ".orchestration-md",
   ".msg-bubble-bot"/".msg-bubble-greeting" (Cockpit-Chat),
   ".message.bot-message" (eingebetteter/oeffentlicher Chatbot),
   ".result-card" (KI-Service-Ergebnisse) und
   ".function-assistant-explanation". Die letzten vier tauchen in keiner
   Liste auf, die dieser Task geerbt hat -- und sie sind die
   meistbenutzten Oberflaechen des Produkts.

   WARUM STRUKTURELL UND NICHT ALS BEHAELTERLISTE: eine Kommaliste dieser
   sieben Klassen waere am Tag ihrer Entstehung vollstaendig und beim
   naechsten neuen Markdown-Ort still unvollstaendig -- und die
   Fehlerrichtung waere die SCHAEDLICHE (Inhalt wird entstellt, niemand
   merkt es). Der Unterschied ist stattdessen im Baum ablesbar:

     * "marked" erzeugt fuer JEDE Markdown-Tabelle
       "<table><thead><tr><th>" -- an der echten CDN-Datei
       (cdn.jsdelivr.net/npm/marked/lib/marked.esm.js, dieselbe, die
       markdownrenderer.js und markdownconverter.js laden) ausgefuehrt und
       nachgelesen, nicht angenommen.
     * "MoleculeTable" erzeugt NIE ein <thead>: renderUi() baut das <table>
       per document.createElement(), AtomDisplayTableRow haengt die <tr>
       direkt hinein, und ein per DOM erzeugtes <table> bekommt kein
       automatisches <thead>/<tbody>.

   "thead > tr > th" trennt die beiden also sauber, ohne eine Liste, die
   verrotten kann. Die Fehlerrichtung dreht sich damit um: eine kuenftige
   Oberflaechentabelle MIT <thead> bekommt die neue Kopftypografie nicht
   (sichtbar, harmlos) statt dass ein kuenftiger Fliesstext sie faelschlich
   bekaeme (still, schaedlich).

   PREIS, namentlich: die vier Oberflaechentabellen, die selbst ein <thead>
   bauen, fallen mit darunter -- "dialogentityversions.js"
   (".entity-versions-table"; dort folgenlos, deren eigene Regel
   webapp.css:12335 steht bei (0,1,2) und schlaegt diese hier),
   "showanalysisresultpage.js" ("#analysisresult-table"),
   "showanalysisresultforchunkpage.js" ("#analyseresult-table") und
   "helper/tablebuilder.js" (Funktions-/HTTP-Service-Tabellen des alten
   Workfloweditors). Die drei letzten behalten Fliesstext-Typografie im
   Kopf und bekommen nur das neue Band. Wer sie einbeziehen will, gibt
   ihnen eine eigene, POSITIVE Regel -- das ist die harmlose Richtung.

   ZURUECKGESETZT WIRD NUR DIE TYPOGRAFIE. Flaeche, Rahmen, Innenabstand
   und "font-weight: 600" bleiben: ein abgesetztes Kopfband ist auch im
   Fliesstext richtig, und fett ist die Kopfzeile in Markdown ohnehin.
   "font-size: inherit" trifft dabei exakt den umgebenden Fliesstext, was
   immer der Behaelter setzt -- gemessen 13,3333px in
   ".notification-markdown" und 13px in ".msg-bubble-bot"/".bot-message"/
   ".reference-content". "--ax-text-primary" ist die Farbe des <p> daneben;
   die <td> darunter stehen auf "--ax-text-muted", die Kopfzeile ist damit
   der staerkere Text, ohne ein Akzent zu sein.

   BASISREGEL, nicht Zweckregel: der Selektor besteht ausschliesslich aus
   Elementnamen und Kombinatoren. Rechtestes Element ist "th" (nicht
   "thead", dessen Legacy-Menge leer ist) -- der Waechter aus Task 1 prueft
   sie also weiter gegen die 23 "th"-Eigenschaften, und alle vier hier
   gesetzten stehen darin. Spezifitaet (0,0,3): schlaegt die Regel darueber
   (0,0,1), unterliegt aber weiterhin JEDER Zweckklasse (0,1,x) --
   ".notification-markdown th" (0,1,1) behaelt seinen eigenen
   Innenabstand. */
:where([data-design="new"]) thead > tr > th {
  color: var(--ax-text-primary);
  font-size: inherit;
  text-transform: none;
  letter-spacing: normal;
}

/* T1 (2026-09-15): DAS TUERKIS AM TABELLENKOPF HAELT IM HELLEN THEME NUR
   3,333 -- unter der 4,5, die WCAG 1.4.3 fuer Text verlangt.
   Am echten <th> gemessen (API-Schluessel-Tabelle der Profilseite, helles
   Theme, voller Stapel): "--ax-accent-knowledge" = teal/600 rgb(8,145,178)
   auf "--ax-bg-table-header" = ink/50 rgb(244,243,247) -> 3,333.
   "--ax-accent-knowledge-on-bg" = teal/800 rgb(21,94,117) haelt auf
   derselben Flaeche 6,578.

   DERSELBE FALL UND DIESELBE HEILUNG WIE AM AGENTENNAMEN: ".msg-sender"
   (weiter unten in dieser Datei) traegt denselben Ton in derselben Rolle
   und hat im hellen Theme dieselbe Zahl -- "--ax-bg-app" und
   "--ax-bg-table-header" sind hell BEIDE "--ax-ink-50". Der Kommentar dort
   fuehrt die drei erwogenen Farben samt Abstandsmass; hier wird die dort
   gewaehlte uebernommen, weil der Auftraggeber "gleich behandeln"
   entschieden hat.

   WEN SIE ERREICHT, GEMESSEN STATT ANGENOMMEN: tuerkis rendert ueberhaupt
   nur an <th>, die NICHT unter "thead > tr" haengen -- die Regel darueber
   steht bei (0,0,3) auf "--ax-text-primary" und schlaegt diese hier. Eine
   Erhebung ueber die fuer eine Rolle ohne Adminrechte erreichbaren Seiten
   fand 25 <th>, davon 23 ohne <thead>: allesamt von "MoleculeTable"
   erzeugt, das nie ein <thead> baut (siehe die Regel darueber). Die
   uebrigen zwei stammen aus einer Markdown-Tabelle im Fliesstext und
   stehen schon heute auf text/primary -- die bleiben, wo sie sind.

   DIE ":where()"-KLAMMER IST TRAGEND, NICHT GESCHMACK. Die Grundregel
   steht absichtlich als ":where([data-design=new]) th" bei (0,0,1), damit
   Legacy-Regeln darueber weiterhin greifen koennen. Eine gewoehnliche
   Gegenregel "[data-design=new][data-theme=light] th" laege bei (0,2,1)
   und schluege alles, was die ":where()"-Form bewusst offen laesst --
   einschliesslich der "thead"-Regel darueber, womit jede Markdown-Tabelle
   im Fliesstext eine tuerkise Kopfzeile bekaeme. Eine AENDERUNG im Gewand
   einer Wiederherstellung; die Leckprobe dazu steht in
   tests/features/design-heller-modus.spec.ts.

   "[data-theme=light]" POSITIV, weil dunkel auch OHNE Attribut vorkommt
   (teamstheme.js:17/19 setzt es nur fuer hell). In drei Zustaenden belegt:
   hell 6,578 mit teal/800; dunkel 7,193 mit teal/500; Attribut entfernt
   ebenfalls 7,193 -- der dunkle Block bleibt unangetastet, dort gibt es
   kein Problem.

   STELLUNG IN DER DATEI: die Regel steht bewusst HINTER der
   "thead"-Regel und nicht zwischen den beiden Grundregeln -- deren
   Kommentar beginnt mit "GEGENREGEL ZUR REGEL DARUEBER" und meint die
   "th"-Grundregel; ein Einschub dazwischen wuerde diesen Verweis still
   umlenken. Fuer die Kaskade ist die Stellung gleichgueltig: gegen die
   "th"-Grundregel (0,0,1) entscheidet die Quellreihenfolge, gegen die
   "thead"-Regel (0,0,3) die Spezifitaet. */
:where([data-design="new"][data-theme="light"]) th {
  color: var(--ax-accent-knowledge-on-bg);
}


/* Table / Row — Figma-Knoten 40:51: Zelltext "text/muted".
   Figma faerbt in derselben Zeile DREI Dinge verschieden -- die ID
   (Mono/Small) und die Beschreibung (Body/Small) in text/muted, den Namen
   (Body/Medium Strong) in text/primary. Eine nackte "td"-Regel kann das
   nicht unterscheiden; genommen wird der Wert der Mehrheit. Legacy stand
   auf "--clr-text-secondary", ueber die Bruecke also auf ink/300.
   ink/400 gegen die neue Zeilenflaeche gemessen: 4,80:1 (dunkel) und
   7,42:1 (hell) -- beides ueber der 4,5-Schwelle fuer Fliesstext.

   "tr:hover td" (webapp.css:3842, (0,1,2)) bleibt bewusst unangetastet;
   die Begruendung steht an der Hover-Gegenregel unten.

   INNENABSTAND 15px senkrecht. Figma legt die Zeile NICHT ueber einen
   Innenabstand fest, sondern ueber eine Hoehe von 50 mit senkrecht
   ZENTRIERTEM Inhalt -- am Knoten 40:51 nachgelesen, Zelle fuer Zelle:
   die ID sitzt bei y=16 mit h=18 (also 16 oben, 16 unten), der Name bei
   y=13 mit h=24, die Beschreibung bei y=5 mit h=40 (zwei Zeilen), die
   Aktionsknoepfe bei y=11 mit h=28. Es gibt dort also gar keinen einen
   Innenabstandswert; was alle Zellen teilen, ist die Zeilenhoehe 50.
   Unser Zeilenkasten ist 20px hoch, 20 + 2 x 15 = 50 trifft sie genau
   (gemessen 51 -- die 1px-Trennlinie kommt als Rahmen hinzu).

   (Eine erste Fassung dieses Tasks behauptete, Figma nenne fuer die
   Datenzelle dieselben 10/16 wie Legacy. Das war falsch, siehe oben.)

   Waagerecht bleibt es bei 16 -- Legacys Wert und Figmas zugleich. */
:where([data-design="new"]) td {
  color: var(--ax-text-muted);
  padding: 15px 16px;
}

/* #2028 -- TABELLENZELLEN IM CHAT: "--ax-text-secondary" statt "-muted".
   Die Regel darueber meint Oberflaechentabellen. In einer Chatantwort ist
   die Zelle dagegen INHALT, und "--ax-text-muted" hielt dort dunkel nur
   4,8:1 gegen ~15:1 im Fliesstext daneben. "--ax-text-secondary" haelt
   8,3:1 und ist zugleich Legacys Zellenfarbe (webapp.css "td",
   "--clr-text-secondary").

   BEGRENZT AUF DIE BEIDEN CHATBLASEN (Antwort und Begruessung), alle
   anderen Tabellen bleiben auf text/muted.

   SPEZIFITAET (0,1,1) BEWUSST: schlaegt die Basisregel (0,0,1), unterliegt
   aber "tr:hover td" (webapp.css, (0,1,2)) -- die Aufhellung auf
   text/primary beim Hover bleibt damit erhalten. */
:where([data-design="new"]) .msg-bubble-bot td,
:where([data-design="new"]) .msg-bubble-greeting td {
  color: var(--ax-text-secondary);
}

/* Figma kennt keine Zebrastreifen: jede Zeile traegt dieselbe Flaeche und
   wird nur durch eine Linie getrennt. Der Selektor wiederholt Legacys
   ":nth-child" bewusst -- eine nackte "tr"-Regel stuende bei (0,0,1) und
   verloere gegen Legacys "tr:nth-child(odd)"/"(even)" bei (0,1,1).

   Er trifft AUCH die Kopfzeile (ohne <tbody> ist sie "tr:nth-child(1)").
   Das ist folgenlos: die <th> darin tragen eine eigene, deckende Flaeche.

   DER TEURE TEIL DIESER REGEL: bei (0,1,1) steht sie im Gleichstand mit
   "tr:hover" (webapp.css:3838), "tr.sortable-chosen" (:3883) und
   "tr.sortable-ghost" (:3887) -- und components.css laedt zuletzt, gewinnt
   den Gleichstand also GEGEN alle drei. Ohne die drei Gegenregeln darunter
   waeren im neuen Design die Zeilen-Hoverflaeche und beide
   Drag-Rueckmeldungen ersatzlos verschwunden. Die Gegenregeln stehen NACH
   dieser Regel und gewinnen ihrerseits ueber die Ladereihenfolge. */
:where([data-design="new"]) tr:nth-child(odd),
:where([data-design="new"]) tr:nth-child(even) {
  background: var(--ax-bg-surface-1);
}

/* Gegenregel 1 -- die Hoverflaeche. Der WERT aendert sich nicht: die
   Bruecke haengt "--clr-row-hover" bereits auf "--ax-bg-hover"
   (tokens.css:152), im vollen Stapel gemessen rgb(36, 34, 51) dunkel und
   rgb(232, 230, 238) hell, und genau das ist Figmas "bg/hover". Die Regel
   stellt also nichts um, sie stellt wieder her, was die Zebra-Regel
   darueber sonst schluckt.

   WARUM "tr:hover td" (Legacys Aufhellung des Zellentextes auf
   text/primary) TROTZ Figma stehen bleibt: die Hoverflaeche allein haelt
   gegen die Ruheflaeche nur 1,20:1 (dunkel) bzw. 1,24:1 (hell) -- gemessen
   MIT den Regeln dieses Tasks, also gegen die jetzt einheitliche
   ink/900-Zeile; vorher, gegen die dunklere Zebra-Zeile, waren es 1,11
   bzw. 1,19. Figmas Hover-Variante (Knoten 40:92) laesst den Text
   unveraendert -- in der Vorlage genuegt das, weil dort niemand mit der
   Maus faehrt. Im Produkt ist die Texthelligkeit der einzige klar
   wahrnehmbare Hover-Hinweis; ihn wegzunehmen waere eine korrekte
   Deklaration, die niemand sieht. Bewusste, gemessene Abweichung -- sie
   steht im Bericht. */
:where([data-design="new"]) tr:hover {
  background: var(--ax-bg-hover);
}

/* Gegenregel 2 und 3 -- die beiden Drag-Zustaende von SortableJS
   (webapp.css:3883/3887). Bewusst mit den LEGACY-Variablen und nicht mit
   "--ax-*": diese zwei Regeln gestalten nichts, sie halten den Bestand.
   "--clr-surface-3" und "--clr-accent" haengen im neuen Design ohnehin an
   "--ax-bg-surface-3" bzw. "--ax-action-primary" (tokens.css:150 und :153;
   im hellen Theme steht "--clr-accent" auf "--ax-text-link", tokens.css:257
   -- auch das unveraendert). Der gerechnete Wert ist also derselbe wie vor
   diesem Task; die Schreibweise sagt, dass hier bewahrt wird. Figma
   zeichnet fuer den Drag keinen Zustand.

   Nur "background": "cursor: grabbing" (sortable-chosen) und
   "opacity: 0.4" (sortable-ghost) deklariert die Zebra-Regel nicht, sie
   bleiben unberuehrt und brauchen keine Wiederherstellung. */
:where([data-design="new"]) tr.sortable-chosen {
  background: var(--clr-surface-3);
}

:where([data-design="new"]) tr.sortable-ghost {
  background: var(--clr-accent);
}

/* Table / Row — die Trennlinie. Figma gibt der Zeile unten "border/soft"
   (Knoten 40:51, dort als "--clr-border-soft" = ink/800 gebunden); Legacy
   setzt an derselben Stelle "--clr-border", ueber die Bruecke ink/700.

   Der Selektor ist Legacys eigener (webapp.css:3834) und steht bei
   (0,1,2) -- eine nackte "td"-Regel bei (0,0,1) koennte ihn nicht
   schlagen. Rechtestes Element ist "td", und "border-bottom" gehoert zu
   dessen Legacy-Menge (aus genau dieser Regel sowie ".persona-list-table
   td" und ".entity-versions-table td").

   GEMESSENER EINWAND, der hierhin gehoert und nicht nur in den Bericht:
   ink/800 auf ink/900 haelt im dunklen Theme 1,07:1 -- schwaecher als die
   1,20:1, die Legacys ink/700 auf derselben Flaeche haelt. Zugleich faellt
   mit den Zebrastreifen der zweite Trennungshinweis weg. Umgesetzt wird
   die Vorlage (Spec Abschnitt 7: nach der Vorlage, nicht eigenmaechtig
   korrigiert); die Frage geht als Sichtpruefungs-Befund an den
   Auftraggeber. */
:where([data-design="new"]) tr:not(:last-child) td {
  border-bottom: 1px solid var(--ax-border-soft);
}

/* ══ 05 · Data — Task 3: Tabellenrahmen und Gruppenzeile ══════════
   ZWECKKLASSEN, keine Element-Basisregeln: jeder Selektor unten hat eine
   Klasse als rechtestes Glied, die Subset-Invariante aus Task 1 betrifft
   ihn also nicht. Die Spezifitaeten stehen trotzdem an jeder Regel -- der
   teuerste Fund von Task 2 war ein GLEICHSTAND, den kein Test sieht. */

/* ── Der Tabellenrahmen ──
   FIGMA HAT FUER DIESES BAUTEIL KEINEN KNOTEN. Die Seite "05 · Data"
   (1:7) fuehrt "Table / Header" (40:39), "Table / Row" (40:169),
   "Table / Group Row" (40:214), "Table / Sort Indicator" (222:2292) und
   "Pagination" (41:125) -- einen Rahmen um die Tabelle gibt es dort
   nicht. Die drei Werte hier sind deshalb KEINE Messung an der Vorlage,
   sondern Tokenhygiene: sie haengen den Rahmen von Legacy-Variablen ab,
   die die Bruecke NICHT umhaengt und die im neuen Design als Fremdkoerper
   stehen bleiben. Genau das steht auch so im Bericht.

   border-radius: WERTGLEICH. "--ax-radius-md" ist 10px (tokens.css:352),
   Legacy steht woertlich auf 10px -- und "--ax-radius-md" schrumpft
   unterhalb 768px nicht (nur -lg und -xl tun das, tokens.css:405).
   Gemessen in beiden Designs und beiden Themes: 10px. Deshalb bleiben
   webapp.css:3861/3865 (die 9px an der ersten Kopfzeile) unangetastet --
   sie muessten nur nachgezogen werden, wenn sich der Radius aendert.

   border: DAS IST DIE EINZIGE SICHTBARE AENDERUNG hier.
   "--clr-border-accent" ist "color-mix(--clr-accent 22%, --clr-border)"
   (webapp.css:33) und wird von der Bruecke nicht umgehaengt; im vollen
   Stapel gemessen meldet Chromium dafuer im neuen Design
   "color(srgb 0.110118 0.241176 0.351843)" (dunkel, also etwa
   rgb(28, 62, 90)) bzw. "color(srgb 0.65 0.817451 0.891569)" (hell, etwa
   rgb(166, 208, 227)) -- ein BLAUER Rahmen um eine Tabelle,
   deren Kopfband und Zeilen inzwischen auf der Tinten-Skala liegen.
   "--ax-border-default" ist ink/700 (dunkel) bzw. ink/200 (hell),
   gemessen rgb(36, 34, 51) und rgb(210, 208, 218) -- derselbe Wert, den
   die Kopfzeile aus Task 2 als "border-bottom" traegt. Rahmen und
   Kopftrennlinie sind damit eine Linie statt zweier Farben.

   box-shadow: HIER MIT ERLEDIGT, obwohl der Auftrag nur Radius und
   Rahmen nennt -- aber die Begruendung traegt nur fuer EIN Theme, und das
   gehoert gesagt statt geglaettet. Beide Werte im vollen Stapel gemessen,
   je einmal mit und einmal ohne diese Regel:

     DUNKEL -- ein Bruecken-Fremdkoerper, wie beim Rahmen.
       webapp.css:228 setzt "--shadow-card: 0 4px 20px
       rgba(var(--clr-accent-rgb), .08)". "--clr-accent-rgb" WIRD
       gebrueckt (tokens.css:199, cyan/500), "--shadow-card" selbst
       nicht. Gemessen: altes Design "rgba(59, 130, 246, 0.08)", neues
       Design ohne diese Regel "rgba(0, 159, 227, 0.08)" -- ein CYAN-
       Schimmer, den niemand bestellt hat.

     HELL -- KEIN Fremdkoerper. webapp.css:431 setzt "--shadow-card:
       0 4px 12px rgba(var(--clr-indigo-rgb), .14)", und
       "--clr-indigo-rgb" steht NICHT in tokens.css, wird also nicht
       gebrueckt. Gemessen ist der Schatten im neuen Design ohne diese
       Regel "rgba(99, 102, 241, 0.14) 0px 4px 12px 0px" -- BITGLEICH mit
       dem alten Design. Die Ersetzung ist im hellen Theme deshalb eine
       reine GESTALTUNGSENTSCHEIDUNG, und sie macht den Schatten
       deutlich schwerer: Schwarz 0,28 auf 20px Weichzeichnung statt
       Indigo 0,14 auf 12px.

   Genommen wird trotzdem "--ax-shadow-card", weil beide Themes denselben
   Schatten tragen sollen und der Karten-Task dieselbe Ersetzung schon
   begruendet hat (components.css um :1497). Aber im hellen Theme raeumt
   sie nichts auf -- sie entscheidet.

   NICHT ANGEFASST: "overflow: hidden", "margin-top/-bottom" und vor
   allem "flex-shrink: 0" samt seiner Begruendung -- das ist Funktion,
   nicht Gestaltung, und die Vorlage sagt dazu nichts.

   SPEZIFITAET (0,2,0). Legacys ".molecule-table-wrap" (webapp.css:3847)
   steht bei (0,1,0), es gibt keinen Gleichstand. Die einzige weitere
   Legacy-Regel auf dieser Klasse ist
   "#aiservice-parameter-table-wrapper > .molecule-table-wrap"
   (webapp.css:7636) bei (1,1,0) -- sie gewinnt gegen diese Regel, setzt
   aber ausschliesslich "flex-shrink" und "margin-top", also keine der
   drei Eigenschaften hier. Ueber die GANZE webapp.css gesucht
   (Hell-Theme-Block und alle Media-Queries eingeschlossen): mehr gibt es
   nicht. */
[data-design="new"] .molecule-table-wrap {
  border-radius: var(--ax-radius-md);
  border: 1px solid var(--ax-border-default);
  box-shadow: var(--ax-shadow-card);
}

/* ── Die Gruppenzeile — Figma-Knoten 40:214 / 40:170 ──
   Der Knoten und der Code-Selektor zeigen auf DASSELBE Bauteil: Figmas
   Komponentenbeschreibung sagt woertlich "Collapsible group header used
   by Functions, MCP Servers and HTTP Services", und genau diese drei
   Seiten (functionservicelistpage.js, mcpservicelistpage.js,
   httpservicelistpage.js) rufen MoleculeTable.setGroups(). Kein
   Namensgleichklang.

   DER FUND DIESES TASKS, und er kippt die naheliegende Umsetzung:
   ".molecule-table-group-header" IST NICHT DIE ZEILE. MoleculeTable
   ._addGroupHeaderRow() (moleculetable.js:396) legt eine <tr> mit EINER
   <td> ueber alle Spalten an und haengt das <div> erst DAHINEIN -- mit
   dem ausdruecklichen Kommentar, dass das Flex-Layout nie auf der <td>
   selbst liegen darf, weil eine "display:flex"-Tabellenzelle ihren
   colSpan verliert. Das <div> sitzt also INNERHALB des Innenabstands der
   Zelle, und seit Task 2 sind das 15px/16px.

   Die naheliegende Fassung -- "padding: 12px 16px" plus Flaeche auf dem
   <div>, ohne die Regel unten -- wurde im vollen Stapel gemessen und ist
   an drei Stellen falsch:
     * Zeilenhoehe 80px statt Figmas 52 (15 + 12 + 25 + 12 + 15 + 1),
     * der Chevron steht 32px vom Zeilenrand statt Figmas 16 -- also
       doppelt so weit eingerueckt wie der Text der Datenzellen
       darunter, die auf 16 stehen,
     * und die Flaeche deckt nur den Kern der Zelle: rundherum bliebe ein
       15/16px breiter Rand in der ZEILENfarbe stehen. Figmas
       "bg/surface-2" fuellt die Zeile randlos.
   Dazu kommt, dass genau diese Fassung den Rahmen zum Kappen bringt: das
   <div> ist "width: 100%" der Zellen-INNENbreite und rechnet mit Legacys
   content-box, der eigene Innenabstand kommt also OBENDRAUF -- 32px, und
   damit 16px breiter als die Tabelle. ".molecule-table-wrap" ist
   "overflow: hidden": gemessen scrollWidth 1214 gegen clientWidth 1198.
   KEIN EINZIGER GERECHNETER WERT haette sich dabei geruehrt:
   "background", "padding-top" und "padding-left" melden in beiden
   Fassungen exakt dasselbe. (Dieselbe Falle ein zweites Mal, in einer
   Zwischenfassung DIESES Tasks: Zelle schon auf 0, aber noch ohne
   "box-sizing: border-box" am <div> -- scrollWidth 1230 gegen 1198.
   Begruendung an der Regel darunter.)

   OHNE DIE REGEL HIER, per deleteRule im fertigen Stand gemessen: das
   <div> steht bei x 57 statt 41, ist 1166 statt 1198 breit, der Chevron
   rueckt auf 32 statt 16 und die Zeile wird 80px statt 50 hoch.

   DIE ZELLE GIBT IHREN INNENABSTAND AB, dann traegt das <div> Figmas
   Kasten ungestoert. Danach ist das <div> deckungsgleich mit der <tr>
   (gemessen x 41 und Breite 1198, identisch mit der Zeile), der Chevron
   steht auf 16px und faellt mit dem Textanfang der ersten Datenspalte
   zusammen, und die Flaeche fuellt die Zeile randlos.

   VERWORFEN: eine reine Klassenfassung mit "margin: -15px -16px" und
   "width: auto" am <div>. Sie misst sich bitgleich (Zeile 50, x 41,
   Breite 1198, Chevron 16), aber die beiden Zahlen sind der WOERTLICHE
   Innenabstand von ":where([data-design=new]) td" aus Task 2 -- eine
   fremde Zahl gespiegelt statt die Absicht ausgedrueckt. Aendert
   irgendwann jemand den td-Innenabstand, bricht die Gruppenzeile STILL
   und an einer Stelle, an der niemand nachschaut. Die Regel hier sagt
   dagegen, was gemeint ist: diese eine Zelle bringt keinen eigenen
   Innenabstand mit.

   ":has()" UND DER WAECHTER AUS TASK 1: die Klasse steckt im Argument
   von ":has()", und der Waechter sieht Klammerinhalte nicht -- er zaehlt
   die Regel deshalb als Element-Basisregel fuer "td" und prueft sie
   gegen dessen Legacy-Eigenschaftsmenge (16 Eigenschaften, "padding"
   steht darin). Sie besteht die Subset-Invariante also, und das ist
   richtig so: sie setzt nichts, was Legacy fuer "td" nicht kennt. Im
   BROWSER dagegen scopt die Klasse sehr wohl -- die Regel trifft
   ausschliesslich Zellen mit einem Gruppenkopf darin. Beides ist
   gemessen: die Gruppenzelle meldet "0px", eine gewoehnliche Datenzelle
   derselben Tabelle unveraendert "15px 16px".

   ":where()" um den Design-Marker, wie an allen Basisregeln dieses
   Teilprojekts: die Regel wiegt damit (0,1,1) -- "td" (0,0,1) plus die
   Spezifitaet des ":has()"-Arguments, also die der Klasse (0,1,0). Das
   schlaegt Legacys "th, td" (webapp.css:3801, (0,0,1)) und Task 2s
   ":where(...) td" (ebenfalls (0,0,1)) sauber ueber die Spezifitaet.
   GLEICHSTAENDE bei (0,1,1), ueber die ganze webapp.css gesucht:
   ".persona-list-table td" (:12064), ".entity-versions-table td"
   (:12329), ".notification-markdown td" (:12814), ".reference-content
   td" (:13150) und ".orchestration-md td" (:13438). Keine davon kann
   dieselbe Zelle treffen -- die drei Fliesstext-Klassen umschliessen
   Markdown-Tabellen (die nie eine MoleculeTable sind),
   ".entity-versions-table" ist eine handgebaute Tabelle in
   dialogentityversions.js ohne Gruppen, und ".persona-list-table" wird
   im ganzen frontend/ von KEINER Zeile vergeben -- ein toter Selektor
   (nur benannt, nicht angefasst). Die Regeln mit ID
   ("#aiservice-parameter-table th:first-child, td:first-child",
   :3870/:3871) wiegen mehr,
   gehoeren aber zur Parametertabelle, die keine Gruppen kennt. */
:where([data-design="new"]) td:has(> .molecule-table-group-header) {
  padding: 0;
}

/* Und hier Figmas Kasten.

   "box-sizing: border-box" IST NICHT OPTIONAL, und der Grund ist
   gemessen, nicht angenommen. Legacys "width: 100%" (webapp.css:2801)
   meint ohne diese Zeile die INNENbreite: das <div> wird 100 % der
   Zellenbreite PLUS seinem eigenen Innenabstand. Mit der Zelle auf 0 und
   Figmas 12/16 auf dem <div> sind das 1198 + 32 = 1230 gegen eine 1198px
   breite Zeile -- und weil ".molecule-table-wrap" "overflow: hidden"
   ist, KAPPT der Rahmen die 32px: gemessen scrollWidth 1230 gegen
   clientWidth 1198. Eine erste Fassung dieses Tasks hatte genau das, und
   gefunden hat es nicht der Blick auf die Regel, sondern die
   Kappungs-Zusicherung im Test.
   WAS IM ALTEN DESIGN DARAUS FOLGT -- nachgemessen, weil eine erste
   Fassung dieses Kommentars hier einen Ueberlauf behauptete, den es
   nicht gibt: dieselbe Legacy-Zeile macht das <div> auch dort breiter
   als den Inhaltskasten seiner Zelle (gemessen 1231,31 gegen 1226), aber
   es laeuft NICHT ueber die Zelle hinaus. In beiden alten Themes: Zelle
   x 11, Breite 1258, rechte Kante bei 1269; das <div> beginnt bei x 27
   und endet bei 1258,31, also 10,69px INNERHALB. Der Rahmen meldet
   scrollWidth 1258 = clientWidth 1258, "overflow: hidden" verdeckt
   nichts. Uebrig bleibt eine unsichtbare Asymmetrie des Innenabstands --
   16px links, 10,69px rechts. Das ist kein vorbestehender Fehler und
   nichts zum Nachziehen.
   In dieser Anwendung gibt es bewusst KEINEN universellen
   box-sizing-Reset (siehe den Kommentar um components.css:2399); die
   Eigenschaft steht deshalb dort, wo sie gebraucht wird.

   Mit ihr ist "width: 100%" der richtige Wert und bleibt Legacys: die
   Zelle hat keinen Innenabstand mehr, 100 % ihrer Innenbreite IST die
   Zeilenbreite.

   HOEHE: gemessen 50px (12 + 25 + 12 + 1px Trennlinie), Figma sagt 52.
   Die 25 sind der Zeilenkasten des Aktionsblocks (drei <img> zu 20px in
   einer Zeile); Figma rechnet dort mit einem 28px-Knopf
   ("--size-control-sm"). Dieselbe Ursache wie bei Kopf und Datenzeile in
   Task 2, und dieselbe Entscheidung: die Vorlage wird nicht ueber eine
   erfundene Hoehe erzwungen.

   DIE FOLGE GEHOERT AUSGESPROCHEN, und zwar gegen den BESTAND gemessen,
   nicht gegen Figma -- gegen Figma sieht sie nach einer Marginalie aus
   (2px hoeher gegen 1px flacher), gegen das, was die Anwendung heute
   zeigt, ist sie es nicht. Alle sechs Werte im vollen Stapel gemessen:

                Kopf     Gruppenzeile   Datenzeile
       alt      40,5     56,66          41
       neu      44,5     50             51

   Heute ist die Gruppenzeile die HOECHSTE Zeile der Tabelle und liegt
   15,66px ueber einer Datenzeile; danach ist sie die NIEDRIGSTE. Die
   Hoehe traegt die Hierarchie also nicht mehr mit, sie kehrt sie um.
   Unterscheidbar bleiben die beiden ueber die Flaeche (ink/800 gegen
   ink/900) und den 15px-Titel. Der Befund geht mit diesen Zahlen an den
   Auftraggeber -- gemeinsam mit den Kontrastwerten, es ist derselbe
   Befund.

   ZUM "gap" GEHOERT EINE EINSCHRAENKUNG, und sie steht hier, statt
   verschwiegen zu werden: Figmas 8 liegt zwischen Chevron, Titel und
   Anzahl -- das sind dort DIREKTE Kinder des Flex-Kastens. In unserem
   Baum sind die direkten Kinder "-header-left" (mit Chevron und Titel
   darin), "-header-summary" und "-header-actions"; das "gap" trifft also
   andere Fugen als in der Vorlage, und solange
   "justify-content: space-between" freien Platz zu verteilen hat, ist es
   ueberhaupt nicht zu sehen. Es bleibt trotzdem stehen: es ist Figmas
   eigener Wert fuer diesen Kasten und wirkt als Mindestabstand, sobald
   der Platz eng wird. Die 8px, die man WIRKLICH sieht, sind die zwischen
   Chevron und Titel -- die setzt die Regel weiter unten, und der Test
   misst genau diese Luecke.

   INNENABSTAND 12/16 LITERAL, ABSTAND 8 ALS TOKEN: 12 und 16 muessen
   woertlich stehen, weil "--ax-space-3"/"-4" unterhalb 768px auf 10 bzw.
   12 schrumpfen (tokens.css, im Media-Block ab :389) -- die 16 muss mit
   dem woertlichen 16 der Datenzelle zusammenpassen, sonst rutschen
   Chevron und Zellentext auseinander. "--ax-space-2" (8) schrumpft in
   KEINER Media-Query (definiert in tokens.css:347; in den beiden
   Media-":root"-Bloecken ab :378 und :389 nicht wiederholt -- nachgezaehlt,
   nicht angenommen) und darf deshalb Token bleiben.

   KEIN Rahmen (Figma: kein Stroke am Knoten) -- und keiner wird gesetzt.
   Die 1px-Linie unter der Gruppenzeile kommt von Task 2s
   "tr:not(:last-child) td" und bleibt: sie liegt AUSSERHALB des
   Fuellbereichs dieses <div> und trennt die Gruppe von ihrer ersten
   Datenzeile. Auch das ist eine benannte Abweichung.

   SPEZIFITAET (0,2,0) gegen Legacys (0,1,0) (webapp.css:2797). Ueber die
   ganze webapp.css gesucht: das sind die einzigen zwei Regeln auf dieser
   Klasse. Kein Gleichstand. */
[data-design="new"] .molecule-table-group-header {
  box-sizing: border-box;
  padding: 12px 16px;
  gap: var(--ax-space-2);
  background: var(--ax-bg-surface-2);
}

/* GEGENREGEL -- die Rueckmeldung beim Ueberfahren. Sie steht hier NICHT
   aus Figma (der Knoten kennt nur "Expanded=True/False", keinen Hover),
   sondern weil die Regel darueber eine vorhandene Affordanz vernichtet:
   die Gruppenzeile ist anklickbar (moleculetable.js:412 setzt
   "cursor: pointer", :415 den Umschalter), und ihre Rueckmeldung kommt
   heute von "tr:hover" (webapp.css:3838). Eine DECKENDE Flaeche auf dem
   <div> legt sich darueber. Im vollen Stapel per elementFromPoint
   gemessen -- also an der Farbe, die man TATSAECHLICH sieht, nicht an
   der, die getComputedStyle am <tr> meldet:
     ohne diese Regel   ruhend rgb(26, 24, 38)  ueberfahren rgb(26, 24, 38)
     mit dieser Regel   ruhend rgb(26, 24, 38)  ueberfahren rgb(36, 34, 51)
   Der Bestand meldet an derselben Stelle rgb(18, 17, 28) -> rgb(36, 34,
   51), die Affordanz gab es also und sie bleibt erhalten.
   "--ax-bg-hover" ist derselbe Wert, den Task 2 fuer die Datenzeilen
   nimmt; hell gemessen rgb(232, 230, 238) gegen die Ruheflaeche
   rgb(244, 243, 247).
   Spezifitaet (0,3,0) -- schlaegt die Regel darueber ueber die
   Spezifitaet und nicht ueber die Ladereihenfolge. */
[data-design="new"] .molecule-table-group-header:hover {
  background: var(--ax-bg-hover);
}

/* Der Chevron. Figma setzt ihn auf x=16 und den Titel auf x=40 -- also
   16px Icon plus 8px Abstand (Knoten 40:171/40:174). Legacys
   ".collapsible-arrow" traegt "margin-right: 0.2em", im vollen Stapel
   gemessen 2,13px.

   DER SELEKTOR IST BEWUSST VERSCHACHTELT. ".collapsible-arrow" gehoert
   NICHT allein der Tabelle: MoleculeCollapsibleSection
   (moleculecollapsiblesection.js:29) benutzt dieselbe Klasse fuer die
   aufklappbaren Tooleinsatz-Abschnitte im Chat. Eine nackte Regel auf
   der Klasse haette den Abstand dort mitgeaendert -- ein Bauteil, das
   dieser Task gar nicht betrachtet. Die beiden Baeume sind sauber
   getrennt: der Chat-Pfeil sitzt immer in ".collapsible-header", der
   Tabellen-Pfeil immer in ".molecule-table-group-header".
   Spezifitaet (0,3,0) gegen (0,1,0).

   NICHT GEAENDERT wird der Pfeil selbst: Figma zeichnet ein 16x16-Icon,
   MoleculeTable schreibt die Schriftzeichen "▸"/"▾" (moleculetable.js
   :419). Ein Icontausch waere eine Aenderung an moleculetable.js und
   gehoert nicht zu diesem Auftrag. Benannte Abweichung. */
[data-design="new"] .molecule-table-group-header .collapsible-arrow {
  margin-right: var(--ax-space-2);
}

/* Der Gruppentitel — Figmas "Body/Medium Strong": 15px, Semi Bold,
   text/primary (Knoten 40:174).

   WAS HIER NICHT GEHT, und der Kommentar sagt es, statt es zu
   verschweigen: Figma setzt den NAMEN und die ANZAHL als zwei getrennte
   Textknoten mit zwei verschiedenen Stilen -- 40:174 "Microsoft365
   Services" in 15px/600/text-primary, 40:175 "(15)" in
   13px/400/text-muted. MoleculeTable schreibt beides in EINEN Textknoten
   ("`${group.name} (${group.rows.length})`", moleculetable.js:423). Die
   Anzahl laesst sich damit nicht eigenstaendig setzen; sie erbt die
   Werte des Titels. Auseinanderziehen liesse sich das nur in
   moleculetable.js, und die Datei gehoert nicht zu diesem Auftrag. Der
   Titel gibt den Ton an, also bekommt die Zeile dessen Stil -- dieselbe
   Entscheidung wie bei Task 2s "td"-Farbe ("genommen wird der Wert der
   Mehrheit"). Benannte Abweichung, sie steht im Bericht.

   Legacy steht auf "font-size: 0.85em" (gemessen 11,33px),
   "font-weight: 500" und "color: var(--clr-text-muted)" -- alle drei
   aendern sich, deshalb stehen alle drei hier. Der Kontrast des neuen
   Titels gegen die neue Gruppenflaeche, aus den im vollen Stapel
   gemessenen Tripeln gerechnet (WCAG 2.x): ink/100 auf ink/800 = 14,12:1
   (dunkel), ink/900 auf ink/50 = 16,93:1 (hell). Zum Vergleich, aus den
   im ALTEN Design gemessenen Tripeln derselben Stelle gerechnet
   (color(srgb 0.636863 0.668235 0.705882) auf
   color(srgb 0.101961 0.133333 0.182353), dunkel): 6,84:1. Der Titel
   wird also nicht nur groesser, sondern auch lesbarer.

   DERSELBE VERSCHACHTELTE SELEKTOR AUS DEMSELBEN GRUND wie beim Chevron:
   ".collapsible-label" gehoert auch den Tooleinsatz-Abschnitten im Chat.
   Spezifitaet (0,3,0). */
[data-design="new"] .molecule-table-group-header .collapsible-label {
  font-size: var(--ax-font-size-body-md);
  font-weight: 600;
  color: var(--ax-text-primary);
}

/* Der rechte Kennzahlenblock. FIGMA KENNT IHN NICHT -- der Knoten 40:170
   hat an dieser Stelle einen "spacer" und danach die Aktionsknoepfe. Der
   naechstgelegene Textstil der Vorlage ist der der Anzahl ("Body/Small",
   13px Regular, text/muted, Knoten 40:175), und inhaltlich ist der Block
   genau das: eine Zahlenangabe neben dem Gruppennamen. Also wird er
   darauf gesetzt.

   Gemessen aendert sich nur die Groesse: 13,3333px (Legacys geerbter
   Fliesstext) auf 13px. "font-weight: 400" steht schon in Legacys Regel
   und wird nicht wiederholt. "color" muss dagegen stehen: ohne die Zeile
   ERBT der Block die Farbe der <td>, und die ist zwar heute
   "--ax-text-muted" (Task 2) -- aber geerbt, nicht gesetzt. Der Wert ist
   damit derselbe, die AUSSAGE eine andere; ohne sie wandert die Kennzahl
   mit, wenn die Zellenfarbe je wandert, und stuende dann in der
   Titelfarbe neben dem Titel.
   ("padding-left: 1em" bleibt Legacy: der Block wird von
   "justify-content: space-between" ohnehin an den rechten Rand
   gedrueckt, Figma sagt dazu nichts, und ein Wert, den die Vorlage nicht
   kennt, wird nicht erfunden.)

   Spezifitaet (0,2,0) gegen Legacys (0,1,0) (webapp.css:2808). */
[data-design="new"] .molecule-table-group-header-summary {
  font-size: var(--ax-font-size-body-sm);
  color: var(--ax-text-muted);
}

/* ══ 05 · Data — Task 4: Sortierindikator ═════════════════════════
   ZWECKKLASSEN wie in Task 3: rechtestes Glied jeder Regel unten ist
   ".molecule-table-sort", die Subset-Invariante aus Task 1 betrifft sie
   also nicht (ihr Waechter verwirft jede Regel, die ausserhalb von
   Klammern eine Klasse traegt). Die Spezifitaeten stehen trotzdem an
   jeder Regel.

   DIE KLASSE IST NEU, und mit ihr eine Aenderung an moleculetable.js --
   dem einzigen Produktionscode, den dieses Teilprojekt anfasst. Der
   Grund steht dort ausfuehrlich; kurz: bis zu diesem Task stand die
   Sortierrichtung AUSSCHLIESSLICH als Schriftzeichen im Text der
   Kopfzelle ("Name ▲"). Ein Zeichen im Text ist fuer CSS unlesbar --
   weder ein Pseudoelement noch eine Regel kann daran drei Zustaende
   unterscheiden. Der Pfeil sitzt jetzt in einem eigenen <span>, die
   Richtung als "data-sort-dir" an der <th>; die Zeichen selbst sind
   geblieben, damit das alte Design unveraendert bleibt (nachgewiesen:
   der Kachel-Screenshot ist vor und nach der Aenderung in beiden Themes
   BYTEGLEICH).

   DREI ZUSTAENDE, alle drei aus Figma-Knoten 222:2292 gelesen und die
   Vorlagen-SVGs selbst geholt:
     Ruhe        Caret nach unten, "text/muted" (#817f92), Deckkraft 0,55
     aufsteigend Caret nach OBEN,  "text/secondary" (#adabbb)
     absteigend  Caret nach unten, "text/secondary"
   Ruhe und "absteigend" tragen dieselbe Kurve ("M3 4.5L6 7.5L9 4.5"),
   "aufsteigend" ist deren exakte Spiegelung ("M3 7.5L6 4.5L9 7.5" --
   4,5 und 7,5 liegen symmetrisch um die Kastenmitte 6). Deshalb genuegt
   EINE Maske plus "transform: scaleY(-1)"; ein zweites Bild waere eine
   zweite Stelle, an der dieselbe Kurve verrotten kann.

   UND DER RUHEZUSTAND IST UNSICHTBAR, bis die Zelle ueberfahren wird.
   Das ist nicht ausgedacht, es steht zweimal woertlich in der Vorlage:
   die Komponentenbeschreibung von 222:2292 sagt "in the product this
   only appears on hover and focus", die von 40:39 "in the product the
   caret is hidden until hover, and the active column keeps it visible".
   FOKUS BLEIBT AUS, und das ist eine benannte Abweichung: eine <th> ist
   nicht fokussierbar (MoleculeTable haengt den Umschalter an ihr
   onclick, ohne tabindex), ":focus-visible" traefe dort nie etwas. Ein
   tabindex waere eine zweite Markup-Aenderung und ist nicht beauftragt.

   DER PLATZ WIRD IMMER RESERVIERT (Deckkraft 0 statt "display: none"):
   sonst spraengen beim Ueberfahren alle Spalten um. Figma haelt es
   genauso -- am Knoten 40:39 ist der 12px-Kasten ein fester Flex-Sohn
   jeder sortierbaren Zelle. */

/* Der Kasten. 12 x 12 aus der Vorlage ("12 px, never larger -- this is
   an affordance, not one of the 24 px icons"), 8px Abstand zur
   Beschriftung aus dem "gap" der Kopfzelle (Knoten 40:39:
   "var(--space-2, 8px)"). "--ax-space-2" schrumpft in keiner
   Media-Query: es steht einmal in tokens.css:347 und wird in KEINEM der
   beiden Media-Bloecke wiederholt ("@media (max-width: 1024px)" ab :378,
   "@media (max-width: 768px)" ab :389 -- die Zeilen :382 und :401 liegen
   INNERHALB dieser Bloecke und nennen andere Abstaende). Es darf deshalb
   Token bleiben -- anders als die 12/16 der Kopfzelle, die
   woertlich stehen muessen.

   "font-size: 0" macht das Schriftzeichen im <span> unsichtbar, OHNE es
   aus dem Baum zu nehmen. Genau darin liegt der Trick dieses Tasks: das
   alte Design zeigt weiterhin das Zeichen, das neue zeigt Figmas Caret,
   und beide lesen dieselbe Quelle. "color: transparent" haette den
   Platz des Zeichens stehen lassen und den 8px-Abstand um dessen Breite
   verfaelscht.

   MASKE STATT BILD: die Farbe kommt aus "background-color", die Form aus
   der Maske. Nur so folgt der Caret dem Token je Zustand und Theme --
   ein <img> oder ein "background-image" mit eingebautem Farbwert
   koennte das nicht (und truege einen hartcodierten Farbwert in eine
   Datei, die keine haben soll). Dieselbe Technik benutzt webapp.css:2252
   fuer das Sende-Icon des Chatfensters, dort ebenfalls mit
   "-webkit-mask" davor; ein Browser ohne Maskenunterstuetzung zeigte
   einen 12x12-Block statt eines Carets. Das Gate faehrt Chromium.

   Die Kurve ist WOERTLICH die der Vorlage: 12x12-Sichtfeld, Pfad
   "M3 4.5L6 7.5L9 4.5" (also 6 breit, 3 hoch), Strichstaerke 1,5, runde
   Enden und Ecken. Der Strichfarbwert in der Maske ist bedeutungslos --
   verwertet wird allein der Alphakanal.

   Spezifitaet (0,2,0). Ueber die ganze webapp.css gesucht: KEINE
   Legacy-Regel nennt ".molecule-table-sort" (die Klasse entsteht mit
   diesem Task) und keine nennt "span" nackt. Kein Gleichstand, kein
   Vorbestand. */
[data-design="new"] .molecule-table-sort {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-left: var(--ax-space-2);
  vertical-align: middle;
  font-size: 0;
  opacity: 0;
  background-color: var(--ax-text-muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / 12px 12px;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / 12px 12px;
}

/* RUHEZUSTAND -- sichtbar nur, solange die Zelle ueberfahren wird, und
   nur an Spalten, die NICHT sortieren. Die 0,55 sind kein Gestaltungs-
   griff von mir: die Vorlage traegt sie als "opacity" am Caret-PFAD des
   Ruhezustands (Knoten 222:2287, dem Pfad IN der Ruhe-Variante 222:2286),
   waehrend die beiden aktiven Zustaende ohne Deckkraft auskommen.

   RULING 11 -- DIE 0,55 BLEIBEN, ALS BEWUSSTE ABWEICHUNG VON WCAG 1.4.11.
   Sie druecken den Kontrast des Ruhe-Carets gegen die Kopfflaeche auf
   2,25:1 (dunkel) und 2,47:1 (hell); die Schwelle fuer Bedienelemente ist
   3:1. Alle Zahlen hier aus den im vollen Stapel gemessenen Farbtripeln
   gerechnet, die Deckkraft dabei wie im Browser als Fliesskomma gemischt.

   Warum trotzdem: bei VOLLER Deckkraft haelt derselbe Caret 4,48 (dunkel)
   und 6,71 (hell) -- im hellen Theme also doppelt so viel wie die
   Spaltenbeschriftung, zu der er gehoert (die tuerkise Kopfschrift misst
   dort 3,33). Die Affordanz uebertoente ihren eigenen Inhalt, und das ist
   gestalterisch schlechter, als die Zahl schlecht ist. Dazu: den ZUSTAND
   traegt der aktive Caret, und der liegt bei 7,75 / 11,14 -- um ihn geht
   es in 1.4.11. Der Ruhe-Caret ist ein fluechtiger Hinweis, der nur unter
   der Maus erscheint und dort redundant zum "cursor: pointer" derselben
   Zelle ist.

   DER PRAEZEDENZFALL AUS "06 - Shell & Nav" TRAEGT HIER NICHT: dort war
   das Element bei 1,74 faktisch unsichtbar UND der einzige Traeger seines
   Zustands. Beides ist hier anders.

   BILLIGER MITTELWEG, falls die Sichtpruefung ueber 3:1 will: 0,75 statt
   1,0 ergibt 3,09 (dunkel) und 3,74 (hell) -- ueber der Schwelle, und die
   Hierarchie im hellen Theme bleibt heil (3,74 gegen 3,33 der
   Beschriftung, statt 6,71 gegen 3,33). Eine Zahl aendern, sonst nichts.

   ":not([data-sort-dir])" macht die Regel und die darunter zu einem
   ECHTEN Entweder-Oder statt zu einem Spezifitaets-Wettlauf. Ohne das
   ":not()" stuenden beide bei (0,3,1) im Gleichstand -- die aktive
   Spalte behielte beim Ueberfahren nur deshalb ihre volle Deckkraft,
   weil ihre Regel weiter unten steht. Genau diese Sorte Gleichstand war
   der teuerste Fund von Task 2; hier ist er ausgeschlossen, nicht
   gewonnen.

   Spezifitaet (0,4,1). */
[data-design="new"] th:not([data-sort-dir]):hover .molecule-table-sort {
  opacity: 0.55;
}

/* AKTIV -- die Spalte, die gerade sortiert. Bleibt sichtbar, auch ohne
   Maus ("the active column keeps it visible"), und wechselt auf
   "text/secondary": das ist eine Stufe HELLER als der Ruhezustand
   (ink/300 gegen ink/400 dunkel, ink/600 gegen ink/500 hell), der
   aktive Zustand ist also nicht nur staerker deckend, sondern auch
   kontrastreicher.

   Spezifitaet (0,3,1) -- schlaegt die Kastenregel (0,2,0) ueber die
   Spezifitaet; gegen die Hover-Regel darueber gibt es nichts zu
   schlagen, die beiden schliessen sich aus. */
[data-design="new"] th[data-sort-dir] .molecule-table-sort {
  opacity: 1;
  background-color: var(--ax-text-secondary);
}

/* AUFSTEIGEND -- derselbe Caret, gespiegelt. Siehe die Herleitung im
   Kopfkommentar: Figmas Pfad fuer "Asc" ist die exakte Spiegelung des
   Pfads fuer "Desc" an der Kastenmitte, "scaleY(-1)" trifft ihn also
   nicht ungefaehr, sondern genau.

   Spezifitaet (0,3,1), wertgleich mit der Regel darueber -- aber
   "transform" setzt nur diese hier, es gibt nichts zu ueberschreiben. */
[data-design="new"] th[data-sort-dir="asc"] .molecule-table-sort {
  transform: scaleY(-1);
}

/* ══ 05 · Data — Task 5: Seitenzahlen ═════════════════════════════
   Figma-Knoten 41:125 ("Pagination", Seite 1:7), selbst gelesen:
   Streifen 34 hoch mit Abstand 8; Seitenknopf 34 x 34, Radius 10,
   Beschriftung 13 px Inter Medium (500). Aktuelle Seite Flaeche
   "action/primary" OHNE Rahmen und Text "action/on-primary"; alle
   anderen Seiten Flaeche "bg/surface-2", 1 px "border/default", Text
   "text/secondary". Die Auslassung "…" traegt "text/muted".

   ZWEI DINGE AUS DER VORLAGE STEHEN UNTEN NICHT, WEIL ES SIE IM
   PRODUKT NICHT GIBT -- gemessen, nicht vermutet:

   1. DIE AKTUELLE SEITE IST IM DOM NICHT MARKIERT. MoleculePagination.
      setupUi() setzt auf ihr zwar "image page-btn-seleceted"
      (moleculepagination.js:53), aber AtomContainer.render() schliesst
      mit "this.updateValue()" (atomcontainer.js:368), das rekursiv
      AtomButtonPageNavigation.updateValue() ruft -- und die Methode
      nimmt die Klasse im selben Render-Durchlauf wieder weg
      (atombuttonpagenavigation.js:41-51: "selected" ist false, weil
      "setSelected()" nirgends aufgerufen wird). Gemessen im
      Produktionspfad ("new MoleculePagination(...).render()", wie
      organismschunklist.js:76): ALLE neun Knoepfe tragen danach
      "image page-btn", die aktuelle Seite ist von den anderen nicht zu
      unterscheiden. ".page-btn-seleceted" ist damit im ganzen Produkt
      tot -- und zwar seit ihrem ersten Tag (1f7d95d25, 2025-12-24, der
      Commit, der MoleculePagination eingefuehrt hat). Eine Regel
      darauf traefe nichts und liesse sich ueber den echten Weg nicht
      messen -- sie steht deshalb hier nicht.

      DIE BEHEBUNG IST NICHT "EINE ZEILE", auch wenn sie so aussieht.
      Gemessen an einem Nachbau: setzt man die Klasse wieder (eine
      JS-Zeile), aendert sich im NEUEN Design gar nichts (die
      Knopfregel unten gewinnt), und im ALTEN Design wird die aktuelle
      Seite im hellen Theme UNSICHTBAR -- Text weiss auf weisser
      Flaeche, 1,00:1. Grund: ".page-btn-seleceted" (webapp.css:3924)
      liegt bei (0,1,0) und verliert Flaeche und Rahmen gegen
      "button.image" (0,1,1); uebrig bleibt allein seine Textfarbe
      (invers = weiss). Die kleinste ehrliche Behebung ist deshalb: 1
      JS-Zeile + eine neue Regel oberhalb (0,3,1) fuer das neue Design
      + eine Entscheidung fuer das alte, das unter "webapp.css bleibt
      unangetastet" gar nicht sauber zu reparieren ist. Der Befund
      steht im Bericht und in der Sichtpruefungsliste (Task 7).

   2. KEINE AUSLASSUNG. MoleculePagination zeigt ein gleitendes Fenster
      von hoechstens neun Seitenknoepfen (MAX_PAGE_BUTTONS) und setzt
      an dessen Raendern KEIN "…"-Element; es gibt kein Element, das
      "text/muted" tragen koennte.

   DIE KLASSEN, DIE HIER GEMEINT SIND, sind nicht die aus dem Bestand:
   jeder Knopf traegt "image page-btn" (siehe Punkt 1), also greifen an
   ihm gleichzeitig "button" (webapp.css:844, (0,0,1)), ".page-btn"
   (:3915, (0,1,0)), "button.image" (:3944, (0,1,1)) und
   "button.image.page-btn" (:3938, **(0,2,1)** -- ZWEI Klassen und ein
   Element, nicht eine Klasse und zwei Elemente). Der Aufhaenger unten
   ist der Streifen: ".pagination" entsteht ausschliesslich in
   MoleculePagination.renderUi() (einziger Treffer im ganzen Frontend),
   die Regeln koennen also nichts anderes erwischen.

   DIE (0,2,1) SIND DER GRUND, WARUM DIE KNOPFREGEL EINE KLASSE MEHR
   TRAEGT, ALS SIE ZUM TREFFEN BRAEUCHTE. Eine erste Fassung stand als
   "[data-design=new] .pagination button" selbst bei (0,2,1) -- im
   GLEICHSTAND mit webapp.css:3938, und gewonnen haette allein die
   Ladereihenfolge. Nachgestellt: derselbe Selektor woertlich, nach
   dieser Datei geladen, holt Flaeche (ink/800 -> ink/900) und Rahmen
   (1px -> 0) zurueck. Genau die Fehlerklasse, die Task 2 beinahe
   Zeilen-Hover und beide Drag-Rueckmeldungen gekostet haette, und ein
   Verstoss gegen das, was 04 · Core bei :228-230 festgehalten hat
   ("unabhaengig von der Ladereihenfolge"). ".image" ist dabei der
   RICHTIGE Zusatz und ".page-btn" der falsche: ".image" setzen beide
   Wege (ButtonFactory.create() beim Pfeilknopf, setCssClass() beim
   Zahlenknopf) und keiner nimmt es je wieder weg, waehrend
   ".page-btn" genau dann verschwaende, wenn jemand Punkt 1 behebt --
   die aktuelle Seite fiele dann aus dieser Regel heraus. */

/* DER STREIFEN. Figmas Abstand 8 zwischen den Knoepfen kommt als "gap"
   und nicht als Rand: Legacys ".page-btn" (0,1,0) traegt "margin: 0
   5px" und "button.image" (0,1,1) zusaetzlich "margin-bottom: 10px" --
   beide werden in der Knopfregel darunter auf 0 gesetzt, sonst kaeme
   der Rand zum "gap" hinzu (8 + 10 = 18 statt 8).

   Spezifitaet (0,2,0) gegen Legacys ".pagination" (0,1,0). Diese Regel
   setzt AUSSCHLIESSLICH "gap" -- "display: flex", "justify-content:
   center", "flex-wrap: wrap" und "margin: 20px 0" bleiben Legacys, sie
   stellen den Kontext (mittig, umbrechend) und stehen nicht in der
   Vorlage zur Debatte. */
[data-design="new"] .pagination {
  gap: var(--ax-space-2);
}

/* DER KNOPF -- Seitenzahlen UND Pfeile. Figma gibt beiden dasselbe
   Aussehen: Knoten 41:135 (der Pfeilknopf) bindet dieselben vier
   Variablen wie 41:128 (eine gewoehnliche Seite).

   Spezifitaet (0,3,1) -- Attribut, ".pagination", ".image", Element.
   Sie schlaegt jede der vier Legacy-Regeln, die hier zusammentreffen:
   "button" (0,0,1), ".page-btn" (0,1,0), "button.image" (0,1,1) und
   "button.image.page-btn" (0,2,1); die Basisregel
   ":where([data-design=new]) button" (0,0,1) ohnehin. KEIN
   GLEICHSTAND: die hoechste konkurrierende Regel liegt bei (0,2,1),
   also eine Klasse unter dieser -- Herleitung im Kopfkommentar.
   ("button.image:hover", webapp.css:4253, liegt ebenfalls bei (0,2,1)
   und "[data-design=new] button.image:hover:not(:disabled)",
   components.css:235, bei (0,4,1); beide betreffen nur den
   Hover-Zustand, den diese Regel nicht anfasst.)

   WAS HIER BEWUSST NICHT STEHT: "display", "align-items" und
   "justify-content". Die Zentrierung von Ziffer und Symbol kommt aus
   "button.image" (webapp.css:3944, "display: flex" + beide
   "center") -- unangefochten bei (0,1,1), weil nur die Basisregel
   (0,0,1) etwas anderes wollte. Sie hier zu wiederholen hiesse, eine
   Legacy-Regel zu verdoppeln, die ohnehin gewinnt.

   34 x 34 EINSCHLIESSLICH RAHMEN: gemessen traegt <button> hier
   "box-sizing: border-box" (aus der UA-Formatvorlage; einen
   universellen Reset gibt es in dieser Anwendung nicht), 34 px Breite
   plus 1 px Rahmen ergeben also 34 und nicht 36. Der Test misst
   "boxSizing" mit, damit ein spaeterer Reset nicht still 36 daraus
   macht.

   "letter-spacing" steht bewusst NICHT hier: Legacys "button" setzt
   0,3px, Figmas Label/Medium 0. Gemessen verschiebt das eine
   einstellige Ziffer im mittig ausgerichteten Kasten um 0,15 px --
   unter der Sichtbarkeitsschwelle, und jede Deklaration, die nichts
   bewirkt, ist eine Zeile, die spaeter jemand pruefen muss.

   DREI DER ZEHN DEKLARATIONEN SIND HEUTE WERTGLEICH mit dem, was ohne
   sie gaelte -- per deleteRule an dieser Regel gemessen, in beiden
   Themes, und sie stehen trotzdem hier:
     border-radius  ohne die Regel 10px, aus der Basisregel
                    (":where([data-design=new]) button", ebenfalls
                    "--ax-radius-md")
     font-size      ohne die Regel 13px, aus derselben Basisregel
                    ("--ax-font-size-label-md")
     color          ohne die Regel ink/300 (dunkel) bzw. ink/600
                    (hell), aus "button.image.page-btn" ueber
                    "--font-color-pagination" -> "--clr-text-secondary",
                    das tokens.css:160/230 auf "--ax-text-secondary"
                    umhaengt
   Alle drei sind Figmas eigene Bindungen AN DIESEM Bauteil (Knoten
   41:128 bindet "--radius-md", "Label/Medium" und
   "--clr-text-secondary"); dass sie sich heute mit einem Erbstueck
   decken, ist ein Zufall zweier fremder Ketten -- der Basisregel aus
   "04 · Core" und der Bruecke. Ohne sie folgte die Seitenzahl still
   jeder kuenftigen Aenderung an einer der beiden. Die drei
   Zusicherungen im Test sind deshalb als WAECHTER benannt. */
[data-design="new"] .pagination button.image {
  width: 34px;
  height: 34px;
  padding: 0;
  margin: 0;
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-md);
  background: var(--ax-bg-surface-2);
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-label-md);
  font-weight: 500;
}

/* DAS SYMBOL DER VIER PFEILKNOEPFE auf Figmas 16 px. Im Bestand haengt
   die Groesse an den HTML-Attributen des <img> (width/height "25px",
   ButtonFactory.create()) -- ein Praesentationshinweis, den jede
   CSS-Regel schlaegt. 25 px in einem 34er Kasten liessen 4,5 px Luft,
   Figma laesst 9.

   Spezifitaet (0,3,2). Ueber die ganze webapp.css gesucht: die einzigen
   Regeln, die ueberhaupt ein <img> in einem Knopf treffen, sind
   "button img:not(.logo)" (:860, (0,1,2)), deren helle Entsprechung
   (:444, (0,2,2)) und "button:hover img" (:871, (0,1,2)) -- alle drei
   setzen nur "filter" und "opacity", keine Groesse. Das ".image"
   steht hier trotzdem: OHNE es laege die Regel bei (0,2,2) und damit
   im Gleichstand mit webapp.css:444. Der waere heute folgenlos (keine
   gemeinsame Eigenschaft), aber ein Gleichstand, den ein spaeterer
   Zusatz an einer der beiden Seiten scharf macht -- und die
   Ladereihenfolge ist kein Argument. */
[data-design="new"] .pagination button.image img {
  width: 16px;
  height: 16px;
}

/* DAS SYMBOL IM HELLEN THEME. Die Bilddateien sind weiss gefuellt
   (images/first.svg u.a., "fill=#fff"); ohne Umfaerbung stuende ein
   weisses Symbol auf "bg/surface-2", im hellen Theme also auf ink/50.
   Deshalb dieselbe Behandlung wie bei Secondary/Ghost (:156):
   "brightness(0)", also schwarz. Die Deckkraft 0,72 ist NICHT neu
   gewaehlt, sondern die, mit der Legacys "button img:not(.logo)"
   (webapp.css:860) dasselbe Symbol im dunklen Theme zeichnet -- beide
   Themes tragen den Pfeil damit gleich stark.

   VEREINFACHT AM 2026-09-17. Vorher stand hier:
     [data-design="new"][data-theme="light"] .pagination button:not(.btn-secondary):not(.btn-ghost):not(.button-icon) img:not(.logo)
   und der Kommentar begruendete die drei ":not()" damit, dass sie die
   Core-Regel (vormals components.css:175) um genau eine Stelle
   ueberbieten mussten -- jene Regel faerbte damals JEDES Knopfsymbol
   weiss, das nicht Secondary/Ghost/Icon-Button war, und traf die
   Seitenknoepfe mit. Diese Gegenregel war also eine Gegenregel gegen
   einen Fehler.

   Der Fehler ist am 2026-09-17 behoben: die Core-Regel nennt ihre vier
   farbig gefuellten Wirte jetzt positiv und trifft Seitenknoepfe gar
   nicht mehr. Damit ist der Gleichstand, gegen den die drei ":not()"
   geschrieben waren, verschwunden -- der einzige verbliebene Gegner
   ist "webapp.css:444" bei (0,2,2), und den schlaegt diese Regel mit
   (0,4,2) muehelos. Geblieben ist allein der Zweck, den die Zahl
   traegt: 0,72 statt der 0,55, die der helle Grundfall setzt. */
[data-design="new"][data-theme="light"] .pagination button.image img:not(.logo) {
  filter: brightness(0);
  opacity: .72;
}

/* UND DIE RUECKMELDUNG BEIM UEBERFAHREN, die die Regel darueber sonst
   kappen wuerde. Ein Pfeilknopf traegt keinen Text; seine Flaeche
   bewegt sich beim Ueberfahren nur um 1,062:1 (gemessen, hell). Was
   ihn im Bestand sichtbar antwortet, ist die Deckkraft des Symbols --
   dunkel 0,72 -> 1 ueber "button:hover img" (webapp.css:871), hell
   0,55 -> 0,85 ueber "[data-theme=light] button:hover img" (:455).
   Beide liegen bei (0,1,2) bzw. (0,2,2) und verlieren gegen die
   (0,7,2) darueber: OHNE diese Regel bliebe die Deckkraft im hellen
   Theme bei 0,72 -- gemessen -- und ein ueberfahrener Pfeilknopf waere
   dort von einem ruhenden nicht zu unterscheiden.

   Die 1 statt Legacys 0,85: der Ruhewert ist hier 0,72 (nicht 0,55),
   der Schritt soll derselbe sein wie im dunklen Theme, und das ist
   dort 0,72 -> 1.

   VEREINFACHT AM 2026-09-17, zusammen mit der Ruheregel darueber.
   Vorher stand hier:
     [data-design="new"][data-theme="light"] .pagination button:not(.btn-secondary):not(.btn-ghost):not(.button-icon):hover img:not(.logo)
   mit der Begruendung, ".pagination button.image:hover img:not(.logo)"
   laege bei (0,6,2) und verlore gegen die damalige (0,7,2)-Ruheregel.
   Diese Rechnung ist mit der Ruheregel entfallen: die steht jetzt bei
   (0,3,2), diese Regel bei (0,4,2) -- ":hover" zaehlt als Klasse und
   gibt genau die eine Stelle Vorsprung, die noetig ist. Beide Ketten
   waren nur da, um eine fehlerhafte Core-Regel zu ueberbieten, die es
   nicht mehr gibt. */
[data-design="new"][data-theme="light"] .pagination button.image:hover img:not(.logo) {
  opacity: 1;
}

/* == 05 - Data - Task 6: Filterleiste =============================
   FIGMAS BAUTEIL WIRD NICHT GEBAUT, UND DAS IST DER GANZE TASK.
   Knoten 118:367 ("Filter Bar", Seite 1:7) selbst gelesen -- nicht die
   Komponentenbeschreibung, die in diesem Teilprojekt schon dreimal
   danebenlag: Figmas Filter Bar ist eine ZEILE ENTFERNBARER
   FILTERPILLEN. Je Pille 120 x 28 (Knoten 118:308), Radius 999
   ("--radius-full"), Flaeche "--clr-surface-2", 1 px "--clr-border",
   Beschriftung "Label/Small" (12 px Inter Medium) in
   "--clr-text-primary", daneben ein 10 x 10 grosses Entfernen-Kreuz
   (118:310) in "--clr-text-muted"; danach ein Textknopf "Alle
   zuruecksetzen" (118:311) in "--background-color-button" und
   rechtsbuendig ein Ergebniszaehler (118:313) in "--clr-text-muted".
   Sechs Varianten (ein bis drei Pillen, Zaehler an/aus).

   DER BESTAND HAT DAVON NICHTS. "AtomContainerFilterBar" (24 Verwender)
   rendert ".filter-bar-container" -- eine AUFKLAPPBARE KARTE MIT
   ANSICHTSSTEUERUNGEN (Suchfeld, Sortierung, Status-Kaestchen,
   Seitengroesse). Der Kommentar an der Klasse sagt es selbst: "A filter
   bar only holds view controls. Nothing in it is ever saved." Keine
   entfernbaren Pillen, kein "Alle zuruecksetzen", kein Ergebniszaehler.
   Figmas Bauteil zu bauen waere ein FEATURE, kein Umbau; es geht als
   Befund an die Eigentuemer der Vorlage (Spec, Abschnitt 5 und 7).

   WAS DIESE REGEL STATTDESSEN TUT: dieselbe Tokenhygiene wie am
   Tabellenrahmen in Task 3 (oben, um :4336) -- Radius, Rahmen und
   Schatten haengen an Legacy-Variablen, die die Bruecke NICHT umhaengt,
   und die Flaeche an einer, die sie umhaengt und dabei bitgleich mit
   dem Untergrund macht. Alle vier Werte je einmal MIT und einmal OHNE
   diese Regel im vollen Stapel gemessen (webapp.css -> tokens.css ->
   components.css, Chromium, 1280x720):

   background: DER EIGENTLICHE FUND. Legacy setzt "--card-gradient"
     (webapp.css:225/428), also "linear-gradient(135deg,
     var(--clr-surface-1), var(--clr-surface-2))" -- und die Bruecke
     haengt genau "--clr-surface-1" auf "--ax-bg-surface-1"
     (tokens.css:149/221). Der ERSTE FARBSTOPP der Karte ist im neuen
     Design damit exakt die Flaeche, auf der sie steht:
       Galerie   dunkel  rgb(18, 17, 28)  auf  rgb(18, 17, 28)  = 1,0000:1
       Galerie   hell    rgb(255,255,255) auf  rgb(255,255,255) = 1,0000:1
     Im PRODUKT steht sie nicht auf ".gallery-group", sondern auf
     ".welcome" ("--background-color-application" -> "--clr-base" ->
     "--ax-bg-app"); dort bleibt ein Abstand, aber ein winziger:
       Produkt   dunkel  rgb(18, 17, 28)  auf  rgb(11, 10, 20)  = 1,0514:1
       Produkt   hell    rgb(255,255,255) auf  rgb(244,243,247) = 1,1047:1
     Im ALTEN Design ist der Abstand groesser (dunkel rgb(22, 27, 34)
     auf rgb(10, 14, 26) = 1,1131:1, hell 1,1182:1) -- die Bitgleichheit
     entsteht erst durch die Bruecke.

     WICHTIG ZUR EHRLICHKEIT DIESER REGEL: identisch mit und ohne diese
     Regel ist per deleteRule gemessen NUR der ERSTE Farbstopp -- und die
     Bitgleichheit in der Galerie oben ist ein Artefakt von
     ".gallery-group", nicht eine Eigenschaft dieser Regel. Im PRODUKT,
     gegen ".welcome" gemessen, nimmt die Regel im DUNKLEN Theme BEIDE
     Trennungen zurueck: den Fernstopp (1,1425:1 ohne die Regel, flach nur
     noch 1,0514:1 mit ihr) UND die Kante gegen die Flaeche (1,6697:1
     ohne, 1,2039:1 mit). Im HELLEN Theme dreht es sich um: die Flaeche
     trennt MIT der Regel staerker (1,1047:1 gegen 1,0620:1 ohne), die
     Kante dagegen schwaecher (1,5245:1 gegen 1,6412:1 ohne). Die
     Entscheidung bleibt richtig und aus demselben Grund wie bisher --
     Tokenhygiene, dieselbe Linie wie ".molecule-table-wrap" in Task 3
     (oben, um :4336) --, es geht hier nur darum, dass die Zahlen
     dastehen, statt eines Satzes, der mehr behauptet als er traegt.

     GENOMMEN WIRD "--ax-bg-surface-1". Die drei Alternativen sind
     durchgemessen, nicht abgewogen (je Zelle das Verhaeltnis der Karte
     zum Untergrund):

       Token              dunkel/Produkt  hell/Produkt  dunkel/Galerie  hell/Galerie
       --ax-bg-surface-1     1,0514         1,1047         1,0000         1,0000
       --ax-bg-surface-2     1,1263         1,0000 (!)     1,0712         1,1047
       --ax-bg-elevated      1,1263         1,1047         1,0712         1,0000
       --ax-bg-surface-3     1,2659         1,1193         1,2039         1,2364

       * "--ax-bg-surface-2" faellt aus: im hellen Theme ist es ink/50
         und damit BITGLEICH mit "--ax-bg-app" -- unsichtbar im PRODUKT,
         also genau dort, wo es zaehlt.
       * "--ax-bg-elevated" ist auf dem Papier ueberall mindestens so
         gut. Es ist aber das Token der SCHWEBENDEN Schicht (in dieser
         Datei traegt es das Flyout-Menue, um :3874) -- die Filterleiste
         schwebt nicht, sie steht im Fluss ueber der Liste.
       * "--ax-bg-surface-3" traegt am weitesten, ist aber die TIEFSTE
         Flaeche des Systems (Fortschrittsbalken-Rinnen, Regler). Eine
         Leiste, die ueber der Liste steht, damit auszuzeichnen, waere
         semantisch verkehrt herum.
       * "--ax-bg-surface-1" ist die Flaeche, die auf einer Listenseite
         ohnehin alles traegt, was ueber dem Seitengrund liegt: die
         Karten (".card", 04 - Core, :1453) UND die Tabellenzeilen
         (05 - Data, Task 2, gemessen ebenfalls rgb(18, 17, 28)). Die
         Leiste bekommt damit dieselbe Ebene wie das, was sie filtert;
         ein vierter Flaechenwert waere der Bruch.

     Der Verlauf selbst faellt weg (eine Flaeche statt zweier Stopps) --
     Figma kennt fuer keinen Container dieses Systems einen Verlauf.
     Was die Karte im Produkt traegt, ist deshalb ihre KANTE, nicht ihre
     Fuellung; der Test misst genau das (gemessen KANTE gegen KARTE:
     1,2039:1 dunkel, 1,5245:1 hell).

   border: 1 px "--clr-border-accent" -> "--ax-border-default".
     "--clr-border-accent" ist "color-mix(--clr-accent 22%, --clr-border)"
     (webapp.css:33) und wird nicht gebrueckt; gemessen meldet Chromium
     dafuer im neuen Design "color(srgb 0.110118 0.241176 0.351843)"
     (dunkel, etwa rgb(28, 62, 90)) bzw. "color(srgb 0.65 0.817451
     0.891569)" (hell, etwa rgb(166, 208, 227)) -- eine BLAUE Kante um
     eine Karte, deren Inhalt inzwischen auf der Tinten-Skala liegt.
     Dieselbe Variable, dieselbe Ersetzung und dieselbe Begruendung wie
     am Tabellenrahmen in Task 3. "--ax-border-accent" (cyan/700 dunkel,
     cyan/300 hell) waere die namensgleiche Uebersetzung, VERSTAERKT den
     Akzent aber, statt ihn zu erhalten -- und kein anderes Bauteil
     dieser Figma-Seite traegt einen Akzentrahmen.

   border-radius: WERTGLEICH -- "--ax-radius-md" ist 10px
     (tokens.css:352), Legacy steht woertlich auf 10px, und -md
     schrumpft unterhalb 768px nicht (nur -lg und -xl, tokens.css:405).
     Steht trotzdem hier, aus demselben Grund wie am Tabellenrahmen: die
     10 waeren sonst eine Zahl ohne Herkunft. Der Test benennt die
     zugehoerige Zusicherung als WAECHTER.

   box-shadow: "--shadow-card" -> "--ax-shadow-card". "--shadow-card"
     wird NICHT gebrueckt. Gemessen ohne diese Regel:
       dunkel  "rgba(0, 159, 227, 0.08) 0px 4px 20px 0px" -- ein
               CYAN-Schimmer aus der gebrueckten "--clr-accent-rgb".
       hell    "rgba(99, 102, 241, 0.14) 0px 4px 12px 0px" -- INDIGO
               #6366f1 aus "--clr-indigo-rgb" (webapp.css:60/322), einer
               Variable der ALTEN Palette, die tokens.css gar nicht
               kennt. Bitgleich mit dem alten Design.
     Wie in Task 3: im dunklen Theme raeumt die Ersetzung einen
     Fremdkoerper weg, im hellen ENTSCHEIDET sie (Schwarz 0,28 auf 20px
     statt Indigo 0,14 auf 12px). Gesagt statt geglaettet.

   WAS DIESE REGEL BEWUSST NICHT SETZT -- und das ist hier kein Beiwerk,
   sondern die Auflage des Tasks:

     gap. DIE AUFKLAPP-MECHANIK HAENGT DARAN. Legacys
       ".filter-bar-container.collapsed" (webapp.css:11006) setzt
       "gap: 0" und liegt bei (0,2,0) -- GENAU DER SPEZIFITAET DIESER
       REGEL. Eine Zeile "gap: ..." hier stuende im GLEICHSTAND, und
       weil components.css spaeter laedt, gewaenne sie: die eingeklappte
       Leiste behielte ihren Abstand. Nachgestellt, im vollen Stapel
       gemessen (siehe Bericht): mit "gap: var(--ax-space-3)" meldet die
       eingeklappte Leiste 12px statt 0px. Legacys 10px bleiben deshalb
       stehen; das naechste Abstandstoken waere ohnehin 8 oder 12 und
       damit eine Geometrieaenderung ohne Vorlage.

     padding. Legacy steht auf 10px, die Skala kennt nur 8
       ("--ax-space-2") und 12 ("--ax-space-3"). Figma sagt zu DIESEM
       Bauteil nichts, weil es das Bauteil dort nicht gibt -- jede Wahl
       waere erfunden, und sie traefe 24 Verwender.

     width / margin. "#impact-tables > .filter-bar-container"
       (webapp.css:1942/1951) liegt bei (1,1,0) und richtet die Leiste
       auf "Meine Wirkung" gegen die Bloecke darueber aus. Diese Regel
       setzt keine der beiden Eigenschaften; die Ausrichtung bleibt
       unberuehrt.

     color. Legacy setzt "--clr-text-primary", und die Bruecke haengt
       das bereits auf "--ax-text-primary" um (gemessen
       rgb(232, 230, 238) dunkel / rgb(18, 17, 28) hell). Eine
       Wiederholung waere eine Zeile ohne Aussage -- der Test sichert
       den Wert stattdessen als WAECHTER.

     Der Chevron. ".filter-bar-container .filter-bar-toggle::before"
       (webapp.css:10997) mit seinem "content" und der Drehung im
       eingeklappten Zustand (:11010) ist VERHALTEN, nicht Gestaltung.
       Unangetastet -- seine Farbe "--clr-text-secondary" ist ohnehin
       gebrueckt.

   SPEZIFITAET (0,2,0) -- ein Attribut, eine Klasse, kein Element. Ueber
   die GANZE webapp.css gesucht (Hell-Theme-Block und alle Media-Queries
   eingeschlossen) treffen ".filter-bar-container" genau sieben Regeln:
     .filter-bar-container                            (0,1,0) geschlagen
     .filter-bar-container h3                         (0,1,1) anderes Ziel
     .filter-bar-container .filter-bar-toggle         (0,2,0) anderes Ziel
     .filter-bar-container .filter-bar-toggle::before (0,2,1) anderes Ziel
     .filter-bar-container.collapsed                  (0,2,0) GLEICHSTAND,
         aber ausschliesslich auf "gap" -- siehe oben, deshalb steht
         "gap" hier nicht.
     .filter-bar-container.collapsed > *:not(h3)      (0,2,1) anderes Ziel
         (":not(h3)" zaehlt als Element, nicht als Klasse; "*" zaehlt
         gar nicht)
     #impact-tables > .filter-bar-container           (1,1,0) gewinnt,
         setzt aber nur width/margin -- siehe oben.
   Keine weitere Datei: "grep -rn filter-bar --include=*.css" findet
   ausserhalb von webapp.css nur die eigenstaendige App
   "apps/filecrawler" mit anderen Klassennamen (".filter-bar",
   ".logs-filter-bar"). */
[data-design="new"] .filter-bar-container {
  background: var(--ax-bg-surface-1);
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-md);
  box-shadow: var(--ax-shadow-card);
}

/* ══════════════════════════════════════════════════════════════════
   05 · Data, Teil B — Marker & Kennzahlen
   Quelle: Figma "AuxData.ai — Core Design System", Seite 05 · Data
   (Knoten 1:7). Spec: docs/superpowers/specs/
   2026-09-09-designsystem-marker-kennzahlen-design.md

   AUSSCHLIESSLICH KLASSENREGELN. Anders als Teil A (Tabellen) setzt
   dieser Abschnitt keine Element-Basisregeln; die Subset-Invariante aus
   Teil A ist hier deshalb nicht anwendbar (Spec, Abschnitt 4). Eine
   Klassenregel unter [data-design="new"] wiegt (0,2,0) und schlaegt die
   Legacy-Klassenregel (0,1,0) sauber.

   GLEICHSTAND HERRSCHT ABER NICHT NUR DORT, WO DER BESTAND ZWEI KLASSEN
   STAPELT -- und eine erste Fassung dieses Kommentars behauptete genau
   das. Ein ATTRIBUT wiegt so viel wie eine Klasse: jedes
   "[data-theme=\"light\"] .foo" des Bestands liegt ebenfalls bei (0,2,0)
   und wird von einer neuen "[data-design=\"new\"] .foo" NICHT geschlagen,
   sondern nur ueber die Ladereihenfolge gewonnen (components.css laedt
   zuletzt, cockpit.html:16-18). Fuer die Badge-Familie sind das SECHS
   Regeln, alle im Hell-Theme-Block von webapp.css:

     :10299  [data-theme="light"] .badge-licence       (0,2,0)  background + color
     :10300  [data-theme="light"] .badge-volume        (0,2,0)  background + color
     :10301  [data-theme="light"] .badge-test          (0,2,0)  background + color
     :10303  [data-theme="light"] .badge-health-good   (0,2,0)  NUR color
     :10304  [data-theme="light"] .badge-health-watch  (0,2,0)  NUR color
     :10305  [data-theme="light"] .badge-health-weak   (0,2,0)  NUR color

   Bei den drei ".badge-health-*" betrifft der Gleichstand ausschliesslich
   "color"; ihre Flaeche steht bei (0,1,0) (webapp.css:10243-10245) und
   wird sauber geschlagen. Alle sechs sind im vollen Stapel gemessen und
   im hellen Theme einzeln zugesichert
   (tests/features/design-marker-kennzahlen.spec.ts, zweiter Block) --
   ein Ladereihenfolge-Zufall, der von keiner Zusicherung bewacht wird,
   ist genau die Fehlerklasse, vor der Teil A gewarnt hat.

   Wo der Bestand zusaetzlich zwei KLASSEN stapelt, steht die Rechnung
   bei der jeweiligen Regel.

   DREI NAMEN, DIE HIER NICHT VORKOMMEN DUERFEN:
     .chip       -- alle 34 .chip*-Regeln gehoeren der Navigationsleiste,
                    deren Bereichsfarben 06 · Shell & Nav ausdruecklich
                    erhalten hat (components.css um :2470). Figmas beide
                    Chips heissen im Produkt .cap-chip und
                    .llm-selector-chip (Spec 3c).
     .status-dot -- gleicher Name, anderes Bauteil: der Bestand meint den
                    Benachrichtigungspunkt am Reiter (webapp.css:7882),
                    Figma einen Inline-Statuspunkt (Spec 3b).
     .badge-ai   -- gehoert der ZWEITEN, unabhaengigen Badge-Familie im
                    Workflow-Editor (frontend/css/workfloweditor.css:264,
                    erzeugt ueber steptyperegistry.js:11-23). Sie ist von
                    diesem Teilprojekt ausdruecklich ausgenommen
                    (Spec, Abschnitt 11). Folge fuer Task 1: Figmas
                    sechste Absicht "AI" bekommt hier KEINE Regel --
                    ausfuehrlich bei den Farbpaaren unten.
   ══════════════════════════════════════════════════════════════════ */

/* ══ 05 · Data, Teil B — Task 1: Das Badge-Raster ═════════════════
   Figma-Knoten 166:214. 24 Varianten aus drei orthogonalen Achsen:
   Intent (6) x Shape (2) x Size (2). Umgesetzt werden die sechs
   Absichten und die zwei Formen; zur Groesse siehe "Md" weiter unten.

   ── DER BESTAND, EIGENSCHAFT FUER EIGENSCHAFT ──
   Legacys Grundregel ist eine einzige Zeile (webapp.css:10234):
   "padding: 2px 8px; border-radius: 10px; font-size: 10px;
   display: inline-block; font-weight: 500". Fuenf Eigenschaften, fuenf
   Entscheidungen:

     padding: 2px 8px   -> ERSETZT durch "0 8px". Figma legt die Hoehe
       ueber den Zeilenkasten fest, nicht ueber einen senkrechten
       Innenabstand (Sm: Hoehe 22, waagerecht 8, senkrecht 0).
     border-radius: 10px -> ERSETZT durch var(--ax-radius-sm) = 6px,
       Figmas Form "Rounded". Die Form "Pill" (999px) steht in einer
       eigenen Regel weiter unten, weil sie nur drei Klassen trifft.
     font-size: 10px    -> ERSETZT durch 11px.
     font-weight: 500   -> ERSETZT durch 600 (Semi Bold).
     display: inline-block -> UEBERNOMMEN, und bewusst NICHT wiederholt.
       Legacys Deklaration steht unangefochten (keine der 16 Varianten
       setzt "display" anders; ".badge-success/-danger/-accent"
       wiederholen es sogar), und die Bruecke fasst sie nicht an. Eine
       Wiederholung waere eine Zeile ohne Aussage. Der Test sichert den
       Wert stattdessen als WAECHTER.

   ── WIE ENTSTEHT DIE HOEHE 22? GEMESSEN, NICHT GERATEN ──
   Zuerst der Bestand: ".badge" ist heute 24px hoch, nicht 22 (Plan und
   Spec vermuteten 22). Die 24 sind 20 + 2 x 2 -- der Zeilenkasten kommt
   aus "line-height: 20px" an "body" (webapp.css:533), einem festen
   LAENGENWERT, der ueberall hin vererbt.

   Fuenf Kandidaten im vollen Stapel gemessen (Chromium 1280x720, neues
   Design, beide Themes, echter AtomDisplayBadge-Knoten). "Text oben/
   unten" ist der Abstand der Zeilenbox zur Kastenkante:

     A  min-height: 22px, padding 0 8px      -> h=22, Text 3 / 5
     B  padding: 1px 8px (erbt lh 20px)      -> h=22, Text 4 / 4
     C  line-height: 22px, padding 0 8px     -> h=22, Text 4 / 4
     D  inline-flex + height 22 + center     -> h=22, Text 4 / 4
     E  gar nichts zur Hoehe                 -> h=20, Text 3 / 3

   E verfehlt Figma um 2px. A trifft die 22, setzt den Text aber
   ausser Mitte (3 oben, 5 unten): "min-height" streckt den Kasten nach
   UNTEN, der 20px-Zeilenkasten bleibt oben stehen. A beantwortet damit
   auch die zweite Frage des Auftrags -- "min-height" vertraegt sich
   sehr wohl mit "display: inline-block" (inline-block ist ein
   Blockcontainer, die Eigenschaft greift), es zentriert nur nicht.
   D zentriert, muesste dafuer aber "display" auf inline-flex kippen und
   damit Legacys uebernommene Eigenschaft doch anfassen.

   GEWAEHLT: C. Es trifft die 22 exakt, zentriert den Text (4/4), laesst
   "display: inline-block" unberuehrt -- und ist als einzige Variante
   unabhaengig vom GEERBTEN Zeilenkasten. Gegenprobe dazu: in einem
   Wirt, der den Zeilenkasten als ZAHL setzt statt als Laenge -- etwa
   ".msg-bubble-bot" mit "line-height: 1.65" (webapp.css:2644) --
   misst B 20,14px statt 22, C weiterhin 22. B haette Figmas Zahl also nur
   dort getroffen, wo body's 20px unangefochten durchreichen.

   ── VIER EIGENSCHAFTEN, DIE LEGACYS ".badge" NICHT KENNT ──
   Sie stehen hier nicht aus Ordnungsliebe, sondern weil je eine
   Variante sie setzt und Figma sie ueber alle 24 gleich verlangt:

     line-height: 22px  -> siehe oben. ".badge-success/-danger/-accent"
       setzen 1.2 (= 14,4px bei 12px), das muss weg.
     letter-spacing: 0  -> ".badge-deprecated" (webapp.css:4534) setzt
       0.04em. Figma: Laufweite 0. Chromium serialisiert den gerechneten
       Wert als "normal".
     text-transform: none -> dieselbe Regel setzt "uppercase". Figma
       zeigt ueber alle 24 Varianten gemischte Schreibung. SICHTBARE
       ENTSCHEIDUNG: der Marker am veralteten Modell liest sich im neuen
       Design "Veraltet" statt "VERALTET"
       (organismsmodelselectioncard.js:96).
     border: none       -> dieselbe Regel setzt "1px solid
       var(--clr-danger)". Figma: "Rahmen: keiner", ueber alle 24. Der
       Rahmen ist auch der Grund, warum ".badge-deprecated" heute 26px
       hoch ist statt 24.

   ── MD (24 / 10) WIRD NICHT GEBAUT ──
   Figmas zweite Groesse hat im Bestand keinen Traeger: keine der 42
   AtomDisplayBadge-Instanziierungen unterscheidet Groessen, und es gibt
   keine Klasse, an der "Md" haengen koennte. Eine Klasse zu erfinden,
   die niemand benutzt, waere derselbe Fehler wie Figmas Filter Bar in
   Teil A nachzubauen. Befund fuer die Eigentuemer der Vorlage. */
[data-design="new"] .badge {
  padding: 0 8px;
  line-height: 22px;
  border-radius: var(--ax-radius-sm);
  font-size: var(--ax-font-size-label-caps);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  border: none;
}

/* ── Die sechs Absichten: je eine Regel, nur Flaeche und Text ──
   Zuordnung nach Spec, Abschnitt 5 ("Zuordnung der Bestandsvarianten auf
   die sechs Absichten"). 16 Bestandsvarianten, fuenf Regeln -- die
   sechste Absicht hat keinen Traeger, siehe unten.

   "background" als Kurzform, nicht "background-color": die Kurzform
   setzt background-image auf "none". Genau daran ist in Teil A der
   Spaltenkopf haengen geblieben, dessen Legacy-Flaeche ein VERLAUF war;
   hier tut sie nichts, aber sie kostet auch nichts.

   .badge-volume IST DER UNSICHERE FALL, und die Messung faellt anders
   aus, als die Spec vermuten laesst. Sie schreibt, der Bestand faerbe
   ihn "im hellen Theme mit --clr-success-pale, im dunklen mit
   --clr-badge-volume-bg" -- das klingt nach zwei verschiedenen
   Familien. Gemessen (voller Stapel, echter Knoten, beide Themes) --
   die Werte stammen aus color-mix() und werden von Chromium deshalb als
   "color(srgb ...)" serialisiert, NICHT als "rgb(...)"; die
   menschenlesbare Naeherung steht in Klammern daneben, gegreppt wird
   nach der ersten Form:
     dunkel: Flaeche color(srgb 0.075451 0.226353 0.13051)
                                                  (etwa rgb(19, 58, 33))
             Text    color(srgb 0.503137 0.909412 0.651373)
                                                (etwa rgb(128, 232, 166))
     hell:   Flaeche color(srgb 0.835529 0.935059 0.872235)
                                                (etwa rgb(213, 238, 222))
             Text    color(srgb 0.0431373 0.319608 0.145098)
                                                   (etwa rgb(11, 81, 37))
   Beides ist GRUEN, in beiden Themes, denn --clr-badge-volume-bg ist
   ueber --clr-success-darkest selbst aus --clr-success abgeleitet
   (webapp.css:104/120). Der Bestand zeigt "Volumen" also heute im
   Success-Ton.
   TROTZDEM Neutral, wie die Spec es vorschlaegt: ".badge-volume",
   ".badge-licence" und ".badge-test" sind drei GLEICHRANGIGE
   Abrechnungsarten (moleculepartnerselfrow.js:60,
   organismsaccordioncustomerrow.js:47) -- eine davon gruen zu faerben
   liest sich als Wertung ("Volumen ist gut"), die der Bestand nie
   gemeint hat. Die Aenderung ist sichtbar und steht deshalb als
   eigener Punkt in der Sichtpruefung (Plan, Task 7, Punkt 4).

   DIE SECHSTE ABSICHT "AI" BEKOMMT KEINE REGEL. Ihre Tokens
   (--ax-accent-ai-bg / --ax-accent-ai-on-bg) existieren und sind
   gemessen (Kontrast 7,75:1 dunkel / 5,36:1 hell), aber der einzige
   Klassenname, der dafuer in Frage kaeme, ist ".badge-ai" -- und der
   gehoert der Badge-Familie des Workflow-Editors, die dieses
   Teilprojekt ausdruecklich nicht anfasst (Spec, Abschnitt 11). Eine
   Regel darauf haette den Schritttyp-Marker "AI Step" umgefaerbt --
   aber nur zur HAELFTE, und das ist das staerkere Argument:
     dunkel: ".badge-ai" (workfloweditor.css:264) wiegt (0,1,0), die
       neue Regel (0,2,0) -- sie GEWINNT, Blau wuerde Violett.
     hell:   "[data-theme=\"light\"] .badge-ai" (workfloweditor.css:634)
       wiegt ebenfalls (0,2,0), also GLEICHSTAND -- und
       workfloweditor.css laedt NACH components.css
       (aiprocesseditor.html:14-17, aiprocessstepeditor.html:14-17),
       gewinnt ihn also. Das helle Theme bliebe, wie es ist.
   Herausgekommen waere ein Marker, der im dunklen Theme violett und im
   hellen blau ist: eine theme-inkonsistente Halbaenderung an einem
   Bauteil, das die Vorlage gar nicht meint.
   Befund fuer die Eigentuemer der Vorlage, nicht Aufgabe dieses Tasks.

   ZWEI KLASSEN GEWINNEN DURCH DIESE REGELN NICHTS, und das ist Absicht,
   kein Versehen: ".badge-ok" und ".badge-fail" haengen an
   --clr-badge-ok-bg/-fg und --clr-badge-fail-bg/-fg (webapp.css:13307-13308),
   und die Bruecke haengt genau die vier bereits auf dieselben Tokens um,
   die hier stehen (tokens.css:180-183). Loescht man die Success- oder
   die Danger-Regel per deleteRule, aendert sich an diesen beiden
   Markern in KEINEM Theme etwas -- gemessen. Sie stehen trotzdem in der
   Selektorliste: die Regel sagt, welcher ABSICHT eine Klasse angehoert,
   und das darf nicht davon abhaengen, ob die Bruecke denselben Wert
   zufaellig schon liefert. Wer den Task pruefen will, darf sie deshalb
   nicht als Nachweis fuer die Regel lesen (Task 7 weiss davon).

   KONTRASTE, Text gegen Flaeche, gemessen im vollen Stapel
   (WCAG (L1+0,05)/(L2+0,05)); alle zwoelf Werte, auch die der
   traegerlosen AI-Absicht:
                 dunkel      hell
     Neutral      7,75:1     9,95:1
     Info         9,23:1     7,53:1
     Success     11,09:1     4,57:1
     Warning     12,26:1     6,37:1
     Danger       6,06:1     5,30:1
     AI           7,75:1     5,36:1
   Keiner liegt unter 4,5:1. Der knappste ist Success im hellen Theme
   (4,57:1, green/100 gegen green/700) -- er haelt die Schwelle, aber
   ohne Reserve; das gehoert als Beobachtung in die Spec, nicht in einen
   eigenmaechtigen Tokenwechsel. */
[data-design="new"] .badge-success,
[data-design="new"] .badge-ok,
[data-design="new"] .badge-health-good {
  background: var(--ax-status-success-bg);
  color: var(--ax-status-success-on-bg);
}

[data-design="new"] .badge-danger,
[data-design="new"] .badge-fail,
[data-design="new"] .badge-health-weak,
[data-design="new"] .badge-deprecated {
  background: var(--ax-status-danger-bg);
  color: var(--ax-status-danger-on-bg);
}

[data-design="new"] .badge-warning,
[data-design="new"] .badge-health-watch {
  background: var(--ax-status-warning-bg);
  color: var(--ax-status-warning-on-bg);
}

[data-design="new"] .badge-accent,
[data-design="new"] .badge-licence {
  background: var(--ax-action-primary-bg);
  color: var(--ax-action-primary-on-bg);
}

[data-design="new"] .badge-test,
[data-design="new"] .badge-volume {
  background: var(--ax-text-muted-bg);
  color: var(--ax-text-muted-on-bg);
}

/* ── Figmas zweite Form: Pill ──
   Die Grundregel oben gibt allen Markern "Rounded" (6px). "Pill" (999px)
   bekommen genau die drei Klassen, die heute schon Pillen SIND:
   ".badge-success/-danger/-accent" tragen ueber webapp.css:11715
   "border-radius: 999px". Ohne diese Regel wuerde die Grundregel sie bei
   (0,2,0) gegen (0,1,0) auf 6px eindampfen -- eine Formaenderung an den
   Laufzustaenden des Aufrufprotokolls (toolprotocoldetaildialog.js:41-43)
   und den HTTP-Methoden des Swagger-Imports
   (organismsswaggerendpointrow.js:41), die niemand beauftragt hat.
   Die Regel ist damit zugleich Figmas "Pill" UND die Bewahrung des
   Bestands: beide Lesarten fuehren zum selben Wert. */
[data-design="new"] .badge-success,
[data-design="new"] .badge-danger,
[data-design="new"] .badge-accent {
  border-radius: var(--ax-radius-full);
}

/* ── GEGENREGEL: die Branding-Vorschau behaelt die Organisationsfarben ──
   ".badge-success", ".badge-danger" und ".badge-accent" dienen zwei
   Herren, und nur einer von ihnen darf das neue Aussehen bekommen.

   Der eine: OrganismsBrandingPreview. Sie setzt --clr-accent,
   --clr-success, --clr-danger und neun weitere Legacy-Wurzeln als
   INLINE-Variablen auf ihre Huelle ".branding-preview-shell"
   (organismsbrandingpreview.js:14-27 und :118-131, "shell.setAttribute
   ('style', ...)") und baut darin drei Marker aus genau diesen drei
   Klassen (:79-81). Die Marker sind dort die Farbprobe der
   Organisation; webapp.css:11708-11709 sagt es im Kommentar selbst ("pick up
   the local data-theme overrides set by OrganismsBrandingPreview's
   inline style"). Die Farbregeln oben ersetzten var(--clr-success)
   durch var(--ax-status-success-bg) -- die Vorschau zeigte dann die
   Farbe des DESIGNSYSTEMS und haette aufgehoert, ihre Aufgabe zu
   erfuellen.

   Der andere: dieselben drei Klassen ausserhalb der Vorschau --
   Laufzustaende im Aufrufprotokoll (toolprotocoldetaildialog.js:41-43)
   und HTTP-Methoden im Swagger-Import
   (organismsswaggerendpointrow.js:41). DORT ist das neue Aussehen
   gewollt.

   SPEZIFITAETEN, ausgerechnet:
     .badge-success                                 (0,1,0) Legacy
     [data-design="new"] .badge-success             (0,2,0) neue Farbe
     [data-design="new"] .branding-preview-shell
         .badge-success                             (0,3,0) diese Regel
   (0,3,0) schlaegt (0,2,0) unabhaengig von der Ladereihenfolge -- die
   Gegenregel haengt also nicht am Zufall, dass sie weiter unten steht.

   FLAECHE, TEXT UND FORM werden zurueckgeholt, woertlich wie
   webapp.css:11715 und :11721-11733.

   ZUR FORM, denn eine erste Fassung dieses Kommentars hat sich hier
   geirrt. Richtig ist: die GRUNDREGEL erreicht die Vorschaumarker
   nicht -- die Vorschau ist die EINZIGE Stelle im Produkt, die diese
   drei Klassen OHNE die Klasse "badge" vergibt (:79-81 gegen
   toolprotocoldetaildialog.js:40-44 und
   organismsswaggerendpointrow.js:41). Fuer die PILL-REGEL gilt das
   NICHT: sie lautet auf ".badge-success/-danger/-accent" selbst und
   regiert den Radius der Vorschaumarker sehr wohl. Dass es niemandem
   auffaellt, liegt allein daran, dass --ax-radius-full zufaellig
   denselben Wert traegt wie Legacys Literal. Nachgestellt: setzt man
   --ax-radius-full auf 7px, misst der Vorschaumarker 7px; mit der
   Zeile "border-radius: 999px" unten bleibt er bei 999px -- beide
   Fassungen gemessen, bevor gewaehlt wurde.

   GEWAEHLT: die Form haengt in der Vorschau NICHT am Token. Das Bauteil
   zeigt die Farben der Organisation in einem Rahmen, der sich nicht
   mitbewegen darf; eine Vorschau, deren Farben Legacy und deren Form
   das Designsystem sind, waere ein Zwitter, den niemand entworfen hat.
   Die Zeile kostet heute nichts und haelt die Aussage dieses Blocks
   ("innerhalb der Vorschau gelten die Legacy-Deklarationen") wahr,
   statt sie von einem Tokenwert abhaengen zu lassen.

   NACHGEWIESEN, nicht behauptet: im Messaufbau bekommt die Huelle ueber
   die oeffentliche setBranding() zwei ERKENNBARE Fantasiepaletten --
   dunkel #ff00ff / #00ff00 / #ffff00, hell #123456 / #654321 / #abcdef.
   Gemessen an den drei echten, von OrganismsBrandingPreview erzeugten
   Knoten meldet Chromium rgb(255, 0, 255) / rgb(0, 255, 0) /
   rgb(255, 255, 0) bzw. rgb(18, 52, 86) / rgb(101, 67, 33) /
   rgb(171, 205, 239) -- in allen vier Seitenzustaenden gleich, denn die
   Huelle traegt ihr EIGENES data-theme und folgt nicht dem der Seite.
   Welche der beiden Paletten gilt, entscheidet allein ihr eigener
   Umschalter; der Test betaetigt ihn.

   Ohne die drei FARB-Gegenregeln -- per deleteRule nur an ihnen
   nachgestellt, die Farbregeln oben blieben stehen -- meldet derselbe
   Aufbau die Tokens des Designsystems: dunkel rgb(18, 48, 30) /
   rgb(51, 20, 22) / rgb(8, 43, 61), hell rgb(220, 252, 231) /
   rgb(254, 226, 226) / rgb(223, 244, 254). Der Test haelt beide Seiten
   fest. */
[data-design="new"] .branding-preview-shell .badge-success,
[data-design="new"] .branding-preview-shell .badge-danger,
[data-design="new"] .branding-preview-shell .badge-accent {
  border-radius: 999px;
}

[data-design="new"] .branding-preview-shell .badge-success {
  background-color: var(--clr-success);
  color: var(--clr-text-inverse);
}

[data-design="new"] .branding-preview-shell .badge-danger {
  background-color: var(--clr-danger);
  color: var(--clr-text-inverse);
}

[data-design="new"] .branding-preview-shell .badge-accent {
  background-color: var(--clr-accent);
  color: var(--clr-text-inverse);
}

/* ══ 05 · Data, Teil B — Task 2: Die Sonderfaelle der Badge-Familie ═
   Fuenf Stellen der Badge-Familie, die das Raster aus Task 1 NICHT trifft
   oder anders treffen muss. Gemessen wurde ausnahmslos an den Knoten, die
   das Produkt erzeugt: OrganismsAiServiceManagerCard und
   OrganismsAgentCard, im vollen Stapel (webapp.css -> tokens.css ->
   components.css), Chromium 1280x900, beide Designs, beide Themes.

   -- SCHRITT 1: WAS TASK 1 NICHT TRIFFT -- MIT ZAHLEN, NICHT MIT
      "TRIFFT NICHT ZU" --
   Der Plan sagt, die vier positionierten Kartenmarker teilten sich keine
   Basisklasse mit ".badge". Das ist nachgemessen, in zwei Schritten.

   ZUERST IM JS: "AtomDisplayBadge" vergibt AUSSCHLIESSLICH die Klasse, die
   ihm der Aufrufer mitgibt (atomdisplaybadge.js:24, "cssClass.split(...)
   .forEach(c => element.classList.add(c))") -- es gibt dort keine
   Grundklasse "badge". Die erzeugenden Stellen geben genau einen Namen mit:
     organismsaiservicemanagercard.js:40  "badge-internal"
     organismsaiservicemanagercard.js:45  "badge-draft"
     organismsaiservicemanagercard.js:47  "badge-test"
     organismsaiservicemanagercard.js:52  "badge-pinned"
     organismsagentcard.js:77             "badge-collaboration"
   Am gerenderten Knoten gemessen lautet die Klassenliste dementsprechend
   exakt "badge-internal" / "badge-draft" / "badge-test" / "badge-pinned" /
   "badge-collaboration" -- ein Eintrag, nie zwei.

   DANN IM BROWSER, Regel fuer Regel: jede der SIEBEN Task-1-Regeln wurde
   EINZELN per deleteRule entfernt (Neuaufbau der Seite zwischen den
   Laeufen -- alle auf einmal zu loeschen faelscht in beide Richtungen) und
   der volle Eigenschaftssatz der Marker davor/danach verglichen.
   36 Eigenschaften je Marker, sechs Marker, beide Themes:

     [data-design="new"] .badge                          0 von 36 x 6
     ... .badge-success/-ok/-health-good                 0 von 36 x 6
     ... .badge-danger/-fail/-health-weak/-deprecated    0 von 36 x 6
     ... .badge-warning/-health-watch                    0 von 36 x 6
     ... .badge-accent/-licence                          0 von 36 x 6
     ... .badge-success/-danger/-accent (Pill)           0 von 36 x 6
     ... .badge-test, ... .badge-volume                  2 von 36, und
                                                         nur an EINEM

   Die ZWEI sind "background" und "color" an ".badge-test" -- Schritt 2.
   Alle uebrigen Unterschiede zwischen altem und neuem Design an diesen
   Markern stammen NICHT aus Task 1, sondern aus Vorgaengerprojekten, und
   bleiben hier unangetastet:
     Schriftbreiten (z. B. ".badge-internal" 54,03 -> 55,55px) aus dem
       Schriftwechsel auf Inter (04 · Core);
     ".badge-internal" und ".agent-update-badge" rgb(29, 78, 216) ->
       rgb(0, 159, 227) (dunkel) bzw. rgb(67, 56, 202) -> rgb(0, 159, 227)
       (hell) aus der Bruecke auf --clr-accent-btn;
     ".badge-draft" rgb(30, 41, 59)/rgb(203, 213, 225) ->
       rgb(36, 34, 51)/rgb(173, 171, 187) (dunkel) aus der Bruecke auf
       --clr-surface-3 / --clr-text-secondary.

   EIN SECHSTER POSITIONIERTER MARKER, den weder Spec noch Plan nennen:
   ".agent-update-badge" (webapp.css:11187, erzeugt in
   organismsagentcard.js:81). Er gehoert derselben Familie an -- absolut
   positioniert, unten mittig, Pille, eigener Schatten -- und hat mit
   ".card.card-collaboration .agent-update-badge" (:11206) sogar seine
   eigene Stapelregel. Sein Name faengt nicht mit "badge-" an, deshalb
   trifft ihn keine Regel dieses Teilprojekts; er ist trotzdem mitgemessen
   worden (Zeile drei der Tabelle oben) und steht als Befund fuer die
   Eigentuemer der Vorlage.

   -- SCHRITT 2: DER GLEICHSTAND BEI ".card-info .badge-test" --
   SPEZIFITAETEN, ausgerechnet:
     .badge-test                                  (0,1,0) webapp.css:10237
     [data-theme="light"] .badge-test             (0,2,0) webapp.css:10301
     .card-info .badge-test                       (0,2,0) webapp.css:11095
     [data-design="new"] .badge-test              (0,2,0) Task 1
     [data-design="new"] .card-info .badge-test   (0,3,0) diese Regel
     .card-info .badge-internal ~ .badge-test     (0,3,0) webapp.css:11141
   Die mittleren drei liegen alle bei (0,2,0). Im ALTEN Design entscheidet
   die Reihenfolge INNERHALB von webapp.css: :11095 steht hinter :10301,
   der Kartenmarker ist also in beiden Themes amberfarben. Im NEUEN Design
   entscheidet die Reihenfolge der DATEIEN: components.css laedt zuletzt
   (cockpit.html:16-18), Task 1s Neutral-Regel gewinnt -- und der bewusst
   gesetzte Warnton der Testkarte faellt weg.

   DIE LETZTE ZEILE DER TABELLE IST EINE LATENTE FALLE, keine heutige.
   Legacys Stapelregel (webapp.css:11140-11146) enthaelt mit
   ".card-info .badge-internal ~ .badge-test" einen Selektor, der auf DEMSELBEN
   Element im exakten Gleichstand (0,3,0) mit der Gegenregel unten steht --
   im Zweier- wie im Dreierstapel. Heute harmlos, weil die Eigenschaften
   disjunkt sind: die Stapelregel setzt "bottom", die Gegenregel Flaeche und
   Text. Ergaenzt aber jemand hier ein "bottom", gewinnt es STILL ueber die
   Ladereihenfolge und die Stapelung faellt in sich zusammen, ohne dass eine
   Spezifitaet dagegenspraeche. Wer diese Regel erweitert, muss das gelesen
   haben.

   GEMESSEN, jeweils an ".card-info .badge-test" der echten Karte:
     dunkel  Legacy rgb(252, 211, 77) auf color(srgb 0.247059 0.206863
             0.0754902)   ->   neu ohne Gegenregel rgb(26, 24, 38) auf
             rgb(173, 171, 187)
     hell    Legacy color(srgb 0.638235 0.35 0.0176471) auf
             rgb(255, 255, 255)   ->   neu ohne Gegenregel
             rgb(232, 230, 238) auf rgb(53, 50, 74)
   Betroffen sind GENAU ZWEI DEKLARATIONEN -- Lage, Radius, Schatten,
   Schrift, Sperrmass, z-index bleiben unberuehrt. Die "36" oben ist die
   Feldzahl des MESSAUFBAUS, nicht die des Testhelfers: dort sind es zwei
   Ablesungen von 36. "box()" in der Spec-Datei liest 33 Felder und meldet
   VIER geaenderte, weil es "borderTopColor" und "borderBottomColor"
   mitliest und die ohne eigene Rahmenfarbe "currentColor" folgen. Zwei
   Deklarationen, vier Ablesungen, je nach Leser -- die Zahl allein sagt
   nichts, ohne die Feldliste, aus der sie stammt.

   DER GLEICHSTAND IST NACHGESTELLT, nicht nur ausgerechnet: laedt man
   Legacys Regel woertlich HINTER components.css, kippt der Marker in
   beiden Themes zurueck auf Amber -- die Neutral-Regel haelt hier also
   allein die Ladereihenfolge. Mit der Gegenregel unten ist das Ergebnis in
   BEIDER Reihenfolge dasselbe (beide Faelle gemessen).

   ENTSCHIEDEN: DEN BESTANDSLOOK HALTEN, mit (0,3,0). Drei Gruende, in
   dieser Reihenfolge:
     1. Der Kartenmarker ist ein ANDERES BAUTEIL als der gleichnamige
        Zeilenmarker. Legacys eigener Kommentar sagt es (webapp.css:11090-
        11094): die Klasse wurde hier unter ".card-info" gehaengt, damit
        die Testkarte ihren eigenen, absolut positionierten Warnton
        bekommt, ohne die davon unabhaengige, anders gestaltete Nutzung
        desselben Klassennamens umzufaerben. Die Zuordnung der Spec
        (Abschnitt 5, ".badge-test" -> Neutral) meint den ZEILENMARKER --
        die vier Stellen mit der Klasse "badge"
        (moleculepartnerselfrow.js:61, organismsaccordioncustomerrow.js:47,
        organismsswaggerendpointrow.js:45, designgallerypage.js:1276). Sie
        meint nicht das Karten-Overlay.
     2. Sonst zerfaellt eine Kartenfamilie. ".badge-pinned"
        (webapp.css:11114) und ".badge-collaboration" (:11155) haengen an
        DENSELBEN Variablen --clr-badge-warning-bg/-fg und werden von
        diesem Teilprojekt bewusst nicht angefasst. Ohne Gegenregel stuende
        auf EINER Karte -- interner Testdienst mit festgehaltener Version,
        ein Fall, den die Stapelregel :11140-11144 ausdruecklich vorsieht --
        ein graues "Test" direkt neben einem amberfarbenen
        "Aeltere Version". Das ist kein Designsystem, das ist ein Bruch.
     3. Die Warnbedeutung geht sonst verloren. "Test" ist ein Zustand, vor
        dem die Karte warnt; Neutral sagt das nicht.
   Zurueckgeholt werden die Legacy-Deklarationen WOERTLICH wie
   webapp.css:11104-11105, also ueber --clr-badge-warning-*, nicht ueber
   --ax-status-warning-*. Gemessen: die Bruecke laesst diese beiden
   Variablen unveraendert -- der Marker ist mit dieser Regel im neuen
   Design bitgenau so gefaerbt wie im alten, in beiden Themes. Das ist der
   Punkt: er soll zu seinen unveraenderten Geschwistern passen, nicht zu
   einer halb umgestellten Absicht.

   -- SCHRITT 3: DIE GESCHWISTER-RECHNUNG --
   ".card-info .badge-internal ~ .badge-draft" und vier weitere
   (webapp.css:11140-11144) setzen "bottom: 34px" statt 8px -- 26px
   Versatz. Bei einer Markerhoehe von 24px bleiben 2px Luft.

   GEMESSEN, zwei Marker (intern + festgehalten), beide Designs, beide
   Themes: ".badge-internal" bottom 8px, Hoehe 24, Kasten 266..290 (neu)
   bzw. 278..302 (alt); ".badge-pinned" bottom 34px, Hoehe 24, Kasten
   240..264 bzw. 252..276 -- Luecke 2px, keine Ueberdeckung. Die
   Agentenkarte stapelt ueber eine ZWEITE, unabhaengige Regel
   (".card.card-collaboration .agent-update-badge", webapp.css:11206):
   ".badge-collaboration" bottom 8px bei Hoehe 24, ".agent-update-badge"
   bottom 34px -- Luecke ebenfalls 2px, aber siehe Befund C zur Hoehe des
   oberen Markers.

   ZWEI BEFUNDE, und beide gehoeren in den Kommentar, weil das Messergebnis
   von der Erwartung des Auftrags abweicht.

   BEFUND A -- EINE REGRESSION DES NEUEN DESIGNS, HIER BEHOBEN.
   ".badge-pinned" traegt den laengsten Text der Familie ("Aeltere
   Version"). Sein Kasten ist absolut positioniert mit "left: 50%" und
   "right: auto"; die Schrumpfbreite ist damit auf 200 - 100 = 100px
   gedeckelt (".card-info" ist 200px breit, webapp.css:4578). Gemessene
   Eigenbreite bei "white-space: nowrap":
     altes Design (-apple-system):  99,52px  -- passt, Hoehe 24
     neues Design (Inter):         105,53px  -- passt NICHT, umbricht auf
                                                zwei Zeilen, Hoehe 44
   44px gegen 26px Versatz: die Rechnung stimmt nicht mehr, und der Marker
   steht 18px in die Reihe darueber hinein. Ursache ist der Schriftwechsel
   aus 04 · Core, nicht Task 1 -- die Folge trifft aber genau die Rechnung,
   die dieser Schritt zu pruefen hat, deshalb wird sie hier geheilt:
   "white-space: nowrap" stellt die eine Zeile und damit die 24px wieder
   her (gemessen: Hoehe 44 -> 24, Breite 100 -> 105,53).
   DIE 5,53px ueber der Deckelung sind gemessen und unschaedlich: der
   Marker steht dann bei 430,23..535,77 in einer ".card-info" von
   383..583 und einer ".card" von 362..604 -- beidseitig gut 47px Luft,
   nichts wird beschnitten (".card" setzt kein "overflow").

   "nowrap" ALLEIN WAERE ABER EIN TAUSCH, KEINE HEILUNG, und eine erste
   Fassung dieser Regel hat genau den gemacht. "Aeltere Version" ist kein
   festes Literal: der Text laeuft durch AtomDisplay.translate() und damit
   durch die serverseitigen Sprachdateien. Mit einem laengeren Ersatztext
   gemessen ("Aeltere Version des Arbeitsablaufs vom letzten Quartal"):
     nur "nowrap":  Marker 307,59..658,41 gegen ".card" 362..604
                    -> 54,41px UEBERSTAND je Seite, Hoehe 24
     altes Design:  Marker 432,34..533,66, Hoehe 104 (fuenf Zeilen)
                    -> bleibt in der Karte, bricht dafuer um
   Der Ueberstand waechst mit dem Text; die 54,41 gelten fuer diesen einen
   Satz. Das alte Design tauscht also Hoehe gegen Breite -- haesslich, aber
   eingerahmt. "nowrap" ohne Deckel tauscht andersherum, und das ist
   schlechter: es laeuft aus der Karte heraus.

   LEGACYS EIGENE ANTWORT AUF GENAU DIESES PROBLEM steht drei Regeln
   weiter: ".badge-collaboration" (webapp.css:11164-11167) kombiniert
   "nowrap" mit "max-width: calc(100% - 12px)", "overflow: hidden" und
   Ellipse. Uebernommen, mit denselben Werten. Gemessen mit dem langen
   Ersatztext: Marker 379..587 in einer ".card" von 362..604 -- 17px Luft
   je Seite, Hoehe 24, und die Ellipse greift (Textbreite 351px gegen 188px
   Inhaltskasten). Der deutsche Fall bleibt unberuehrt: 105,53px, einzeilig,
   Hoehe 24 -- der Deckel liegt bei 188 + 2 x 10 Innenabstand = 208px und
   wird von ihm nicht erreicht.

   SICHTBARE AENDERUNG, gehoert in die Sichtpruefung: der Marker ist im
   neuen Design 6px breiter als im alten -- und einzeilig statt zweizeilig;
   bei einer langen Uebersetzung endet er mit einer Ellipse, wo das alte
   Design mehrzeilig wird.

   BEFUND B -- EIN ALTLASTFEHLER, NICHT BEHOBEN.
   Die Stapelregel kennt nur EINE Stufe (34px). Bei DREI Markern -- intern
   + Test + festgehalten, erreichbar ueber internal=true, status=TEST,
   pinnedworkflowversionid>0 -- greifen fuer den dritten Marker gleich zwei
   ihrer Selektoren (".badge-internal ~ .badge-pinned" und
   ".badge-test ~ .badge-pinned"), beide mit demselben Wert. Gemessen:
     altes Design:  .badge-test   34px Kasten 252..276
                    .badge-pinned 34px Kasten 252..276  -> DECKUNGSGLEICH
     neues Design:  .badge-test   34px Kasten 240..264
                    .badge-pinned 34px Kasten 240..264  -> DECKUNGSGLEICH
   Der Fehler existiert im BESTAND und ist in beiden Designs derselbe; eine
   dritte Stufe (60px) fehlt. Er wird hier NICHT behoben: webapp.css ist
   unantastbar, und eine Heilung allein unter [data-design="new"] liesse
   die beiden Designs an einer Stelle auseinanderlaufen, die dieses
   Teilprojekt gar nicht umbaut. Befund fuer die Eigentuemer.
   Der Test haelt beide Seiten fest: die Zweierstapelung steht frei, und
   die Dreierstapelung ist im neuen Design um KEINEN Pixel schlechter als
   im alten.

   BEFUND C -- DERSELBE UMBRUCH BEIM SECHSTEN MARKER, EBENFALLS NICHT
   BEHOBEN. ".agent-update-badge" ("Update verfuegbar", webapp.css:11187)
   misst Hoehe 44 und Breite 100 -- in BEIDEN Designs. Es ist derselbe
   Schrumpfbreiten-Umbruch wie bei ".badge-pinned", nur hat ihn dort nicht
   erst Inter ausgeloest: der Text ist schon mit der Systemschrift zu breit.
   Die 26px-Rechnung ist auf der Agentenkarte also VORBESTEHEND verletzt,
   mit 18px Ueberstand in die Zeile darueber.
   Nicht geheilt, aus derselben Begruendung wie Befund B: in beiden Designs
   identisch, webapp.css unantastbar, und eine Heilung allein unter
   [data-design="new"] liesse die Designs auseinanderlaufen -- waehrend die
   Heilung an ".badge-pinned" sie ZUSAMMENfuehrt, weil sie dort einen
   Unterschied beseitigt, den erst das neue Design gemacht hat. Das ist der
   Trennstrich zwischen Befund A einerseits und B/C andererseits.
   Der Test setzt die 44 als ehrlichen WAECHTER, damit eine spaetere
   Reparatur auffaellt statt still durchzugehen. Befund fuer die
   Eigentuemer.

   FUER DIE SICHTPRUEFUNG, schaerfer als "eine Klasse traegt zwei
   Absichten": die KARTENMARKER-FAMILIE ist im neuen Design die eine
   Stelle, die die LEGACY-Warnfarbe behaelt, waehrend die Absicht Warning
   sonst auf Figmas Paar umgestellt ist (Task 1). Bewusst, reversibel, und
   innerhalb EINER Karte konsistent -- deshalb kein Bruch, sondern eine
   Grenze, die zu bestaetigen ist. */
[data-design="new"] .card-info .badge-test {
  background: var(--clr-badge-warning-bg);
  color: var(--clr-badge-warning-fg);
}

[data-design="new"] .badge-pinned {
  white-space: nowrap;
  max-width: calc(100% - 12px);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ══ 05 · Data, Teil B — Task 3: Faehigkeits- und Filterchips ═════
   Figma-Knoten 14:24 (Chip / Capability) und 182:175 (Chip / Filter).
   Beide Bauteile sind im vollen Stapel an den Knoten gemessen, die das
   PRODUKT erzeugt -- eine OrganismsModelSelectionCard fuer ".cap-chip"
   (organismsmodelselectioncard.js:76/80) und ein
   OrganismsLlmProviderSelector mit geoeffnetem Filterkopf fuer
   ".llm-selector-chip" (_appendChipGroup(), :786-800) --, danach an den
   beiden Galeriekacheln gegengeprueft. Beide Reihen lieferten dieselben
   Werte. Chromium, 1280x900, beide Designs, beide Themes.

   NUR EIN ERZEUGER JE CHIP. ".cap-chip" entsteht ausschliesslich in der
   Modellkarte, ".llm-selector-chip" ausschliesslich in
   OrganismsLlmProviderSelector. Der Persona-Selektor
   (organismspersonaselect.js) benutzt zwar dieselbe ".llm-selector-*"-
   Familie, aber KEINE Chips -- er hat keinen Filterkopf. Ein
   [data-theme="light"]-Gleichstand wie bei der Badge-Familie existiert
   hier nicht: ueber alle CSS-Dateien gibt es zu beiden Klassen keine
   einzige Theme-Regel.

   ── TEIL 1: .cap-chip ──────────────────────────────────────────────
   Der Bestand (webapp.css:4490): "font-size: 10px; padding: 2px 8px;
   border-radius: 999px; background: rgba(var(--clr-accent-rgb), 0.18);
   color: var(--clr-accent); border: 1px solid rgba(..., 0.35);
   line-height: 1.5; white-space: nowrap". Acht Deklarationen, und die
   Entscheidung je Deklaration:

     border-radius: 999px -> UEBERNOMMEN, und bewusst NICHT wiederholt.
       Figmas Form ist dieselbe Pille. Eine Wiederholung waere eine Zeile
       ohne Aussage (dieselbe Entscheidung wie "display: inline-block" im
       Badge-Raster); der Test sichert den Wert als WAECHTER.
     white-space: nowrap -> UEBERNOMMEN, ebenfalls nicht wiederholt.
     background/color   -> ERSETZT durch das Paar accent/knowledge.
     border             -> ENTFAELLT ("border: none"). Figma kennt fuer
       dieses Bauteil keinen Rahmen.
     padding            -> ERSETZT durch Figmas "4px 8px". Nur die
       SENKRECHTE Haelfte aendert sich dabei; 8px waagerecht stehen im
       Bestand schon.
     font-size 10 -> 11, font-weight (Legacy setzt keins, geerbt 400)
       -> 600. Figma: Semi Bold 11.
     line-height: 1.5   -> ERSETZT durch 14px. Begruendung gleich unten.

   ── WIE ENTSTEHT DIE HOEHE 22? GEMESSEN, NICHT GERATEN ──
   Figmas Knoten sagt Hoehe 22 UND Innenabstand 4/8. Das ist bereits die
   ganze Rechnung: 4 + 14 + 4. Trotzdem vier Wege gemessen, am echten
   Knoten der Modellkarte (neues Design, dunkel):

     0  gar nichts zur Hoehe (nur Farbe/Schrift/kein Rahmen) -> h=20,5
     A  padding 4px 8px, line-height 14px                    -> h=22, Text 4/4
     B  padding 4px 8px, line-height geerbt (1.5 = 16,5px)   -> h=24,5
     C  padding 0 8px, line-height 22px                      -> h=22, Text 4/4
     D  min-height 22px, padding 4px 8px, line-height 14px   -> h=30

   B verfehlt um 2,5px. D verfehlt um 8: ".cap-chip" ist ein Flex-Element
   in ".model-card-chips" (webapp.css:4482, "display: flex; flex-wrap:
   wrap"), und "min-height" verhaelt sich dort anders als am Blockkasten
   des Badge-Rasters -- die Variante, die in Task 1 nur die Textmitte
   verfehlt hat, verfehlt hier die Zahl selbst.
   A und C treffen beide exakt 22 und setzen den Text beide mittig (4/4).
   GEWAEHLT: A, weil es Figmas eigene Rechnung stehen laesst -- der Knoten
   nennt 4/8 als Innenabstand, nicht 0/8. C traefe dieselbe Zahl mit einer
   Rechnung, die im Knoten nicht steht.

   ── DER GLEICHSTAND BEI ".cap-chip.more" ──
   SPEZIFITAETEN:
     .cap-chip                              (0,1,0)  webapp.css:4490
     .cap-chip.more                         (0,2,0)  webapp.css:4497
     [data-design="new"] .cap-chip          (0,2,0)  Regel unten
     [data-design="new"] .cap-chip.more     (0,3,0)  Regel unten
   Die MITTLEREN ZWEI liegen im Gleichstand, und components.css laedt
   zuletzt (cockpit.html:16-18). Ohne die zweite Regel wuerde die
   Grundregel den Ueberlaufchip mitfaerben: gemessen faellt er dann auf
   rgb(11, 44, 54) -- dasselbe Tuerkis wie die echten Faehigkeiten. Die
   (0,3,0)-Regel ist also kein Feinschliff, sie haelt die Unterscheidung.

   ── "HEBT SICH AB" -- IN DER RICHTIGEN EINHEIT ──
   Der Auftrag verlangte eine WCAG-Zahl. Ein WCAG-Verhaeltnis misst
   LEUCHTDICHTE und kann eine Farbtontrennung grundsaetzlich nicht
   abbilden -- die Zahl war in einer Einheit verlangt, die die Aussage
   nicht messen kann. Gemessen wurde deshalb beides, an den Flaechen der
   beiden Chips gegeneinander:

                    WCAG-Verhaeltnis          Farbabstand (CIE76)
     neues Design   1,187 dunkel / 1,104 hell  14,758 / 15,705
     altes Design   1,025 dunkel / 1,314 hell  14,101 / 17,868

   Bei einer Wahrnehmungsschwelle um 2,3 sind ~15 ein klar sichtbarer
   Unterschied. Die Trennung ist also da -- sie steht nur im Farbton
   (Tuerkis gegen Neutral), nicht in der Helligkeit, und deshalb sagt das
   WCAG-Verhaeltnis dazu nichts.

   ZUR VERGLEICHBARKEIT DER ZEILE "altes Design": seine Flaechen sind
   halbdurchsichtig (Alpha 0,18 bzw. 0,08), seine Farbe haengt also davon
   ab, worauf der Chip liegt. Ueber der Seitenflaeche der Galerie
   (rgb(10,14,26)) misst er dunkel 14,101, ueber der Kartenflaeche
   (rgb(26,24,38)) 13,741, ueber surface-2 13,253, ueber Schwarz 16,088.
   Die Zahlen oben sind die ueber der Seitenflaeche. Die Flaechen des
   neuen Designs sind deckend und damit wirtunabhaengig -- das ist selbst
   ein Ergebnis, kein Messdetail.

   Die TEXTKONTRASTE sind in beiden Chips gut und im neuen Design
   deutlich besser: Faehigkeit 8,139 (hell 6,491), Ueberlauf 7,750 (hell
   9,953); das alte Design kommt am Faehigkeitschip auf 4,248 (hell
   4,320). Die beiden Textfarben stehen zueinander bei 1,247 dunkel /
   1,693 hell -- auch das eine Leuchtdichtezahl ohne Aussagekraft ueber
   die Farbtontrennung.

   ── BEFUND: LANGE UEBERSETZUNGEN ──
   Der Text laeuft durch AtomDisplay.translate() und ist damit nicht
   fest. Mit den echten Beschriftungen ("Text" ... "Deep Research",
   organismsmodelselectioncard.js) passt alles: zwei Reihen, sechs von
   sechs Chips im Kasten, in BEIDEN Designs. Mit einem langen
   Ersatztext ("Automatische Spracherkennung und Transkription") am
   ersten Chip gemessen:
     altes Design  Chipbreite 238,44px, rechte Kante 19,44px ueber der
                   Karte
     neues Design  Chipbreite 284,28px, rechte Kante 65,28px ueber der
                   Karte
   ".model-card-chips" ist "height: 56px; overflow: hidden"
   (webapp.css:4482) und schneidet in beiden Faellen ab -- das neue
   Design verliert 45,84px mehr. NICHT GEHEILT, aus derselben
   Begruendung wie Befund B/C in Task 2: den Schnitt gibt es in beiden
   Designs, er ist eine Eigenschaft des Wirts, und eine Heilung allein
   unter [data-design="new"] liesse die Designs auseinanderlaufen.
   Ursache des Zuwachses sind Figmas eigene Werte (Schrift 10 -> 11px,
   Innenabstand 2 -> 4px). Befund fuer die Eigentuemer der Vorlage.

   ── TEIL 2: .llm-selector-chip UND DIE DREI REGELN, DIE SCHON DA WAREN ─
   SPEZIFITAETEN, ausgerechnet, BEVOR die Ruheregel geschrieben wurde:
     :where([data-design="new"]) button                        (0,0,1)
     :where([data-design="new"]) button:hover:not(:disabled)    (0,2,1)
     .llm-selector-chip                                         (0,1,0)
     .llm-selector-chip:hover                                   (0,2,0)
     .llm-selector-chip.active                                  (0,2,0)
     [data-design="new"] .llm-selector-chip                     (0,2,0)  <- neu
     [data-design="new"] .llm-selector-chip.active              (0,3,0)  <- neu
     .llm-selector.compact .llm-selector-chip                   (0,3,0)
     [data-design="new"] .llm-selector-chip:hover:not(.active)  (0,4,0)  <- neu
     [data-design="new"] button.llm-selector-chip.active        (0,3,1)  <- 04 · Core
     [data-design="new"] button.llm-selector-filter-toggle:hover:not(:disabled)
                                                                (0,4,1)  <- 04 · Core
     [data-design="new"] button.llm-selector-chip:hover:not(:disabled):not(.active)
                                                                (0,5,1)  <- 04 · Core
     [data-design="new"][data-theme="light"] .llm-selector-chip.active
                                                                (0,4,0)  <- ENTFALLEN
                                                                            mit T1,
                                                                            2026-09-15
   Die letzte Zeile ist seit T1 nur noch Geschichte: die Regel gab es, sie
   ist gefallen, und der Block weiter unten sagt warum. Sie steht hier,
   weil die Spezifitaetsrechnung darunter sie einmal gebraucht hat.
   Daraus folgen die vier Entscheidungen dieses Teils.

   1. DIE RAHMENFARBE WIRD NICHT WIEDERHOLT -- und das ist der Kern.
      Figma verlangt fuer den ruhenden Chip "1px solid --ax-border-default".
      Genau das liefert die BRUECKE bereits: Legacys "border: 1px solid
      var(--editborder)" laeuft ueber --clr-border (tokens.css:151/223)
      auf --ax-border-default. Gemessen im neuen Design, ohne jede neue
      Regel: rgb(36, 34, 51) dunkel, rgb(210, 208, 218) hell -- ink/700
      bzw. ink/200, also Figmas Wert.
      Haette die Ruheregel ihn trotzdem gesetzt, stuende sie bei (0,2,0)
      im GLEICHSTAND mit Legacys eigenem ":hover" (webapp.css:7335,
      ebenfalls (0,2,0)) und gewaenne ueber die Ladereihenfolge -- die
      Hover-Rueckmeldung waere lautlos verschwunden, und
      getComputedStyle haette weiter brav den Zielwert gemeldet. Das ist
      die Falle aus Teil A, Task 5, und sie steht hier eine Zeile weit
      neben dem Weg. Der Test haelt beide Seiten fest: im Ruhezustand
      ink/700, beim Zeigen cyan/500.
      Die Textaufhellung beim Zeigen ueberlebt NICHT von selbst: sie
      kommt aus "button:hover" (webapp.css:1461, (0,1,1)) und wird von
      der Ruheregel (0,2,0) geschlagen. Sie wird deshalb ausdruecklich
      wiederhergestellt -- text/secondary im Ruhezustand,
      text/primary beim Zeigen.

   2. ZWEI WERTE IN 04 · Core WURDEN NACHGEZOGEN, statt sie hier zu
      verdoppeln. Beide dortigen Regeln haben genau eine Aufgabe: die
      EIGENE Flaeche des Chips gegen die (0,2,1) schwere Hover-Rechnung
      der Basisregel zu halten. Ihre Werte waren Kopien der damaligen
      Ruhe- bzw. Aktivflaeche ("transparent", "var(--clr-accent)");
      dieser Task aendert beide Flaechen, also aendern sich die Kopien
      mit. Der Alternativweg -- denselben Selektor hier unten ein zweites
      Mal zu schreiben und ueber die Reihenfolge zu gewinnen -- haette
      zwei widersprechende Wahrheiten je Zustand in einer Datei
      hinterlassen. Gemessen, was ohne das Nachziehen passiert waere:
        Ruhezustand beim Zeigen: Flaeche kippt auf
          --ax-action-primary-hover, cyan/400 dunkel (rgb(56,189,248)),
          cyan/600 hell -- der Chip flackert hellblau auf.
        Aktivzustand: bleibt --clr-accent. Im DUNKLEN Theme faellt das
          nicht auf (dort ist --clr-accent dieselbe cyan/500,
          tokens.css:153), im HELLEN sehr wohl: dort haengt --clr-accent
          auf --ax-text-link = cyan/600 (tokens.css:257). Eine
          Aktivregel mit (0,3,0) haette daran NICHTS geaendert -- sie
          waere gegen die (0,3,1) eine tote Deklaration gewesen.
      Die dritte 04-Core-Regel (".llm-selector-filter-toggle:hover",
      (0,4,1)) betrifft ein ANDERES Element und ist unberuehrt: der
      Umschalter misst vor und nach diesem Task dieselben Werte
      (h=24, Flaeche transparent, Radius 3px, 12px/600).

   3. WIE ENTSTEHT DIE HOEHE 32? Fuenf Wege gemessen, am echten Chip:
        0  nichts zur Hoehe                    -> h=21 (aktiv) / 20 (ruhend)
        A  height 32, padding 0 13             -> h=32, Text 1 oben / 16 unten
        B  height 32, padding 0 13, align-items: center -> h=32, Text 8,5/8,5
        C  line-height 30, padding 0 13        -> h=32, Text 8/9
        D  padding 8px 13px                    -> h=33 / 34
        E  min-height 32, padding 0 13, align-items: center -> h=32
      Zuerst zu 0: der Bestand ist im neuen Design NICHT einheitlich hoch
      -- 20px fuer den einen, 21px fuer den anderen Chip derselben
      Gruppe. Ursache ist "line-height: normal" zusammen mit verschieden
      hohen Glyphen. Jede Variante mit fester Hoehe raeumt das mit auf.
      A ist die Falle: die Zahl stimmt, der Text steht oben. Der Chip
      traegt seit 04 · Core "display: inline-flex", und ein Flex-Element
      ohne "align-items" streckt.
      C zentriert und ist glyphenunabhaengig (8/9 fuer beide Chips) --
      und scheitert trotzdem: die 30 sind 32 minus zwei Rahmen. Der
      AUSGEWAEHLTE Chip hat nach Figma keinen Rahmen und maesse damit 30
      statt 32. Zwei Pixel Versatz zwischen ausgewaehlt und nicht
      ausgewaehlt, in einer Reihe nebeneinander.
      GEWAEHLT: B. "height" auf einem border-box-Kasten ist von der
      Rahmenbreite unabhaengig (gemessen: ruhend 32 MIT Rahmen, aktiv 32
      OHNE), und "align-items: center" holt den Text in die Mitte. Der
      Preis ist ein halber Pixel Unterschied in der Textlage zwischen den
      beiden Glyphen (8,5/8,5 gegen 9/8) -- glyphenbedingt und nicht
      vermeidbar, solange zentriert statt ausgezeichnet wird.

   4. DER KOMPAKTZWEIG BEHAELT SEINEN ENGEREN INNENABSTAND.
      ".llm-selector.compact .llm-selector-chip" (webapp.css:7489)
      liegt bei (0,3,0) und schlaegt den Innenabstand der Ruheregel
      (0,2,0). Gemessen im neuen Design mit gesetzter Klasse: h=32,
      padding-left 6px, Radius 999px, 12px/500 -- also Figmas Hoehe,
      Form und Schrift bei Legacys engeren Seiten. Das ist gewollt: die
      Enge ist die Aussage des Kompaktzweigs, die Hoehe nicht.

   ── DREI BEFUNDE FUER DIE EIGENTUEMER DER VORLAGE ──
   BEFUND 1 -- FIGMAS AKTIVPAAR VERFEHLT WCAG 1.4.3.
   Weiss auf --ax-action-primary (cyan/500) misst 2,971. Fuer 12px-Text
   verlangt WCAG 1.4.3 4,5; fuer UI-Komponenten gilt 3,0, auch die wird
   verfehlt. Das ist keine Eigenart dieses Bauteils: derselbe nackte Knopf
   des neuen Designs misst dieselben 2,971 (04 · Core-Basisregel), und
   tokens.css:250-257 nennt die Zahl bereits selbst -- dort wurde
   --clr-accent im hellen Theme deswegen auf --ax-text-link (cyan/600)
   umgehaengt, gemessen 4,761.
   IM HELLEN THEME WIRD DIE VORLAGE DESHALB NICHT BEFOLGT (Regel weiter
   unten, ausfuehrlich dort begruendet): der Chip behaelt cyan/600 und
   damit 4,761.
   BERICHTIGT MIT T1 (2026-09-15, nachgetragen im Abschlussreview): DIE
   "REGEL WEITER UNTEN" IST GEFALLEN -- der Verweis ginge ins Leere. An
   ihrer Stelle steht ein "HIER STAND EINE HELLE SONDERREGEL"-Block mit der
   Herleitung und der zweiseitigen Messung; dort ist nachzulesen, was frueher
   "ausfuehrlich dort begruendet" war. DIE ENTSCHEIDUNG GILT UNVERAENDERT:
   der Chip traegt hell weiterhin cyan/600 und 4,761 -- jetzt aber ueber das
   FUNDAMENT ("--ax-action-primary" steht hell seit T1 selbst auf cyan/600),
   nicht ueber eine Sonderregel. Auch der Satz "die Vorlage wird nicht
   befolgt" stimmt nur noch dem Wert nach, nicht mehr dem Mechanismus:
   befolgt wird heute Figmas eigener Tokenpfad, der hell einen anderen Wert
   traegt als in Figmas Sammlung.
   Und ein Satz weiter oben ist mitgewandert: "tokens.css:250-257 nennt die
   Zahl bereits selbst" verweist auf genau den Block, der die 2,971 kannte
   und ihr ausgewichen ist. Er steht heute rund zwanzig Zeilen weiter unten
   und traegt dort seinerseits einen Berichtigungsvermerk -- Zeilennummern
   sind in dieser Datei eine bekannte Fehlerquelle, der Selektor bzw. die
   Kommentarzeile "Kein Drift, sondern Rollentrennung" traegt laenger.
   Im DUNKLEN Theme bleibt Figmas cyan/500 mit 2,971 --
   dort waere --ax-text-link cyan/400 und mit weissem Text schlechter,
   nicht besser; der Wert ist ausserdem derselbe wie vor diesem
   Teilprojekt. Zum Vergleich das alte Design am selben Chip: 3,678
   dunkel, 6,288 hell.
   Der Befund an die Eigentuemer der Vorlage bleibt also stehen und ist
   schaerfer als eine Chip-Frage: Figmas eigenes Aktivpaar erfuellt
   WCAG 1.4.3 nicht, und das betrifft jeden Traeger dieses Paares.
   BEFUND 2 -- DIE RUHEFLAECHE TRENNT NUR IM DUNKLEN THEME, DER RAHMEN IN
   BEIDEN. UND DIE ERSTE FASSUNG DIESES BEFUNDS MASS IN DER FALSCHEN
   EINHEIT.
   Der ruhende Chip soll bg/surface-1 tragen; er steht aber im
   Filterkopf (".llm-selector-filter", webapp.css:7255 ->
   --background-color-card -> --clr-surface-mid, :181/:17/:279), und der
   ist eine Mischung aus derselben Flaechenfamilie.

   ZWEI EINHEITEN, ZWEI FRAGEN, und die erste Fassung hat sie verwechselt.
   Das Leuchtdichte-Verhaeltnis beantwortet WCAG 1.4.11 (Schwelle 3,0 fuer
   Bedienelemente). Ob sich etwas ABHEBT, beantwortet es nicht -- dafuer
   ist der Farbabstand dE (CIE76, Wahrnehmungsschwelle 2,3) da. Genau das
   haben Ruling 11 (Task 4) und Ruling 20 (Task 7) festgelegt, beide NACH
   diesem Task; zu diesem Befund ist niemand zurueckgegangen. Beide Reihen,
   gegen den gerasterten Wirt gemessen (dunkel / hell):

                        WCAG 1.4.11        dE (CIE76)
     Flaeche  neu       1,068 / 1,034      3,925 /  1,449
              alt       1,000 / 1,000      0,000 /  0,000
     Rahmen   neu       1,128 / 1,474      5,770 / 15,512
              alt       1,065 / 1,431      4,007 / 24,857

   Farben, aus denen das gerechnet ist: Wirt rgb(25,24,37) / (251,251,252),
   neue Flaeche rgb(18,17,28) / (255,255,255), neuer Rahmen rgb(36,34,51) /
   (210,208,218); alt Wirt rgb(25,33,44) / (249,250,255), Flaeche
   "transparent" (= der Wirt selbst), Rahmen #21262d / #c7d2fe.

   DIE WCAG-SEITE bleibt richtig und unveraendert: die 3,0 erreicht in
   KEINEM Design und an KEINER der vier Stellen etwas. Ererbte Luecke,
   kein Rueckschritt.

   DIE dE-SEITE sagt im dunklen Theme das GEGENTEIL der ersten Fassung:
     - Der RAHMEN trennt in BEIDEN Themes deutlich (5,77 / 15,51 gegen
       eine Schwelle von 2,3). "Im dunklen Theme trennt weder Flaeche noch
       Rahmen nennenswert" war falsch.
     - Die FLAECHE trennt im DUNKLEN (3,93) und NICHT im hellen (1,45) --
       auch das umgekehrt zur ersten Fassung, die den hellen Fall fuer den
       besseren hielt.
     - Bei der FLAECHE ist es gegen das alte Design kein "kein
       Rueckschritt", sondern ein FORTSCHRITT: Legacys Flaeche ist
       "transparent" und damit per Bauart der Wirt selbst, dE zwingend
       0,000 in beiden Themes.
     - Beim RAHMEN faellt es geteilt aus: dunkel ein kleiner Fortschritt
       (4,01 -> 5,77), hell ein Rueckschritt (24,86 -> 15,51), weil Legacys
       #c7d2fe sich vom fast weissen Wirt staerker abhob als ink/200.
       Beide liegen weit ueber 2,3; das ist eine Frage der Betonung, nicht
       der Sichtbarkeit.
   Die Deklaration bleibt, aber mit einer anderen Begruendung als in der
   ersten Fassung: sie gibt dem Chip im dunklen Theme erstmals eine eigene,
   gegen das alte Design ueberhaupt erst sichtbare Flaeche. Im hellen bleibt
   sie unter der Schwelle, dort traegt der Rahmen allein. "Melden, nicht
   heilen" traegt weiter -- der Adressat ist aber der HELLE Fall.
   BEFUND 3 -- FIGMAS ZAEHLER HAT KEINEN TRAEGER.
   Der Knoten 182:175 zeigt im Chip einen Zaehler (Semi Bold 11,
   --ax-text-muted bzw. --ax-action-on-primary, Abstand 6px). Das
   Produkt baut den Chip als reinen Textknopf (_appendChipGroup():
   "el.textContent = chip.label"); die einzige Zahl im Filterkopf sitzt
   in ".llm-selector-filter-count" am Umschalter, einem anderen Element.
   Kein Traeger, also keine Regel -- kein erfundener Stil.

   ── WAS IM ALTEN DESIGN NICHT NACHWEISBAR IST ──
   Fuer jede der 23 neuen Deklarationen wurde im alten Design derselbe
   Selektor OHNE Praefix hinter components.css nachgeladen. 20 bewegen
   dort etwas und sind im Test zugesichert. DREI bewegen nichts:
     .llm-selector-chip { background: var(--ax-bg-surface-1) }  Die
       Variable existiert im alten Design nicht -> "transparent", und das
       ist Legacys eigener Wert.
     .llm-selector-chip { color: var(--ax-text-secondary) }  Dasselbe;
       die geerbte Textfarbe ist Legacys Wert.
     .llm-selector-chip { font-weight: 500 }  Legacy steht bereits auf
       500; die 500 unterscheiden sich von der BASISREGEL des neuen
       Designs (600), nicht vom Bestand.
   Ein verlorener [data-design="new"]-Praefix an genau diesen drei
   Deklarationen bliebe unentdeckt. Das steht hier, statt dass der
   Leck-Waechter eine Abdeckung behauptet, die er nicht hat. */
[data-design="new"] .cap-chip {
  padding: 4px 8px;
  font-size: 11px;
  font-weight: 600;
  line-height: 14px;
  background: var(--ax-accent-knowledge-bg);
  color: var(--ax-accent-knowledge-on-bg);
  border: none;
}

[data-design="new"] .cap-chip.more {
  background: var(--ax-text-muted-bg);
  color: var(--ax-text-muted-on-bg);
}

[data-design="new"] .llm-selector-chip {
  height: 32px;
  padding: 0 13px;
  align-items: center;
  border-radius: var(--ax-radius-full);
  background: var(--ax-bg-surface-1);
  color: var(--ax-text-secondary);
  font-size: 12px;
  font-weight: 500;
}

[data-design="new"] .llm-selector-chip:hover:not(.active) {
  color: var(--ax-text-primary);
}

[data-design="new"] .llm-selector-chip.active {
  border: none;
  color: var(--ax-action-on-primary);
}

/* HIER STAND EINE HELLE SONDERREGEL -- ENTFALLEN MIT T1 (2026-09-15).
   Der Block bleibt stehen und wird umgeschrieben, statt geloescht zu
   werden: er erklaert, warum es die Regel gab und warum sie heute nichts
   mehr tut. Ohne ihn stellt der naechste Bearbeiter dieselbe Frage noch
   einmal.

   WAS HIER STAND:
     [data-design="new"][data-theme="light"] .llm-selector-chip.active {
       background: var(--ax-text-link);
     }

   WARUM ES SIE GAB -- eine bewusste Abweichung von der Vorlage: Figmas
   Knoten 182:175 bindet fuer den ausgewaehlten Chip action/primary
   (cyan/500). Im hellen Theme hielt die weisse Beschriftung darauf nur
   2,971, unter der 4,5 fuer Text UND unter der 3,0 fuer UI-Komponenten;
   "--ax-text-link" (cyan/600) hielt 4,761. Die Regel holte diesen Wert
   zurueck. Im dunklen Theme gab es sie nie, dort waere cyan/400 mit
   weisser Schrift schlechter, nicht besser.

   WARUM SIE FAELLT: T1 hat die Ursache an der Wurzel geheilt.
   "--ax-action-primary" steht im hellen Theme seither selbst auf cyan/600
   (tokens.css:127). Die 04-Core-Aktivregel weiter oben
   ("[data-design=new] button.llm-selector-chip.active", (0,3,1)) liefert
   damit genau den Wert, den diese Regel herstellen sollte.

   ZWEISEITIG GEMESSEN, BEVOR SIE FIEL (Galerie-Kachel
   "gallery-chips-filter", ".llm-selector-chip.active", "background-color",
   Marke #ff5500):
                        mit dieser Regel   ohne sie
     dunkel ungebrandet rgb(0,159,227)     rgb(0,159,227)
     dunkel gebrandet   rgb(0,159,227)     rgb(0,159,227)
     hell   ungebrandet rgb(0,122,176)     rgb(0,122,176)
     hell   gebrandet   rgb(0,122,176)     rgb(0,122,176)
   VIERMAL DASSELBE, und die gebrandete Spalte ist der eigentliche Beleg.
   Wertgleich heisst nicht wirkungslos: eine Deklaration, die eine
   brandbare Wurzel gegen ein festes Token tauscht, ist ungebrandet
   wertgleich und entzieht trotzdem die Organisationsfarbe. HIER TUT SIE
   DAS NICHT -- beide Seiten sind "--ax-"-Tokens, und brandingapplier.js
   haengt ausschliesslich "--clr-"-Wurzeln um (:6-17). Die Regel war nach
   der Heilung in allen vier Konfigurationen ohne Wirkung.

   EIN NEBENEFFEKT, UND ER IST EINE VERBESSERUNG: die gefallene Regel war
   (0,4,0) OHNE Elementqualifizierer, die verbleibende ist (0,3,1) MIT
   "button". Die hier frueher gemeldete Asymmetrie -- ein zweiter Erzeuger
   mit <span> oder <a> verloere die Fuellung NUR im dunklen Theme -- ist
   damit aufgehoben: beide Themes haengen jetzt an derselben Regel.

   WAS BLEIBT: der Befund an die Eigentuemer der Vorlage. Figmas eigenes
   Aktivpaar (weiss auf action/primary) verfehlt WCAG 1.4.3 im hellen
   Theme. Er wird nur nicht mehr hier beantwortet, sondern am Fundament. */

/* ══ 05 · Data, Teil B — Task 4: Der DSGVO-Marker ═════════
   Figma-Knoten 14:15 (Badge / GDPR), Rounded/Sm: Radius 6px, Innenabstand
   4px 8px, Semi Bold 11, KEIN Rahmen, Success- bzw. Danger-Paar.

   Gemessen wurde ausnahmslos an den Knoten, die das PRODUKT erzeugt --
   der Marker entsteht nirgends ueber eine Atom-Klasse, sondern per
   Template-Literal: <span class='llm-gdpr-badge ${gdprClass}'>
   ${gdprLabel}</span> (organismsllmproviderselector.js:550/559/611/617,
   organismsorchestrationtimeline.js:112, organismspersonalist.js:255/259,
   organismspersonamultiselect.js:129/132, organismspersonaselect.js:
   195/198). Vier Wirte wurden nachgestellt und getrennt gemessen:
   Dropdownzeile, Auswahlzeile, kompakter Zweig und Personenkarte; dazu
   die Galeriekachel, an der jede Zahl unten gegengeprueft ist (Chromium
   1280x900, beide Designs, beide Themes).

   -- SCHRITT 1: DREI ZUSTAENDE, NICHT ZWEI --
   Figma kennt "Compliant=True/False". Das Produkt fuehrt seit Langem
   DREI Zustaende (_gdprClass(), organismsllmproviderselector.js:504-508):
   "compliant", "conditional" und "non-compliant". Der dritte BLEIBT und
   bekommt das Warning-Paar. Das ist eine Entscheidung GEGEN die Vorlage,
   und sie steht hier, damit sie nicht spaeter als Versehen gelesen wird:
   eine unvollstaendige Vorlage ist kein Auftrag zum Loeschen. Befund an
   die Eigentuemer der Vorlage (Spec, Abschnitt 7, Punkt 2).

   -- DER BESTAND, EIGENSCHAFT FUER EIGENSCHAFT --
   Legacys Grundregel (webapp.css:7352) hat NEUN Deklarationen. Fuer jede
   eine Entscheidung:

     display: inline-flex   -> UEBERNOMMEN, bewusst NICHT wiederholt.
     align-items: center    -> dito. Sie zentrieren den Text im Kasten und
     justify-content: center   sind unangefochten; keine der drei
       Zustandsregeln fasst sie an. Eine Wiederholung waere eine Zeile
       ohne Aussage (dieselbe Entscheidung wie "display: inline-block" im
       Badge-Raster). Der Test sichert sie als WAECHTER.
     white-space: nowrap    -> UEBERNOMMEN, ebenfalls nicht wiederholt.
     flex-shrink: 0         -> dito.
     font-size: 11px        -> Figmas Wert steht im Bestand schon.
     font-weight: 600       -> Figmas "Semi Bold" ebenfalls. Beide werden
       NICHT wiederholt und als WAECHTER zugesichert -- das ist der
       eigentliche Befund dieses Bauteils: von Figmas Typografie war schon
       alles da.
     padding: 2px 7px       -> ERSETZT durch Figmas "4px 8px".
     border-radius: 3px     -> ERSETZT durch var(--ax-radius-sm) = 6px.

   Dazu EINE Eigenschaft, die Legacys Grundregel nicht kennt:
     line-height: 14px      -> NEU. Legacy erbt 20px von "body"
       (webapp.css:533). Warum 14, steht gleich unten.

   -- WIE ENTSTEHT DIE HOEHE 22? GEMESSEN, NICHT GERATEN --
   Figmas Knoten nennt Hoehe 22 UND Innenabstand 4/8; das ist bereits die
   ganze Rechnung: 4 + 14 + 4. Trotzdem sechs Wege gemessen, am echten
   Marker der Auswahlzeile (neues Design, dunkel), und zusaetzlich in
   einem Wirt, der den Zeilenkasten als ZAHL setzt (line-height: 1.65)
   statt als Laenge -- die Gegenprobe aus Task 1 ("T" = Text oben/unten):

                                          body-Wirt      Wirt mit 1.65
     0  nichts zur Hoehe (Legacy 2px 7px)  h=24 T 5/5     h=22,14 T 4/4,14
     A  padding 4px 8px + line-height 14   h=22 T 4/4     h=22    T 4/4
     B  padding 4px 8px, Kasten geerbt     h=28 T 7/7     h=26,14 T 6/6,14
     C  padding 0 8px + line-height 22     h=22 T 4/4     h=22    T 4/4
     D  min-height 22 + 4px 8px + lh 14    h=30 T 8/8     h=30    T 8/8
     E  height 22 + 4px 8px + lh 14        h=30 T 8/8     h=30    T 8/8

   D und E verfehlen die Zahl um 8px, nicht knapp: der Marker ist
   "inline-flex" bei "box-sizing: content-box", die 22 kommen also ZUM
   Innenabstand hinzu. (In Task 3 hat "min-height" am Faehigkeitschip aus
   demselben Grund 30 statt 22 ergeben -- derselbe Fehlschlag, zweites
   Bauteil.) 0 und B haengen am geerbten Zeilenkasten und liefern im
   zweiten Wirt andere Zahlen.
   GEWAEHLT: A. Es trifft die 22, zentriert den Text (4/4), ist vom Wirt
   unabhaengig -- und laesst Figmas eigene Rechnung stehen: der Knoten
   nennt 4/8 als Innenabstand, nicht 0/8. C traefe dieselbe Zahl mit einer
   Rechnung, die im Knoten nicht steht.

   -- SPEZIFITAETEN, AUSGERECHNET UND NACHGESTELLT --
     .llm-gdpr-badge                                   (0,1,0) webapp:7352
     .llm-gdpr-badge.compliant / .conditional /
       .non-compliant                                  (0,2,0) webapp:7364+
     .persona-card .llm-gdpr-badge                     (0,2,0) webapp:12202
     [data-design="new"] .llm-gdpr-badge               (0,2,0) unten
     [data-design="new"] .llm-gdpr-badge.compliant     (0,3,0) unten
     [data-design="new"] .persona-card .llm-gdpr-badge (0,3,0) unten
   Ein [data-theme="light"]-Gleichstand wie bei der Badge-Familie existiert
   hier NICHT: ueber alle CSS-Dateien gibt es zu ".llm-gdpr-badge" keine
   einzige Theme-Regel (geprueft, nicht angenommen).

   ZWEI GLEICHSTAENDE GIBT ES TROTZDEM, und beide sind der Grund fuer je
   eine (0,3,0)-Regel:

   1. DER RAHMEN STEHT IN DEN ZUSTANDSREGELN, NICHT IN DER GRUNDREGEL.
      Legacy deklariert ihn dreimal einzeln (":7366", ":7372", ":7378"),
      jeweils bei (0,2,0). "border: none" in der neuen GRUNDREGEL laege im
      Gleichstand und gewaenne nur ueber die Ladereihenfolge
      (components.css laedt zuletzt, cockpit.html:16-18). Deshalb steht es
      in den drei Zustandsregeln bei (0,3,0) -- gewonnen wird ueber die
      Zahl, nicht ueber die Reihenfolge.
      NACHGESTELLT, nicht nur ausgerechnet: laedt man Legacys
      Zustandsregel woertlich HINTER components.css, bleibt der Marker mit
      der Regel unten in beiden Themes rahmenlos und 22px hoch. Mit
      "border: none" in der Grundregel (0,2,0) kippt derselbe Aufbau
      zurueck auf 1px Rahmen und 24px Hoehe. Beide Faelle gemessen.

   2. DIE PERSONENKARTE HAELT IHREN ENGEREN INNENABSTAND.
      ".persona-card .llm-gdpr-badge" (webapp.css:12202) setzt
      "font-size: 9.5px; padding: 1px 5px" -- eine bewusste Verdichtung in
      einer dichten Karte (moleculepersonacardlist.js:308-324, Wert aus
      organismspersonalist.js:259). Beim "font-size" gibt es keinen
      Konflikt: die neue Grundregel setzt gar keins. Beim "padding" schon,
      und dort steht (0,2,0) gegen (0,2,0). Ohne die Gegenregel gewaenne
      die Grundregel ueber die Ladereihenfolge; gemessen springt der
      Marker der Karte dann von 1px/5px auf 4px/8px, von 16px auf 22px
      Hoehe und von 53,31px auf 59,31px Breite.
      ENTSCHIEDEN: die Enge bleibt, die Hoehe nicht. Die Gegenregel holt
      Legacys Wert WOERTLICH zurueck -- den INNENABSTAND, denn nur den
      deklariert Legacy dort.
      DAS ERGEBNIS STEHT DAMIT IN KEINER DER BEIDEN AUTORITAETEN, und das
      gehoert ausdruecklich auf die Sichtpruefungsliste: der Marker der
      Personenkarte misst im neuen Design 16px, nicht Legacys 24 und nicht
      Figmas 22. Legacys Verdichtung war 24 gegen 26, also -8 %; die neue
      ist 16 gegen 22, also -27 %. Der Unterschied ist der ZEILENKASTEN:
      Legacys 24 entstanden zum groessten Teil aus den geerbten 20px, die
      die Gegenregel nicht zurueckholt, weil Legacy sie dort nie
      deklariert hat.
      Der Vergleich mit dem Kompaktzweig des Filterchips (Task 3) traegt
      nur halb: dort WUCHS der Chip (19 -> 32), hier SCHRUMPFT der Marker,
      und ueberproportional.
      KEIN LAYOUTSCHADEN, nachgemessen: der neue Marker ist mit 53,31px
      schmaler als derselbe Marker mit erhaltenem Rahmen (55,31px) und
      auch schmaler als der alte (53,47px in derselben Zeile) -- er kann
      also keinen Umbruch ausloesen. Liest die Verdichtung in der
      Sichtpruefung zu klein, ist ein "line-height" in der Gegenregel die
      Ein-Zeilen-Antwort; gemessen ergibt 20px eine Hoehe von 22 (also
      Figmas Standardhoehe, keine Verdichtung mehr), 18px eine von 20
      (-9 %) und 16px eine von 18 (-18 %). Die Breite bleibt in allen
      Faellen bei 53,31px.

   -- SCHRITT 2: DER RAHMEN ENTFAELLT -- WAS TRAEGT DANN DIE TRENNUNG? --
   Ohne Rahmen traegt allein die Flaeche die Unterscheidung. Der Auftrag
   verlangte dafuer eine WCAG-Zahl und die Schwelle 1,2:1. Beides ist
   gemessen, aber die WCAG-Zahl allein KANN die Frage nicht beantworten:
   sie misst Leuchtdichte und bildet eine Farbtontrennung grundsaetzlich
   nicht ab. Gemessen wurde deshalb zusaetzlich der Farbabstand nach
   CIE76; die Wahrnehmungsschwelle liegt um 2,3. Alle Zahlen am Marker der
   Dropdownzeile (Wirt --background-color-card), ohne Zwischenrundung:

     Flaechen gegeneinander       neues Design        altes Design
                                  dunkel / hell       dunkel / hell
     compliant vs conditional     1,031 / 1,014       1,032 / 1,005   WCAG
                                 21,589 / 19,482      9,700 / 10,291  dE
     compliant vs non-compliant   1,172 / 1,112       1,153 / 1,056   WCAG
                                 32,924 / 24,358     19,170 / 15,059  dE
     conditional vs non-compliant 1,136 / 1,097       1,191 / 1,061   WCAG
                                 19,003 / 23,204     14,342 /  8,150  dE

     Flaeche gegen Wirt           neues Design        altes Design
     compliant                    1,225 / 1,061       1,289 / 1,139   WCAG
                                 28,326 / 16,435     14,930 /  9,771  dE
     conditional                  1,188 / 1,076       1,331 / 1,133   WCAG
                                 28,473 / 23,656     15,943 /  9,730  dE
     non-compliant                1,046 / 1,180       1,118 / 1,203   WCAG
                                 18,837 / 12,023     10,557 / 10,710  dE

   BEFUND FUER DIE SPEC, wie im Auftrag verlangt: gemessen an der Schwelle
   1,2:1 liegt die MEHRHEIT der Paare darunter -- alle drei Flaechenpaare
   in beiden Themes (1,014..1,172) und FUENF der sechs
   Flaeche-gegen-Wirt-Werte (1,046 / 1,061 / 1,076 / 1,180 / 1,188; nur
   compliant/dunkel liegt mit 1,225 darueber). Das gilt aber fuer das ALTE Design genauso
   (dort 1,004..1,331, ebenfalls meist unter 1,2), es ist also KEIN
   Rueckschritt, sondern eine Eigenschaft getoenter Statusflaechen.
   In der Einheit, die die Frage beantworten kann, ist das Ergebnis
   eindeutig und in JEDEM der zwoelf Vergleiche besser als vorher: der
   kleinste Farbabstand des neuen Designs (12,023) liegt ueber dem
   groessten Randfall des alten (10,710 gegen den Wirt, 8,150 zwischen
   zwei Flaechen) und beim Fuenffachen der Wahrnehmungsschwelle. Die
   Trennung steht im Farbton, nicht in der Helligkeit -- deshalb sagt das
   WCAG-Verhaeltnis dazu nichts.

   WAS DER RAHMEN WERT WAR, ehrlich gerechnet -- UND EINMAL FALSCH
   GERECHNET. Eine erste Fassung dieses Kommentars hat die Rahmenfarbe
   (Alpha 0,28) direkt ueber dem WIRT kompositiert. Das ist falsch:
   "background-clip" steht per Voreinstellung auf "border-box", die
   halbdurchsichtige Flaeche (Alpha 0,12) liegt also UNTER dem Rahmen. Der
   Rahmen kompositiert ueber Flaeche UND Wirt, und das macht ihn
   dunkler/saettigter, nicht heller. Beide Modelle nachgerechnet, an der
   Dropdownzeile:
                        dE dunkel        dE hell         WCAG bis
     falsches Modell    26,178..35,185   23,000..25,675  2,089
     richtiges Modell   34,562..44,858   30,203..34,089  2,667

   ER WAR ALSO LEGACYS STAERKSTE KANTE, und deutlicher als zuerst
   berichtet. Die neue Flaeche allein erreicht 18,837..28,473 (dunkel) und
   12,023..23,656 (hell), bleibt also unter der alten Rahmenkante, liegt
   aber deutlich ueber der alten Flaeche. Kurz: Figmas Entscheidung kostet
   Kante und gewinnt Flaeche. Das ist eine Abwaegung, kein Fehler -- und
   sie gehoert in die Sichtpruefung, weil sie sich rechnerisch nicht
   entscheiden laesst.
   DER FEHLER GING ZU GUNSTEN DER EIGENEN AUSSAGE, und deshalb steht er
   hier: unter den falschen Zahlen war der Satz "die neue Flaeche bleibt
   unter der alten Kante" NICHT wahr -- 28,473 uebertraf die schwaechste
   berichtete Kante 26,178. Erst das richtige Modell traegt ihn (28,473
   gegen 34,562). Wer halbdurchsichtige Rahmen misst, muss die Flaeche
   darunter mitrechnen.

   WIRTUNABHAENGIGKEIT -- selbst ein Ergebnis, kein Messdetail. Legacys
   Flaechen sind halbdurchsichtig (Alpha 0,12), ihre Farbe haengt also
   davon ab, worauf der Marker liegt: dieselbe compliant-Flaeche misst im
   alten Design rgb(31,55,54) in der Dropdownzeile, rgb(21,42,40) in der
   Auswahlzeile -- und damit auch in der Galeriekachel, die genau diesen
   Wirt traegt --, rgb(28,50,45) in der Personenkarte und rgb(18,39,38)
   auf der NACKTEN Kachelflaeche, also in dem Zustand, den die Kachel
   gerade nicht mehr hat, weil der Wirt bewusst eingebaut ist. Die neuen
   Flaechen sind deckend und ueberall rgb(18,48,30).

   TEXTKONTRAST -- HIER HEILT DAS NEUE DESIGN EINEN ECHTEN WCAG-FEHLER.
   Text auf eigener Flaeche, gemessen (dunkel / hell):
                     neues Design         altes Design
     compliant        11,095 /  4,567      7,240 / 2,784
     conditional      12,255 /  6,367      8,474 / 2,704
     non-compliant     6,062 /  5,296      3,866 / 3,863
   Das alte Design verfehlt im HELLEN Theme die 4,5 aus WCAG 1.4.3 an
   allen drei Zustaenden (2,704..3,863) und im dunklen an einem (3,866).
   Das neue erfuellt sie ueberall; der knappste Wert ist 4,567.
   KEIN ZIELPAAR DIESES TASKS LIEGT UNTER DER SCHWELLE -- anders als in
   Task 3, wo Figmas Aktivpaar 2,971 mass und deshalb im hellen Theme
   nicht ausgeliefert wurde. Hier war keine Abweichung noetig.
   Was die 3,0 fuer UI-Komponenten (WCAG 1.4.11) angeht: die Flaeche gegen
   den Wirt erreicht sie in KEINEM der beiden Designs (neu 1,046..1,356,
   alt 1,110..1,331) -- UND AUCH LEGACYS RAHMENKANTE NICHT: richtig
   gerechnet kommt sie auf 1,563..2,667 (dunkel) und 1,483..1,801 (hell),
   ueber alle drei Wirte gemessen 1,460..2,667. Es gibt hier also keinen
   Rueckschritt zu heilen, und das ist das Argument: der Rahmen hat die
   Schwelle auch nie erreicht. Die Aussage steht ohnehin nicht in der
   Flaeche, sondern im Text (Kontrast >= 4,567) und in dessen Farbe, deren
   Abstaende untereinander bei dE 27,4..104,7 liegen. Befund gemeldet,
   nicht geheilt: eine Heilung hiesse, Figmas Flaechenpaare zu verwerfen.

   -- WAS IM ALTEN DESIGN NICHT NACHWEISBAR IST --
   Fuer jede der 13 neuen Deklarationen wurde im alten Design derselbe
   Selektor OHNE Praefix hinter components.css nachgeladen -- also an
   genau der Stelle der Kaskade, an der sie stuende, wenn jemand den
   Praefix verloere. ZWOELF bewegen dort etwas und sind im Test
   zugesichert. EINE nicht:
     .persona-card .llm-gdpr-badge { padding: 1px 5px }  Sie holt Legacys
       eigenen Wert zurueck; im alten Design steht er ohnehin. Ein
       verlorener Praefix bliebe an dieser einen Deklaration unentdeckt.
   Das steht hier, statt dass der Leck-Waechter eine Abdeckung behauptet,
   die er nicht hat.

   -- ZWEI BEFUNDE FUER DIE EIGENTUEMER DER VORLAGE --
   BEFUND 1 -- DIE ZWEITE DSGVO-FAMILIE IST AB JETZT DIE EINZIGE STELLE
   UNTER 4,5. Die Modellkarte zeigt denselben Sachverhalt ueber
   ".dgsvo-label" und den Farbstreifen ".model-card-accent"
   (webapp.css:4450-4468, erzeugt in organismsmodelselectioncard.js:44/55,
   ein einziger Verwender: organisationllmconfig.js:206) -- ebenfalls
   dreizustaendig, aber mit anderem Klassennamen ("noncompliant" ohne
   Bindestrich), anderem Text, 10px statt 11px und OHNE Flaeche.
   DASS SIE ANDERS GEFAERBT IST, IST KEIN BEFUND: sie traegt
   --clr-success/-warning/-danger auf dem Seitengrund, der Marker das
   "-on-bg" auf seiner Flaeche. Genau dafuer ist ein Tokenpaar da.
   DER BEFUND IST DER KONTRAST -- UND DIE METHODE GEHOERT DAZU.
   ".dgsvo-label" steht ohne eigene Flaeche direkt auf dem Kartengrund,
   und der ist ein VERLAUF: webapp.css:4421 setzt --card-gradient,
   webapp.css:225 definiert ihn als linear-gradient(135deg,
   --clr-surface-1, --clr-surface-2) ueber eine 230x250-Karte
   (:4419-4420). Ein Verlauf hat keine gerechnete Farbe; getComputedStyle
   meldet dort nichts, und wer stattdessen --clr-surface-1 nimmt, misst
   den ANFANG des Verlaufs statt die Stelle, an der die Beschriftung
   steht. Deshalb stehen hier BEIDE Reihen (je dunkel / hell):

   (a) FLACH gegen --clr-surface-1:
                     neues Design         altes Design
     compliant        10,735 /  3,296      9,927 / 3,296
     conditional      12,973 /  3,186     11,997 / 3,186
     noncompliant      4,971 /  4,829      4,597 / 4,829

   (b) GERASTERT an der Stelle der Beschriftung -- und der
   Verlaufsparameter ist hergeleitet, nicht geraten: die Gradientenlinie
   misst 230*sin(135) + 250*|cos(135)| = 339,41px, die Beschriftung sitzt
   rechtsbuendig in der zweiten Zeile von ".model-card-header"
   (padding 10px 12px 6px, :4455), also bei x ~ 170..220 und y ~ 30..50.
   Das ergibt t = 0,417..0,562:
                     neues Design              altes Design
     compliant     10,26..10,36 / 3,220..3,242   9,51.. 9,61 / 3,213..3,238
     conditional   12,40..12,52 / 3,113..3,134  11,50..11,62 / 3,105..3,130
     noncompliant   4,75.. 4,80 / 4,719..4,751   4,41.. 4,45 / 4,708..4,745

   ES GILT (b). (a) steht nur da, weil eine fruehere Fassung dieses
   Kommentars BEIDE METHODEN IN EINER TABELLE mischte: die Spalte "neues
   Design" war (a), die Spalte "altes Design" war (b). Nachgerechnet
   trifft die alte Spalte den Verlauf bei t ~ 0,68 (hell: rgb(250,251,255),
   Abweichung 0,0002 ueber alle drei Zustaende) -- sie war also sehr wohl
   gerastert, nur die neue nicht. Aus genau dieser Mischung entstand der
   Satz "das neue Design ist um rund 0,10 besser": 3,296 (flach) minus
   3,187 (gerastert). UNTER EINER METHODE gibt es diesen Vorsprung im
   hellen Theme nicht -- flach ist er 0,000 (beide Designs haben dort
   dasselbe Weiss, webapp.css:280 gegen --ax-ink-0, und dieselben drei
   Textfarben #16a34a/#d97706/#dc2626, webapp.css:356/358/369 gegen
   --ax-green-600/-amber-600/-red-600), gerastert +0,02..+0,03. Im
   dunklen Theme ist er real (+0,75..+0,89), dort unterscheiden sich die
   Flaechen (#161b22 gegen --ax-ink-900).

   DIE AUSSAGE BLEIBT DIESELBE: im HELLEN Theme verfehlen "compliant" und
   "conditional" WCAG 1.4.3 in BEIDEN Designs (3,105..3,242 gegen 4,5);
   im dunklen erfuellen alle drei die Schwelle (knappster Wert 4,41).
   Da dieser Task denselben Fehler am MARKER geheilt hat (dort jetzt
   4,567..12,255, opake Flaechen und deshalb ohne Rastern messbar), ist
   die Modellkarte ab sofort die einzige Stelle, an der die
   DSGVO-Aussage unter 4,5 bleibt. Das ist der Adressat des Befunds.
   NICHT ANGEFASST: die Familie steht in Figmas Zuordnungstabelle nicht,
   ein Selektor hat einen Eigentuemer -- dieselbe Lage wie bei der
   Badge-Familie des Workflow-Editors (Spec, Abschnitt 7, Punkt 7).
   BEFUND 2 -- EIN MARKER OHNE ZUSTANDSKLASSE BLEIBT FARBLOS.
   organismsorchestrationtimeline.js:112 setzt die Klasse aus einem
   Serverwert ("step.gdpr"). Trifft der keinen der drei Namen, greift
   keine Zustandsregel -- in BEIDEN Designs, denn Legacys Grundregel
   faerbt ebenfalls nicht. Vorbestehend, unveraendert, gemeldet. */
[data-design="new"] .llm-gdpr-badge {
  padding: 4px 8px;
  border-radius: var(--ax-radius-sm);
  line-height: 14px;
}

/* Die drei Zustandsregeln liegen bei (0,3,0) und schlagen Legacys
   (0,2,0)-Zustandsregeln ueber die Zahl statt ueber die Ladereihenfolge --
   ausfuehrlich im Kopf dieses Abschnitts. "border: none" steht deshalb
   dreimal hier und nicht einmal in der Grundregel. */
[data-design="new"] .llm-gdpr-badge.compliant {
  background: var(--ax-status-success-bg);
  color: var(--ax-status-success-on-bg);
  border: none;
}

/* DER ZUSTAND, DEN FIGMA NICHT KENNT. Warning-Paar, siehe Schritt 1. */
[data-design="new"] .llm-gdpr-badge.conditional {
  background: var(--ax-status-warning-bg);
  color: var(--ax-status-warning-on-bg);
  border: none;
}

[data-design="new"] .llm-gdpr-badge.non-compliant {
  background: var(--ax-status-danger-bg);
  color: var(--ax-status-danger-on-bg);
  border: none;
}

/* Legacys Wert woertlich zurueckgeholt (webapp.css:12203), gegen den
   Gleichstand mit der Grundregel oben. Begruendung im Kopf des
   Abschnitts, Punkt 2 der Spezifitaetsrechnung. */
[data-design="new"] .persona-card .llm-gdpr-badge {
  padding: 1px 5px;
}

/* ══ 05 · Data, Teil B — Task 5: Die Modellzeile ══════════════════
   Figma-Knoten 15:116 (Model Picker Row): Hoehe 68, Radius 10, Flaeche
   --ax-bg-input, Rahmen 1px solid --ax-border-default, Innenabstand
   12px 16px, Abstand 16px. Inhalt: DSGVO-Marker, Anbieter (Medium 12,
   --ax-text-muted) UEBER Modellname (Semi Bold 15, --ax-text-primary),
   Faehigkeits-Chips, Kostenanzeige.

   Erzeugt wird das Bauteil per Template-Literal in
   organismsllmproviderselector.js -- _updateSelectedDisplay() (:522-563)
   fuer das geschlossene Auswahlfeld, _buildDropdownItems() (:567-627)
   fuer die Zeilen der aufgeklappten Liste. organismspersonaselect.js
   nutzt DIESELBEN Klassen fuer den Persona-Selektor; der CSS-Kommentar
   des Bestands vermerkt das ausdruecklich als Absicht (webapp.css:
   7232-7233). Alle Zahlen unten sind im vollen Stapel gemessen
   (Chromium, 1280x900, beide Designs, beide Themes), an nachgestellten
   Produktknoten und an den drei Galeriekacheln gegengeprueft -- und alle
   125 Zusicherungen der Testbloecke zusaetzlich bei 1280x720, der
   Voreinstellung des Playwright-Laufs.

   ── SCHRITT 1: WELCHE DER BEIDEN FASSUNGEN IST FIGMAS ZEILE? ──
   Der Bestand baut die Zeile zweimal. Die EINZEILIGE Fassung setzt
   Anbieter und Modellname in EINEN Textknoten ("${providerName} –
   ${model.name}", :559/:624); die DREIZEILIGE Fassung des
   .compact-Zweigs (webapp.css:7420-7492) gibt dem Anbieter ein eigenes
   Element (".llm-model-provider") und stapelt Anbieter, Modellname und
   eine Metazeile.

   BESTIMMT, NICHT GERATEN -- zwei Zahlenreihen, beide im Messaufbau
   aufgebaut und gegen Figmas Masse gerechnet:

   (1) DIE HOEHE 68. Figmas Kasten ist 1 + 12 + Inhalt + 12 + 1. Der
       Inhalt muss also 42 hoch sein. Gemessen, mit Figmas Kasten auf
       beiden Fassungen:
         einzeilige Fassung, Zeile              48,00   (-20,00 zu 68)
         einzeilige Fassung + Name 15/600/24    50,00   (-18,00)
         Kompaktzweig, Zeile                    85,44   (+17,44)
         Kompaktzweig + Figmas Typografie       89,14   (+21,14)
       Keine der vier trifft. Mit Figmas ZWEI Schriftgroessen auf den
       zwei Zeilenkaesten des Tokensatzes -- Anbieter 12 auf 18
       (= --ax-line-height-label-md), Modellname 15 auf 24
       (= --ax-line-height-body-md, das Paar zu --ax-font-size-body-md:
       15px) -- und Stapelabstand 0 misst der Stapel exakt
       18 + 24 = 42,00 und die Zeile exakt 68,00. AUF DEN PIXEL, in
       beiden Themes. Die einzeilige Fassung kommt mit derselben
       Typografie auf 50,00 und kann die 42 gar nicht erreichen: sie hat
       nur EINE Zeile.
   (2) DIE TRAEGER. Von Figmas sechs Sollwerten haben im Kompaktzweig
       alle sechs einen Traeger, in der einzeiligen Fassung nur vier.
       "Anbieter Medium 12" und "Anbieter --ax-text-muted" haben dort
       KEINEN: der Anbieter steht im selben Textknoten wie der Name.
       Eine Regel darauf traefe beide Haelften -- der Anbieter bekaeme
       Semi Bold 15 statt Medium 12, also das GEGENTEIL von Figmas Wert.
       "Kein Traeger, also keine Regel" (dieselbe Linie wie Befund 3 in
       Task 3).

   ERGEBNIS: FIGMAS ZEILE IST DER .compact-ZWEIG. Seine Typografie
   bekommt deshalb Figmas Werte, die der einzeiligen Fassung bleibt
   unangetastet -- ausfuehrlich unter "Was NICHT geregelt wird".

   DAS ENTSCHEIDENDE GEGENARGUMENT, UND ES BLEIBT STEHEN: FIGMAS 68 IST
   IM KOMPAKTZWEIG UNERREICHBAR. Beide Template-Literale setzen
   ".llm-model-meta" im Kompaktmodus IMMER (:545-548 und :608-611); das
   Feld misst dort gemessen 92, die Zeile 91. Die 68 entstehen dort nur,
   wenn man die Metazeile ausblendet -- also in einem Zustand, den das
   Produkt nie zeigt. Die Fassung, die HEUTE wirklich 68 rendert, ist die
   EINZEILIGE (gemessen 68,00, siehe naechster Absatz).
   Diese Zuordnung liefert Figmas TYPOGRAFIE also dorthin, wo Figmas
   HOEHE nie erscheint, und Figmas HOEHE dorthin, wo Figmas Typografie
   keinen Traeger hat. Das ist eine Abwaegung und keine saubere
   Eins-zu-eins-Zuordnung -- die Traegerfrage (2) wiegt schwerer als die
   Hoehe (1), weil eine Regel ohne Traeger gar nicht erst geschrieben
   werden kann. Die Metazeile ist Markup und gehoert einem spaeteren
   Task; bis dahin steht der Unterschied hier und in der Sichtpruefung.

   EINE ZWEITE ZAHL, DIE AUCH AUF 68 KOMMT, und sie steht hier, weil sie
   gegen die eigene Wahl spricht: das geschlossene Auswahlfeld der
   EINZEILIGEN Fassung misst mit Figmas Innenabstand ebenfalls exakt
   68,00 -- aus Legacys eigenem "min-height: 42px" (webapp.css:7165) plus
   2 x 12 Innenabstand plus 2 x 1 Rahmen. Das ist kein Gegenbeweis,
   sondern ein Zusammentreffen: die 42 stehen in Legacys Regel, nicht in
   Figmas Knoten, und sie sagen ueber den Anbieter nichts. Die Wahl faellt
   ueber (2), nicht ueber (1) allein.

   DIE GROSSSCHREIBUNG ENTFAELLT. webapp.css:7441 setzt am Anbieter
   "text-transform: uppercase; letter-spacing: 0.4px"; Figmas Knoten
   zeigt beides nicht. Gemessen, was das Zuruecknehmen bringt (Inter,
   12px/500):
     "OpenAI"                  42,67 statt 47,39   (-10,0 %)
     "Google Vertex AI"        96,34 statt 121,94  (-21,0 %)
     "Microsoft Azure OpenAI" 137,44 statt 172,14  (-20,2 %)
   Der Kompaktzweig ist fuer SCHMALE Wirte gebaut (Projektleiste,
   Dialoge); dort ist ein um ein Fuenftel schmalerer Anbietername kein
   Nebeneffekt, sondern der Zweck des Zweigs.

   ── SCHRITT 2: WAS SICH AM PERSONA-SELEKTOR AENDERT ──
   organismspersonaselect.js baut ".llm-selector.persona-selector" mit
   ".llm-selector-selected" und ".llm-selector-item" -- OHNE ".compact",
   ohne Filterkopf, ohne ".llm-model-provider" und ohne
   ".llm-model-name": im Inhalt steht ein Emoji, der Personenname, ein
   Modellname als roher Text und ein DSGVO-Marker, alles in EINEM
   ".llm-model-info" (:173-187, :232-250). Von den sechs Regeln dieses
   Tasks treffen ihn deshalb genau ZWEI -- die beiden ohne ".compact".
   Gemessen (dunkel / hell identisch):
     Auswahlfeld     46,00 -> 48,00   Innenabstand 9/12 -> 12/16,
                                      Radius 4 -> 10, Abstand 10 -> 16
     Listenzeile     39,00 -> 45,00   Innenabstand und Abstand wie oben,
                                      als letzte Zeile 38,00 -> 44,00
   DAS FELD BLEIBT BEI 48 UND ERREICHT FIGMAS 68 NICHT, und das ist kein
   Versehen: ".persona-selector .llm-selector-selected" (webapp.css:7495)
   setzt "box-sizing: border-box". Legacys "min-height: 42px" ist dort
   also eine Untergrenze fuer den RAHMENkasten und nicht fuer den
   Inhaltskasten -- 42 gegen 22 + 24 + 2 = 48 gewinnt der Inhalt. In der
   einzeiligen Modellzeile ist derselbe Kasten "content-box", dort
   ergibt dieselbe Untergrenze 42 + 24 + 2 = 68. Zwei Bauteile, eine
   Regel, zwei Hoehen. Gemeldet, nicht geheilt: Figmas Knoten meint die
   Modellzeile, und ".persona-selector" hat einen anderen Eigentuemer.
   DER GLEICHSTAND DAZU IST AUSGERECHNET: jene Regel liegt bei (0,2,0),
   die neue ".llm-selector-selected"-Regel ebenfalls. Sie ueberschneiden
   sich in KEINER Deklaration (dort "width" und "box-sizing", hier
   Innenabstand, Abstand, Radius und Flaeche), der Gleichstand bleibt
   also folgenlos -- aber er steht hier, weil ein ungenannter
   Gleichstand in Task 4 beinahe eine bewusste Verdichtung aufgehoben
   haette.

   ── DER BESTAND, EIGENSCHAFT FUER EIGENSCHAFT ──
   ".llm-selector-item" (webapp.css:7209), sechs Deklarationen:
     display: flex          -> UEBERNOMMEN, nicht wiederholt. Figmas
     align-items: center       Zeile ist eine waagerechte Reihe mit
       mittig sitzenden Gliedern; der Bestand steht schon so. WAECHTER.
     gap: 10px              -> ERSETZT durch Figmas 16px.
     padding: 9px 12px      -> ERSETZT durch Figmas 12px 16px.
     cursor: pointer        -> UEBERNOMMEN, unangefochten. WAECHTER.
     border-bottom: 1px solid var(--clr-border)  -> UEBERNOMMEN, und das
       ist ein BEFUND statt einer Regel: "--clr-border" haengt seit
       Schritt 1 auf "--ax-border-default" (tokens.css:151/223), die
       Trennlinie traegt Figmas Rahmenfarbe also bereits. Gemessen
       rgb(36, 34, 51) im dunklen, rgb(210, 208, 218) im hellen Theme --
       beides der Wert von --ax-border-default. Eine Regel dafuer waere
       eine Zeile ohne Wirkung. WAECHTER.
   ".llm-selector-selected" (webapp.css:7156), zehn Deklarationen:
     display/align-items/gap/padding wie oben.
     background: var(--background-color-input)  -> ERSETZT durch Figmas
       --ax-bg-input. Die Bruecke fuehrt hier NICHT zu Figmas Wert:
       "--background-color-input" haengt auf "--clr-shell"
       (webapp.css:186), und "--clr-shell" ist ein color-mix() aus
       --clr-base und --clr-surface-1 (webapp.css:15/277), das in
       tokens.css nirgends umgehaengt wurde. Gemessen stand das Feld im
       neuen Design auf rgb(13, 12, 22) dunkel; Figmas --ax-bg-input ist
       rgb(26, 24, 38).
     border: 1px solid var(--editborder)  -> UEBERNOMMEN. "--editborder"
       haengt auf "--clr-border" und damit auf --ax-border-default
       (webapp.css:189, tokens.css:151/223): Figmas Rahmen steht bereits
       da, in Breite, Art und Farbe. Gemessen rgb(36, 34, 51) dunkel und
       rgb(210, 208, 218) hell. Eine Wiederholung waere eine Zeile ohne
       Aussage. WAECHTER -- und der eigentliche Befund dieses Bauteils:
       von Figmas Kasten war der Rahmen schon fertig.
     border-radius: 4px     -> ERSETZT durch var(--ax-radius-md) = 10px.
     min-height: 42px       -> UEBERNOMMEN, und sie ist der Grund, warum
       die einzeilige Fassung ueberhaupt auf 68 kommt (siehe Schritt 1).
       WAECHTER.
     cursor/transition/user-select -> UEBERNOMMEN, unangefochten.

   ── WAS NICHT GEREGELT WIRD, UND WARUM ──
   1. KEINE FLAECHE, KEIN RAHMEN, KEIN RADIUS AUF DER LISTENZEILE.
      Figmas Knoten traegt alle drei; im Produkt hat sie EIN Traeger,
      naemlich das geschlossene Auswahlfeld. Die Listenzeile steht in
      der Huelle ".llm-selector-dropdown", die ihrerseits Flaeche
      (--background-color-card), Rahmen und Radius traegt. Gemessen,
      warum eine Fuellung dort nichts brächte: Figmas --ax-bg-input
      steht gegen genau diese Huellenflaeche bei einem Farbabstand von
      dE 0,893 (dunkel) und 1,449 (hell) -- beides UNTER der
      Wahrnehmungsschwelle von 2,3. Vierzig gefuellte Zeilen in einer
      Huelle derselben Farbe waeren vierzig unsichtbare Karten; der
      Radius dagegen waere sichtbar und wuerde die Zeilenhervorhebung
      beim Zeigen und die Markierung der ausgewaehlten Zeile
      (webapp.css:7223/7227, beide vollflaechig) zu Pillen abrunden.
      Entschieden: die Zeile bekommt Figmas RHYTHMUS (Innenabstand,
      Abstand), das Feld bekommt Figmas KASTEN. Das Bauteil zerfaellt
      dabei NICHT: ".llm-selector.compact .llm-selector-selected" traegt
      Figmas Kasten (Regeln 2 und 3) UND ueber seine Kinder Figmas Inhalt
      (Regeln 5 und 6) -- es ist die vollstaendige Figma-Zeile. Nur die
      LISTENZEILE bekommt bloss den Rhythmus.
      EINE WARNUNG ZUR OBIGEN BEGRUENDUNG: die Huellenflaeche
      "--background-color-card" haengt auf "--clr-surface-mid"
      (webapp.css:181), und das ist ein UNGEBRUECKTES Legacy-Token --
      tokens.css haengt es nirgends auf einen --ax-Wert um. Die 0,893
      sind also ein ZUFALL zweier unabhaengiger Farben, keine
      Entwurfsentscheidung. Haengt jemand das Token spaeter um, ist diese
      Begruendung weg und die Frage neu zu stellen.
   2. KEINE REGEL AUF ".llm-model-name" IN DER EINZEILIGEN FASSUNG.
      Begruendung in Schritt 1, Punkt (2): das Element traegt dort
      Anbieter UND Namen. Seine Farbe ist ohnehin schon Figmas Wert --
      "--clr-text-primary" haengt auf "--ax-text-primary"
      (tokens.css:159/229), gemessen rgb(232, 230, 238) dunkel und
      rgb(18, 17, 28) hell. WAECHTER.
   3. KEINE FARBE AM MODELLNAMEN DES KOMPAKTZWEIGS. Dieselbe Bruecke,
      derselbe Wert. Figmas --ax-text-primary steht schon da; die Regel
      unten setzt deshalb nur Groesse, Gewicht und Zeilenkasten.
      WAECHTER.
   4. KEINE REGEL AUF ".llm-model-meta", ".llm-token-factor" UND
      ".llm-selector-arrow". Figmas Knoten nennt fuer die Kostenanzeige
      keinen eigenen Wert, kennt die Metazeile nicht (dazu gleich) und
      hat fuer den Pfeil kein Gegenstueck.
   5. KEINE FAEHIGKEITS-CHIPS IN DIESER ZEILE. Figmas Knoten zeigt
      welche; das Produkt setzt in der Modellzeile keine (".cap-chip"
      kommt ausschliesslich in der Modellkarte vor,
      organismsmodelselectioncard.js:76/80). Deren Gestalt gehoert
      ohnehin Task 3 -- ein Selektor, ein Eigentuemer.
   6. KEINE REGEL AUF ".llm-selector-dropdown" -- UND EIN BEFUND DAZU.
      Die Huelle behaelt ihren Radius 4 (webapp.css:7190-7191), waehrend
      das Feld darueber jetzt 10 traegt. Der Bruch sitzt gemessen an den
      UNTEREN Huellenecken: im geoeffneten Zustand misst das Feld oben
      10/10 und unten 0/0 (die Open-Regel quadriert es korrekt,
      webapp.css:7174), die Huelle oben 0/0 und unten 4/4. Sichtbar ist
      also die untere Kante des aufgeklappten Blocks.
      NICHT GEHEILT: ".llm-selector-dropdown" steht in keiner
      Zuordnungstabelle der Spec und hat einen anderen Eigentuemer. Die
      Heilung waere ein Zweizeiler fuer einen spaeteren Task -- die
      beiden unteren Radien der Huelle auf var(--ax-radius-md), dazu die
      beiden oberen fuer den Zweig ".open-up" (webapp.css:7201-7202).

   ── DIE EINE STELLE, AN DER DAS PRODUKT FIGMAS AUFBAU NICHT HAT ──
   Figma setzt DSGVO-Marker und Kostenanzeige NEBEN den Stapel, in
   dieselbe waagerechte Reihe. Der Kompaktzweig setzt sie DARUNTER, in
   eine dritte Zeile (".llm-model-meta", erzeugt in :545-548/:608-611).
   Das ist Markup, nicht Gestaltung, und dieser Task fasst keinen
   Produktionscode an. Die Folge ist gemessen und gehoert in die
   Sichtpruefung:
     Kompaktzweig, Zeile mit Metazeile        91,00  (Legacy 84,44)
       dieselbe Zeile als letzte einer Liste   90,00  (Legacy 83,44)
       -- ":last-child" nimmt ihr die Trennlinie (webapp.css:7219)
     Kompaktzweig, Feld ohne Metazeile         68,00  <- Figmas Zahl
     Kompaktzweig, Auswahlfeld mit Metazeile   92,00  (Legacy 85,44)
   Der Zweizeilenteil des Stapels trifft Figmas 42 exakt; die dritte
   Zeile legt 24 drauf (22 Metazeile + 2 "margin-top", webapp.css:7466).
   In einer 210px schmalen Leiste -- dem Wirt, fuer den der Zweig gebaut
   wurde -- haengt der Zuwachs am Modellnamen, und der schlimmere Fall
   gehoert hierher, nicht der freundlichere (alle bei 210px gemessen):
     "gpt-4o"                          85,44 ->  92,00   + 7,7 %
     "gemini-2.5-flash-preview-05-20" 100,69 -> 115,00   +14,2 %
       (bricht in BEIDEN Designs auf zwei Zeilen)
     "gpt-4o-mini-2024-07-18"          84,44 -> 115,00   +36,2 %
       (bricht NUR im neuen Design um -- 13px passen, 15px nicht)
   Das ist der Preis von Figmas groesserer Schrift, und er ist sichtbar.

   ── SPEZIFITAETEN, AUSGERECHNET UND NACHGESTELLT ──
     .llm-selector-item                                  (0,1,0) webapp:7209
     .llm-selector-item:hover / .selected                (0,2,0) webapp:7223/7227
     .llm-selector-selected                              (0,1,0) webapp:7156
     .llm-selector-selected:hover                        (0,2,0) webapp:7170
     .persona-selector .llm-selector-selected            (0,2,0) webapp:7495
     .llm-selector.open .llm-selector-selected           (0,3,0) webapp:7174
     .llm-selector.compact .llm-selector-selected,
       .llm-selector.compact .llm-selector-item          (0,3,0) webapp:7424
     .llm-selector.compact .llm-model-info               (0,3,0) webapp:7433
     .llm-selector.compact .llm-model-provider           (0,3,0) webapp:7441
     .llm-selector.compact .llm-model-name               (0,3,0) webapp:7452
     [data-design="new"] .llm-selector-item              (0,2,0) unten
     [data-design="new"] .llm-selector-selected          (0,2,0) unten
     [data-design="new"] .llm-selector.compact …         (0,4,0) unten
   ZU KEINEM DIESER SELEKTOREN GIBT ES IM BESTAND EINE
   [data-theme="light"]-REGEL -- ueber alle CSS-Dateien geprueft, nicht
   angenommen. Der Gleichstandstyp, der in Task 4 an der Personenkarte
   beinahe zugeschlagen haette, kommt hier also in seiner
   THEME-Auspraegung gar nicht vor.
   GLEICHSTAENDE BEI (0,2,0) GIBT ES TROTZDEM VIER, und die Tabelle
   darueber listet sie alle -- eine fruehere Fassung dieses Satzes sprach
   von EINEM und widersprach damit ihrer eigenen Tabelle:
     .persona-selector .llm-selector-selected  (width, box-sizing)
     .llm-selector-selected:hover              (border-color)
     .llm-selector-item:hover                  (background)
     .llm-selector-item.selected               (background)
   ALLE VIER SIND FOLGENLOS, weil keine neue Regel eine ihrer
   Deklarationen anfasst: die neue ".llm-selector-selected"-Regel setzt
   Innenabstand, Abstand, Radius und Flaeche, die neue
   ".llm-selector-item"-Regel Innenabstand und Abstand. Nachgemessen
   behalten Hover und Auswahl ihre Flaechen (rgb(27, 26, 40) beim Zeigen,
   rgb(36, 34, 51) markiert, dunkel) und das Feld seine Hover-Rahmenfarbe.
   Der erste ist der interessante: er ist der Grund, warum der
   Persona-Selektor Figmas 68 nicht erreicht (Schritt 2).
   DREI (0,4,0)-REGELN, UND DIE ZAHL IST NOETIG, nicht vorsorglich: der
   .compact-Zweig deklariert "padding-top"/"padding-bottom" (nicht die
   Kurzform), den Stapelabstand und die Typografie bei (0,3,0). Eine
   (0,2,0)-Regel verloere gegen ihn ueber die ZAHL und nicht ueber die
   Ladereihenfolge -- gemessen bliebe der Kompaktzweig sonst bei 10px
   oben und unten, bei Stapelabstand 3 und bei Grossschreibung.
   NACHGESTELLT: laedt man Legacys ".llm-selector.compact
   .llm-model-provider" woertlich HINTER components.css, bleibt der
   Anbieter mit den Regeln unten bei 12px/500/18px ohne
   Grossschreibung. Mit denselben Deklarationen in einer
   (0,3,0)-Fassung kippt derselbe Aufbau zurueck auf 11px/13,2px mit
   "uppercase" und 0,4px Laufweite -- nur das Gewicht 500 ueberlebt, weil
   Legacys Regel keins deklariert. Alle drei Faelle gemessen.

   ── DER ANBIETER: FIGMAS FARBE WIRD NICHT AUSGELIEFERT ──
   Figmas Knoten bindet fuer den Anbieter --ax-text-muted. Gemessen,
   Text auf dem jeweiligen Untergrund (GERASTERT gelesen, weil Panel- und
   Zeilenflaeche color-mix() sind und getComputedStyle sie als
   "color(srgb …)" mit Kanaelen in 0..1 meldet -- eine erste Fassung
   dieser Messung hat genau daran vier Zahlen verfaelscht):

                          Figmas --ax-text-muted    ausgeliefert
                          dunkel / hell             dunkel / hell
     Auswahlfeld           4,477 /  7,416            7,750 / 12,306
     Listenzeile           4,495 /  7,165            7,775 / 11,899
     Zeile beim Zeigen     4,414 /  7,130            7,608 / 11,826
     Zeile ausgewaehlt     3,984 /  5,998            6,895 /  9,953
     Galeriekachel         4,796 /  7,416            8,301 / 12,306

   MIT FIGMAS TOKEN LIEGEN IM DUNKLEN THEME VIER VON FUENF UNTER DEN 4,5
   AUS WCAG 1.4.3 -- drei knapp (4,414..4,495), eines deutlich (3,984 auf
   der AUSGEWAEHLTEN Zeile, also dort, wo der Nutzer sein aktuelles
   Modell liest). Und es ist ein RUECKSCHRITT, keine ererbte Schwaeche:
   der Bestand faerbt den Anbieter mit --clr-text-secondary und misst
   9,853..12,607 (dunkel) bzw. 8,062..9,529 (hell).
   EINE BEKANNT SCHLECHTE KONTRASTZAHL WIRD NICHT AUSGELIEFERT, auch
   wenn die Vorlage sie vorschreibt -- Ruling 10 aus 06 · Shell & Nav,
   dort als REGEL formuliert und nicht als Einzelanordnung. Derselbe Fall
   wie beim Aktivchip in Task 3.

   DIE HEILUNG IST EINE GELOESCHTE ZEILE, KEINE HINZUGEFUEGTE. Diese
   Regel setzt GAR KEINE Farbe. Damit greift Legacys eigene Regel
   (webapp.css:7443, "color: var(--clr-text-secondary)", (0,3,0)) weiter
   -- und die Bruecke haengt "--clr-text-secondary" im neuen Design
   bereits auf --ax-text-secondary (tokens.css:160/230). Gemessen
   rgb(173, 171, 187) dunkel und rgb(53, 50, 74) hell: punktgenau der
   Wert, der die rechte Spalte oben erzeugt. Kein Theme-Gate, keine
   zusaetzliche Regel, eine Deklaration WENIGER -- und die eine
   var()-Bindung, die im alten Design zur Laufzeit ungueltig geworden
   waere, verschwindet mit.
   DIE RANGFOLGE GEHT DABEI NICHT VERLOREN. Farbabstand Anbieter gegen
   Modellname:
     Bestand (altes Design)      dE  7,364 dunkel / 41,154 hell
     ausgeliefert (neues Design) dE 21,555 dunkel / 18,557 hell
     mit Figmas Token waere es   dE 38,318 dunkel / 31,433 hell
   Figmas Paar traegt im dunklen Theme also real weiter -- aber die
   ausgelieferten 21,555 sind das Neunfache der Wahrnehmungsschwelle 2,3
   und das Dreifache des Bestands. Man bekommt beides: Rangfolge UND 4,5.
   ZU BEACHTEN: die 21,555 sind NICHT der Verdienst dieses Tasks. Sie
   stehen im neuen Design schon durch die Bruecke; was dieser Task zur
   Rangfolge beitraegt, ist der Groessen- und Gewichtsunterschied
   (12/500/18 gegen 15/600/24 statt 11/400/13,2 gegen 13/500/16,25).

   BEFUND FUER DIE EIGENTUEMER DER VORLAGE, schaerfer als "ein Token mit
   Verwendern": --ax-text-muted besteht die 4,5 NUR auf den zwei
   dunkelsten Gruenden (--ax-bg-app 5,043, --ax-bg-surface-1 4,796). Auf
   JEDER erhoehten Flaeche faellt es durch -- --ax-bg-surface-2,
   --ax-bg-input und --ax-bg-elevated je 4,477, --ax-bg-surface-3 und
   --ax-bg-hover je 3,984. Drei weitere Verwender in components.css
   stehen damit unter 4,5 und gehoeren auf die Liste von Task 7:
   ".upload-dropzone p" (:1334), ".nav-rail .chip-collapse" (:2542) und
   ".molecule-table-group-header-summary" (:4723). Nebenbei:
   components.css:2527 dokumentiert die 4,477 bereits -- dort aber als
   VERBESSERUNG (3,733 -> 4,477). Als RUECKSCHRITT von 9,85..12,61 ist
   das Token noch nie ausgeliefert worden; genau das waere hier passiert.

   ── DER KASTEN GEGEN SEINEN UNTERGRUND, UND EIN KORRIGIERTER FEHLER ──
   EINE ERSTE FASSUNG DIESES ABSCHNITTS WAR FALSCH GEMESSEN, und sie hat
   damit eine ausgesprochene SCHLUSSFOLGERUNG verfaelscht, nicht nur eine
   Zahl. Sie las den "Seitengrund" an einem Punkt, der IM FELD lag --
   gemessen wurde also der Rahmen gegen die eigene Flaeche des Feldes,
   und "Flaeche gegen Grund dE 0,000" war eine Farbe gegen sich selbst.
   Vierte Instanz derselben Fehlerklasse in diesem Projekt. Der
   Untergrund wird deshalb jetzt GERASTERT und an einer Stelle gelesen,
   an der er wirklich gemalt wird (1x1-Screenshot, PNG selbst dekodiert,
   800px rechts vom Selektor und weit ueber "body::before",
   webapp.css:507).

                     Grund        Flaeche      Flaeche/Grund   Rahmen/Grund
     neu dunkel      11,10,20     26,24,38     dE  8,020       dE 13,084
     neu hell        244,243,247  255,255,255  dE  4,494       dE 12,544
     alt dunkel      10,14,26     14,18,28     dE  1,582       dE 11,274
     alt hell        238,242,255  232,238,255  dE  2,598       dE 19,826

   WCAG-Verhaeltnis Rahmen gegen Grund: 1,266 / 1,380 (neu),
   1,265 / 1,334 (alt).

   DIESER TASK GIBT DEM FELD IM DUNKLEN THEME ZUM ERSTEN MAL EINE
   SICHTBARE FLAECHE. Figmas --ax-bg-input hebt sich mit dE 8,020
   (dunkel) und 4,494 (hell) vom Seitengrund ab, beides ueber der
   Wahrnehmungsschwelle 2,3; Legacys --clr-shell erreicht 1,582 (dunkel,
   unsichtbar) und 2,598 (hell, an der Grenze). Der Satz der ersten
   Fassung -- "kein Rueckschritt, kein Fortschritt, derselbe Zustand" --
   war falsch, und zwar zuungunsten der eigenen Arbeit.
   STEHEN BLEIBT ALLEIN DIE WCAG-1.4.11-AUSSAGE: die 3,0 fuer
   Bedienelemente erreicht der Rahmen in KEINEM der beiden Designs
   (1,265..1,380). Gemeldet, nicht geheilt -- eine Heilung hiesse,
   --ax-border-default zu verwerfen, und das ist eine Tokenfrage.
   Auf der Galeriekachel (Wirt --ax-bg-surface-1, rgb(18,17,28) dunkel /
   rgb(255,255,255) hell) steht dieselbe Flaeche bei dE 4,531 bzw. 0,000.
   Die Kachel ist also im dunklen Theme ein SCHWAECHERER Zeuge als das
   Produkt (4,531 gegen 8,020) und im hellen gar keiner -- dort ist der
   Kachelgrund derselbe Weisston wie die Feldflaeche. Wer die Trennung
   sehen will, muss auf eine echte Seite schauen; das gehoert in die
   Sichtpruefung.

   ── WAS IM ALTEN DESIGN NICHT NACHWEISBAR IST ──
   Fuer jede der 16 neuen Deklarationen wurde im alten Design derselbe
   Selektor OHNE Praefix hinter components.css nachgeladen -- also an
   genau der Stelle der Kaskade, an der sie stuende, wenn jemand den
   Praefix verloere. ALLE SECHZEHN bewegen dort etwas, und alle
   sechzehn sind im Test zugesichert
   (tests/features/design-marker-kennzahlen.spec.ts, Task-5-Bloecke).
   Es gibt hier also keine unbeweisbare Deklaration -- anders als in
   Task 3 (drei) und Task 4 (eine).
   EINE davon bewegt etwas anderes, als man erwarten wuerde:
     background: var(--ax-bg-input)  Die Variable existiert im alten
       Design nicht (tokens.css:48 bindet sie unter [data-design="new"]).
       Die Deklaration wird dadurch nicht etwa uebersprungen, sondern
       zur Laufzeit ungueltig -- das Feld faellt auf "transparent"
       zurueck und verliert seine Flaeche ganz. Gemessen.
   Sie ist nach der Heilung des Anbieterkontrasts die EINZIGE
   var()-Bindung dieses Tasks auf ein designgegatetes Token; die zweite
   ("color: var(--ax-text-muted)") ist mit der Abweichung entfallen.
   "border-radius: var(--ax-radius-md)" ist der Gegenfall: dieses Token
   steht in einem ungegateten ":root" (tokens.css:352) und gilt in
   BEIDEN Designs. Ein verlorener Praefix zoege dort also den echten
   Wert 10px ins alte Design -- gut sichtbar und zugesichert. */
[data-design="new"] .llm-selector-item {
  padding: 12px 16px;
  gap: 16px;
}

/* Figmas Kasten. Rahmen und "min-height" stehen im Bestand schon richtig
   und werden nicht wiederholt (Begruendung oben); die 68 entstehen aus
   Legacys "min-height: 42px" plus diesem Innenabstand plus dem Rahmen. */
[data-design="new"] .llm-selector-selected {
  padding: 12px 16px;
  gap: 16px;
  border-radius: var(--ax-radius-md);
  background: var(--ax-bg-input);
}

/* (0,4,0) gegen den .compact-Zweig bei (0,3,0). Legacy deklariert dort
   "padding-top"/"padding-bottom" einzeln (webapp.css:7427-7428); die
   Kurzform der Regel oben liegt bei (0,2,0) und verloere gegen sie. */
[data-design="new"] .llm-selector.compact .llm-selector-selected,
[data-design="new"] .llm-selector.compact .llm-selector-item {
  padding: 12px 16px;
}

/* Der Stapelabstand geht auf 0. Die Zeilenkaesten 18 und 24 tragen den
   Abstand selbst und ergeben zusammen Figmas Inhaltshoehe 42; Legacys
   3px machten daraus 45 und das Feld ohne Metazeile 71 statt 68.
   Gemessen. */
[data-design="new"] .llm-selector.compact .llm-model-info {
  gap: 0;
}

/* Der Anbieter. Groesse und Zeilenkasten sind die Tokenwerte
   --ax-font-size-label-sm (12px) und --ax-line-height-label-md (18px),
   hier als Zahl geschrieben wie in den Tasks 1, 3 und 4. Die
   Grossschreibung und die Laufweite des Bestands werden ausdruecklich
   zurueckgenommen -- Figmas Knoten zeigt beides nicht. */
[data-design="new"] .llm-selector.compact .llm-model-provider {
  font-size: 12px;
  font-weight: 500;
  line-height: 18px;
  text-transform: none;
  letter-spacing: normal;
}

/* Der Modellname. 15px und 24px sind das Tokenpaar
   --ax-font-size-body-md / --ax-line-height-body-md. Keine Farbe:
   "--clr-text-primary" haengt bereits auf --ax-text-primary. */
[data-design="new"] .llm-selector.compact .llm-model-name {
  font-size: 15px;
  font-weight: 600;
  line-height: 24px;
}

/* ══ 05 · Data, Teil B — Task 6: Die Kennzahlkachel ═══════════════
   Figma-Knoten 121:213 (Stat Tile): Breite 260, Radius 14, Flaeche
   --ax-bg-surface-1, Rahmen 1px solid --ax-border-soft, Innenabstand 16,
   Abstand 8. Beschriftung Semi Bold 11 in Grossbuchstaben mit Laufweite 6,
   --ax-text-muted; Wert Bold 28 mit Laufweite -1, --ax-text-primary. Dazu
   Trendpfeil, Vergleichswert, Unterzeile und Verlaufslinie.

   Erzeugt wird das Bauteil ueber OrganismsKpiTile an ACHT Stellen in DREI
   Dateien: moleculeusagesummary.js:49-52 (vier), myimpactpage.js:317
   (fuenf in einer Schleife), :322 und :324 sowie moleculetimesavingrow.js:69.
   Drei Wirte, und sie behandeln dieselbe Kachel verschieden -- siehe
   SCHRITT 3. Alle Zahlen unten sind im vollen Stapel gemessen (Chromium,
   webapp.css -> tokens.css -> components.css, beide Designs, beide Themes,
   Transitionen UND weiches Scrollen abgeschaltet), an den drei
   Galeriekacheln und am nachgestellten Cockpit-Panel; jede Zusicherung
   zusaetzlich bei 1280x900 und 1280x720 -- kein Unterschied.

   ── SCHRITT 1: NUR UMGEBAUT, WAS EXISTIERT ──
   Trendpfeil, Vergleichswert, Unterzeile und Verlaufslinie sind FEATURES
   (Spec, Abschnitt 3a) und werden hier NICHT gebaut. OrganismsKpiTile
   kennt eine Beschriftung, einen Wert und ein optionales Sinnbild
   (organismskpitile.js:47-64), sonst nichts -- fuer die andere Haelfte von
   Figmas Knoten gibt es im Produkt keinen Traeger. Gebaut wird deshalb
   genau: Rahmen, Radius, Flaeche, Innenabstand, Beschriftung, Wert.

   ── FIGMAS LAUFWEITEN SIND PROZENTE, NICHT PIXEL ──
   "Laufweite 6" und "Laufweite -1" stehen in der Aufgabenstellung ohne
   Einheit. Als Pixel gelesen waeren 6px auf einer 11px-Schrift mehr als
   eine halbe Geviertbreite -- eine Beschriftung, die um zwei Drittel
   breiter wird.
   AM KNOTEN AUSGELESEN, und das ist der Beleg; die Rasterarbeit darunter
   ist nur noch die Gegenprobe:
     "AKTIVE NUTZER"  11 Semi Bold  letterSpacing {unit: PERCENT, value: 6}
                      UPPER, textStyle: null
     "1.284"          28 Bold       letterSpacing {unit: PERCENT, value: -1}
                      textStyle: "Heading/2"
   Der Versalienstil "Label/Caps" der Vorlage (10 %) schlaegt NICHT durch:
   die Beschriftung traegt gar keinen benannten Textstil. Wer das nachlesen
   will, braucht den Knoten, nicht das Bild.
   GEGENPROBE AM BILD: Figmas Bild des Knotens ist 1:1 gerendert
   (584px fuer 2 x 260 + 64 Abstand). Die Tinte der Beschriftung
   "AKTIVE NUTZER" misst darin 95px, die des Werts "1.284" 73px. Dieselben
   Zeichenfolgen in Chromium mit Inter, mit DERSELBEN Schwellenwertsuche auf
   einem Canvas vermessen:
     Beschriftung 11/600   ohne Laufweite 88     0,5px 94
                           0,66px 96 <-- Figma 95        6px 160
     Wert 28/700           ohne Laufweite 75    -0,28px 74 <-- Figma 73
                           -1px 71
   6px ist um 65px daneben, 0,66px um 1px -- das Bild bestaetigt den
   Knoten. 0,66px sind 6 % von 11px, -0,28px sind 1 % von 28px. Deshalb
   stehen unten "0.06em" und "-0.01em" und nicht die Pixelzahlen -- die
   Prozentschreibweise ist Figmas eigene, und sie traegt in die beiden
   verkleinerten Wirte richtig weiter (gemessen -0,16px am 16px-Wert der
   Nebenzeile, -0,19px am 19px-Wert der Panel-Zeile; eine feste
   -0,28px-Angabe waere dort das Anderthalb- bis Doppelte von Figmas
   Verhaeltnis gewesen).

   ── DER BESTAND, EIGENSCHAFT FUER EIGENSCHAFT ──
   ".kpi-tile" (webapp.css:10068), sechs Deklarationen:
     background: var(--clr-surface-2)     -> ERSETZT. Die Bruecke fuehrt
       hier NICHT zu Figmas Wert: "--clr-surface-2" ist ein color-mix()
       (webapp.css:19/281), das tokens.css nirgends umhaengt. Gemessen stand
       die Kachel im neuen Design auf color(srgb 0.105882 0.1 0.154902)
       (dunkel) bzw. color(srgb 0.982745 0.981176 0.987451) (hell), Figmas
       --ax-bg-surface-1 ist rgb(18, 17, 28) bzw. rgb(255, 255, 255).
     border: 1px solid var(--clr-border-accent)  -> nur die FARBE ersetzt.
       Breite und Art stehen bereits auf Figmas Wert; die Regel unten
       wiederholt sie nicht und sichert sie als WAECHTER. Die Farbe dagegen
       ist im Bestand akzentgetoent (color-mix aus --clr-accent 22 % und
       --clr-border, webapp.css:33), gemessen
       color(srgb 0.110118 0.241176 0.351843) dunkel -- ein blaustichiger
       Rahmen, wo Figma die stillste Kante des Tokensatzes vorsieht.
     border-radius: 8px  -> ERSETZT durch --ax-radius-lg (14px).
     padding: 14px 22px  -> ERSETZT durch Figmas 16px. Waagerecht ist das
       eine VERSCHMAELERUNG (22 -> 16): die Kachel misst 196 -> 184.
     min-width: 150px    -> UEBERNOMMEN. Figmas feste Breite 260 wird NICHT
       gesetzt; die fuenf Kacheln der Zeitersparnis-Seite stehen in einer
       Flex-Zeile (".usage-summary-kpi", webapp.css:10029) und braechen bei
       5 x 260 + 4 x 16 = 1364 auf jedem Bildschirm unter 1364px um.
       WAECHTER.
     text-align: center  -> UEBERNOMMEN, als Entscheidung. Siehe SCHRITT 2.
   ".kpi-label" (:10076), sechs Deklarationen:
     display: block, font-size: 11px, text-transform: uppercase
       -> UEBERNOMMEN, alle drei auf Figmas Wert. WAECHTER.
     color: var(--clr-text-secondary)  -> ERSETZT durch --ax-text-muted.
       Die Bruecke fuehrt hier auf --ax-text-secondary (tokens.css:160/230),
       also eine Stufe heller als Figmas Wert. Kontraste unten.
     letter-spacing: 0.5px  -> ERSETZT durch Figmas 6 % (= 0,66px).
     margin-bottom: 6px     -> ERSETZT durch Figmas Abstand 8.
       DAS IST DER TRAEGER FUER "ABSTAND 8": der Kachelinhalt ist KEIN
       Flex-Container, ein "gap" haette hier nichts zu greifen.
     font-weight (nicht deklariert) -> Figmas Semi Bold ergaenzt. Ohne die
       Zeile steht die Beschriftung auf 400 (Vorgabe des <label>).
   ".kpi-value" (:10084), drei Deklarationen:
     font-size: 24px   -> ERSETZT durch Figmas 28.
     font-weight: bold -> UEBERNOMMEN (gemessen 700). WAECHTER.
     color: var(--clr-text-primary)  -> UEBERNOMMEN, und das ist ein BEFUND
       statt einer Regel: die Bruecke haengt "--clr-text-primary" bereits
       auf --ax-text-primary (tokens.css:159/229), gemessen
       rgb(232, 230, 238) dunkel und rgb(18, 17, 28) hell. Figmas Farbe
       steht also schon da.
       EINE FARBREGEL WAERE HIER SOGAR SCHAEDLICH: sieben der acht Aufrufe
       geben dem Wert eine Akzentklasse mit (".kpi-accent-user/-pkg/-vol").
       Eine "[data-design=new] .kpi-value { color: ... }"-Regel laege bei
       (0,2,0) und schluege die drei Akzentregeln (0,1,0) -- und im hellen
       Theme staende sie im GLEICHSTAND mit "[data-theme=light]
       .kpi-accent-*" (webapp.css:10267-10269, ebenfalls (0,2,0)), den sie
       ueber die Ladereihenfolge gewaenne. Die Kachelfamilie verloere ihre
       Farbcodierung in beiden Themes. Die Heilung ist die geloeschte
       Zeile: diese Regel setzt GAR KEINE Farbe. Nachgemessen behalten alle
       drei Akzente ihre Werte, im dunklen wie im hellen Theme.
     Laufweite (nicht deklariert) -> Figmas -1 % ergaenzt.
   ".kpi-value-row" (:10092) und ".kpi-icon" (:10098) bleiben unberuehrt:
   sie tragen das optionale Sinnbild, das Figmas Knoten gar nicht kennt.
   WAECHTER (gemessen "justify-content: center", 26px im Panel).

   ── SCHRITT 2: DIE AUSRICHTUNG BLEIBT MITTIG, UND ZWAR ENTSCHIEDEN ──
   Figmas Kachel ist linksbuendig, der Bestand mittig. Beides gemessen,
   an allen sieben Galeriekacheln, im AUSGELIEFERTEN Zustand -- also MIT
   den Wiederherstellungen aus SCHRITT 3. Eine erste Fassung dieser Tabelle
   mass den Stand davor (Innenabstand 16 und Wert 28px auch in Nebenzeile
   und Panel) und beschrieb damit einen Zustand, den es nie gab; Lehre 5
   des Plans, verletzt in der eigenen Kopftabelle. "Wert" ist ".kpi-value",
   nicht ".kpi-value-row" -- die Zeile fuellt die volle Inhaltsbreite und
   sagt ueber die Wanderung nichts. Die Inhaltsbreite ist aus dem Rechteck
   gerechnet, nicht aus "clientWidth": das ist eine ganze Zahl und rundete
   345,75 auf 346.
                                   Inhalt  Beschriftung   Wert   Wert-x
     "Kunden gesamt"                150     105,84      33,81   75,09 -> 17
     "Lizenzierte User"             150     111,86      74,83   54,58 -> 17
     "Tokenpakete (Lizenz)"         150     143,61      35,81   74,09 -> 17
     "Token-Verbrauch (Volumen)"    194,31  194,31     101,45   63,42 -> 17
     "Punkte gesamt"                110     103,91      42,48   48,75 -> 15
     "Vorgaenge gesamt"             122,42  122,42      26,89   62,77 -> 15
     "Diese Woche gespart" (Panel)  345,75  142,72      64,28  170,73 -> 47
   DER WERT IST IN JEDER KACHEL DEUTLICH SCHMALER ALS DER KASTEN -- er
   traegt zwei bis sieben Zeichen, die Breite bestimmt die Beschriftung.
   Linksbuendig wandert er deshalb an JEDER der acht Stellen um 33,75 bis
   123,73 Pixel nach links. Dazu kommt "min-width: 150px": in genau drei
   der vier Hauptkacheln greift die Untergrenze, dort bliebe rechts neben
   der Beschriftung ein toter Streifen von 44,16 / 38,14 / 6,39 Pixeln in
   einer Zeile, die ihre Kacheln mittig setzt ("justify-content: center",
   webapp.css:10032); die vierte traegt 194,31 Tinte und wird nicht
   gedeckelt.
   Und es waere nicht EINE Regel: ".kpi-value-row" zentriert Sinnbild und
   Wert per "justify-content" (:10092), eine Ausrichtungsaenderung muesste
   dort mitgehen, sonst stuenden in derselben Kachelfamilie zwei
   Ausrichtungen.
   ENTSCHIEDEN: die Ausrichtung bleibt. Figmas linke Kante gehoert zu einer
   260px BREITEN Karte mit Unterzeile und Verlaufslinie, die beide eine
   linke Kante setzen -- genau die Haelfte, die das Produkt nicht hat. Der
   Unterschied ist damit kein Versehen, sondern ein Punkt fuer die
   Sichtpruefung, und er steht auch dort.
   NEBENBEI, weil es die Rechnung mittig betrifft: Chromium haengt die
   Laufweite auch HINTER das letzte Zeichen (gemessen: Kasten 96,78 gegen
   96 Tinte). Mittig ausgerichtet liegt die Beschriftung dadurch um 0,33px
   links der Mitte. Mit den fehlgelesenen 6px waeren es 3px gewesen --
   sichtbar schief, und ein zweites Argument gegen die Pixel-Lesart.

   ── SCHRITT 3: DIE SECHS KONTEXT-OVERRIDES ──
   Zwei Wirte nehmen die Kachel bewusst zurueck:
     ".impact-kpi-secondary .kpi-tile"  (webapp.css:1686)  (0,2,0)
        padding: 8px 14px; min-width: 110px; border-color: var(--clr-border)
     ".impact-kpi-secondary .kpi-value" (:1692)            (0,2,0) 16px
     ".timesaving-row .kpi-tile"        (:10049)           (0,2,0)
        min-width: 0; padding: 10px 12px; border-radius: 9px
     ".timesaving-row:hover .kpi-tile"  (:10054)           (0,3,0)
     ".timesaving-row .kpi-value"       (:10060)           (0,2,0) 19px
     ".timesaving-row .kpi-icon"        (:10063)           (0,2,0) 26px
   NACHGERECHNET: vier davon liegen bei (0,2,0) -- im GLEICHSTAND mit einer
   "[data-design=new] .kpi-tile"-Regel, die ebenfalls (0,2,0) wiegt.
   components.css laedt zuletzt, der Gleichstand faellt also zu ihren
   Ungunsten aus. NACHGESTELLT, was das ohne Gegenmassnahme bedeutet
   haette (gemessen, neues Design):
     Nebenzeile: Innenabstand 8/14 -> 16, Wert 16px -> 28px (+75 %),
                 Kachelhoehe 65 -> 87 (+34 %)
     Panelzeile: Innenabstand 10/12 -> 16, Wert 19px -> 28px,
                 Kachelhoehe 74 -> 88 (+19 %)
   Die Nebenzeile stuende damit exakt so laut wie die Hauptzeile darueber,
   auf derselben Seite, zwei Zeilen untereinander -- die Rangfolge der
   Seite waere weg. Genau der Fall, in dem in Task 4 ein ungenannter
   Gleichstand beinahe eine bewusste Verdichtung aufgehoben haette.
   ENTSCHIEDEN: die beiden Verdichtungen werden bei (0,3,0)
   wiederhergestellt, mit den Zahlen des Bestands (unten). Sie sind eine
   Produktentscheidung ueber die Rangfolge IN EINEM WIRT, und Figmas Knoten
   sagt ueber Nebenzeile und Panel nichts.
   DREI GLEICHSTAENDE BLEIBEN BEWUSST STEHEN, jeder mit Grund:
     border-radius 9px (Panel) -> 14. Legacys 9 war GROESSER als die
       Grundform (8); im neuen Design waere dieselbe Zahl kleiner als die
       Grundform (14). Die Beziehung, die die 9 ausdrueckte, gibt es nicht
       mehr; die Panel-Kachel nimmt den Radius des Systems.
     border-color (Nebenzeile) -> --ax-border-soft. Legacys Override nimmt
       den Rahmen von --clr-border-accent auf --clr-border zurueck, also
       ZURUECK-genommen. Die Bruecke haengt "--clr-border" aber auf
       --ax-border-default (rgb(36, 34, 51)), und das ist STAERKER als
       Figmas --ax-border-soft (rgb(26, 24, 38)) der Grundform. Eine
       Wiederherstellung kehrte die Betonung also um: die zurueckgenommene
       Zeile bekaeme den kraeftigeren Rahmen. Gemessen, deshalb nicht
       wiederhergestellt.
     min-width (beide) -> unberuehrt: die neue Grundregel setzt keine
       Breite, 110px und 0px bleiben stehen. WAECHTER.
   ".timesaving-row:hover .kpi-tile" liegt bei (0,3,0) und schlaegt die
   neue Regel ueber die ZAHL. Nachgemessen wechselt die Rahmenfarbe beim
   Zeigen weiter, in beiden Designs und beiden Themes.
   ".kpi-icon" (26px im Panel) beruehrt keine Deklaration dieses Tasks.

   ── DER THEME-BLOCK ──
   "[data-theme=light] .kpi-accent-user/-pkg/-vol" (webapp.css:10267-10269)
   wiegt (0,2,0) -- Gleichstand mit jeder neuen Klassenregel unter
   "[data-design=new]", und components.css laedt spaeter. AUSGERECHNET UND
   FOLGENLOS: keine Regel dieses Tasks deklariert "color" auf ".kpi-value"
   (Begruendung oben). Gemessen im hellen Theme behalten die drei Akzente
   ihre Theme-Werte: rgb(109, 40, 217), rgb(0, 159, 227),
   color(srgb 0.0603922 0.447451 0.203137).

   ── FARBEN, GERASTERT GEMESSEN ──
   Untergruende werden GERASTERT gelesen (1x1-Ausschnitt, PNG selbst
   dekodiert): der Kachelgrund des Bestands ist ein color-mix(), der
   Seitengrund traegt unter "body::before" einen Verlauf, und
   getComputedStyle meldet dort keine Malfarbe. Eine erste Fassung dieser
   Messreihe hat sieben Punkte auf denselben Grund gelegt und ueberall
   "dE 0,000" ausgewiesen -- Ursache war ein Vollseiten-Ausschnitt auf
   einer Seite, die in einem INNEREN Container scrollt. Korrigiert;
   dieselbe Fehlerklasse wie in Task 5, nur eine Achse weiter.

   Text auf der Kachelflaeche (WCAG 1.4.3). DREI Bezugsgroessen, weil zwei
   nicht reichen: "Bruecke" ist der Zustand des NEUEN Designs ohne die eine
   Farbdeklaration dieses Tasks -- also die lebende Alternative --, "alt"
   ist das alte Design. Eine fruehere Fassung dieses Absatzes nannte die
   10,766 "die Bruecke" und verglich damit die WCAG-Haelfte gegen Legacy und
   die dE-Haelfte gegen die Bruecke:
                                    neu dunkel / hell  Bruecke  alt dunkel / hell
     Beschriftung (--ax-text-muted)   4,796 /  7,416   8,301/12,306  10,766 / 9,512
     Wert ohne Akzent                15,129 / 18,705       --      12,966 / 15,309
     Wert .kpi-accent-user            8,254 /  7,105       --       7,053 / 6,804
     Wert .kpi-accent-pkg             7,737 /  2,971       --       5,757 / 7,568
     Wert .kpi-accent-vol             8,256 /  6,040       --       7,055 / 5,784
   FIGMAS BESCHRIFTUNGSFARBE WIRD AUSGELIEFERT, und das ist hier
   vertretbar: --ax-text-muted besteht die 4,5 nur auf den zwei dunkelsten
   Gruenden -- --ax-bg-app (5,043) und --ax-bg-surface-1 (4,796) --, und
   Figmas Kachel steht auf genau diesem --ax-bg-surface-1. Auf jeder
   erhoehten Flaeche faellt das Token durch (--ax-bg-surface-2/-input/
   -elevated 4,477, --ax-bg-surface-3/-hover 3,984); DIESE Kachel bringt
   ihre Flaeche selbst mit, an allen acht Stellen, auch im Cockpit-Panel --
   einen vierten Wirt gibt es nicht.
   Die 4,796 sind trotzdem ein Rueckschritt gegenueber den 8,301, die die
   Bruecke ohne diese eine Zeile lieferte (gemessen, indem genau sie
   entfernt wurde), und was dafuer gewonnen wird, ist die Rangfolge: der
   Farbabstand zwischen Beschriftung und Wert steigt von dE 21,555 auf
   38,318 (dunkel) und von 18,557 auf 31,433 (hell). Beides ueber der
   Wahrnehmungsschwelle 2,3, das neue Paar deutlich staerker. Kein Wert
   dieses Tasks liegt unter 4,5.
   DER EINE WERT UNTER DER SCHWELLE IST GEHEILT, UND DIE TOKENFRAGE IST
   BEANTWORTET (T1, 2026-09-15). Hier stand, ".kpi-accent-pkg" messe im
   hellen Theme 2,971 und eine Heilung hiesse, die Akzentfarbe der
   Kachelfamilie zu verwerfen -- "das ist eine Tokenfrage". T1 hat genau
   diese Tokenfrage entschieden: "--ax-action-primary" steht im hellen
   Theme jetzt auf cyan/600 (tokens.css:127). DIE HEILUNG KOMMT HIER AN,
   ohne dass eine Akzentfarbe verworfen wurde. An der Hauptzeile steht die
   Farbe auf einem 28px-Wert (Schwelle 3,0 fuer grosse Schrift), an der
   NEBENZEILE auf einem 16px-Wert (myimpactpage.js:322, "Punkte gesamt")
   -- und 16px Bold ist nach WCAG keine grosse Schrift, fett beginnt sie
   bei 18,66px, dort gilt 4,5:
                        Hauptzeile 28px       Nebenzeile 16px
     bis T1             2,971 (Schwelle 3,0)  2,971 (Schwelle 4,5)
     SEIT T1            4,761                 4,761
     ohne Flaechenregel 2,855 (Stand bis T1)  2,855 (Stand bis T1)
     altes Design       7,568                 7,568
   Gemessen an den Galerie-Kacheln "gallery-kpi" und "gallery-kpi-secondary":
   die Farbe faellt von rgb(0,159,227) auf rgb(0,122,176), die
   Kachelflaeche ist gemessen rgb(255,255,255); 4,761 nach derselben Formel
   wie tests/features/design-contrast.spec.ts. Beide Schwellen sind damit
   erfuellt, auch die strengere 4,5 der Nebenzeile.

   EINE BERICHTIGUNG IM SELBEN ATEMZUG, denn die alte Fassung nannte die
   falsche Wurzel: "der Wert entsteht aus der Bruecke -- --clr-accent-light
   haengt im neuen Design auf --ax-action-primary". Das gilt nur fuer das
   DUNKLE Theme (webapp.css:10130). Im HELLEN gilt
   "[data-theme=light] .kpi-accent-pkg { color: var(--clr-accent-btn) }"
   (webapp.css:10294; (0,1,1) schlaegt (0,1,0)), und "--clr-accent-btn"
   haengt auf "--ax-action-primary" (tokens.css:243). Zweiseitig belegt:
   wird webapp.css:10294 entkraeftet, meldet die helle Zeile
   "color(srgb 0.2 0.582745 0.752157)" -- die "--clr-accent-light"-Mischung
   -- statt rgb(0,122,176); wird stattdessen webapp.css:10130 entkraeftet,
   aendert sich der helle Wert NICHT, wohl aber der dunkle (rgb(232,230,238),
   der geerbte Textwert). Die ZAHL der alten Fassung war richtig, der
   genannte Pfad nicht.

   GEBRANDET BLEIBT GEBRANDET: "--clr-accent-btn" ist eine brandbare
   Wurzel. Mit Marke #ff5500 gemessen meldet die helle Zeile rgb(255,85,0),
   die dunkle "color(srgb 1 0.466667 0.2)". Die Heilung wirkt also auf der
   nackten Plattform; eine Organisation, die ihre Farbe setzt, bekommt
   weiterhin ihre Farbe -- mit dem Kontrast, den sie waehlt. Das bleibt auf
   der Liste von Task 7.

   ── DER KASTEN GEGEN SEINEN UNTERGRUND ──
   Gerastert, gegen den jeweils RICHTIGEN Bezug (Grund NEBEN der Kachel,
   nicht die eigene Flaeche):
                        Grund        Flaeche      Flaeche/Grund  Rahmen/Grund
     neu dunkel, Seite  11,10,20     18,17,28     dE 3,545       dE 8,020
     neu hell,  Seite   244,243,247  255,255,255  dE 4,494       dE 4,857
     neu dunkel, Panel  18,17,28     18,17,28     dE 0,000       dE 4,531
     neu hell,  Panel   255,255,255  255,255,255  dE 0,000       dE 9,350
     alt dunkel, Seite  10,14,26     26,34,47     dE 9,211       dE 24,097
     alt hell,  Seite   238,242,255  248,250,255  dE 4,968       dE 28,809
   DIE PANEL-ZEILE STAND IN EINER ERSTEN FASSUNG AUF 1,054 / 0,545, UND DAS
   WAR EIN VERLAUFSARTEFAKT -- fuenfte Instanz derselben Fehlerklasse in
   diesem Teilprojekt, diesmal sogar im Widerspruch zum eigenen Fliesstext
   zwei Zeilen darunter. "--ax-bg-nav" und "--ax-bg-surface-1" sind
   DASSELBE Token (--ax-ink-900 dunkel, --ax-ink-0 hell; tokens.css:50/54
   und :98/102), die Trennung ist also zwingend 0,000. Gemessen hatte die
   erste Fassung ".chatbot-service-panel::before" (webapp.css:5091): einen
   180x180 grossen radialen Akzentschein an der linken oberen Panelecke
   (top -30, left -30, rgba(--clr-accent-rgb, .08)), den die Kachel abdeckt
   (".chatbot-service-panel > *" hebt die Kinder auf z-index 1) und der
   Grund daneben nicht. Senkrechtschnitt, gerastert, neues Design dunkel,
   Panel ab y=20: y=19 rgb(11,10,20) (Seite), y=20..39 rgb(18,18,30) bis
   rgb(18,20,32) (Panel MIT Schein), y=40 rgb(26,24,38) (Rahmen), ab y=41
   rgb(18,17,28) (Kachelflaeche). Der Panelgrund beginnt also NICHT bei
   rgb(18,17,28).
   DAS HAT EINE PRODUKTFOLGE: die Zeitersparnis-Zeile ist in der Profil-
   und der Suche-Vorlage das ERSTE Panel-Kind
   (templatecockpitnavigationprofile.js:20,
   templatecockpitnavigationsearch.js:18) und liegt damit mitten im Schein.
   Die Flaechentrennung ist dort nicht null, sondern ORTSABHAENGIG:
   gemessen entlang der Kachelkante bis dE 3,395 oben und 4,250 unten
   (dunkel) bzw. 1,945 / 2,134 (hell); im Zentrum des Scheins
   (Panel-Koordinate 60/60) erreicht der Grund dE 6,842 (dunkel) und 3,851
   (hell) gegenueber der Kachelflaeche, unterhalb von y=150 exakt 0,000. In
   den Vorlagen, die die Zeile weiter unten montieren
   (templatecockpitnavigationchatbot.js:234 hinter Agentenwahl und
   "Neuer Chat"), ist sie null.
   ZWEI BEFUNDE BLEIBEN. Erstens: auf den Auswertungsseiten traegt die
   Flaeche (dE 3,545 / 4,494 gegen die Wahrnehmungsschwelle 2,3), im
   Cockpit-Panel dagegen NICHT -- dort ist --ax-bg-nav dasselbe Token wie
   --ax-bg-surface-1, die Kachel steht flaechengleich auf ihrem Wirt und
   lebt allein von ihrem Rahmen (dE 4,531 / 9,350). Im Bestand ist das
   anders (dE 9,211) und gehoert in die Sichtpruefung.
   Zweitens, und das ist der Preis fuer Figmas stillste Kante: der Rahmen
   verliert im dunklen Theme deutlich an Zeichnung (dE 24,097 -> 8,020 auf
   der Seite, gegen den Panelgrund 4,531). Die 3,0 aus WCAG 1.4.11 erreicht
   er in KEINEM der beiden Designs (neu 1,071..1,236, alt 1,570..1,683) --
   die Kachel ist aber auch kein Bedienelement, sondern eine Anzeige.
   AUF DER GALERIEKACHEL IST DIE FLAECHE GAR KEIN ZEUGE: der Kachelgrund
   der Galerie ist selbst --ax-bg-surface-1, gemessen dE 0,000 in beiden
   Themes. Wer die Flaechentrennung sehen will, muss auf eine echte Seite
   schauen; in der Galerie zeigt sich nur der Rahmen (dE 4,531 dunkel /
   9,350 hell).

   ── DER NACHBAR AUS 06 · SHELL & NAV ──
   "[data-design=new] .chatbot-service-panel .timesaving-row" (oben in
   dieser Datei) rechnet mit 200px Panel-Inhaltsbreite und vermerkt, die
   Reserve sei aufgebraucht. Nachgestellt (Panel 224, Inhalt 200, beide
   Themes): die Kachel misst weiterhin 200, scrollWidth 198 gegen
   clientWidth 198, die Beschriftung bleibt EINZEILIG (174px Kasten), kein
   Ueberlauf. Die Hoehe waechst von 74 auf 76 -- die zwei Pixel sind Figmas
   Abstand 8 statt Legacys 6. Ohne die Wiederherstellung aus SCHRITT 3
   waeren es 88 gewesen.

   ── WAS IM ALTEN DESIGN NICHT NACHWEISBAR IST ──
   Fuer jede der 14 Deklarationen wurde im alten Design derselbe Selektor
   OHNE Praefix hinter components.css nachgeladen. ZEHN bewegen dort etwas
   und sind zugesichert. VIER bewegen NICHTS, und das ist kein Loch,
   sondern ihre Bauart: die vier Wiederherstellungen aus SCHRITT 3 tragen
   WERTGLEICH die Zahlen, die der Bestand an derselben Stelle ohnehin setzt
   (8px 14px, 16px, 10px 12px, 19px). Ein verlorener Praefix waere dort
   folgenlos -- sie koennen kein Leck erzeugen, also auch keins beweisen.
   DAS GILT ALLERDINGS NUR, SOLANGE DIE ZAHLEN GLEICH BLEIBEN: die vier
   sind eine STILLE KOPPLUNG an webapp.css:1686/1692 und :10049/10060.
   Aenderte jemand dort den Innenabstand oder die Schriftgroesse, froere
   eine entpraefixte Fassung den alten Wert im alten Design ein -- aus der
   Unbeweisbarkeit wuerde dann ein echtes Leck. Wer die Legacy-Zahlen
   anfasst, muss die vier Regeln hier mitziehen.
   ZWEI der zehn bewegen etwas anderes, als man erwarten wuerde:
     background: var(--ax-bg-surface-1)  und
     color: var(--ax-text-muted)   binden Variablen, die es im alten Design
       nicht gibt (tokens.css:50/65 binden sie unter [data-design=new]).
       Sie werden nicht uebersprungen, sondern zur Laufzeit UNGUELTIG: die
       Kachel faellt auf "transparent" zurueck und verliert ihre Flaeche
       ganz, die Beschriftung erbt die Textfarbe der Kachel. Gemessen.
   "border-radius: var(--ax-radius-lg)" ist der Gegenfall: das Token steht
   in einem ungegateten ":root" (tokens.css:352) und zoege den echten Wert
   14px ins alte Design.
   ALLE 14 SIND NACHWEISE, keine ist ein blosser Waechter: jede einzeln aus
   der lebenden Regel entfernt (mit reload() dazwischen, kein
   Sammel-Gegenversuch) bewegt in BEIDEN Themes etwas. */
[data-design="new"] .kpi-tile {
  background: var(--ax-bg-surface-1);
  /* Nur die Farbe: Breite und Art des Rahmens stehen im Bestand bereits
     auf Figmas Wert. */
  border-color: var(--ax-border-soft);
  /* "--ax-radius-lg" ist bei <=768px 12px statt 14 (tokens.css:404) -- die
     Zeile darunter nimmt den Innenabstand genau deswegen literal, und
     beides zusammen ist ein Widerspruch, den der Kommentar frueher
     verschwieg. Der Vorrang liegt bei der Umsetzung: components.css nutzt
     dasselbe Token an drei weiteren Stellen (:74, :1309, :1454), eine
     Ausnahme hier waere eine Sonderform ohne Anlass. Gemessen bei 700px
     und bei 768px: Radius 12, Innenabstand 16, alles uebrige unveraendert
     (Kachel 184 x 87, Beschriftung 11/600/0,66/8, Wert 28/-0,28). Der
     Haltepunkt ist damit gemessen und nicht nur behauptet.
     ZUM MITSCHREIBEN FUER SPAETERE TASKS: das ist der EINZIGE Wert dieses
     ganzen Teilprojekts, der sich mit dem Viewport aendert
     (tokens.css:389/405, @media max-width 768px). Alle Zusicherungen der
     Testdatei nageln 14px fest und gelten deshalb nur beim
     Projekt-Viewport; unter 768px sind sie richtig falsch. */
  border-radius: var(--ax-radius-lg);
  /* Literal, nicht "--ax-space-4": das Token ist bei <=768px 12px statt
     16 -- dieselbe Linie wie in den Tasks 3 bis 5. */
  padding: 16px;
}

/* Die Beschriftung. 11px und "uppercase" stehen im Bestand schon richtig
   und werden nicht wiederholt. "0.06em" ist Figmas Laufweite 6 % -- die
   Einheit ist gemessen, nicht angenommen (siehe oben). */
[data-design="new"] .kpi-label {
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ax-text-muted);
  /* Figmas "Abstand 8". Der Kachelinhalt ist kein Flex-Container, der
     Abstand haengt deshalb am unteren Aussenabstand der Beschriftung. */
  margin-bottom: 8px;
}

/* Der Wert. Keine Farbe und kein Gewicht: beides steht bereits auf Figmas
   Wert, und eine Farbregel naehme der Kachelfamilie ihre Akzente. */
[data-design="new"] .kpi-value {
  font-size: 28px;
  letter-spacing: -0.01em;
}

/* Die beiden Verdichtungen des Bestands, bei (0,3,0) wiederhergestellt.
   Ohne sie gewaenne die Grundregel oben den Gleichstand bei (0,2,0) ueber
   die Ladereihenfolge -- und die zurueckgenommene zweite Kennzahlenzeile
   der Zeitersparnis-Seite stuende so laut wie die Hauptzeile darueber
   (Wert 16 -> 28, Kachel 65 -> 87). Werte des Bestands, absichtlich
   unveraendert: sie sind eine Aussage ueber die Rangfolge in DIESEM Wirt,
   nicht ueber die Kachel. */
[data-design="new"] .impact-kpi-secondary .kpi-tile {
  padding: 8px 14px;
}

[data-design="new"] .impact-kpi-secondary .kpi-value {
  font-size: 16px;
}

/* Dasselbe fuer die Zeile im Cockpit-Panel. Der Kommentar an
   webapp.css:10057-10059 begruendet die Verdichtung mit der Panelbreite;
   nachgemessen passte Figmas Innenabstand dort zwar (200px Inhalt, kein
   Ueberlauf, Beschriftung einzeilig), die Kachel waere aber von 74 auf 88
   gewachsen -- in einem Panel, dessen Hoehe an der Fensterhoehe haengt und
   unter dem eine Liste steht. Mit dieser Regel sind es 76. */
[data-design="new"] .timesaving-row .kpi-tile {
  padding: 10px 12px;
}

[data-design="new"] .timesaving-row .kpi-value {
  font-size: 19px;
}

/* ══════════════════════════════════════════════════════════════════
   07 · Chat & AI, Teil A — Die Antwortflaeche
   Quelle: Figma "AuxData.ai — Core Design System", Seite 07 · Chat & AI
   (Knoten 1:9). Spec: docs/superpowers/specs/
   2026-09-10-designsystem-chat-antwortflaeche-design.md

   VIER EINBAUORTE TEILEN JEDE KLASSE DIESES ABSCHNITTS: Cockpit-Chat
   (cockpitchatbot.js:56), Cockpit-Suche (cockpitsearch.js:52),
   Projekt-Chat (projectpage.js:168) und der oeffentliche Chat
   (publicchatbot.js:64). Der vierte wird zweimal als <iframe>
   weiterverwendet -- In-App-Hilfe (helpchatpanel.js:79-85) und externes
   Einbettungs-Widget (frontend/js/embed/widget.js), beide mit
   "?embedded=true". EIN FEHLER HIER IST AUF KUNDENSEITEN SICHTBAR.

   Hier stand "das gilt fuer keines der vier Teilprojekte davor". Das
   ist nicht haltbar: "publicchatbot.html:16-18" laedt webapp.css,
   tokens.css und components.css wie jede Cockpit-Seite -- die
   Element-Basisregeln aus "04 · Core" (button, input, a, ...)
   erreichen den eingebetteten Chat also laengst. NEU IST NICHT DIE
   REICHWEITE, SONDERN DAS ZIEL: hier wird die Flaeche umgebaut, die
   der Besucher liest. (Spec §3c, Abnahme.)

   DREI SPEZIFITAETEN, DIE MAN VOR DER ERSTEN REGEL KENNEN MUSS. Alle
   drei sind gemessen, nicht aus der Datei gelesen:

   1. "[data-theme=\"light\"] .msg-bubble-user" (webapp.css:3034) wiegt
      (0,2,0) und setzt "background" ein ZWEITES Mal. Eine neue Regel
      "[data-design=\"new\"] .msg-bubble-user" wiegt ebenfalls (0,2,0)
      und gewinnt dort NUR ueber die Ladereihenfolge (components.css
      laedt zuletzt, cockpit.html:16-18). Das ist eine Gefahr, kein
      Vorteil: verliert diese Datei ihren Platz am Ende, faellt das helle
      Theme lautlos auf Legacys Verlauf zurueck -- und nur dort.
      Zugesichert im hellen Block der Testdatei.

   2. "body.chat-embedded .msg-bubble-user" (webapp.css:2225) wiegt
      (0,2,1) und SCHLAEGT damit jede Regel dieses Abschnitts -- aber
      NUR fuer "background" und "color", die beiden Eigenschaften, die
      sie selbst setzt. Radius, Innenabstand, Schrift und
      "white-space" dieses Tasks kommen dort sehr wohl an (gemessen:
      14 / 12-16 / 15 / 24 / pre-wrap). Fuer die Flaeche gilt weiter
      "var(--acw-user-bg, var(--clr-embed-user-grad))".

      DAS IST EINE REGRESSION AUS SCHRITT 1, KEINE FRAGE AN DIE
      VORLAGE. Die Bruecke haengt "--clr-embed-user-grad"
      (tokens.css:191) von Legacys "#1e3a8a -> #1d4ed8" auf
      "cyan/500 -> cyan/400". Gerastert, weisser Text:

        altes Design, beide Themes   6,746 … 10,167   erfuellt
        neues Design, dunkel         2,971 …  2,165   VERFEHLT
        neues Design, hell           3,009 …  4,700   VERFEHLT (bis auf
                                                      das dunkle Ende)

      UND DIE REICHWEITE IST GROESSER, ALS "Einbettung" klingt: die
      In-App-Hilfe ist IMMER betroffen -- helpchatpanel.js:84 baut die
      iframe-URL ohne jeden Farbparameter, und publicchatbot.js:42-58
      liest "--acw-*" ausschliesslich aus URL-Parametern. Das externe
      Widget ist es STANDARDMAESSIG: die Checkbox "Eigene Farben
      verwenden" steht auf false (organismsagentaccesstokencard.js:118-124)
      und _copyEmbedSnippet() (:265) schreibt die Farben nur, wenn sie
      gesetzt ist. Also nicht nur auf Kundenseiten, sondern auch in der
      eigenen Anwendung, jedes Mal wenn jemand die Hilfe oeffnet.

      NICHT GEHEILT, und das mit Absicht: die Behebung liegt in der
      Bruecke, also im Fundament, und gehoert zu derselben Entscheidung
      wie "--ax-text-muted". Eine Gegenregel hier muesste ausserdem die
      kundeneigene Farbe "--acw-user-bg" nachbauen. Der Ist-Stand ist
      stattdessen in der Testdatei ZUGESICHERT (vierter Block), damit
      ihn niemand versehentlich verschiebt -- in keine der beiden
      Richtungen. Befund an Spec Abschnitt 7.

      GEHEILT MIT T2 (2026-09-16): die Bruecke haengt "--clr-embed-user-grad"
      seither nicht mehr an "action/primary", sondern an einem eigenen,
      themeunabhaengigen Rollenpaar ("--ax-chat-bubble-user-from"/"-to",
      tokens.css, wertgleich cyan/600 -> cyan/700 -- Begruendung beim
      Verlaufs-Block von Task 1 dieses Abschnitts, wenige Zeilen unten).
      Gerastert, weisser Text, DANACH:

        neues Design, dunkel   4,761 …  8,544   erfuellt
        neues Design, hell     4,761 …  8,544   erfuellt (unveraendert)

      Der Ist-Stand oben beschreibt damit nur noch die Ausgangslage VOR
      T2, nicht mehr das Produkt; er bleibt stehen, weil er die Herkunft
      der Heilung ist. Der vierte Block der Testdatei ist mit T2 auf den
      geheilten Zustand umgeschrieben (design-chat-antwortflaeche.spec.ts,
      Abschnitt "Der eingebettete Wirt"), nicht abgeschaltet.

   3. "@media (max-width: 640px)" (webapp.css:8587/8653) setzt an allen
      drei Blasen Radius 8. Ein Media-Block traegt keine Spezifitaet:
      diese Datei gewaenne dort ueber die Ladereihenfolge und haette die
      bewusste Verdichtung des Bestands lautlos aufgehoben. Sie wird
      unten ausdruecklich zurueckgeholt -- und die Gegenregel ist
      gemessen ein voller NACHWEIS: bei 620 px Viewport springt der
      Radius ohne sie von 8 auf 12 px.
   ══════════════════════════════════════════════════════════════════ */

/* ══ 07 · Chat & AI, Teil A — Task 1: Die Nutzerblase ═════════════
   Figma-Knoten 46:2. Der Bestand steht in webapp.css:2971-2980
   (".msg-bubble-user", neun Deklarationen) und :2627-2637
   (".msg-sender-user"). Erzeugt werden beide ausschliesslich von
   OrganismsChatWindowUserMessage (chatwindowusermessage.js:40/43) --
   kein zweiter Verwender, im ganzen Frontend geprueft.

   DIE NEUN DEKLARATIONEN DER BLASE, EINZELN ENTSCHIEDEN. Gemessen im
   vollen Stapel (1280x720, echte Organismus-Instanzen im echten Wirt
   ".chat-window"), nicht aus Figma abgeschrieben:

     background      ERSETZT  -- siehe den Verlaufs-Block unten.
     border          BLEIBT   -- Figma kennt am Nutzerknoten keinen
                                Rahmen. Der Bestand traegt
                                "1px solid rgba(--clr-accent-btn-rgb,.33)";
                                gerastert hebt er sich vom Verlauf
                                darunter ab -- ueber der
                                Wahrnehmungsschwelle 2,3, also KEIN
                                unsichtbarer Rest, den man beilaeufig
                                mitnehmen koennte. DIE ZAHL HAENGT AM
                                ABTASTPUNKT, weil der Untergrund selbst
                                ein Verlauf ist; deshalb drei Kanten
                                statt einer, je Rahmenpixel gegen das
                                Pixel 3 px weiter innen, gemessen in der
                                Galeriekachel:

                                  links, halbe Hoehe   ΔE  3,328
                                  oben, halbe Breite   ΔE  5,056
                                  rechts, halbe Hoehe  ΔE 19,691

                                (Bestand zum Vergleich, dieselben drei
                                Punkte: 39,080 / 17,471 / 23,061 dunkel,
                                4,031 / 1,150 / 6,645 hell.) Der Rahmen
                                bleibt trotzdem:
                                der Kasten ist "content-box" (gemessen),
                                ein "border: none" naehme der Blase
                                2 px Breite und Hoehe, und Figmas
                                Schweigen ueber einen Effekt ist kein
                                Sollwert. Befund an die Vorlage.
     border-radius   ERSETZT  -- 14 auf allen vier Ecken, siehe unten.
     padding         ERSETZT  -- 12 / 16 statt 12 / 15.
     color           BLEIBT   -- Figma will "--ax-text-on-accent". Der
                                Bestand setzt "var(--clr-white)", und die
                                Bruecke haengt "--clr-white" auf
                                "--ax-ink-0" (tokens.css). Beide Wege
                                enden gemessen auf rgb(255, 255, 255).
                                Eine Deklaration, die nichts aendert,
                                waere genau die Sorte richtiger Regel,
                                die niemand sieht -- und im eingebetteten
                                Fall schluege "body.chat-embedded ..."
                                (0,2,1) sie ohnehin.
     line-height     ERSETZT  -- 24 px statt 1,65 (= 21,45 px bei 13 px).
     box-shadow      ERSETZT  -- #2028: Figmas Knoten fuehrt keinen Effekt,
                                und der Bestandsschein ".3" liess die
                                Nutzerblase gegenueber der Antwort (".1")
                                gluehen. Gesetzt ist jetzt derselbe
                                Schein wie an der Antwortblase,
                                "0 2px 16px rgba(--clr-accent-rgb,.1)";
                                das alte Design behaelt ".3". Nachweis in
                                der Testdatei.
     font-size       ERSETZT  -- und zwar von GEMESSENEN 13 px auf 15.
                                "small" ist ein SCHLUESSELWORT, kein
                                Pixelwert: Chromium loest es gegen die
                                absolute Groessentabelle auf, nicht gegen
                                die 13,333 px des Elternteils
                                ("body { font-size: smaller }",
                                webapp.css:532). Nachgemessen an einem
                                nackten Element: 13 px. Der Unterschied
                                zu Figmas 15 ist damit +2 px, nicht +1,67.
     white-space     UNANGETASTET -- "pre-wrap" traegt die
                                Zeilenumbrueche der Eingabe. Wer es
                                verliert, zerstoert JEDE mehrzeilige
                                Nutzernachricht, und zwar unsichtbar fuer
                                jeden Test, der nur einzeilige misst. Die
                                Galerie zeigt deshalb eine dreizeilige
                                Nachricht, und die Testdatei bewacht den
                                Wert an ihr.

   WAS DER GANZE BLOCK AN GROESSE KOSTET, gemessen an den beiden echten
   Instanzen der Galeriekachel (1280 x 720): die Blase der kurzen
   Nachricht waechst von 227,31 x 68,88 auf 272,95 x 74 px, die der
   dreizeiligen von 90,31 auf 98 px Hoehe. Isoliert betrachtet -- nur
   Schriftgroesse und Zeilenkasten geaendert, Innenabstand unveraendert --
   sind es 243,11 -> 271,39 px Breite; der Rest kommt vom Innenabstand.
   Der Zeilenkasten steigt von 21,45 auf 24. */

/* Die Blase. Figma-Knoten 46:2.

   DER RADIUS IST EINE ENTSCHEIDUNG, KEINE KORREKTUR. Der Bestand setzt
   "14px 4px 14px 14px" -- die Ecke ZUM ABSENDER hin ist scharf, und die
   Assistentenblase spiegelt das ("4px 14px 14px 14px", webapp.css:2639).
   Figma setzt an beiden Knoten 14 auf allen Ecken. Uebernommen wird
   Figma: die Spec ist die bindende Autoritaet, Nutzer- und
   Assistentenblase sind ohnehin durch Seite, Farbe und Avatar
   unterschieden, und Task 2 zieht die Assistentenblase auf denselben
   Wert nach -- eine halbe Uebernahme waere schlimmer als beide
   Antworten. DIE SCHARFE ECKE GEHT DAMIT BEWUSST VERLOREN; sie steht
   als Punkt 6 auf der Vorlage zur Sichtpruefung (Task 7).

   "--ax-radius-lg" statt der literalen 14: das Token ist bei <= 768 px
   12 px, das ist die Antwort des Designsystems auf den schmalen
   Bildschirm und hier erwuenscht. Darunter, ab <= 640 px, holt die
   Gegenregel Legacys 8 zurueck; sie steht am ENDE VON TASK 3, samt
   ihrer Begruendung, und zwar zwingend dort: ein Media-Block traegt
   keine Spezifitaet, also muss sie hinter Task 2s Radius-Regeln
   stehen (nachgemessen, siehe der Kommentar bei ihr). Die Leiter
   14 / 12 / 8 ist damit vollstaendig und faellt monoton.

   Der Innenabstand steht dagegen LITERAL da: "--ax-space-3/-4" sind bei
   <= 768 px 10 bzw. 12 px, und Figmas 12 / 16 ist eine Aussage ueber die
   Blase, nicht ueber den Bildschirm. Dieselbe Linie wie in
   "05 · Data, Teil B", Tasks 3 bis 6. */
[data-design="new"] .msg-bubble-user {
  border-radius: var(--ax-radius-lg);
  padding: 12px 16px;
  font-size: var(--ax-font-size-body-md);
  line-height: var(--ax-line-height-body-md);
  box-shadow: 0 2px 16px rgba(var(--clr-accent-rgb),.1);
}

/* Der Verlauf — und die einzige bewusste Abweichung von der Vorlage.

   FIGMAS VERLAUF IST AN KEIN TOKEN GEBUNDEN: die beiden Stopps stehen im
   Knoten als rohe Werte, rgb(0, 158, 227) -> rgb(0, 122, 184). Der erste
   ist cyan/500 bis auf ein Digit (ΔE 0,784 gegen #009fe3), der zweite
   liegt zwischen cyan/600 und cyan/700 (ΔE 5,064 gegen #007ab0).

   ER IST ABER NICHT AUSLIEFERBAR, WEIL DER TEXT DARAUF WEISS IST.
   Gerastert (Regel 2: getComputedStyle meldet an einem Verlauf nur
   "rgba(0, 0, 0, 0)"; gemessen wird per 1x1-Screenshot, fuenf Punkte
   entlang der Achse, Glyphen vorher ausgeblendet) haelt Weiss gegen
   Figmas Verlauf:

     hellster Stopp rgb(0, 158, 227)   3,000   VERFEHLT (4,5)
     dunkelster     rgb(0, 122, 184)   4,692   erfuellt

   Das ist derselbe Wert, an dem "04 · Core", Task 10 schon einmal
   entschieden hat: cyan/500 haelt gegen Weiss 2,971 und wurde deshalb
   fuer Textrollen durch cyan/600 ersetzt (Begruendung in tokens.css am
   hellen "--clr-accent"). Rulings 10 und 12: eine bekannt schlechte
   Kontrastzahl wird nicht ausgeliefert, auch wenn die Vorlage sie
   vorschreibt.

   GEBAUT WIRD DESHALB cyan/600 -> cyan/700. Der hellste Punkt des
   Verlaufs haelt damit 4,761, der dunkelste 8,544 -- die ganze Achse
   liegt ueber 4,5.

   DER HELLE STOPP IST DAMIT AUSGEREIZT, DER DUNKLE NICHT -- und das
   sind zwei getrennte Fragen, die eine erste Fassung dieses Kommentars
   zu einer verschmolzen hat ("eine Zwischenstufe gibt es nicht"; das
   gilt nur fuer den hellen). Nachgerechnet:

     heller Stopp  Figma rgb(0,158,227)          3,000
                   minimale farbtonerhaltende Abdunklung, die 4,5
                   erreicht: rgb(0,126,182)      4,507   ΔE 13,699
                   cyan/600  rgb(0,122,176)      4,761   ΔE 15,550
                   -> cyan/600 liegt von dieser Untergrenze nur ΔE
                      1,862 entfernt, also UNTER der Wahrnehmungs-
                      schwelle 2,3. Hier ist nichts zu holen.

     dunkler Stopp Figma rgb(0,122,184)          4,692  -- erfuellt
                   die Schwelle BEREITS.
                   cyan/700  rgb(0,81,122)       8,544   ΔE 19,835
                   Fassung 2: color-mix(in srgb, var(--ax-cyan-600)
                   50%, var(--ax-cyan-700)) = rgb(0,102,149)
                                              6,298   ΔE 11,378

   Der gebaute Verlauf ist deshalb nicht nur dunkler als die Vorlage,
   sondern auch KRAEFTIGER: seine Helligkeitsspanne betraegt ΔL 15,869
   gegen Figmas 12,919; Fassung 2 kaeme auf 7,636. Summiert ueber beide
   Stopps: gebaut ΔE 35,384, Fassung 2 ΔE 26,928.

   BEIDE FASSUNGEN GEHEN IN DIE RUECKFRAGE an die Vorlagen-Eigentuemer,
   samt Sichtpruefung. Gebaut ist die erste, weil sie den groesseren
   Kontrastabstand mitbringt; die zweite halbiert die Abweichung und
   haelt die Schwelle ebenfalls ueberall. Die Entscheidung ist
   offengelegt, nicht getroffen.

   ZUM VERGLEICH, WAS OHNE DIESE REGEL DASTUENDE (gerastert, fuenf
   Punkte, ohne die Regel gemessen):
     neues Design, dunkel  8,523 / 6,626 / 5,052 / 3,859 / 3,079
     neues Design, hell    3,009 / 3,316 / 3,708 / 4,216 / 4,700
   Also heute schon in beiden Themes unter der Schwelle, weil die
   Bruecke "--clr-accent-btn" auf cyan/500 haengt. Der Bestand im ALTEN
   Design ist davon nicht betroffen (6,480 bis 9,833) -- dies ist eine
   Luecke des neuen Designs, die dieser Task schliesst, kein Erbe.

   PRIMITIVE STATT SEMANTIK, UND WARUM. "--ax-action-primary" ist in
   BEIDEN Themes cyan/500, waere also genau der Wert mit 2,971. Ein
   themenstabiles Paar auf cyan/600 + cyan/700 gibt es in der
   Semantikschicht nicht: "--ax-action-primary-pressed" ist dunkel
   cyan/600, hell cyan/700, "--ax-action-primary-hover" dunkel cyan/400,
   hell cyan/600 -- ueber beide Themes ergaebe jede Kombination einen
   ANDEREN Verlauf, waehrend Figmas Verlauf themenunabhaengig ist. Die
   Primitive sind hier deshalb die ehrliche Schreibweise, und sie hat
   Vorbild: tokens.css setzt "--clr-voice-thinking: var(--ax-cyan-500)"
   mit derselben Begruendung ("fixed primitive, not the brandable
   chain"). Es ist die erste Stelle in dieser Datei, an der eine
   Primitive steht -- absichtlich, und nur an dieser einen.

   Die Richtung 135deg bleibt; Figma laeuft hell -> dunkel von links
   oben nach rechts unten, der Bestand umgekehrt. Uebernommen ist
   Figmas Richtung.

   NACHGETRAGEN MIT T2 (2026-09-16): DIE PRIMITIVEN SIND ERSETZT, DIE ZAHLEN
   NICHT. Die beiden "--ax-cyan-600/700" oben sind durch das Tokenpaar
   "--ax-chat-bubble-user-from"/"-to" ersetzt (tokens.css, blankes :root,
   neben "--ax-chart-series-1"; wertgleich cyan/600 -> cyan/700, die ganze
   Begruendung oben gilt unveraendert). Der Grund ist derselbe wie der fuer
   ".msg-bubble-user" selbst: der eingebettete Wirt (In-App-Hilfe, externes
   Widget) hing bisher an einem EIGENEN, themeabhaengigen Verlauf ueber
   "--clr-embed-user-grad" -> "action/primary" -> "-hover", der im dunklen
   Theme cyan/500 -> cyan/400 lieferte und weisse Schrift dort nur 2,971 bzw.
   2,142 hielt -- unter der 4,5. Ein Rollen-Token statt zweier Primitiven
   bindet jetzt BEIDE Wirte an dieselbe Entscheidung: "--clr-embed-user-grad"
   (tokens.css:229) zeigt seither auf dasselbe Paar, und der Mangel des
   eingebetteten Verlaufs ist damit geheilt, nicht nur dokumentiert. */
[data-design="new"] .msg-bubble-user {
  background: linear-gradient(135deg, var(--ax-chat-bubble-user-from), var(--ax-chat-bubble-user-to));
}

/* Die Typografie BEIDER Absenderzeilen. Figma-Knoten 46:2 (Nutzer) und
   46:6 (Assistent).

   RULING 2 DES LOGBUCHS: ".msg-sender" (webapp.css:2617-2626) und
   ".msg-sender-user" (:2627-2637) tragen im Bestand SECHS identische
   Deklarationen und unterscheiden sich nur in Farbe und Ausrichtung.
   Die gemeinsame Typografie schreibt deshalb dieser Task, EINMAL; Task 2
   setzt an ".msg-sender" nur noch die abweichende Farbe
   (--ax-accent-knowledge). Stuende sie nur am Nutzer-Label, muesste
   Task 2 dieselben drei Zeilen ein zweites Mal schreiben -- zwei Regeln
   mit derselben Aussage, die auseinanderlaufen, sobald eine geaendert
   wird.

   WAS ".msg-sender" DADURCH BEKOMMT, gemessen an einer echten
   OrganismsChatWindowBotMessage im echten Wirt: 11 px statt 10,
   Zeilenkasten 14 statt 20, Laufweite 1,1 statt 0,6 px. Farbe
   (--clr-accent) und "margin-bottom: 5px" bleiben unberuehrt -- sie
   stehen in der zweiten Regel unten, die nur das Nutzer-Label meint.
   Folgen im Aufbau: die Beschriftung wird 66,44 -> 77,48 px breit, ihr
   Kasten 20 -> 14 px hoch, ".msg-sender-row" 25 -> 20 px (der
   KI-Marker daneben bleibt 20 px hoch und bestimmt die Zeile jetzt
   allein), und die Assistentenblase rueckt 2,5 px nach oben. Das alte
   Design bleibt an allen diesen Werten unveraendert (gemessen).
   ZUR UEBERGABE AN TASK 2: diese drei Deklarationen sind bis dahin von
   KEINER Zusicherung gedeckt -- in der Galerie steht noch keine
   Assistentenblase. Task 2 baut die Kachel und muss sie mitbewachen.

   Vier Deklarationen des Bestands stehen schon richtig und werden nicht
   wiederholt: "font-weight: 600", "text-transform: uppercase",
   "text-align: right" (nur am Nutzer-Label) und "display: block".

   "0.1em" ist Figmas Laufweite 10 % -- PROZENT ist bei Figma der
   Normalfall, nicht Pixel (Messregel 6, erarbeitet in "05 · Data",
   Teil B). Als 10 px gelesen waere die Beschriftung unbrauchbar breit.

   "--ax-text-muted" statt Legacys "--clr-text-secondary" senkt den
   Kontrast, und wie weit, haengt am WIRT -- der ist deshalb gerastert
   und nicht angenommen worden. Die Beschriftung steht im Cockpit auf
   dem Seitengrund (".chat-window" ist durchsichtig, gemessen), in der
   Galerie dagegen auf ".gallery-group" (--ax-bg-surface-1):

     Seitengrund   dunkel 5,070   hell 6,659
     surface-1     dunkel 4,796   hell 7,416

   Alle vier ueber 4,5. Auf "surface-2" waeren es 4,477 und auf
   "surface-3" 3,984 -- dort verfehlte dieses Token die Schwelle; kein
   Wirt dieses Bauteils traegt eine dieser beiden Flaechen. Legacy kaeme
   auf 8,775 bzw. 11,049; die Absenkung ist also gewollt und gemessen,
   nicht uebersehen.

   Figmas "Abstand 8" liegt am unteren Aussenabstand, nicht an einem
   "gap": ".msg-user-content" IST zwar ein Flex-Container
   (webapp.css:2963), aber sein "gap" traefe auch die Fusszeile
   darunter, deren Abstand Figma nicht nennt (".msg-user-footer" traegt
   "margin-top: 4px", webapp.css:2984). Der Aussenabstand trifft genau
   die eine Fuge, um die es geht -- und es ist derselbe Mechanismus, den
   der Bestand mit "margin-bottom: 5px" schon benutzt. */
[data-design="new"] .msg-sender,
[data-design="new"] .msg-sender-user {
  font-size: var(--ax-font-size-label-caps);
  line-height: var(--ax-line-height-label-caps);
  letter-spacing: 0.1em;
}

/* Farbe und Abstand gehoeren dagegen NUR dem Nutzer-Label: die
   Assistentenzeile traegt im Bestand "--clr-accent" und bekommt in
   Task 2 "--ax-accent-knowledge", und ueber ihren Abstand entscheidet
   Figmas Knoten 46:6, nicht dieser Task. */
[data-design="new"] .msg-sender-user {
  color: var(--ax-text-muted);
  margin-bottom: 8px;
}

/* ══ 07 · Chat & AI, Teil A — Task 2: Die Assistentenblase ════════
   Figma-Knoten 46:6, der RAHMEN der Antwort -- ohne den Markdown-Fluss
   darin (Task 3), ohne Codeblock (4), Quellenzeile (5) und
   Werkzeugaufruf (6). Der Bestand steht in webapp.css:2589-2695
   (Avatar, Absenderzeile, Koerper, Begruessung, Fusszeile) und :2729
   (Aktionsknoepfe). Erzeugt wird das alles ausschliesslich von
   OrganismsChatWindowBotMessage (chatwindowbotmessage.js:173-342) --
   ".msg-sender", ".msg-sender-row", ".msg-footer" und ".msg-meta-chip"
   haben im ganzen Frontend keinen zweiten Erzeuger (geprueft).

   ZWEI VARIANTEN AUS EINEM ORGANISMUS. "renderUi()" (:136-141) und
   "setupUi()" (:173-177) entscheiden per Ternary auf
   "messageData.title": mit Titel ".msg-greeting"/".msg-bubble-greeting"
   (die Begruessung), ohne ".msg-bot"/".msg-bubble-bot". Beide teilen
   Avatar-, Inhalts- und Absenderzeilenklassen; nur die Begruessung hat
   KEINE Fusszeile (setupUi kehrt vor ihr zurueck). Jede Regel dieses
   Abschnitts wurde deshalb an BEIDEN Kacheln gemessen.

   DREI SPEZIFITAETEN, ZUSAETZLICH ZU DEN DREI IM KOPF DIESES
   ABSCHNITTS (alle drei gemessen, nicht gelesen):

   4. "[data-theme=\"light\"] .msg-bubble-bot" (webapp.css:3023) wiegt
      (0,2,0) und setzt "background", "border-color" UND "box-shadow".
      Zwei davon setzt dieser Task ebenfalls -- gewonnen wird im hellen
      Theme also NUR ueber die Ladereihenfolge, wie beim Verlauf der
      Nutzerblase in Task 1. Verliert diese Datei ihren letzten Platz,
      faellt die Antwortblase im hellen Theme lautlos auf
      "--clr-surface-pale-1" zurueck -- und nur dort. Im hellen Block
      der Testdatei ausdruecklich zugesichert.

   5. "[data-theme=\"light\"] .msg-bubble-greeting" (webapp.css:3029)
      setzt "background" und "border-color" der Begruessung. Dieser Task
      setzt an der Begruessung BEIDES NICHT (Begruendung unten) -- die
      Regel bleibt also unangetastet wirksam, und das ist Absicht.

   6. "body.chat-embedded .msg-bubble-bot, ... .msg-bubble-greeting"
      (webapp.css:2220) wiegt (0,2,1) und SCHLAEGT damit jede Regel
      dieses Abschnitts -- aber nur fuer "background" und "color". Die
      In-App-Hilfe und das externe Widget behalten fuer die Antwortblase
      deshalb "var(--acw-bot-bg, var(--clr-embed-bot-bg))", und die
      Bruecke haengt "--clr-embed-bot-bg" auf "--ax-bg-surface-2"
      (tokens.css:190) -- also NICHT auf Figmas "--ax-bg-surface-1".
      ANDERS ALS BEIM NUTZER-VERLAUF (Task 1) IST DAS KEIN
      KONTRASTPROBLEM -- im Gegenteil. Gerastert im eingebetteten Wirt:

        neues Design, dunkel   Text auf rgb(26,24,38)     14,124
        neues Design, hell     Text auf rgb(244,243,247)  16,933
        altes Design, dunkel   Text auf rgb(19,25,41)     14,210
        altes Design, HELL     Text auf rgb(19,25,41)      1,096

      Die letzte Zeile ist ein Fund aus dieser Messung und ein Mangel
      des ALTEN Designs: "--clr-embed-bot-bg" ist dort ein fester
      dunkler Wert, den der helle Theme-Block nicht nachzieht -- die
      eingebettete Antwort steht im hellen alten Design also faktisch
      unlesbar da. Die Bruecke heilt das nebenbei, weil sie das Token
      auf "--ax-bg-surface-2" haengt. Radius, Innenabstand,
      Schriftgroesse und Zeilenkasten dieses Tasks kommen im
      eingebetteten Wirt sehr wohl an (gemessen). Befund an Spec
      Abschnitt 7.

   WAS DER TASK AN GROESSE KOSTET, gemessen an den echten Instanzen der
   Galeriekacheln (1280 x 720, dunkel): die Antwortblase waechst in der
   HOEHE von 73,44 auf 88,00 px, die ganze Nachricht von 122,44 auf
   160,00 px. Die 37,56 loesen sich restlos auf:
     14,56  die Blase selbst -- davon 8 Innenabstand (12 -> 16 oben und
            unten), 2,56 Zeilenkasten (21,44 -> 24) und 4 aus den
            em-Aussenabstaenden des <p> im Fluss, die mit der
            Schriftgroesse wachsen (13 -> 15 px). Der letzte Posten
            gehoert dem Fluss und damit Task 3; er steht hier, weil er
            sonst als unerklaerter Rest daneben laege.
     12     der neue Abstand unter der Absenderzeile
      7     der groessere Abstand ueber der Fusszeile (5 -> 12)
      4     die hoeheren Aktionsknoepfe (Fusszeile 24 -> 28)
   Die Begruessungsblase geht von 74,09 auf 88,00, ihre Nachricht von
   94,09 auf 120,00 px.

   NACHTRAG AUS TASK 3, weil dieser Absatz sonst eine gemessene Zahl
   behauptete, die es nicht mehr gibt: Task 3 setzt den ersten und
   letzten Block des Flusses buendig an den Innenabstand
   ("margin-top"/"margin-bottom" auf 0). Bei einer einsaetzigen Antwort
   ist derselbe <p> beides -- die 15 px oben UND unten fallen weg, und
   beide Blasen der Galeriekacheln messen jetzt 58,00 statt 88,00 px
   (16 Innenabstand + 24 Zeilenkasten + 16 Innenabstand + 2 Rahmen).
   Das ist Figmas "Innenabstand 16"; vorher waren es faktisch 31.
   MIT DEN BLASEN WANDERN DIE BEIDEN NACHRICHTENHOEHEN DESSELBEN
   ABSATZES: ".msg-bot" misst jetzt 130,00 statt 160,00 und
   ".msg-greeting" 90,00 statt 120,00 px (gemessen an denselben
   Kacheln). Die Rechnungen oben bleiben als Rechnungen dieses Tasks
   richtig, ihre Ergebnisse gelten nur ohne Task 3.
   NEBENBEFUND BEIM NACHMESSEN, nicht Task 3s Gebiet und deshalb nur
   vermerkt: die Legacy-AUSGANGSwerte derselben zwei Zeilen messen
   sich heute als 127,44 und 99,09 statt der oben genannten 122,44 und
   94,09 -- je 5 px mehr, in beiden Faellen. Die Blasenwerte 73,44 und
   74,09 daneben stimmen exakt, der Unterschied liegt also ausserhalb
   der Blase. Woher die 5 px kommen, ist hier nicht nachgegangen
   worden; sie sind unabhaengig von diesem Task (der Elterncommit
   liefert dieselben Zahlen).

   DIE BREITE IST KEIN SOLLWERT DIESES TASKS und steht deshalb nicht
   daneben: die Galeriekachel waechst mit ihrem Inhalt, und die
   Fusszeile in Geist Mono ist breiter als vorher -- gemessen wird die
   Blase dadurch 532,61 statt 416,22 px breit, ohne dass eine Regel
   dieses Abschnitts die Breite anfasst. Im Cockpit haengt sie an der
   Fensterbreite.

   Der Zeilenkasten des Koerpers steigt von 21,45 auf 24, die Schrift
   von 13 auf 15 px -- "small" ist ein Schluesselwort und ergibt
   gemessen 13 px (Task 1 hat das an der Nutzerblase nachgewiesen). */

/* Der Koerper der Antwort. Figma-Knoten 46:6.

   DIE ACHT DEKLARATIONEN DES BESTANDS (webapp.css:2638-2647), EINZELN
   ENTSCHIEDEN:

     background      ERSETZT  -- der Bestand setzt "--clr-surface-mid"
                                (60 % surface-1 + 40 % surface-3, im
                                neuen Design rgb(25, 24, 37)); im hellen
                                Theme schlaegt ihn webapp.css:3024 mit
                                "--clr-surface-pale-1", gemessen
                                rgb(243, 243, 244). Figma will
                                "--ax-bg-surface-1", also rgb(18, 17, 28)
                                bzw. reines Weiss.
                                DIE BLASE HEBT SICH DADURCH IN DEN
                                THEMEN GEGENLAEUFIG AB, gerechnet gegen
                                "--ax-bg-app", den Grund im Cockpit:
                                  dunkel  ΔE 7,390 -> 3,545  (weniger)
                                  hell    ΔE 1,587 -> 4,494  (mehr)
                                Beide bleiben ueber der Wahrnehmungs-
                                schwelle 2,3; im hellen Theme war der
                                Bestand mit 1,587 faktisch nicht vom
                                Seitengrund zu unterscheiden und wurde
                                nur ueber seinen Rahmen sichtbar.
                                IN DER GALERIE misst man das NICHT:
                                dort steht die Kachel auf
                                ".gallery-group", und das IST
                                "--ax-bg-surface-1" -- gerastert also
                                ΔE 0,000 zur Blase. Der Wirt gehoert
                                zur Messung (Messregel 3); die
                                Testdatei sichert deshalb die Farbe
                                und den Rahmen zu, nicht den Abstand
                                zum Grund.
     border-color    ERSETZT  -- Figma: 1px "--ax-border-soft". Der
                                Bestand faerbt den Rahmen mit dem Akzent
                                ("--clr-border-accent", im neuen Design
                                22 % cyan/500 auf surface-3). NUR die
                                Farbe wird ersetzt: Breite und Stil des
                                Bestands sind schon Figmas 1px solid,
                                und eine Kurzform "border:" wuerde sie
                                ohne Not neu behaupten. Gemessen hebt
                                sich der neue Rahmen von der neuen
                                Flaeche mit ΔE 4,531 (dunkel) und 9,350
                                (hell) ab -- in beiden Themes ueber der
                                Wahrnehmungsschwelle 2,3.
     border-radius   ERSETZT  -- 14 auf allen vier Ecken. Siehe unten.
     padding         ERSETZT  -- Figmas 16 rundum statt 12 / 15.
     color           BLEIBT   -- Figma will "--ax-text-primary". Der
                                Bestand setzt "var(--font-color-application)",
                                das haengt ueber "--clr-text-primary" an
                                der Bruecke und endet gemessen auf
                                rgb(232, 230, 238) bzw. rgb(18, 17, 28)
                                -- Figmas Werte, Zeichen fuer Zeichen.
                                Eine eigene Deklaration waere eine Regel
                                ohne Wirkung; im eingebetteten Fall
                                schluege "body.chat-embedded ..." (0,2,1)
                                sie ohnehin. Waechter in der Testdatei.
     line-height     ERSETZT  -- Figma 24 px. RULING 3: Zeilenkasten und
                                Schriftgroesse des Koerpers gehoeren
                                diesem Task, weil der Bestand sie an der
                                KLASSE setzt; Task 3 setzt Groessen nur
                                dort, wo ein Element im Fluss sie selbst
                                braucht.
     box-shadow      BLEIBT   -- Figmas Knoten fuehrt keinen Effekt.
                                Dieselbe Entscheidung und dieselbe
                                Begruendung wie an der Nutzerblase: das
                                Schweigen der Vorlage ueber einen Effekt
                                ist kein Sollwert. Waechter in der
                                Testdatei -- und im hellen Theme setzt
                                webapp.css:3026 einen EIGENEN, schwaecheren
                                Schein (.06 statt .1), der ebenfalls
                                stehen bleibt.
     font-size       ERSETZT  -- 15 px statt des Schluesselworts "small"
                                (gemessen 13 px, nicht 13,333).

   DER RADIUS ZIEHT MIT, UND ZWAR ZWINGEND. Der Bestand setzt an der
   Antwortblase "4px 14px 14px 14px" -- die Ecke ZUM ABSENDER hin ist
   scharf, spiegelbildlich zur Nutzerblase ("14px 4px 14px 14px").
   Task 1 hat die Nutzerblase auf Figmas 14 rundum gebracht; bliebe die
   Antwortblase auf ihrer scharfen Ecke, stuende die Familie halb
   umgebaut da -- eine scharfe Ecke ohne ihr Gegenstueck. Die Vorlage
   setzt an beiden Knoten 14. Die Begruessung faehrt aus demselben
   Grund mit (sie steht in derselben Legacy-Regel).

   "--ax-radius-lg" statt der literalen 14, der Innenabstand dagegen
   LITERAL: beides genau wie an der Nutzerblase. Das Radius-Token faellt
   bei <= 768 px bewusst auf 12, "--ax-space-4" faellt dort aber auf 12,
   und Figmas 16 ist eine Aussage ueber die Blase, nicht ueber den
   Bildschirm. */
[data-design="new"] .msg-bubble-bot {
  background: var(--ax-bg-surface-1);
  border-color: var(--ax-border-soft);
  border-radius: var(--ax-radius-lg);
  padding: 16px;
  font-size: var(--ax-font-size-body-md);
  line-height: var(--ax-line-height-body-md);
}

/* Die Begruessungsblase faehrt in FORM und SCHRIFT mit, behaelt aber
   ihre Farben. Sie hat in Figma keinen eigenen Knoten -- die Vorlage
   kennt sie nicht -- und deshalb ist hier zu entscheiden statt
   abzuschreiben.

   ENTSCHIEDEN WURDE ENTLANG DER FRAGE, WAS AN IHR AUSSAGE IST UND WAS
   BLOSS ALTER WERT IST:

     Radius, Innenabstand, Schriftgroesse, Zeilenkasten -> MITZIEHEN.
       Der Radius steht mit der Antwortblase in DERSELBEN Legacy-Regel
       (webapp.css:2662) und in derselben 640-px-Verdichtung
       (:8652-8655); 12/15 und "small" sind bei ihr Zeichen fuer Zeichen
       dieselben Werte wie an der Antwort. Das ist kein Sonderfall,
       sondern gemeinsames Erbe -- und zwei Blasen im selben Gespraech
       mit verschiedenem Radius waeren genau die halbe Uebernahme, vor
       der Task 1 warnt. Ihr Zeilenkasten war 1,7 statt 1,65 (22,1 statt
       21,45 px bei 13 px); die 0,05 Unterschied sind kein
       Gestaltungssatz, und beide landen jetzt auf Figmas 24.

     Verlauf, Rahmenfarbe, Textfarbe -> BLEIBEN.
       Das IST der Sonderfall: eine Begruessung soll sich von einer
       Antwort unterscheiden, und der Bestand sagt das mit einem eigenen
       Verlauf ("--clr-shell" -> "--clr-surface-mid") und
       "--clr-text-secondary". Die Kursivschrift ist seit #2023 in
       beiden Designs entfallen (webapp.css). Nichts davon widerspricht der Vorlage,
       weil die Vorlage dazu schweigt.
       GERASTERT, weil getComputedStyle an einem Verlauf nur
       "rgba(0, 0, 0, 0)" meldet (Messregel 2) -- der Text haelt nach
       diesem Task auf beiden Enden der Achse:
         dunkel  rgb(14,12,23) .. rgb(25,24,37)      8,600 .. 7,775
         hell    rgb(236,236,237) .. rgb(243,243,244) 10,423 .. 11,097
       Alle vier ueber 4,5, mit Abstand.
       EIN NEBENBEFUND, DER BEIM MESSEN HERAUSKAM und der Grund ist,
       warum die Rahmenfarbe hier ueberhaupt zur Frage stand: die
       Grundregel gibt der Begruessung "--clr-surface-3"
       (im neuen Design dunkel rgb(36,34,51), ΔE 5,334 zu Figmas
       "--ax-border-soft"), im HELLEN Theme aber setzt
       webapp.css:3031 "border-color: var(--clr-text-primary)" -- also
       gemessen rgb(18, 17, 28), einen fast schwarzen 1-px-Rand um eine
       fast weisse Blase. Das ist eine Aussage des Bestands und keine
       Folge dieses Tasks; sie bleibt unangetastet und geht als Befund
       in die Sichtpruefung. */
[data-design="new"] .msg-bubble-greeting {
  border-radius: var(--ax-radius-lg);
  padding: 16px;
  font-size: var(--ax-font-size-body-md);
  line-height: var(--ax-line-height-body-md);
}

/* Der Agentenname. Figma-Knoten 46:6: Semi Bold 11, 10 % Laufweite,
   Versalien, "--ax-accent-knowledge" (tuerkis).

   TYPOGRAFIE STEHT SCHON DA (Ruling 2): "font-size", "line-height" und
   "letter-spacing" hat Task 1 auf die gemeinsame Selektorliste
   ".msg-sender, .msg-sender-user" gehoben, weil beide Absenderzeilen im
   Bestand sechs identische Deklarationen tragen. Dieser Task setzt
   deshalb NUR die abweichende Farbe -- und deckt im Gegenzug die drei
   Deklarationen dort mit ab, die bis hierher von keiner Zusicherung
   gedeckt waren (Task 1s Bringschuld, ausdruecklich mit Frist bis
   Task 2). Die Zeilenhoehe 14 wird NICHT zurueckgenommen: Figmas
   Agentenname traegt denselben Textstil wie das Nutzer-Label, und
   gemessen sitzt die Zeile sauber (Kasten 14 px, Zeile 20 px, vom
   KI-Marker daneben bestimmt).

   HIER WEICHT DIESER TASK VON DER VORLAGE AB, UND ZWAR NUR IM HELLEN
   THEME. Gerastert gegen den Grund, auf dem die Zeile wirklich steht
   (Cockpit: "--ax-bg-app"; Galerie: ".gallery-group" = surface-1):

     dunkel  teal/500 rgb(6,182,212)   auf bg-app  8,101   surface-1 7,705
     hell    teal/600 rgb(8,145,178)   auf bg-app  3,333   surface-1 3,682

   Das helle Theme VERFEHLT 4,5 auf beiden Wirten. Der IST-Stand traegt
   dort "--clr-accent", im neuen Design also cyan/600 rgb(0,122,176) --
   und DER VERFEHLT SIE AUF EINEM DER BEIDEN WIRTEN EBENFALLS:
   4,310 auf bg-app, 4,761 auf surface-1. Die Lage ist also nicht
   "Figma waere eine Verschlechterung", sondern: Figma verfehlt auf
   beiden Wirten, der Bestand auf einem, und nur der gebaute Wert traegt
   auf beiden. Rulings 10 und 12: eine bekannt schlechte Kontrastzahl
   wird nicht ausgeliefert, auch wenn die Vorlage sie vorschreibt.

   GEBAUT WIRD DESHALB im hellen Theme "--ax-accent-knowledge-on-bg",
   der lesbare Tuerkiston derselben Rampe (teal/800, rgb(21,94,117)):
   6,578 auf bg-app, 7,267 auf surface-1. Es ist die HELLSTE Stufe der
   Teal-Rampe, die 4,5 haelt -- eine Zwischenstufe zwischen teal/600 und
   teal/800 gibt es nicht. Preis: ΔE 21,265 zur Vorlage.

   IN DIE RUECKFRAGE GEHEN DREI FASSUNGEN, NICHT ZWEI -- die Einschraen-
   kung "keine Zwischenstufe" gilt fuer die TOKENS, nicht fuer die
   Frage. Task 1 hat an derselben Stelle eine Zwischenfassung per
   "color-mix" gebaut und mitgegeben, damit nicht ueber eine Option
   abgestimmt wird, wo es zwei gibt:

     1  gebaut: "--ax-accent-knowledge-on-bg" (teal/800, rgb(21,94,117))
        4,5 mit Luft: 6,578 / 7,267.  ΔE 21,265.
     2  color-mix(in srgb, --ax-teal-600 50%, --ax-teal-800), gemessen
        rgb(14,119,147): 4,661 auf bg-app, 5,149 auf surface-1.
        ΔE 10,557 -- also KNAPP DIE HAELFTE der Abweichung, und auf
        beiden Wirten ueber der Schwelle. Preis: eine Primitive-Mischung
        statt eines Tokens, und nur 0,161 Luft zur Schwelle.
     3  die minimale farbtonerhaltende Abdunklung von teal/600,
        rgb(7,129,159): 4,516 gegen Weiss, ΔE 6,388 -- steht an keinem
        Token UND liegt auf dem Wirt "--ax-bg-app" bereits wieder unter
        der Schwelle. Vollstaendigkeitshalber genannt, nicht empfohlen.

   Gebaut ist die erste, weil sie den groessten Kontrastabstand hat.

   IM DUNKLEN THEME BLEIBT ES BEI FIGMAS WERT. Nur das helle Theme hat
   das Problem, und eine Abweichung dort, wo keine noetig ist, waere
   eine zweite Abweichung ohne Grund.

   DER BEFUND IST GROESSER ALS DIESER TASK, UND ES IST DIESELBE ZAHL.
   "05 · Data", Teil A traegt denselben Tuerkiston in derselben Rolle am
   Tabellenkopf (components.css:4154, ":where([data-design=\"new\"]) th").
   Am echten <th> gemessen, Grund gerastert, helles Theme:
   rgb(8,145,178) auf rgb(244,243,247) = 3,333 -- ZEICHENGLEICH die Zahl
   des Agentennamens auf dem Cockpit-Grund, denn "--ax-bg-app" und
   "--ax-bg-table-header" sind im hellen Theme BEIDE "--ax-ink-50".
   Derselbe Ton, dieselbe Rolle, dieselbe Flaeche, dieselbe Zahl -- dort
   einmal sehenden Auges abgenommen (Spec-Befund 15 der Abnahme von
   "05 · Data" Teil A). Eine erste Fassung dieses Kommentars nannte hier
   2,978; das ist teal/600 gegen "--ax-ink-100", im hellen Theme also
   surface-3/hover/border-soft und NICHT der Grund des Kopfes --
   Messregel 3, verletzt an genau der Stelle, die einen Befund in fremde,
   abgenommene Arbeit traegt.

   Spec Abschnitt 7.3 fuehrt den tuerkisen Agentennamen schon als offene
   Frage an die Vorlagen-Eigentuemer; die Antwort darauf gehoert in die
   Tokenschicht und muss BEIDE Stellen treffen, nicht diese eine. Bis
   dahin ist die Gegenregel unten die kleinstmoegliche Fassung: ein
   Selektor, ein Token, ein Theme.

   Im DUNKLEN Theme fallen die beiden Faelle dagegen auseinander: der
   Tabellenkopf steht dort auf "--ax-ink-800" (7,193), der Agentenname
   auf "--ax-bg-app" (8,101). Beide ueber der Schwelle, aber es ist
   nicht mehr derselbe Messpunkt. */
[data-design="new"] .msg-sender {
  color: var(--ax-accent-knowledge);
}

[data-design="new"][data-theme="light"] .msg-sender {
  color: var(--ax-accent-knowledge-on-bg);
}

/* Figmas "Abstand 12" der Nachrichtenspalte. Der Knoten stapelt
   Absenderzeile, Koerper und Fusszeile mit 12 px Zwischenraum; der
   Bestand hat zwischen Absenderzeile und Blase GAR KEINEN Abstand
   (gemessen: 0 px -- ".msg-sender" traegt zwar "margin-bottom: 5px",
   das aber innerhalb der Flexzeile ".msg-sender-row", wo der 20 px hohe
   KI-Marker die Hoehe bestimmt) und unter der Blase 5 px
   ("margin-top" an ".msg-footer", webapp.css:2674).

   GESETZT WIRD DER AUSSENABSTAND, NICHT "gap". ".msg-bot-content" ist
   kein Flex-Container (gemessen "display: block"), ein "gap" waere dort
   wirkungslos; und "margin-bottom" an ".msg-sender" selbst traefe ein
   Flex-Kind und wuerde von der Zeilenhoehe des KI-Markers verschluckt.
   Die beiden Aussenabstaende unten treffen genau die zwei Fugen, um die
   es geht -- und "margin-top" an der Fusszeile ist derselbe Mechanismus,
   den der Bestand dort schon benutzt.

   LITERAL 12 statt "var(--ax-space-3)": das Token faellt bei <= 768 px
   auf 10. Dieselbe Linie wie beim Innenabstand oben.

   OFFEN GEBLIEBEN IST, WAS "Abstand 12" IN DER ZEILE "Fusszeile" DER
   SOLLWERTE MEINT: den Abstand der Fusszeile nach oben (so gelesen) oder
   den Zwischenraum IHRER Elemente. ".msg-meta" traegt heute "gap: 8px"
   (webapp.css:2681); der bleibt unangetastet, weil die zweite Lesart
   den ersten Wert der Koerperzeile doppelt und die erste ihn
   fortsetzt. Befund fuer die Sichtpruefung. */
[data-design="new"] .msg-sender-row {
  margin-bottom: 12px;
}

[data-design="new"] .msg-footer {
  margin-top: 12px;
}

/* Der Avatar. Figma: 34 x 34, rund, Flaeche "--ax-accent-ai" (violett).

   GROESSE UND FORM STEHEN SCHON RICHTIG (34 x 34, "border-radius: 50%",
   webapp.css:2589-2602) und werden nicht wiederholt -- Waechter in der
   Testdatei. Zu aendern ist nur die Flaeche: der Bestand legt dort
   einen cyanfarbenen Verlauf an ("--clr-accent-btn" -> "--clr-accent"),
   Figma eine einzelne violette Flaeche.

   SIE IST SICHTBAR, ENTGEGEN DEM ERSTEN EINDRUCK. Im Kreis liegt ein
   34 x 34 grosses <img> mit "object-fit: cover" -- man koennte meinen,
   es deckt die Flaeche vollstaendig. Gerastert stimmt das nur in der
   Mitte (dort liegt in allen vier Kombinationen rgb(162,175,192), das
   Bild). An der Ecke (12 % / 12 %) misst die Galeriekachel dagegen die
   FLAECHE, durch die Transparenz des Bildes hindurch -- und genau dort
   schlaegt dieser Task durch:
     dunkel  rgb(14, 41, 62)   -> rgb(38, 29, 65)
     hell    rgb(211,238,250)  -> rgb(229,217,248)
   Agenten ohne eigenes Avatarbild fallen ausserdem auf
   "./images/favicon.png" zurueck (templatechatwindow.js:63/507), das
   ebenfalls transparente Raender hat.

   DER SCHEIN FAEHRT MIT, UND ZWAR NUR IN DER FARBE. Der Bestand legt
   einen 12-px-Schein in der Akzentfarbe um den Kreis
   ("0 0 12px rgba(--clr-accent-rgb,.45)"). Figmas Knoten fuehrt keinen
   Effekt, und nach derselben Regel wie an den Blasen ("Schweigen ueber
   einen Effekt ist kein Sollwert") bleibt er. Seine FARBE aber war an
   die Flaeche gebunden, die dieser Task austauscht: ein cyanfarbener
   Hof um eine violette Scheibe waere kein erhaltener Bestand, sondern
   ein Bruch, den dieser Task selbst verursacht haette. "color-mix" statt
   "rgba(var(--...-rgb), .45)", weil es Deckung und Ton aus DERSELBEN
   Quelle nimmt und damit auch dem Themenwechsel folgt
   (violet/300 dunkel, violet/400 hell). Geometrie und Deckkraft des
   Bestands bleiben unveraendert. */
[data-design="new"] .msg-bot-avatar,
[data-design="new"] .msg-greeting-avatar {
  background: var(--ax-accent-ai);
  box-shadow: 0 0 12px color-mix(in srgb, var(--ax-accent-ai) 45%, transparent);
}

/* Die Fusszeile -- DER ERSTE VERWENDER VON GEIST MONO IM GANZEN
   PRODUKT. Figma: Geist Mono Regular 12 / 18, "--ax-text-muted".

   Die Tokens sind seit Schritt 1 da und waren bis hierher unbenutzt:
   "--ax-font-mono" (tokens.css:317, selbst gehostet, zwei @font-face
   fuer latin und latin-ext), "--ax-font-size-mono-sm: 12px" und
   "--ax-line-height-mono-sm: 18px" -- exakt Figmas Werte.

   WAS EINE FESTBREITENSCHRIFT KOSTET, gemessen am Modellchip
   ("gpt-4o-mini", der einzige Chip mit stabilem Text -- der zweite
   traegt einen Zeitstempel und haengt damit an Zeitzone und Locale des
   Laeufers): 56,50 -> 79,20 px, also +40 %. Die Fusszeile traegt
   Modellname, Dauer und Zeitstempel NEBENEINANDER in einer Flexzeile
   mit "flex-wrap: wrap" (webapp.css:2682); sie bricht bei 1280 px nicht
   um, und bei <= 1024 px blendet der Bestand den dritten Chip ohnehin
   aus (webapp.css:6720). Die Zeile wird ausserdem flacher, nicht hoeher:
   Zeilenkasten 20 -> 18.

   DIE FARBE IST DIE EIGENTLICHE ENTSCHEIDUNG DIESES BLOCKS.
   "--clr-text-muted" ist ueber die Bruecke NICHT auf "--ax-text-muted"
   umgehaengt -- es rechnet sich statt dessen aus dem gebrueckten
   "--clr-text-secondary" (webapp.css:79/341: 80 % davon mit Schwarz
   dunkel, 60 % mit Weiss hell). Gemessen, jeweils auf dem Wirt, auf dem
   die Fusszeile wirklich steht:

     dunkel  Ist  rgb(138,137,150)  bg-app 5,712   surface-1 5,433
             Soll rgb(129,127,146)  bg-app 5,043   surface-1 4,796
     hell    Ist  rgb(134,132,146)  bg-app 3,318   surface-1 3,665
             Soll rgb( 85, 83,106)  bg-app 6,713   surface-1 7,416

   Im hellen Theme verfehlt der IST-Stand die 4,5 auf beiden Wirten --
   Figmas Token repariert das. Im dunklen kostet der Wechsel etwas
   Kontrast, bleibt aber ueber der Schwelle. Beide Richtungen sprechen
   fuer Figmas Wert, und er ist kein Nichts: ΔE 20,424 (hell) und 5,095
   (dunkel) zum Ist-Stand, beide ueber der Wahrnehmungsschwelle.

   "--ax-text-muted" haelt 4,5 nicht ueberall (auf surface-2 4,477, auf
   surface-3 3,984) -- deshalb wurde der Grund gerastert statt
   angenommen. Die Fusszeile steht AUSSERHALB der Blase, direkt in
   ".msg-bot-content", also auf dem Seitengrund (Cockpit) bzw. auf
   ".gallery-group" (Galerie). Beides sind bg-app und surface-1, die
   zwei Flaechen, auf denen dieses Token traegt. */
[data-design="new"] .msg-meta-chip {
  font-family: var(--ax-font-mono);
  font-size: var(--ax-font-size-mono-sm);
  line-height: var(--ax-line-height-mono-sm);
  color: var(--ax-text-muted);
}

/* #2057: Details-Knopf neben dem Datum und sein Popover
   (moleculeantwortdetails.js; Grundgeruest in webapp.css). Der Knopf
   (0,2,0) schlaegt die Basisregel ":where(...) button" (0,0,1); deren
   Hover-Regel faerbt NUR den Hintergrund (auf --ax-action-primary-hover)
   -- deshalb eine eigene Hover-Regel (0,3,0) mit Schriftfarbe. */
[data-design="new"] .antwort-details-knopf {
  display: inline-flex;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 1px solid var(--ax-border-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--ax-text-secondary);
  font-family: var(--ax-font-mono);
  font-size: 11px;
  font-style: normal;
  font-weight: 600;
}
[data-design="new"] .antwort-details-knopf:hover,
[data-design="new"] .antwort-details-knopf[aria-expanded="true"] {
  background: var(--ax-bg-surface-3);
  border-color: var(--ax-text-secondary);
  color: var(--ax-text-primary);
}
[data-design="new"] .antwort-details-popover {
  padding: var(--ax-space-2) var(--ax-space-3);
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-sm);
  background: var(--ax-bg-elevated);
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  font-size: var(--ax-font-size-label-sm);
  line-height: var(--ax-line-height-label-sm);
  box-shadow: var(--ax-shadow-card);
}
[data-design="new"] .antwort-details-liste dt {
  color: var(--ax-text-secondary);
}

/* Die Aktionsknoepfe. Figma: 28 x 28, Radius 10.

   DER RADIUS STEHT SCHON RICHTIG, und zwar aus dem Designsystem selbst:
   ":where([data-design=\"new\"]) button" (components.css:111) setzt
   "--ax-radius-md", also genau 10 px. Gemessen im Bestand des neuen
   Designs: 10 px an allen vier Ecken. Er wird nicht wiederholt --
   Waechter in der Testdatei, denn er ist die einzige Zusicherung, die
   den Knopf noch mit der Basisregel verbindet.

   ZU AENDERN IST DIE GROESSE: "button.image-small" (webapp.css:3972)
   setzt 16 x 16 bei (0,1,1). Der Selektor unten wiegt (0,3,1) und
   gewinnt unabhaengig von der Ladereihenfolge.

   DIE BEIDEN AUSRICHTUNGSZEILEN SIND KEINE ZUGABE, SONDERN DIE FOLGE.
   Die Basisregel deklariert "display: inline-flex"; gerechnet steht am
   Knopf "flex", weil er Flex-Kind von ".msg-actions" ist und
   Flex-Kinder blockifiziert werden (im alten Design entsteht aus
   "inline-block" auf demselben Weg "block"). Solange Kasten und Symbol
   beide 16 px gross sind, faellt der Flex-Kasten nicht auf; bei 28 x 28
   saesse das 16-px-Symbol ohne diese beiden Zeilen oben links statt in
   der Mitte -- gemessen, die Einzelloeschung liefert je "normal".
   Innenabstand statt Groesse waere kein Ausweg: webapp.css setzt
   "box-sizing: border-box", ein Polster wuechse also nach innen.

   ".msg-actions" hat im ganzen Frontend genau einen Erzeuger
   (chatwindowbotmessage.js:294), der Selektor kann also keine anderen
   Knoepfe treffen. Der Zwischenraum der Knoepfe ("gap: 3px",
   webapp.css:2731) bleibt: Figma nennt fuer die Knopfreihe keinen. */
[data-design="new"] .msg-actions button.image-small {
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
}

/* ══ 07 · Chat & AI, Teil A — Task 3: Der Markdown-Fluss ══════════
   Figma-Knoten 46:6, der INHALT der Antwort -- Absaetze, Listen,
   Zitate und Zwischenueberschriften. Ohne Codeblock (Task 4),
   Quellenzeile (5) und Werkzeugaufruf (6).

   DER ANTWORTKOERPER IST EIN KLASSENLOSES <div>
   (chatwindowbotmessage.js:200: "new AtomContainer(messageContainer,
   '')"), in das renderMarkdown() (:694-705) das Ergebnis von
   MarkDownConverter.convertMarkDownToHtml() als innerHTML schreibt.
   Was darin gilt, kommt deshalb aus GLOBALEN, UNGESCOPTEN
   Elementregeln -- oder, wo es keine gibt, aus der Browservorgabe.

   WARUM HIER KEINE EINZIGE ELEMENT-BASISREGEL STEHT. Die
   Subset-Invariante ("05 · Data" Teil A, generischer Waechter in
   tests/unit/components-css.test.js) erlaubt einer Regel auf einem
   nackten Element nur Eigenschaften, die Legacy fuer dasselbe Element
   ueberhaupt kennt -- sonst gilt sie unbekaempft, unabhaengig von
   jeder Spezifitaet. Gemessen an webapp.css (Vereinigung ueber ALLE
   Regeln, wie der Waechter sie bildet):

     p           11 Eigenschaften   ul   7    ol   5
     li          31                 blockquote 4
     h4           9                 h5   2     h6  0

   Die Zahlen taeuschen aber, und das ist der Kern dieses Tasks: KEINE
   dieser Regeln greift INNERHALB der Blase. Sie stammen ausnahmslos
   aus fremden Behaeltern (".cardlist li", ".notification-markdown p",
   ...). Im Antwortkoerper ist fuer p, ul, ol, li und blockquote
   NICHTS deklariert -- eine Element-Basisregel waere dort also
   unbekaempft, egal was der Waechter dazu sagt. Fuer h6 wuerde er
   ueberdies hart durchfallen ("keine einzige Legacy-Eigenschaft
   geparst") -- die Zeile "assert.ok(legacyProps.size > 0)" schlaegt
   fehl, noch VOR der Teilmengenpruefung.

   WAS DER WAECHTER ZU DIESEN REGELN SAGT: NICHTS. Am Waechter selbst
   nachgestellt (findElementBaseRules gegen diese Datei), nicht
   hergeleitet:

     gebaute Fassung (Klasse aussen, Elemente in :is())   uebersprungen
     Kurzform :is(.msg-bubble-bot, .msg-bubble-greeting)  uebersprungen
     dieselbe Kurzform mit h6 in der Liste                uebersprungen
     Klassen in :is(), Element NACKT ("... > * h6")       Basisregel h6,
                                                          harter Abbruch

   Von den 55 Element-Basisregeln, die er in dieser Datei findet, gehoert
   KEINE EINZIGE zu diesem Task. Der Grund ist doppelt: die Klasse
   ausserhalb jeder Klammer macht die Regel zur Zweckregel -- UND das
   ":is()" am rechten Ende laesst rightmostCompound() auf ":is" laufen,
   worauf parseElement() null liefert und die Regel verworfen wird.

   DAS ZWEITE IST EIN BLINDER FLECK, UND ZWAR IN DER STILLEN RICHTUNG:
   wer ":is(h6)" statt "h6" schreibt, macht JEDE Basisregel fuer den
   Waechter unsichtbar. Der Kopfkommentar des Tests warnt heute nur vor
   dem umgekehrten, harmlosen Fall (":is(.datatable) tr" wird
   faelschlich ALS Basisregel gelesen). Befund fuer Task 7 -- hier nicht
   behoben, weil er den Waechter selbst betrifft und nicht diesen Task.

   DIE ENTSCHEIDUNG GEGEN ELEMENT-BASISREGELN FOLGT DESHALB NICHT AUS
   DEM WAECHTER, sondern aus dem CSS: im Antwortkoerper bestreitet
   niemand, also gewinnt jede Basisregel dort unbekaempft.

   DER GELTUNGSBEREICH IST DER KOERPER, NICHT DIE BLASE. In
   ".msg-bubble-bot" haengen NEBEN dem Markdown-Koerper vier weitere
   Behaelter (chatwindowbotmessage.js:205-215): ".src-accordion-wrapper"
   (Task 5), ".chunk-img-wrapper", ".tool-invocations-wrapper" (Task 6)
   und ".pending-tool-gate-wrapper". Der Werkzeugaufruf rendert darin
   ZWEITES Markdown in ".orchestration-md"
   (organismstoolinvocation.js:145), und der Behaelter hat EIGENE
   Flussregeln (webapp.css:13419-13438). Eine Regel
   "[data-design=new] .msg-bubble-bot p" wiegt (0,2,1) und schluege
   ".orchestration-md p" (0,1,1) -- Task 3 haette Task 6 stillschweigend
   ueberschrieben (Ruling 4 des Logbuchs verbietet genau das).
   Gescopt wird deshalb auf den Koerper selbst: er ist das ERSTE Kind
   der Blase (setupUi legt ihn vor allen Wrappern an), also
   "> :first-child". Faellt diese Annahme irgendwann, verliert der Fluss
   seine Gestaltung (sichtbar, harmlos) statt in fremde Behaelter zu
   lecken (still, schaedlich) -- die Fehlerrichtung ist bewusst gewaehlt.
   Zugesichert ist BEIDES: dass der Fluss ankommt UND dass ein
   ".orchestration-md"-Absatz in derselben Blase NICHT den Rhythmus
   dieses Tasks traegt. Zugesichert wird die ABGRENZUNG, nicht Task 6s
   Zahl -- die 4px dort sind sein Sollwert, und ein berechtigter
   Wechsel darf diesen Block nicht rot machen.

   EIN RESTRISIKO, DAS DIESE REGELN NICHT DECKEN: laege
   ".orchestration-md" je INNERHALB des Textkoerpers, gewaenne der
   Nachfahrenselektor dieses Tasks trotzdem. Heute unmoeglich --
   setupUi() legt alle vier Wrapper NEBEN den Koerper, am DOM
   bestaetigt --, aber es ist eine Annahme ueber fremden Code, keine
   Eigenschaft der Regel.

   DIE BEGRUESSUNGSBLASE FAEHRT MIT. Auch sie rendert Markdown
   (chatwindowbotmessage.js:523-524) und auch bei ihr ist der Koerper
   das erste -- dort sogar das einzige -- Kind. Ein Willkommenstext mit
   einer Aufzaehlung stuende sonst mit 40px Browsereinzug neben einer
   Antwort mit 18,2px: genau die halbe Uebernahme, vor der Task 1 und 2
   warnen. Sie bekommt deshalb denselben Fluss, behaelt aber wie in
   Task 2 ihre eigenen Farben (Verlauf, Textfarbe).

   WAS DIESER TASK NICHT ANFASST, jeweils mit Grund:

     pre, code    Ruling 1 des Logbuchs: sie gehoeren Task 4, auch
                  ueber einen Nachfahrenselektor. Deshalb steht "pre"
                  auch NICHT in der Elementliste der Rhythmusregeln --
                  ein "> :first-child { margin-top: 0 }" haette einen
                  Codeblock am Anfang der Antwort sehr wohl getroffen.
                  Preis, gemessen: beginnt oder endet eine Antwort mit
                  einem Codeblock, bleibt dessen senkrechter
                  Aussenabstand stehen -- und der kommt NICHT aus
                  webapp.css:719-728 (die Regel setzt nur "margin-left:
                  40px" und keinen senkrechten Wert), sondern aus der
                  Browservorgabe "1em": im neuen Design also 15px auf
                  die geerbten 15, im alten 12 auf die dortigen 12.
                  Der Rhythmus ist um Codebloecke herum bis Task 4
                  uneinheitlich.
     h1, h2, h3   webapp.css:545/553/561 setzt "text-align: center" --
                  JEDE "#"-Ueberschrift in JEDER Antwort steht
                  zentriert, in beiden Designs (gemessen). Das ist eine
                  Produktentscheidung, ihre Behebung traefe jede Seite
                  der Anwendung; Plan und Spec (Abschnitt 7.6) fuehren
                  sie als Befund. Hier wird sie GEMELDET, NICHT
                  GEAENDERT -- und zwar vollstaendig: auch Groesse und
                  Aussenabstand von h1-h3 bleiben unberuehrt, weil eine
                  halbe Aenderung (kleiner, aber weiter zentriert) das
                  Bild schlechter machte als der Bestand. Gemessen im
                  neuen Design: 32 / 28 / 20px, fett, zentriert, mit
                  21,44 / 23,24 / 20px Aussenabstand -- eine
                  "##"-Ueberschrift als erster Block schiebt den Text
                  also weiterhin ueber Figmas 16px Innenabstand hinaus.
     table/th/td  von "05 · Data" Teil A behandelt. Die dortige
                  Gegenregel fuer Fliesstext-Tabellen
                  (":where([data-design=new]) thead > tr > th")
                  GREIFT in der Chatblase -- an einer echten
                  marked-Tabelle gemessen: 15px statt 10px, keine
                  Versalien, "--ax-text-primary" statt tuerkis.
     .orchestration-md   Ruling 4: gehoert Task 6.

   ZWEI ZAHLEN DER VORLAGE LANDEN HIER, DREI GIBT ES NICHT. Spec
   Abschnitt 5 nennt fuer den Antwortkoerper genau drei Textstile:
   Fliesstext 15/24 (steht seit Task 2 an der Klasse),
   Zwischenueberschrift Semi Bold 15/24 und Liste 13/20 in
   "--ax-text-secondary" -- die Liste ist seit #2048 bewusst NICHT
   gebaut (Begruendung an der Listenregel). Zu Absatzabstand, Listeneinzug und Zitat
   schweigt die Vorlage -- dort folgt dieser Block dem HAUSMUSTER der
   beiden anderen Markdown-Behaelter des Produkts
   (".notification-markdown", webapp.css:12798-12813, und
   ".orchestration-md", :13419-13433), statt etwas zu erfinden. */

/* Der Rhythmus des Flusses. Figmas Koerperknoten stapelt seine
   Bloecke mit "Abstand 12"; der Bestand steht auf der Browservorgabe
   "1em" -- und die ist NICHT ueberall dieselbe Zahl, weil "em" auf die
   Schriftgroesse DES ELEMENTS rechnet. Je Deklaration einzeln geloescht
   und gemessen (neues Design):

     <p> und <blockquote>   12 -> 15px   (Blasenschrift 15)
     <ul> und <ol>          12 -> 15px   (bis #2048 13px, weil die
                                          Listenregel unten damals
                                          selbst 13px setzte)

   Im alten Design sind es an allen vier 13px.

   LITERAL 12 statt "var(--ax-space-3)", dieselbe Linie wie beim
   Innenabstand der Blase in Task 2: das Token faellt bei <= 768px auf
   10 (tokens.css:401), und Figmas 12 ist eine Aussage ueber den
   Fluss, nicht ueber den Bildschirm.

   DIE ELEMENTLISTE IST ABSCHLIESSEND und enthaelt bewusst kein "pre"
   und kein "h1"-"h3" (Begruendung im Kopf). Sie steht in ":is()", die
   beiden Blasen dagegen als zwei ausgeschriebene Selektorzeilen -- das
   ist LESBARKEIT und Absicht, aber KEINE Bedingung des Waechters: der
   ueberspringt beide Fassungen (nachgestellt, Tabelle im Kopf). Die
   Kurzform ":is(.msg-bubble-bot, .msg-bubble-greeting)" waere hier
   erlaubt gewesen; sie haette nur verborgen, dass die zweite Blase
   mitfaehrt, und das ist die Aussage, um die es geht. */
[data-design="new"] .msg-bubble-bot > :first-child :is(p, ul, ol, blockquote),
[data-design="new"] .msg-bubble-greeting > :first-child :is(p, ul, ol, blockquote) {
  margin: 12px 0;
}

/* Der erste und der letzte Block sitzen buendig am Innenabstand.
   OHNE DIESE BEIDEN REGELN IST FIGMAS "Innenabstand 16" NICHT
   HERSTELLBAR: der erste Absatz bringt seinen eigenen oberen
   Aussenabstand mit, gemessen 15px im neuen Design -- der Text saesse
   also 31px unter der Oberkante der Blase statt 16.

   Dasselbe Muster benutzen beide anderen Markdown-Behaelter des
   Produkts (webapp.css:12798-12799 und :13419-13420), dort als
   "> :first-child" mit dem Universalselektor. Hier steht statt dessen
   dieselbe Elementliste wie oben -- der Universalselektor haette einen
   Codeblock am Anfang oder Ende der Antwort getroffen, und "pre"
   gehoert Task 4 (Ruling 1). */
[data-design="new"] .msg-bubble-bot > :first-child > :is(p, ul, ol, blockquote, h4, h5, h6):first-child,
[data-design="new"] .msg-bubble-greeting > :first-child > :is(p, ul, ol, blockquote, h4, h5, h6):first-child {
  margin-top: 0;
}

[data-design="new"] .msg-bubble-bot > :first-child > :is(p, ul, ol, blockquote, h4, h5, h6):last-child,
[data-design="new"] .msg-bubble-greeting > :first-child > :is(p, ul, ol, blockquote, h4, h5, h6):last-child {
  margin-bottom: 0;
}

/* Die Zwischenueberschrift. Figma: Semi Bold 15 / 24,
   "--ax-text-primary".

   DREI ELEMENTE, EIN STIL, und das ist keine Bequemlichkeit: Figmas
   Antwortknoten kennt GENAU EINE Zwischenueberschrift. h1-h3 sind
   ausgenommen (Kopf dieses Blocks), es bleiben h4, h5 und h6.

   DER BESTAND IST HIER NICHT NUR ANDERS, SONDERN FALSCH HERUM.
   Gemessen im vollen Stapel, Antwortkoerper, neues Design:

     h4   15,00px / 24px / 700   -- Groesse stimmt, Gewicht nicht
     h5   12,45px / 24px / 700   -- KLEINER als der Fliesstext daneben
     h6   10,05px / 24px / 700   -- zwei Drittel des Fliesstextes

   Die beiden letzten Zahlen sind die Browservorgabe (0,83em und
   0,67em, gerechnet auf die 15px der Blase): eine "#####"-Ueberschrift
   steht heute kleiner da als der Absatz, den sie ueberschreibt. Im
   alten Design ist es dieselbe Ordnung auf 13px-Basis (10,79 und
   8,71px) -- der Fehler ist Bestand, nicht Folge von Task 2.

   Der Zeilenkasten 24 steht bereits richtig, aber nur mittelbar: er
   kommt als geerbter ABSOLUTWERT von ".msg-bubble-bot" (Task 2,
   "line-height: var(--ax-line-height-body-md)"). Er wird hier trotzdem
   gesetzt, weil eine Zwischenueberschrift ihre Zeile selbst braucht --
   im ALTEN Design steht dort "1,65" und damit ein Vielfaches der
   Schriftgroesse, und dieselbe Regel ohne "line-height" haette bei
   einem kuenftigen Wechsel auf einen relativen Wert stillschweigend
   17,8px statt 24 ergeben.

   HIER STEHEN DIE LANGFORMEN DES AUSSENABSTANDS, oben an den Absaetzen
   die Kurzform -- und das ist kein Stilbruch, sondern die Folge einer
   Einzelmessung. Am <blockquote> traegt die Browservorgabe SEITLICH
   40px, die Kurzform nimmt sie zurueck und beide Seitenwerte sind dort
   Nachweise (gemessen 0 -> 40px je Seite). An h4-h6 sind die
   Seitenwerte dagegen ohnehin 0: eine Kurzform haette zwei
   Deklarationen erzeugt, die nichts bewegen und die niemand
   zusichern kann, ohne eine Zeile zu schreiben, die auch ohne die
   Regel gruen bliebe. */
[data-design="new"] .msg-bubble-bot > :first-child :is(h4, h5, h6),
[data-design="new"] .msg-bubble-greeting > :first-child :is(h4, h5, h6) {
  margin-top: 12px;
  margin-bottom: 12px;
  font-size: var(--ax-font-size-body-md);
  line-height: var(--ax-line-height-body-md);
  font-weight: 600;
}

/* Die Liste. Figma: Regular 13 / 20, "--ax-text-secondary" --
   BEWUSST NICHT GEBAUT (#2048, Freigabe des Product Owners).

   Bis #2048 stand hier Figmas Listenstil: 13/20 in
   "--ax-text-secondary" neben einem Fliesstext von 15/24 in der
   Blasenfarbe. Die Aufzaehlung stand damit KLEINER und BLASSER da als
   der Absatz darueber -- und gerade dort stehen in einer Antwort die
   relevanten Punkte. Das Ticket verlangt Einheitlichkeit: eine Liste
   traegt dieselbe Schriftgroesse, denselben Zeilenkasten und dieselbe
   Farbe wie der Fliesstext derselben Blase. Eine zusaetzliche
   Hervorhebung ist NICHT verlangt und deshalb nicht gebaut.

   DIE HEILUNG IST DIE WEGGELASSENE ZEILE: ohne "font-size",
   "line-height" und "color" erbt die Liste von der Blase -- genau wie
   der Absatz. Das haelt in jedem Wirt, ohne ihn zu kennen: Antwort
   (15/24, "--font-color-application"), Begruessung (eigene
   Textfarbe "--clr-text-secondary") und der eingebettete Chat, dessen
   Kundenfarbe "--acw-bot-fg" an der Blase haengt (webapp.css,
   "body.chat-embedded .msg-bubble-bot") und von der alten Listenfarbe
   bis #2048 in jeder Aufzaehlung ueberschrieben wurde. Das alte
   Design war nie betroffen: dort setzt keine Regel etwas an einer
   Liste im Antwortkoerper, sie erbt seit jeher die 13px der Blase.

   DER EINZUG IST HAUSMUSTER, NICHT VORLAGE. Die Browservorgabe ist
   40px -- in einer Blase mit 16px Innenabstand ein Viertel der
   Textbreite. Beide anderen Markdown-Behaelter des Produkts stehen auf
   "padding-left: 1.4em" (webapp.css:12805 und :13431). Seit #2048
   rechnet das "em" auf die geerbten 15px: 21px statt der 18,2px, die
   es auf Figmas 13px waren. Figma nennt keinen Einzug. */
[data-design="new"] .msg-bubble-bot > :first-child :is(ul, ol),
[data-design="new"] .msg-bubble-greeting > :first-child :is(ul, ol) {
  padding-left: 1.4em;
}

/* Das Zitat. Figma schweigt dazu -- gebaut ist deshalb das HAUSMUSTER
   von ".notification-markdown blockquote" (webapp.css:12811), auf die
   Token dieses Designsystems gehoben.

   DER BESTAND IST DIE NACKTE BROWSERVORGABE: "margin: 1em 40px", kein
   Rand, keine eigene Farbe -- ein Zitat ist heute nur an einem Einzug
   zu erkennen, und der ist derselbe wie bei einer Liste (gemessen:
   beide 40px). Die Kurzform "margin: 12px 0" der ersten Regel oben
   nimmt den seitlichen Einzug zurueck, der 3px-Rand tritt an seine
   Stelle.

   DER RAND HEBT SICH AB, gerechnet gegen die Flaeche der Antwortblase:
   "--ax-border-default" auf "--ax-bg-surface-1" ergibt ΔE 9,686
   (dunkel) und 16,958 (hell) -- beides deutlich ueber der
   Wahrnehmungsschwelle 2,3.

   DER ABSATZ IM ZITAT BRAUCHT KEINE EIGENE REGEL: marked packt den
   Zitattext in ein <p>, dessen Aussenabstaende mit denen des
   <blockquote> VERSCHMELZEN (kein oberer Rand, kein oberes Polster am
   Zitat) -- gemessen bleibt es bei 12px oben und unten, das Zitat
   umschliesst seinen Text buendig. */
[data-design="new"] .msg-bubble-bot > :first-child blockquote,
[data-design="new"] .msg-bubble-greeting > :first-child blockquote {
  padding-left: 12px;
  border-left: 3px solid var(--ax-border-default);
  color: var(--ax-text-secondary);
}

/* Die Verdichtung des Bestands unter 640 px, ausdruecklich
   zurueckgeholt. Der Media-Block traegt keine Spezifitaet: ohne diese
   Regel gewaenne die Grundregel oben ueber die Ladereihenfolge, und
   jede Blase auf dem Telefon truege wieder den grossen Radius --
   dieselbe Fehlerklasse, die in "05 · Data", Teil B bei der
   zurueckgenommenen Kennzahlenzeile stand.

   DIE GANZE LEITER, GEMESSEN (Galeriekachel, dunkel; "ohne" heisst:
   diese Regel per deleteRule entfernt):

     Viewport   neu mit   neu ohne   alt
       620 px    8px       12px      8px
       700 px   12px       12px      14px 4px 14px 14px
       760 px   12px       12px      14px 4px 14px 14px
       780 px   14px       14px      14px 4px 14px 14px

   Die 12 zwischen 641 und 768 px kommen aus "--ax-radius-lg" selbst
   (tokens.css, @media max-width: 768px) und sind die Antwort des
   Designsystems auf den schmalen Bildschirm -- dort ist nichts
   zurueckzuholen, Legacy stuende weiterhin auf 14/4. Erst ab 640 px
   verdichtet der Bestand, und genau das holt diese Regel. Alle vier
   Zeilen sind im vierten Block der Testdatei zugesichert.

   Die Klassen ".msg-bubble-bot" und ".msg-bubble-greeting" stehen in
   derselben Legacy-Regel; Task 2 hat sie hier nachgezogen, nachdem er
   ihren Radius oben auf dasselbe Token gebracht hat.

   DIESE REGEL MUSS HINTER DEN DREI RADIUS-REGELN STEHEN, DIE SIE
   SCHLAEGT -- sie ist ORDNUNGSABHAENGIG. Ein Media-Block traegt keine
   Spezifitaet: "[data-design=\"new\"] .msg-bubble-bot" wiegt hier wie
   dort (0,2,0), entschieden wird allein ueber die Quellreihenfolge.
   Task 1s Nutzerblase steht oben (:7808), Task 2s Antwort- und
   Begruessungsblase stehen bei :8172 und :8222 -- also MUSS dieser
   Block dahinter stehen.

   NACHGEMESSEN, WEIL ES BEINAHE SCHIEFGEGANGEN WAERE: die Abnahme
   sollte den Block zurueck unter diesen Kommentar an Task 1s Ende
   holen (er stand dort ohne ein Wort, 845 Zeilen von seiner
   Begruendung getrennt, und zwei Verweise zeigten ins Leere). Genau
   das wurde versucht und gemessen: bei 620 px trug die ANTWORTBLASE
   dann 12px statt 8px -- Task 2s Regel stand nun spaeter und gewann.
   Zweiseitig belegt (mit Verschiebung rot, ohne gruen, sonst
   unveraendert). Deshalb ist stattdessen der KOMMENTAR zur Regel
   gewandert, nicht die Regel zum Kommentar. Wer sie doch verschiebt,
   faellt ueber den vierten Block der Testdatei. */
@media (max-width: 640px) {
  [data-design="new"] .msg-bubble-user,
  [data-design="new"] .msg-bubble-bot,
  [data-design="new"] .msg-bubble-greeting {
    border-radius: 8px;
  }
}

/* ══ 07 · Chat & AI, Teil A — Task 4: Der Codeblock ═══════════════
   Figma-Knoten 149:74. Gebaut sind Flaeche, Rahmen, Radius,
   Innenabstand und Schrift; NICHT gebaut sind die Kopfzeile, das
   Sprachkennzeichen und die Beschriftung des Kopierknopfs (Spec 3b --
   das ist Feature, nicht Umbau).

   DER BESTAND (webapp.css:719-736), und er ist grundlegend anders:
   "pre" traegt "margin-left: 40px", Radius 5, Flaeche
   "--background-color-input" und einen Innenabstand von 10 oben,
   unten und LINKS -- rechts null. "code" steht in der
   FLIESSTEXTSCHRIFT ("font-family: var(--btxt)"), nicht monospace.
   Der Kopierknopf (webapp.css:746) wird nachtraeglich injiziert
   (chatwindowbotmessage.js:1087-1122) und haengt absolut in der
   rechten oberen Ecke des "pre"; beim Inline-Schnipsel wickelt
   dieselbe Funktion ein "span.inline-code-wrapper" darum.

   HIER STEHEN ELEMENT-BASISREGELN, WAEHREND TASK 3 DANEBEN KEINE
   EINZIGE HAT -- und das ist kein Stilbruch, sondern die Folge
   derselben Pruefung mit anderem Ergebnis. Task 3s Elemente (p, ul,
   ol, blockquote, h4-h6) sind INNERHALB der Antwortblase von keiner
   Legacy-Regel bestritten; eine Basisregel waere dort unbekaempft.
   Fuer "pre" und "code" ist es umgekehrt: webapp.css:719/731 sind
   selbst globale, ungescopte Element-Basisregeln. Wer sie ersetzen
   will, muss auf derselben Ebene antworten.

   DIE SUBSET-INVARIANTE ("05 · Data" Teil A, generischer Waechter in
   tests/unit/components-css.test.js) ist damit die Leitplanke dieses
   Blocks: eine Basisregel darf nur Eigenschaften setzen, die Legacy
   fuer dasselbe Element irgendwo kennt. Mit legacyPropsForElement()
   des Waechters selbst gegen webapp.css gemessen, nicht geschaetzt:

     pre    background, background-color, border, border-radius,
            font-family, font-size, margin, margin-left, overflow-x,
            padding, padding-bottom, padding-left, padding-top,
            position, text-wrap, white-space, word-wrap   (17)
     code   background, background-color, border-radius, color,
            font-family, font-size, padding, text-wrap, word-break,
            word-wrap                                     (10)

   Jede Deklaration unten steht in dieser Liste. WAS NICHT DARIN
   STEHT, IST "line-height" -- fuer BEIDE Elemente. Figmas Codezeile
   braucht aber eine eigene Zeilenhoehe, und deshalb steht sie weiter
   unten an einer KLASSENgescopten Regel statt hier. Das ist der
   vorgesehene Ausweg, nicht ein Schlupfloch.

   DER WAECHTER HAT EINEN BLINDEN FLECK, UND ER WIRD HIER BEWUSST
   NICHT BENUTZT. Task 3 hat ihn am Waechter selbst nachgestellt:
   rightmostCompound() liefert bei "... :is(pre, code)" die
   Zeichenkette ":is(...)", parseElement() gibt null zurueck, die
   Regel wird still verworfen und gar nicht geprueft -- auch ohne
   jede Klasse im Selektor. Wer ":is(pre)" statt "pre" schreibt, macht
   seine Basisregel unsichtbar und sie gilt dann unbekaempft. Die
   beiden Selektoren unten stehen deshalb NACKT.

   ":where()" STATT "[data-design=new]", und das ist eine
   Gewichtsentscheidung: ":where([data-design=new]) pre" wiegt
   (0,0,1), genau wie Legacys "pre {}" -- und gewinnt gegen dieses
   allein ueber die Ladereihenfolge (components.css laedt zuletzt).
   Gegen JEDE Legacy-Zweckklasse (".notification-markdown pre",
   ".readonly-text-block", ".tool-invocation-args", ...) verliert es
   dagegen. Mit "[data-design=new] pre" (0,1,1) waere es umgekehrt:
   der Gleichstand mit ".function-assistant-explanation pre" ginge
   ueber die Reihenfolge an diesen Block, und der haette fremden
   Bauteilen ihre Aussenabstaende ueberschrieben.

   WEN DIESE BEIDEN REGELN AUSSERHALB DES CHATS ERREICHEN. Eine
   globale Basisregel ist global; das ist ihr Sinn und ihr Preis.
   Aufgezaehlt wird deshalb nicht nach Gefuehl, sondern nach dem, was
   sich pruefen laesst: JEDE Legacy-Regel, deren rechtestes Compound
   "pre" oder "code" trifft, plus jedes <pre>, das seine eigene Klasse
   traegt. Die Liste ist damit abgeschlossen -- fuer die Legacy-Seite.

   ZUERST DIE BEHAELTER MIT EIGENER REGEL (neues Design gemessen; das
   alte bleibt in allen bitgenau, s.u.):

     .readonly-text-block            unveraendert (setzt margin, bg,
                                     border, radius, padding, Schrift
                                     alles selbst)
     .function-assistant-explanation pre / code / pre code
                                     unveraendert (dito)
     .notification-markdown pre / code / pre code
                                     + 1px Rahmen, Aussenabstand
                                     10,83 -> 12, Einzug 40 -> 0;
                                     inline: Farbe und Groesse
     .reference-content pre / code   + 1px Rahmen, Einzug 40 -> 0;
                                     inline: nur Farbe
     .resource-entry-snippet         + 1px Rahmen (Hoehe 32 -> 34)
     .tool-invocation-args / -body   voll bis auf Aussenabstand und
                                     Schriftgroesse -- TASK 6s GEBIET
     .orchestration-md pre / code    voll bis auf white-space und
                                     overflow-x -- TASK 6s GEBIET
     pre.mermaid-diagram             voll bis auf overflow-x -- s.u.

   DANN DIE OHNE JEDE GEGENWEHR, weil sie klassenlos sind: das
   ".functiontest-logs-pre" (die Klasse existiert im CSS gar nicht) und
   JEDER klassenlose Markdown-Ausguss des Produkts --
   "AtomDisplayHtml" in den Ergebniskarten der AI-Services
   (organismsresultcard.js:277/284/294/314), aiserviceresult.js:246,
   organismsaiserviceresult.js:193, agentfinderanalysispage.js:349 und
   workflowfeedbacktemplate.js:80. Sie bekommen das VOLLE Bild. Das
   ist hier ausdruecklich GEWOLLT: es ist dieselbe Markdown-Ausgabe
   desselben Konverters wie in der Chatantwort, und sie soll gleich
   aussehen.

   DAS DIAGRAMM IST DER FALL, DER EINE ENTSCHEIDUNG BRAUCHTE.
   MermaidRenderer (mermaidrenderer.js:201) verwandelt einen Codeblock
   DER CHATANTWORT in "<pre class='mermaid-diagram'>" mit einem SVG
   darin; webapp.css:801 setzt dort nur "overflow-x". Ein Bild traegt
   ab hier also die Kleidung eines Codeblocks. Das ist kein fremdes
   Gebiet, sondern dieses -- und deshalb GEMESSEN entschieden, an einem
   echten, ueber die CDN gerenderten mermaid-Diagramm:

                        Knotenfuellung gegen den Grund, ΔE (CIE76)
                        dunkel      hell
     Bestand            10,294      2,607   <- knapp ueber der Schwelle
     dieser Block       12,413      4,868
     mit Ausnahmeregel  10,265      5,902

   Das SVG selbst ist DURCHSICHTIG (gemessen: "background-color:
   rgba(0, 0, 0, 0)", kein inline-Style) -- der Grund kommt also in
   jedem Fall vom "pre". Die neue Flaeche trennt die Diagrammknoten
   vom Grund BESSER als der Bestand, in beiden Themes; im hellen
   liegt der Bestand mit 2,607 sogar knapp an der
   Wahrnehmungsschwelle. Eine klassengescopte Ausnahme
   ("pre.mermaid-diagram { background: transparent; border: 0;
   padding: 0 }") waere erlaubt gewesen und im hellen Theme um 1,03
   besser -- im dunklen um 2,15 schlechter. Sie faellt aus, weil sie
   fuer einen Wert in einem Theme eine Dauerregel kostet UND weil das
   "pre" die Flaeche des Codeblocks HEUTE SCHON traegt: sie
   wegzunehmen waere eine neue Produktentscheidung, nicht die
   Uebernahme der Vorlage. Nebenbei bekommt der Download-Knopf
   (webapp.css:747, absolut in der rechten oberen Ecke) endlich seinen
   Innenabstand nach rechts. Zugesichert in der Testdatei.

   ZWEI POSTEN OBEN SIND RULING 4 UND DESHALB AUSDRUECKLICH GENANNT:
   ".orchestration-md pre" und ".tool-invocation-args" wiegen (0,1,1)
   und schlagen diesen Block (0,0,1) bei jeder Eigenschaft, die sie
   SELBST setzen. Ueberschrieben wird dort also nichts; gefuellt wird
   nur, was heute niemand deklariert. Task 6 kann jede dieser
   Eigenschaften mit seinen eigenen Klassenregeln zurueckholen, ohne
   diesen Block anzufassen -- der Ausgangszustand ist in der
   Testdatei festgeschrieben.

   EIN BEFUND ZUR VORLAGE: "--ax-border-soft" und "--ax-bg-surface-3"
   sind im HELLEN Theme DASSELBE Token ("--ax-ink-100",
   tokens.css:100/108). Figmas 1px-Rahmen um die Codeblockflaeche ist
   dort also unsichtbar -- gerastert gemessen, ΔE (CIE76) = 0,000
   gegen die eigene Flaeche; im dunklen Theme sind es 5,334. Der
   Rahmen bleibt trotzdem stehen: er ist Vorgabe der Vorlage, er
   traegt im dunklen Theme, und eine halbe Uebernahme (Rahmen nur
   dunkel) waere schlechter als beides. Gemeldet, nicht geaendert. */

/* Die Flaeche des Codeblocks. Figma: Radius 10, "--ax-bg-surface-3",
   1px "--ax-border-soft", Innenabstand 12.

   DER 40px-EINZUG FAELLT, und das ist die eine Entscheidung dieses
   Tasks, die die Vorlage nicht vorgibt. Gemessen, was er heute
   bewirkt (neues Design, Codezeile "const quote = umsatz /
   mitarbeiter;"):

     Wirt              Textbreite im pre    Anteil des Einzugs
     Cockpit 1440          1200 -> 1224 px          3,2 %
     Widget   400           252 ->  276 px         13,2 %
     Widget   320           172 ->  196 px         18,0 %

   Im schmalsten Wirt frisst der Einzug fast ein Fuenftel der
   Textbreite -- und der oeffentliche Chatbot IST dieser Wirt
   (widgetconfig.js:8-10: Vorgabe 400, Mindestmass 320). Gemessen
   ueber die Zeilenzahl derselben zwei Codezeilen bei 320 px: 4
   Zeilen mit Einzug, 3 ohne -- und das TROTZ der breiteren
   Monospace-Schrift. Dazu kommt, dass jeder andere Block der Antwort
   seit Task 3 buendig am Innenabstand der Blase sitzt; der Codeblock
   waere der einzige eingerueckte.

   "margin: 12px 0" statt "margin-left: 0", weil dieselbe Deklaration
   zugleich den senkrechten Rhythmus schliesst, den Task 3
   ausdruecklich offen gelassen hat (Ruling 1: "pre" gehoert hierher,
   auch ueber einen Nachfahrenselektor). Der Rueckfallwert ohne diese
   Zeile ist NICHT Legacys Wert, sondern die Browservorgabe "1em",
   gerechnet auf die Blasenschrift: im neuen Design 15px, im alten
   12px -- eine Zahl, die kein voller Stapel je zeigt.

   LITERAL 12 statt "var(--ax-space-3)", dieselbe Linie wie in Task 2
   und 3: das Token faellt bei <= 768px auf 10 (tokens.css:401), und
   Figmas 12 ist eine Aussage ueber den Codeblock, nicht ueber den
   Bildschirm. Beim Radius ist es umgekehrt -- "--ax-radius-md" steht
   an jedem Haltepunkt auf 10 (tokens.css:352 hat keinen Eintrag in
   den beiden @media-Bloecken) und ist damit zeichengleich Figmas
   Wert.

   DER INNENABSTAND WIRD ALLSEITIG, und das behebt nebenbei einen
   Bestandsfehler: Legacy setzt padding-top/bottom/left auf 10 und
   RECHTS auf nichts -- der Kopierknopf sitzt dort mit 0,3rem Abstand
   ueber dem Text. Mit 12 rundum hat er Platz. */
:where([data-design="new"]) pre {
  margin: 12px 0;
  padding: 12px;
  background-color: var(--ax-bg-surface-3);
  border: 1px solid var(--ax-border-soft);
  border-radius: var(--ax-radius-md);
}

/* Die Codeschrift. Figma: Geist Mono Regular 12,
   "--ax-text-secondary".

   DAS IST DIE SICHTBARSTE EINZELAENDERUNG DIESES TEILPROJEKTS: Code
   steht im Bestand in der FLIESSTEXTSCHRIFT. Gemessen, was der
   Wechsel an Breite kostet, an derselben Zeile ("const quote =
   umsatz / mitarbeiter;", 35 Zeichen), ohne Umbruch:

     altes Design   -apple-system 13px    203,48 px
     neues Design   Inter         15px    249,08 px   (Bestand)
     neues Design   Geist Mono    12px    252,00 px   (hier)

   Der Wechsel kostet also 2,92 px gegenueber dem heutigen neuen
   Design -- praktisch nichts, weil die kleinere Schriftgroesse die
   groessere Laufweite der Monospace fast genau ausgleicht. Zusammen
   mit dem entfallenen Einzug wird der Block in JEDEM der drei
   gemessenen Wirte breiter statt schmaler, und "scrollWidth -
   clientWidth" ist ueberall 0: kein waagerechter Ueberlauf, in
   beiden Blasen, beiden Themes und allen drei Wirten. Umbrechen kann
   der Block weiterhin -- Legacys "text-wrap: wrap" und "word-wrap:
   break-word" bleiben unangetastet.

   "--ax-font-size-mono-sm" ist zeichengleich Figmas 12 und faellt an
   keinem Haltepunkt (tokens.css:337). Die Mono-Token werden hier zum
   ZWEITEN MAL benutzt -- der erste Verwender ist die Fusszeile der
   Antwort aus Task 2 (components.css:8454-8456, alle drei).

   DIESE REGEL GILT FUER BEIDE GESTALTEN VON <code>, den Block im
   "pre" UND den Inline-Schnipsel im Fliesstext. Figma zeigt nur den
   Block; der Inline-Fall ist deshalb einzeln gemessen worden:

     - Er behaelt seine Zeilenhoehe (24px, geerbt vom Absatz) -- die
       Regel weiter unten setzt "line-height" nur am "pre". Die
       Absatzhoehe bleibt damit bei 24px, der Rhythmus von Task 3
       unberuehrt.
     - Er behaelt seine Gestalt: kein Innenabstand, kein Radius,
       genau wie heute. Figma schweigt dazu, und ein erfundener
       Chip waere eine Aenderung ohne Vorlage.
     - Sein Kaestchen wird 79,77 -> 79,20 px breit und 19 -> 16 px
       hoch (12px Schrift statt 15).

   DIE FLAECHE IST FUER BEIDE DIESELBE, und das ist der Grund, warum
   hier ueberhaupt eine steht: ohne sie behielte "code" Legacys
   "--background-color-input" und saesse als dunklerer Fleck auf der
   surface-3-Flaeche des "pre". Mit surface-3 verschwindet die Naht
   im Block, waehrend der Inline-Schnipsel im Fliesstext ein sichtbarer
   Chip bleibt -- gerastert gegen die Blase gemessen, ΔE (CIE76):

     Antwortblase  Cockpit 9,686 (dunkel) / 9,350 (hell)
                   eingebettet 5,334 / 4,857
     Begruessung   Cockpit 11,876 / 4,100   (Verlauf -- gerastert,
                   eingebettet 5,334 / 4,857   nicht gerechnet)

   Alle deutlich ueber der Wahrnehmungsschwelle 2,3.

   DIE TEXTFARBE HAELT WCAG 4,5 -- gerastert gegen die Flaeche des
   "pre", nicht gegen das Token gerechnet: 6,895 (dunkel) und 9,953
   (hell), in beiden Blasen und allen drei Wirten identisch, weil die
   Flaeche deckend ist.

   KEIN KURSIVER CODE MEHR IN DER BEGRUESSUNGSblase: bis #2023 setzte
   Legacy ".msg-bubble-greeting { font-style: italic }" (webapp.css) in
   BEIDEN Designs, und weil Geist Mono keine Kursive hat (beide
   @font-face-Bloecke "font-style: normal", tokens.css:300/308), neigte
   Chromium die Glyphen synthetisch. Die offene Produktfrage ist mit
   #2023 entschieden: die Begruessungsblase ist nicht mehr kursiv,
   fuer keinen Inhalt. */
:where([data-design="new"]) code {
  background-color: var(--ax-bg-surface-3);
  color: var(--ax-text-secondary);
  font-family: var(--ax-font-mono);
  font-size: var(--ax-font-size-mono-sm);
}

/* Die Zeilenhoehe der Codezeilen. SIE STEHT HIER UND NICHT OBEN,
   weil Legacy "line-height" fuer "pre" und "code" NIRGENDS
   deklariert (mit legacyPropsForElement() geprueft, s.o.): eine
   Basisregel damit waere unbekaempft und verletzte die
   Subset-Invariante. Eine Klassenregel darf es, weil sie kein
   Element beansprucht, das ihr nicht gehoert.

   DER RUECKFALLWERT IST 24px, und auch der ist kein Legacy-Wert: er
   kommt als geerbter ABSOLUTWERT von ".msg-bubble-bot" (Task 2,
   "--ax-line-height-body-md"). 24px Durchschuss auf 12px Schrift ist
   fuer Code doppelter Zeilenabstand.

   EINE BEWUSSTE ABWEICHUNG VON DER VORLAGE: Figma stapelt seine
   Codezeilen als EINZELNE Textknoten mit Zeilenhoehe 18 und 2px
   ABSTAND dazwischen, der sichtbare Zeilenschritt ist dort also 20.
   Ein "pre" ist EIN Textfluss und kennt keinen Abstand zwischen
   Zeilen -- es gibt hier nur eine Zahl, wo Figma zwei hat.

   Gebaut ist der TOKENWERT, "--ax-line-height-mono-sm" (18,
   zeichengleich Figmas Zeilenhoehe), also 1,5 auf 12px Schrift. Die
   Begruendung ist NICHT "20 gehoert zu keinem Token" -- dieser Block
   setzt zweimal literale 12 (Innenabstand und Aussenabstand), und
   zwar mit gutem Grund. Sie ist: die Mono-Skala bleibt geschlossen.
   Groesse und Zeilenhoehe kommen aus DEMSELBEN Tokenpaar wie in der
   Fusszeile (Task 2); eine literale 20 haette hier einen zweiten,
   nicht ableitbaren Zeilenschritt fuer dieselbe Schriftgroesse
   eingefuehrt. Die dritte Moeglichkeit --
   "calc(var(--ax-line-height-mono-sm) + 2px)" -- traegt beides
   (Tokenbindung und Figmas Zeilenschritt) und bleibt offen, falls die
   Sichtpruefung den engeren Satz beanstandet.

   DER GELTUNGSBEREICH IST DER TEXTKOERPER, wie bei Task 3 und aus
   demselben Grund: ".orchestration-md" (Task 6) haengt NEBEN dem
   Koerper, nicht darin (chatwindowbotmessage.js:205-215), und wird
   von "> :first-child" nicht getroffen. Beide Blasen stehen
   ausgeschrieben, weil beide Gestalten desselben Organismus Markdown
   rendern (chatwindowbotmessage.js:523-524) -- am Messaufbau
   nachgestellt: streicht man die erste Zeile, faellt NUR die
   Antwortblase auf 24px zurueck, die Begruessung haelt ihre 18. */
[data-design="new"] .msg-bubble-bot > :first-child pre,
[data-design="new"] .msg-bubble-greeting > :first-child pre {
  line-height: var(--ax-line-height-mono-sm);
}

/* Der erste und der letzte Block sitzen buendig am Innenabstand --
   dieselbe Aussage wie Task 3s Rhythmusregeln, fuer das Element, das
   dort ausdruecklich ausgespart blieb ("ein '> :first-child {
   margin-top: 0 }' haette einen Codeblock am Anfang der Antwort sehr
   wohl getroffen"). Ohne diese beiden Regeln stuende eine Antwort,
   die MIT einem Codeblock beginnt, 12px zu tief in der Blase, und
   Figmas "Innenabstand 16" waere an ihr nicht herstellbar.

   Eigene Regeln statt einer Erweiterung von Task 3s Elementliste,
   weil ein Selektor einen Eigentuemer hat (Ruling 1) -- und weil
   diese hier die Langformen brauchen: an "pre" nimmt die Kurzform
   "margin" ueber die Regel oben schon den seitlichen Einzug zurueck,
   eine zweite Kurzform hier wuerde ihn wieder mitschreiben. */
[data-design="new"] .msg-bubble-bot > :first-child > pre:first-child,
[data-design="new"] .msg-bubble-greeting > :first-child > pre:first-child {
  margin-top: 0;
}

[data-design="new"] .msg-bubble-bot > :first-child > pre:last-child,
[data-design="new"] .msg-bubble-greeting > :first-child > pre:last-child {
  margin-bottom: 0;
}

/* ══ 07 · Chat & AI, Teil A — Task 5: Die Quellenzeile ════════════
   Figma-Knoten 149:147 ("Sources", Komponentensatz mit sechs
   Varianten: Anzahl 1-3 x State=Collapsed/Expanded). Der Bestand
   steht in webapp.css:1117-1275 (".src-*", 22 Regeln) und entsteht
   ausschliesslich in MoleculeSourceInfoAccordion.

   DIESER BLOCK MACHT EINE GETROFFENE ENTSCHEIDUNG WIEDER AUF, und
   deshalb steht die alte hier WOERTLICH, bevor die neue kommt.
   "04 · Core" hat dieselbe Stelle schon einmal geprueft und
   festgehalten (Absatz 2 des Survey-Kommentars zu den zwei
   Accordion-Klassen, weiter oben in dieser Datei, unveraendert):

     "MoleculeSourceInfoAccordion (".src-trigger"/".src-body", 2
      Aufrufer: chatwindowbotmessage.js ueber sourceinfomanager.js,
      organismsresultcard.js) -- eine kompakte, unumrandete
      Quellenangaben-Zeile (10-12px Badges/Zeilen) unter einer
      Chat-Nachricht bzw. in einer Ergebniskarte. Figmas
      15px-Titel/umrandetes 16px-Panel wuerde diese Einpassung
      sprengen -- unveraendert erwogen und verworfen (dieselbe
      Spannung wie bei Card), nur die Trigger-Textfarbe wird
      token-isiert."

   VERWORFEN WURDE ALSO NICHT DIE UEBERNAHME, SONDERN EINE FASSUNG:
   ein 15px-Titel in einem umrandeten 16px-Panel. Der Grund war die
   Einpassung -- die Zeile sitzt unter einer Chatantwort und in einer
   Ergebniskarte, beide Male INNERHALB eines Kastens, der schon eine
   Flaeche und einen Rahmen traegt; ein zweiter Kasten mit eigenem
   Titel darin liest sich als zweites Bauteil. Diese Begruendung gilt
   unveraendert weiter, und sie ist der Grund, warum dieser Block das
   Panel AUCH JETZT nicht baut.

   FIGMAS HEUTIGER KNOTEN ZEIGT EINE DRITTE FASSUNG, keine
   Wiedervorlage der verworfenen: eine schlanke Zeile -- Symbol 15 in
   "accent/knowledge", Beschriftung Inter Medium 12/16 in
   "accent/knowledge", Chevron in "text/muted", waagerechter Abstand
   8, Zeilenhoehe 16, KEIN Panel, KEIN Rahmen, KEINE Flaeche (Knoten
   149:76, Auto-Layout HORIZONTAL, itemSpacing 8, padding [0,0,0,0],
   fills leer). Die Vorlage hat sich geaendert; die alte Entscheidung
   wird davon nicht widerrufen, sondern bestaetigt.

   UND DIE VORLAGE WIDERSPRICHT SICH SELBST -- eine VIERTE Fassung,
   im selben Dokument, auf derselben Seite, und ausgerechnet in dem
   Knoten, der den Wirt dieses Bauteils zeigt. Die "Chat / Assistant
   Message" (46:6) traegt in ihrem Koerper einen Knoten "sources"
   (46:21), und das ist dasselbe Bedienelement -- Beschriftung
   "Quellen", Zaehler, Chevron. Nur sieht es dort so aus:

                     149:147 (Sollwert)      46:21 (im Wirt)
     Rahmenform      keine                   Radius 10, Flaeche
                                             bg/surface-2, Innen-
                                             abstand 8/12, Hoehe 34
     Beschriftung    Medium 12/16,           Medium 13/18,
                     accent/knowledge        text/secondary
     Zaehler         im Beschriftungstext    eigene Pille, Radius
                     ("1 Quelle")            999, 0/8, Flaeche
                                             accent/knowledge-bg,
                                             Text accent/knowledge
     Symbol          15, accent/knowledge    keines
     Chevron         11x7, text/muted        14x14, text/secondary

   Das ist NICHT zweimal dasselbe mit anderen Zahlen, sondern zweimal
   etwas anderes: einmal eine unaufdringliche Zeile im Akzentton,
   einmal eine graue Schaltflaeche mit eigener Flaeche. Und die
   zweite ist der Sache nach die Fassung, die "04 · Core" verworfen
   hat -- derselbe Kasten im Kasten, nur ohne Titel. Gebaut wird
   deshalb 149:147: die Spec fuehrt diesen Knoten als den Sollwert
   des Bauteils (Abschnitt 5, "Sources"), und die Begruendung von
   "04 · Core" spricht gegen den anderen. Der Widerspruch selbst geht
   als Befund an die Vorlagen-Eigentuemer (Spec Abschnitt 7); die
   Zeile "Quellen-Chip" in Spec Abschnitt 5 unter "Assistant Message"
   beschreibt genau 46:21 und ist damit die zweite Haelfte desselben
   Widerspruchs, nicht ein weiteres Bauteil.

   UND DER WIDERSPRUCH HAT EINEN PREIS, DER NIRGENDS STAND. 46:21 ist
   keine beliebige vierte Fassung: seine Kastenmasse sind
   zeichengleich denen des WERKZEUGAUFRUFS (Knoten 149:148, Task 6) --
   Hoehe 34, Radius 10, Innenabstand [8,12,8,12], Abstand 8, Flaeche
   bg/surface-2. 46:21 ist die Quellenzeile, gezeichnet im
   Ausklapp-Zeilen-Muster des Werkzeugaufrufs. (Zwei Unterschiede,
   selbst nachgemessen und der Vollstaendigkeit halber genannt: 46:21
   traegt KEINEN Rahmen, der Werkzeugaufruf 1px border/soft; und
   46:21s Chevron ist 14x14 in text/secondary, der des
   Werkzeugaufrufs 11x7 in text/muted.)

   Und die beiden haengen im Produkt untereinander:
   ".src-accordion-wrapper" (chatwindowbotmessage.js:205) und
   ".tool-invocations-wrapper" (:211) sind Geschwister im selben
   ".msg-bubble-bot" -- dazwischen nur ".chunk-img-wrapper" (:208),
   das ohne Trefferbilder leer und damit 0 px hoch ist (es hat im
   ganzen CSS keine Regel). Nach Task 6 steht also eine flaechenlose
   tuerkise Zeile unmittelbar ueber einem umrandeten grauen
   34px-Panel. Das ist der Preis dieser Entscheidung: sie entkoppelt
   zwei Zeilen optisch, die die Vorlage im Wirtsknoten gleich
   gezeichnet hat. Der Komponentensatz bleibt die Autoritaet -- ein
   Bildschirmrahmen ist eine Komposition und veraltet --, aber die
   Entscheidung ist in diesem Wissen getroffen, nicht daran vorbei.

   ZWEI AUFRUFER, UND DER ZWEITE STEHT NICHT IM CHAT. Der Baustein
   haengt einmal INNERHALB der Antwortblase (chatwindowbotmessage.js:
   205 -- ".src-accordion-wrapper" ist ein Geschwister des Markdown-
   Koerpers, nicht der Nachrichtenspalte) und einmal DIREKT in einer
   Ergebniskarte der KI-Services (organismsresultcard.js:154, dort
   ohne den Wrapper). Der Untergrund ist damit ein anderer, und jede
   Farbaussage unten ist an BEIDEN gerastert -- Messregel 3:

     Wirt                          gerasterter Grund
     Cockpit-Chat, Blase           rgb(18,17,28) / rgb(255,255,255)
     eingebettet (Hilfe/Widget)    rgb(26,24,38) / rgb(244,243,247)
     Ergebniskarte                 rgb(25,24,37) / rgb(251,251,252)

   Die Ergebniskarte ist NICHT "surface-2", auch wenn sie ihm nahe
   kommt: ".result-card" traegt "--background-color-card", und das
   liegt im neuen Design eine Stufe daneben (25,24,37 statt
   26,24,38). Gemessen, nicht gleichgesetzt.

   HIER WEICHT DIESER BLOCK VON DER VORLAGE AB, UND ZWAR NUR IM
   HELLEN THEME -- dieselbe Abweichung, dieselbe Begruendung und
   dasselbe Token wie beim Agentennamen in Task 2. Gerastert, Text
   gegen Grund:

     Ton                        Chat      eingebettet   Karte
     dunkel teal/500 (Figma)    7,705     7,193         7,216   ok
     hell   teal/600 (Figma)    3,682     3,333         3,560   VERFEHLT
     hell   teal/800 (gebaut)   7,267     6,578         7,027   ok

   Die teal/600-Zeile ist der Rueckfallwert OHNE die Gegenregel
   unten: Ton per Gegenversuch gemessen (rgb(8,145,178)), Grund
   gerastert, Verhaeltnis daraus gerechnet. Die vier anderen Zeilen
   sind durchweg gerastert.

   Figmas heller Ton verfehlt 4,5 auf ALLEN DREI Wirten. Gebaut wird
   deshalb "--ax-accent-knowledge-on-bg" (teal/800, rgb(21,94,117)),
   der lesbare Ton derselben Rampe -- die hellste Stufe, die 4,5
   haelt; eine Zwischenstufe zwischen teal/600 und teal/800 gibt es
   nicht. Preis: ΔE 21,265 zur Vorlage. Im dunklen Theme bleibt es
   bei Figmas Wert; eine Abweichung dort, wo keine noetig ist, waere
   eine zweite ohne Grund. Rulings 10 und 12.

   DIE ANTWORT AUF DIESE FRAGE GEHOERT IN DIE TOKENSCHICHT, nicht in
   dieses Bauteil: es ist die dritte Stelle mit derselben Zahl
   (Tabellenkopf in "05 · Data" Teil A, Agentenname in Task 2, hier).
   Bis dahin ist die Gegenregel unten die kleinstmoegliche Fassung.

   EIN BEFUND, DER NICHT BEHOBEN WIRD -- DER CHEVRON. Figma gibt ihm
   "text/muted", und das Token haelt 4,5 nicht ueberall (die Warnung
   des Plans, hier nachgemessen):

     Wirt                     dunkel               hell
     Cockpit-Chat, Blase      4,796   ok           7,416   ok
     eingebettet              4,477   VERFEHLT     6,713   ok
     Ergebniskarte            4,492   VERFEHLT     7,171   ok

   Gebaut wird trotzdem Figmas Wert, aus drei gemessenen Gruenden:
     1. Der Chevron ist ein Auf-/Zu-Zeiger ("▾"/"▴"), kein Fliess-
        text. Fuer ein Bedienelement gilt 3,0 (Messregel 5), und
        das haelt er mit 1,49-facher Luft.
     2. Der Bestand traegt dort "--clr-accent", und das ist im neuen
        Design cyan/500 im DUNKLEN und cyan/600 im HELLEN Theme --
        die Bruecke haengt es dunkel an "--ax-action-primary"
        (= cyan/500, tokens.css:153) und hell an "--ax-text-link"
        (= cyan/600, tokens.css:257). In beiden Faellen ein ZWEITER,
        anderer Cyanton unmittelbar neben dem tuerkisen Etikett:
        ΔE 25,691 (teal/500 gegen cyan/500) bzw. 21,306 (teal/800
        gegen cyan/600). Zwei verschiedene Cyans in einer Zeile sind
        sichtbar falsch; das ist der eigentliche Grund, warum Figma
        hier entfaerbt.
     3. Die Zeile als Ganzes wird besser, nicht schlechter: in der
        Ergebniskarte trug der GESAMTE Ausloesertext bisher 4,492
        (er erbte "--ax-text-muted"), jetzt sind es 7,216 fuer das
        Etikett und 4,492 nur noch fuer ein einzelnes Zeichen.
        Eingebettet: 4,477 fuer alles -> 7,193 / 4,477.
   Der Befund ist derselbe wie an der Fusszeile aus Task 2 und
   gehoert in dieselbe Antwort: "--ax-text-muted" haelt auf
   "surface-2" nicht. Gemeldet, nicht lokal geflickt -- eine eigene
   Ausnahme hier ergaebe ein zweites, abweichendes Muted.

   FIGMAS SYMBOL HAT IM BESTAND KEINEN SICHTBAREN TRAEGER, und das
   ist kein Uebersehen, sondern gemessen: MoleculeSourceInfoAccordion
   legt zwar ein "span.src-trigger-icon" an, aber mit LEEREM Text
   (moleculesourceinfoaccordion.js:35-36). Der Kasten misst in beiden
   Designs, beiden Themes und allen drei Wirten 0x0. Eine Farbe oder
   Groesse daran waere eine Deklaration ohne Wirkung; ein Symbol
   einzusetzen waere Produktionscode und gehoert nicht in einen
   Umbau-Task. Was bleibt: das leere Element ist ein Flex-Kind und
   belegt weiterhin EINE Luecke -- die Zeile beginnt mit 8px Nichts
   (vorher 6px). Befund an die Eigentuemer.

   DER ZAEHLER: DER BESTAND SPALTET FIGMAS EINEN TEXTKNOTEN IN ZWEI.
   Figma schreibt "1 Quelle" / "2 Quellen" in EINEN Textknoten in
   "accent/knowledge"; der Bestand setzt "Quellen" in
   ".src-trigger-label" und die Zahl daneben in eine Pille
   ".src-badge". Beide Fassungen der Vorlage sind sich darin einig,
   welche Farbe die Zahl traegt (149:78: accent/knowledge im
   Etikettentext; 46:24: accent/knowledge auf accent/knowledge-bg) --
   die Pille bekommt deshalb genau dieses Tokenpaar. Ohne das bliebe
   sie auf Legacys "--clr-accent" stehen und saesse als zweiter,
   anderer Cyanton direkt neben dem tuerkisen Etikett (cyan/500 im
   dunklen, cyan/600 im hellen Theme; ΔE 25,691 bzw. 21,306).

   WAS DIESER BLOCK NICHT ANFASST, mit Begruendung:
     - ".src-body"/".src-row" und die sechs Spannen darin. Figmas
       ausgeklappter Zustand (149:85 u.a.) gibt fuer die Zeile
       Radius 10, Flaeche bg/surface-2, 1px border/soft,
       Innenabstand 8/12, Abstand 12, Texte Medium 12/16 in
       text/primary bzw. text/muted und eine runde Indexpille
       (20x20, bg/hover, text/secondary). Der Bestand hat Radius 6,
       halbdurchsichtige Flaeche, 5/8, 11px -- UND fuenf Elemente,
       die Figma gar nicht kennt (Trefferguete, Persoenlich- und
       Zentral-Abzeichen, Lupe, Weblink). Das ist eine
       Zuordnungsfrage, keine Farbfrage, und weder Plan noch Spec
       geben dafuer Sollwerte an (beide beschreiben unter "Sources"
       ausschliesslich den eingeklappten Zustand). Der Ist-Stand ist
       in der Testdatei zugesichert, damit ihn niemand nebenbei
       verschiebt.
     - Der Trennstrich ueber der Zeile (".src-accordion-wrapper",
       border-top 1px, margin-top 12, padding-top 10). Er trennt die
       Quellen vom Antworttext; Figma stapelt den Koerper
       stattdessen mit Abstand 12 ohne Linie. Ihn zu entfernen waere
       eine Aenderung an der Trennung, nicht an der Zeile -- gehoert
       in die Abnahme.
     - Der Innenabstand "2px 0" des Ausloesers. Figma hat 0, aber
       die 4px sind die Klickflaeche einer Zeile, die im Produkt
       anklickbar ist.
     - Die 640px-Verdichtung braucht KEINE Gegenregel: gemessen bei
       620px Viewport aendert sich an ".src-*" nichts -- anders als
       bei den Blasen (Task 1/2) gibt es fuer diese Klassen keinen
       Media-Block in webapp.css.

   DER EINGEBETTETE WIRT BRAUCHT EBENFALLS KEINE GEGENREGEL:
   "body.chat-embedded" setzt an keiner ".src-*"-Klasse etwas
   (geprueft und gemessen -- alle Werte unten sind dort
   zeichengleich, nur der Grund unter der Blase ist ein anderer). */

/* Die Zeile. Figma 149:76: Abstand 8, Zeilenhoehe 16, Farbe
   "accent/knowledge".

   "--ax-space-2" statt literal 8, und das ist geprueft, nicht
   uebernommen: anders als "--ax-space-3" (das Task 2 bis 4 deshalb
   literal setzen mussten) hat "--ax-space-2" in KEINEM der beiden
   @media-Bloecke von tokens.css einen Eintrag und steht an jedem
   Haltepunkt auf 8.

   DIE ZEILENHOEHE STEHT AM AUSLOESER, nicht am Etikett, und das ist
   der Unterschied zwischen "schlank" und "sieht schlank aus": die
   Hoehe der Zeile bestimmt das hoechste Flex-Kind. Ohne diese
   Deklaration erben Etikett UND Chevron den Absolutwert der Blase
   (24px, Task 2) bzw. der Ergebniskarte (20px) -- gemessen faellt
   die Zeile mit ihr von 28 auf 22 px im Chat und von 24 auf 22 px
   in der Karte. Der Rest bis zu Figmas 16 sind die 2+2 px
   Klickflaeche des Bestands und die 1+1 px der Zaehlerpille.

   DIE FARBE GILT AUCH IM HOVER, ohne eigene Regel dafuer, und das
   ist gemessen: Legacys ".src-trigger:hover" wiegt (0,2,0), genau
   wie diese Regel -- der Gleichstand geht ueber die Ladereihenfolge
   an components.css. Eine zusaetzliche ":hover"-Selektorzeile hier
   waere ein WAECHTER, DER NICHTS BEWACHT: streicht man sie, aendert
   sich kein einziger gerechneter Wert (nachgestellt). Sie ist
   deshalb nicht gebaut; die Abhaengigkeit von der Ladereihenfolge
   ist dieselbe wie bei Punkt 1 des Abschnittskopfes weiter oben und
   in der Testdatei zweiseitig zugesichert (Ruhe UND Hover). */
[data-design="new"] .src-trigger {
  gap: var(--ax-space-2);
  line-height: var(--ax-line-height-label-sm);
  color: var(--ax-accent-knowledge);
}

/* Der lesbare Tuerkiston fuer das helle Theme (Begruendung oben).
   Rueckfallwert ohne diese Regel: teal/600, also 3,682 / 3,333 /
   3,560 auf den drei Wirten. */
[data-design="new"][data-theme="light"] .src-trigger {
  color: var(--ax-accent-knowledge-on-bg);
}

/* Die Rueckmeldung beim Zeigen. Der Bestand faerbt den Ausloeser auf
   Hover um (Legacy: muted -> secondary, "04 · Core": dasselbe mit
   Tokens). DAS GEHT MIT FIGMAS FARBE NICHT MEHR, und der Grund ist
   gemessen: im dunklen Theme haette die Rampe noch Luft
   (teal/500 -> teal/400 waere heller), im HELLEN steht der Ton
   bereits auf teal/800.

   EINE STUFE WEITER GAEBE ES ZWAR -- "--ax-teal-900" (tokens.css:42),
   und sie waere sehr wohl unterscheidbar: ΔE 23,201 zu teal/800,
   14,708 gegen Weiss. Sie faellt aus einem anderen Grund aus, und
   der ist eine ROLLENfrage: teal/900 wird im ganzen System genau
   EINMAL referenziert, als "--ax-accent-knowledge-bg"
   (tokens.css:83) -- eine Flaechenrolle. Einen Vordergrund
   "-on-bg-hover" gibt es nicht. Der analoge Schritt im DUNKLEN Theme
   kaeme dagegen aus "--ax-accent-knowledge-on-bg" (teal/400, 10,351
   auf der Blase), also aus einer Vordergrundrolle. Die beiden Themes
   zoegen ihren Hover damit aus zwei verschiedenen Tokenrollen -- oder
   das helle aus einer Primitive, die dieser Abschnitt sonst
   nirgends anfasst.

   Gebaut ist deshalb die Unterstreichung -- keine Erfindung, sondern
   das Idiom, das dieselbe Bauteilfamilie schon benutzt
   (".src-link:hover", webapp.css:1202). Sie wirkt in beiden Themes
   gleich, laesst Figmas Farbe unangetastet und veraendert keine
   Kastenmasse.

   AM ETIKETT, NICHT AM AUSLOESER: eine Unterstreichung am Flex-
   Behaelter traefe auch Zaehlerpille und Chevron. */
[data-design="new"] .src-trigger:hover .src-trigger-label {
  text-decoration: underline;
}

/* Die Beschriftung. Figma 149:78: Inter Medium 12, Laufweite 0.
   Rueckfallwerte ohne diese Regel: 11px (webapp.css:1147) und 400
   (geerbt). Die Zeilenhoehe steht bewusst NICHT hier, sondern eine
   Regel weiter oben am Ausloeser -- sie muss auch den Chevron
   treffen, sonst bleibt die Zeile 24px hoch. */
[data-design="new"] .src-trigger-label {
  font-size: var(--ax-font-size-label-sm);
  font-weight: 500;
}

/* Die Zaehlerpille (Begruendung oben: der Bestand spaltet Figmas
   einen Textknoten in zwei). Figma 46:23/46:24: Flaeche
   "accent/knowledge-bg", Text "accent/knowledge", Medium 12/16.

   Geometrie bleibt Bestand: Radius 10 auf einer 18px hohen Pille ist
   von Figmas 999 nicht zu unterscheiden, und der Innenabstand 1/7
   traegt sie sauber. Die Zeilenhoehe MUSS mit, weil Legacys
   "line-height: 1.6" relativ ist -- mit der neuen 12px-Schrift
   ergaebe sie 19,2px und machte die Zeile 25,19 statt 22 px hoch
   (gemessen). Das ist ein Rueckfallwert, den KEIN voller Stapel
   zeigt: weder Legacys 16 noch Figmas 16.

   Die Flaeche hebt sich in allen drei Wirten deutlich ab, gerastert,
   ΔE (CIE76): 15,602 / 14,758 / 14,236 (dunkel) und 15,079 / 14,665
   / 14,683 (hell). Der Text darauf haelt 6,058 (dunkel) und 6,491
   (hell) -- gegen die EIGENE Flaeche gemessen, nicht gegen die Blase
   dahinter. */
[data-design="new"] .src-badge {
  background-color: var(--ax-accent-knowledge-bg);
  color: var(--ax-accent-knowledge);
  font-size: var(--ax-font-size-label-sm);
  font-weight: 500;
  line-height: var(--ax-line-height-label-sm);
}

/* Auf teal/100 traegt teal/600 nur 3,289 -- derselbe Grund wie am
   Ausloeser, andere Flaeche. Mit teal/800 sind es 6,491. */
[data-design="new"][data-theme="light"] .src-badge {
  color: var(--ax-accent-knowledge-on-bg);
}

/* Der Chevron. Figma 149:79: "text/muted" (Befund und Begruendung
   oben). Rueckfallwert ohne diese Regel: Legacys "--clr-accent" --
   im neuen Design rgb(0,159,227) (cyan/500) im dunklen und
   rgb(0,122,176) (cyan/600) im hellen Theme, beides gemessen.

   FIGMAS CHEVRON IST EIN VEKTOR VON 11x7, UND DAS MASS WIRD NICHT
   UEBERNOMMEN. Gebaut bleibt Legacys Glyphe "▾"/"▴" bei 10px;
   ihr Kasten misst gemessen 8,36 x 16,00 (neu) bzw. 8,36 x 16,50
   (alt). Ein Vektormass bildet sich nicht auf eine Textglyphe ab --
   uebernommen wird deshalb die Farbe, nicht die Groesse. Dieselbe
   Grenze wie beim Symbol weiter oben, mit dem Unterschied, dass es
   hier ein sichtbares Zeichen GIBT. */
[data-design="new"] .src-chevron {
  color: var(--ax-text-muted);
}

/* ══ 07 · Chat & AI, Teil A — Task 6: Der Werkzeugaufruf ══════════
   Figma-Knoten 149:204 ("Tool Call", Komponentensatz mit sechs
   Varianten: drei Zustaende x State=Collapsed/Expanded). Der Bestand
   steht in webapp.css:2814-2923 und :13440-13444 (".tool-invocation*",
   19 Regeln) und entsteht ausschliesslich in
   OrganismsToolInvocation.

   ZWEI RENDERPFADE, UND SIE ERZEUGEN NICHT DIESELBEN KLASSEN. Plan
   und Spec fuehren beide Wege mit dem Zusatz "Beide erzeugen dieselben
   Klassen". Am DOM nachgemessen (beide Pfade in derselben Seite
   gebaut, Klassenmengen und Baumformen verglichen) stimmt das nicht:

     Framework-Pfad          static buildDomElement()
     (setupUi/fillData,      (:87-163)
      :19-60)
     div.molecule            -
       div.tool-invocation     div.tool-invocation
         div.header              button.header.toggle
           -                       span.caret
           span.icon               span.icon
           span.name               span.name
           span.duration           span.duration
         div.args              div.details
         div.body                pre.args
                                 pre.body

   Der Framework-Pfad kennt ".tool-invocation-caret",
   ".tool-invocation-details" und ".tool-invocation-toggle" NICHT, sein
   Kopf ist ein <div> statt eines <button>, und Argumente und Ergebnis
   sind <div> statt <pre> -- er ist also gar nicht aufklappbar und
   bekommt von Task 4s "pre"-Basisregel nichts ab.

   UND ER HAT KEINEN EINZIGEN AUFRUFER. Im ganzen Repo wird
   "new OrganismsToolInvocation(...)" nirgends geschrieben; benutzt wird
   ausschliesslich die statische Fassung, und zwar an VIER Stellen (Plan
   und Spec nennen zwei):

     chatwindowbotmessage.js:792   "Tools verwendet" in der Antwort
     chatwindowbotmessage.js:821   Vorschlags-Gate (pendingtoolcalls)
     chatwindowbotmessage.js:933   Entscheidungs-Anzeige (History)
     organismsresultcard.js:204    Ergebniskarte der KI-Services
                                   -- AUSSERHALB des Chats

   Jede Regel unten haengt deshalb an KLASSEN, nicht an Elementen, und
   ist an der statischen Fassung gemessen. Der Framework-Pfad ist toter
   Code; das ist ein Befund an die Eigentuemer und wird hier nicht
   behoben (das waere Produktionscode). Zugesichert ist der Unterschied
   trotzdem -- verschwindet er, ist entweder der tote Pfad entfernt oder
   angeglichen worden, und beides soll auffallen.

   DER DRITTE ZUSTAND EXISTIERT IM PRODUKT NICHT ALS EIGENE KLASSE.
   Figma hat drei (fertig, Fehler, "laeuft..."); buildDomElement kennt
   genau zwei Zweige, "error" oder nicht (:88, :92). Der Vorschlag im
   Gate geht ohne "error" und ohne "result" durch dieselbe Funktion und
   traegt deshalb ".tool-invocation-ok" -- mit dem Haken "✔" und
   "0 ms". Gemessen ist er in JEDER Eigenschaft von einem fertigen
   Aufruf ununterscheidbar (ΔE 0,000 zwischen beiden Zustandstoenen),
   der einzige Unterschied im DOM ist sein Vorfahr
   ".pending-tool-gate-wrapper". Eine eigene Klasse dafuer waere
   Produktionscode; eine Farbregel ueber den Vorfahren waere ein blauer
   Haken, der weiterhin "fertig" bedeutet. GEMELDET, NICHT GEFLICKT --
   und zweiseitig zugesichert, damit der Tag auffaellt, an dem das
   Produkt den Zustand bekommt.

   DIE ZUORDNUNG DER ZUSTANDSFARBE IST EINE ENTSCHEIDUNG, KEINE
   ABLESUNG. Figmas Zeile hat VIER Kinder: ein Werkzeug-Sinnbild in
   "accent/ai" (zustandsUNabhaengig), den Namen, einen ZUSTANDSTEXT in
   der Zustandsfarbe und den Chevron. Der Bestand hat ebenfalls vier,
   aber anders belegt: Chevron, Sinnbild, Name, Dauer -- und das
   Sinnbild IST hier der Zustand ("✔"/"✖", gruen/rot), waehrend die
   Dauer ("420 ms") die neutrale rechte Spalte ist. Es gibt also kein
   zustandsunabhaengiges Sinnbild, auf das "accent/ai" passen wuerde.

     Figma                      gebaut
     Sinnbild 15, accent/ai     Groesse 15 uebernommen, FARBE NICHT --
                                ein Haken in Violett ist kein
                                Werkzeugsymbol, sondern ein Haken, der
                                seine Aussage verloren hat.
     Zustandstext Medium 12     die Dauer: Medium 12 in der
     in der Zustandsfarbe       Zustandsfarbe.

   Die Zustandsfarbe steht damit an ZWEI Stellen (Sinnbild und Dauer),
   und das ist Absicht: Figmas Fassung nimmt der Zeile zwei Traeger,
   die der Bestand heute hat -- die getoente Flaeche
   (rgba(74,222,128,0.05) bzw. rgba(239,68,68,0.05)) und den 3px
   breiten Streifen links. Beide fallen unten weg. Bliebe nur das
   Sinnbild, sagte die Zeile im neuen Design WENIGER als heute.

   DIE FLAECHE UND DER RAHMEN, UND HIER WEICHT DIESER BLOCK VON DER
   VORLAGE AB. Figma: Flaeche "bg/surface-2", Rahmen 1px
   "border/soft". Gerastert und gerechnet (ΔE CIE76), je gegen den
   Untergrund, den die Karte tatsaechlich hat:

     Wirt                  Flaeche gegen Wirt   border/soft gegen Flaeche
     Cockpit dunkel        4,531                0,000
     Cockpit hell          4,494                4,857
     eingebettet dunkel    0,000                0,000
     eingebettet hell      0,000                4,857

   Zwei Nullen, und jede hat eine eigene Ursache:

     1. "--ax-border-soft" und "--ax-bg-surface-2" sind im DUNKLEN
        Theme DASSELBE Token ("--ax-ink-800", tokens.css:51/60).
        Figmas Rahmen kann die Kante der Flaeche dort nicht zeichnen.
        Das ist derselbe Fund wie in Task 4 -- dort waren
        "--ax-border-soft" und "--ax-bg-surface-3" im HELLEN Theme
        dasselbe Token (:100/108). Zwei Kollisionen, EINE Frage an die
        Tokenschicht.
     2. Der eingebettete Wirt faerbt die Blase selbst auf
        "--clr-embed-bot-bg", und das haengt im neuen Design auf
        "--ax-bg-surface-2" (tokens.css:190). Die Karte traegt dort
        also die Flaeche ihres Wirts.

   Zusammen ergeben sie den Fall, der die Entscheidung erzwingt:
   EINGEBETTET UND DUNKEL WAERE DIE KARTE VOLLSTAENDIG UNSICHTBAR --
   Flaeche wie Wirt, Rahmen wie Flaeche. Und das ist der Wirt, der per
   <iframe> auf Kundenseiten laeuft (und in der In-App-Hilfe). Heute
   ist die Karte dort sichtbar (getoente Flaeche und Streifen); Figmas
   Werte waeren an dieser Stelle eine Regression.

   GEBAUT IST DESHALB "--ax-border-default", ABER NUR IM DUNKLEN THEME.
   Die Tabelle oben sagt, warum das genuegt: Figmas "border/soft" traegt
   im HELLEN Theme einwandfrei -- ΔE 4,857 gegen die eigene Flaeche, in
   BEIDEN Wirten, auch im eingebetteten. Unrenderbar ist er nur dort, wo
   er mit der Flaeche zusammenfaellt, und das ist genau das dunkle Theme.
   Gemessen, alle vier Konfigurationen:

     Wirt                  border/soft   gebaut (themegescopt)
     Cockpit dunkel        0,000         5,334   (Abweichung)
     Cockpit hell          4,857         4,857   (Figmas Wert)
     eingebettet dunkel    0,000         5,334   (Abweichung)
     eingebettet hell      4,857         4,857   (Figmas Wert)

   Die Abweichung schrumpft damit von vier auf ZWEI Konfigurationen, und
   in genau den beiden ist Figmas Wert nachweislich nicht zeichenbar.
   Das ist dieselbe Regel, die drei Regeln tiefer an den Zustandsfarben
   steht -- und dort ausgeschrieben: "Eine Abweichung dort, wo keine
   noetig ist, waere eine zweite ohne Grund" (Rulings 10 und 12). Die
   erste Fassung dieses Blocks hat gegen die eigene Regel verstossen; die
   Nachbesserung holt sie ein.

   DIE GEGENREGEL TRAEGT ":not([data-theme=\"light\"])" UND NICHT
   "[data-theme=\"dark\"]", und das ist keine Geschmacksfrage: tokens.css
   fuehrt das dunkle Theme als Grundfassung an ":root" (:6) und ueberlagert
   nur das helle ("[data-design=new][data-theme=light]", :96/:219). Ohne
   gesetztes Attribut gilt also DUNKEL -- und ein "[data-theme=dark]"
   liesse die Karte dann mit einem unsichtbaren Rahmen stehen. Die
   Gegenregel wiegt (0,3,0) und schlaegt die Basisregel (0,2,0); sie setzt
   nur "border-color", damit Breite und Stil an einer Stelle bleiben.

   DIE FLAECHE bleibt Figmas "bg/surface-2": sie ist der Sollwert, der den
   Werkzeugaufruf vom Codeblock ("bg/surface-3", Task 4) unterscheidet,
   und eine Abweichung dort haette diesen Unterschied eingeebnet.

   DASS TASK 4 IM SPIEGELFALL ANDERS ENTSCHIEDEN HAT, IST KEIN
   VERSEHEN. Dort blieb Figmas Rahmen stehen, weil er im ANDEREN Theme
   traegt und die Flaeche des Codeblocks in KEINEM Wirt mit ihrem
   Untergrund zusammenfaellt -- der Block war nie unsichtbar, nur
   randlos. Hier faellt beides zusammen, und zwar im Wirt ausserhalb
   des Hauses.

   DER NACHBAR SIEHT ANDERS AUS ALS DIESE KARTE, UND ZWAR BEWUSST
   (Ruling 16). ".src-accordion-wrapper" (chatwindowbotmessage.js:205)
   und ".tool-invocations-wrapper" (:211) sind Geschwister in derselben
   Blase; dazwischen liegt nur ".chunk-img-wrapper" (:208), das ohne
   Trefferbilder 0px hoch ist (im ganzen CSS keine Regel -- gemessen
   0px). Nach diesem Task steht also eine flaechenlose tuerkise Zeile
   (22px hoch, ohne Rahmen) unmittelbar ueber einem umrandeten grauen
   Panel. Figma zeigt dieselbe Quellenzeile im Wirtsknoten 46:21 im
   Ausklapp-Muster DIESER Karte (Hoehe 34, Radius 10, bg/surface-2,
   Innenabstand 8/12) -- die Vorlage widerspricht sich also selbst, die
   Entscheidung fuer die schlanke Zeile ist in Kenntnis dieser Folge
   getroffen (Begruendung im Task-5-Block oben), und der Widerspruch
   geht als EINE Frage an die Vorlagen-Eigentuemer. Hier ist er
   gemessen, an der Galeriekachel in Produktreihenfolge (dunkel,
   Cockpit):

     .src-accordion-wrapper      Hoehe 47, darin die Zeile 22 hoch
     .chunk-img-wrapper          Hoehe 0 -- beginnt und endet an
                                 derselben y-Koordinate wie der naechste
     .tool-invocations-wrapper   beginnt buendig darunter; darin zuerst
                                 der Gruppenkopf ("Tools verwendet",
                                 30,75 hoch), dann die erste Karte

   Zwischen der Unterkante der tuerkisen Zeile und der Oberkante der
   ersten Karte liegen damit 56,5px, und davon gehoeren 30,75 dem
   Gruppenkopf.

   DAMIT SIND ES DREI AUSKLAPP-ZEILEN, NICHT ZWEI -- der Gruppenkopf ist
   selbst ein Bedienelement (".collapsible-header", "cursor: pointer",
   gemessen). Sie stehen an derselben x-Kante (163) in drei Kleidungen:

     Zeile                  Hoehe   Flaeche      Rahmen  Schrift
     .src-trigger (Task 5)  22,00   keine        keiner  11px, tuerkis
     .collapsible-header    30,75   keine        keiner  13,5px, primary
     .tool-invocation (6)   34,00   surface-2    1px     12px Geist Mono

   EINGEKLAPPT -- und das ist der Normalfall -- steht die tuerkise Zeile
   also ueber dem GRUPPENKOPF, und das Panel ist erst nach einem Klick
   da. Ruling 16 beschreibt insofern den ausgeklappten Zustand; der
   Sachverhalt gehoert in die Frage an die Vorlagen-Eigentuemer, denn
   der Gruppenkopf hat in der Vorlage ueberhaupt keine Entsprechung.

   WAS DIESER BLOCK NICHT ANFASST, mit Begruendung:

     .orchestration-md     Ruling 4 gibt den zweiten Markdown-Renderer
                           (utilities/markdownrenderer.js:13-16) diesem
                           Task -- damit ihn NIEMAND still ueberschreibt,
                           nicht damit er umgebaut wird. Weder Plan noch
                           Spec geben fuer den Fluss eines
                           Werkzeugergebnisses einen Sollwert an; Figmas
                           Knoten zeigt den ausgeklappten Zustand ohne
                           Inhalt. Der Bestand (webapp.css:13419-13438:
                           Absaetze 4px, Listeneinzug 1.4em, erster und
                           letzter Block buendig) bleibt deshalb
                           unveraendert und ist stattdessen ZUGESICHERT.
                           Das ist zugleich die Gegenprobe zu Task 3s
                           Abgrenzung: dessen ":first-child"-Scope haelt
                           die 12px des Antwortkoerpers von diesen 4px
                           fern.
     .tool-invocation-     Aussenabstand (0.15em = 1,8px) und
     args / -body          Schriftgroesse (0.8em = 12px) bleiben
                           Bestand. Die 12px sind zeichengleich
                           "--ax-font-size-mono-sm"; eine Zeile, die den
                           Tokennamen setzt, waere im vollen Stapel von
                           ihrer eigenen Abwesenheit nicht zu
                           unterscheiden -- eine Deklaration, die kein
                           Gegenversuch belegen kann, wird hier nicht
                           geschrieben.
     .tool-invocation-     Der Kopf ist ein <button>; Legacys
     toggle                ".tool-invocation-toggle" (webapp.css:2834)
                           setzt background/border/padding/color und
                           "font: inherit" selbst und schlaegt damit die
                           Button-Basisregel aus "04 · Core" direkt. Die
                           beiden Einzelfall-Regeln dazu stehen weiter
                           oben in dieser Datei (Fuenfter Durchgang) und
                           bleiben unveraendert.
     Die Stellung des      Figmas Chevron steht RECHTS, der Bestand
     Chevrons              setzt ihn links vor das Sinnbild. Das ist
                           eine Aenderung an der Reihenfolge, nicht an
                           der Zeile, und ohne Sollwert fuer die
                           Zwischenraeume waere sie geraten. Befund.
     Der Aussenabstand     0.4em = 6px zwischen zwei Karten. Figma
     zwischen den Karten   stapelt die Varianten einzeln und nennt
                           keinen Abstand.
     .tool-invocation-     "Teilergebnis"-Etikett und der Behaelter der
     result-label,         Detailansicht: Figma zeigt fuer den
     -details              ausgeklappten Zustand keinen Inhalt.

   DIE 640-px-VERDICHTUNG BRAUCHT KEINE GEGENREGEL: gemessen bei 620px
   Viewport aendert sich an ".tool-invocation*" nichts -- anders als bei
   den Blasen (Task 1/2) gibt es fuer diese Klassen in webapp.css
   keinen @media-Block. */

/* Die Karte. Figma 149:204: Hoehe 34, Radius 10, Flaeche
   "bg/surface-2", Innenabstand 8/12; Rahmen abweichend
   "--ax-border-default" (Begruendung oben).

   VIER RUECKFALLWERTE, alle einzeln gemessen: die Flaeche faellt auf
   Legacys getoente rgba(74,222,128,0.05) bzw. rgba(239,68,68,0.05),
   der Rahmen auf den 3px-Streifen links (und nur links), der Radius
   auf "0 4px 4px 0" und der Innenabstand auf 6/7,5px im
   Werkzeug-Panel bzw. 6/9px im Gate.

   DIE ZWEI INNENABSTAENDE DES BESTANDS SIND EIN GLEICHSTAND, DEN DIE
   LADEREIHENFOLGE ENTSCHEIDET. ".tool-invocations-wrapper
   .tool-invocation" (webapp.css:13441) wiegt (0,2,0) -- genau wie
   diese Regel -- und setzt dort "0.4em 0.5em" statt der 0.4em/0.6em
   der Basisregel. components.css laedt zuletzt, also gewinnt diese
   Zeile, und beide Wirte tragen danach dieselben 8/12. Das ist die
   Gefahr aus dem Kopf dieser Datei, hier einmal zum Vorteil: die
   Zusicherung misst deshalb im Panel UND im Gate.

   "--ax-space-2" statt literal 8, wie in Task 5 und aus demselben
   geprueften Grund: es hat in KEINEM der beiden @media-Bloecke von
   tokens.css einen Eintrag und steht an jedem Haltepunkt auf 8. Die
   12 dagegen steht literal -- "--ax-space-3" faellt bei <= 768px auf
   10 (tokens.css:401), und Figmas 12 ist eine Aussage ueber die Zeile,
   nicht ueber den Bildschirm (dieselbe Linie wie Task 2 bis 4).

   DIE HOEHE 34 IST EINE SUMME, KEINE DEKLARATION: 1px Rahmen + 8
   Innenabstand + 16 Zeilenkasten des Kopfes + 8 + 1px. Sie steht
   nirgends als "height", und genau deshalb ist die Zeilenhoehe eine
   Regel weiter unten so wichtig wie diese hier. */
[data-design="new"] .tool-invocation {
  background-color: var(--ax-bg-surface-2);
  border: 1px solid var(--ax-border-soft);
  border-radius: var(--ax-radius-md);
  padding: var(--ax-space-2) 12px;
}

/* Die eine Abweichung dieses Tasks, und sie gilt nur im dunklen Theme
   (Begruendung im Abschnittskopf). Rueckfallwert ohne diese Regel:
   Figmas "--ax-border-soft" = rgb(26,24,38), also ΔE 0,000 gegen die
   eigene Flaeche -- und im eingebetteten Wirt zusaetzlich ΔE 0,000
   gegen die Blase, die Karte waere dort vollstaendig unsichtbar. */
[data-design="new"]:not([data-theme="light"]) .tool-invocation {
  border-color: var(--ax-border-default);
}

/* Die Kopfzeile. Figma: Abstand 8, Zeilenkasten 16.

   DIE ZEILENHOEHE STEHT HIER UND NICHT AN DEN VIER SPANNEN, aus dem
   Grund, den Task 5 an derselben Stelle gemessen hat: die Hoehe einer
   Flexzeile bestimmt das hoechste Kind. Ohne diese Deklaration erben
   alle vier den Absolutwert der Blase (24px, Task 2), und die Karte
   waere 42 statt 34 px hoch (gemessen).

   "margin-bottom: 0" IST DER ZWEITE SUMMAND DERSELBEN RECHNUNG.
   Legacy setzt am Kopf "margin-bottom: 0.2em" (3px auf 15px Schrift);
   die traegt jede EINGEKLAPPTE Karte mit, obwohl darunter nichts
   steht. Mit ihr misst die Karte 37 statt 34 px (gemessen). Der
   Abstand zwischen Kopf und Detailansicht geht dabei nicht verloren --
   ".tool-invocation-details" bringt eigene "margin-top: 0.2em" mit
   (webapp.css:2857), und die gilt nur, wenn es die Detailansicht
   ueberhaupt gibt.

   Der Rueckfallwert des Abstands ist 6px (0.4em auf 15px). */
[data-design="new"] .tool-invocation-header {
  gap: var(--ax-space-2);
  line-height: var(--ax-line-height-label-sm);
  margin-bottom: 0;
}

/* Das Sinnbild. Figma: Groesse 15 (die Farbe NICHT -- Begruendung
   oben). Rueckfallwert: 12,75px (0.85em auf die 15px der Blase). */
[data-design="new"] .tool-invocation-icon {
  font-size: var(--ax-font-size-body-md);
}

/* Der Werkzeugname. Figma: Geist Mono Regular 12, "text/primary".

   DER NAME IST DIE EINZIGE STELLE DER ANTWORT AUSSERHALB DES
   CODEBLOCKS, AN DER DIE VORLAGE MONOSPACE VERLANGT -- und das ist
   eine Aussage, keine Zierde: ein Werkzeugname ist eine Kennung
   ("sql_query"), kein Wort. Die Mono-Token werden hier zum DRITTEN Mal
   benutzt (Fusszeile der Antwort in Task 2, Codezeilen in Task 4).

   Rueckfallwerte, einzeln gemessen: Inter (geerbt), 12,75px und
   Gewicht 600. "--ax-font-size-mono-sm" ist zeichengleich Figmas 12
   und faellt an keinem Haltepunkt (tokens.css:337).

   WAS DER WECHSEL AN BREITE KOSTET, an derselben Kennung gemessen
   ("sql_query", neun Zeichen): 57,66px in Inter, 67,50px in Geist Mono
   -- bei gleicher Schriftgroesse also 9,84px mehr. Der Kopf ist eine
   Flexzeile mit "margin-left: auto" an der Dauer; der Zuwachs geht in
   den freien Raum dazwischen, nicht in die Breite der Karte.

   DIE FARBE STEHT NICHT HIER. "text/primary" ist bereits der geerbte
   Wert der Blase (Task 2); eine Zeile dafuer waere von ihrer eigenen
   Abwesenheit nicht zu unterscheiden. Zugesichert wird sie trotzdem --
   als WAECHTER, nicht als Nachweis. */
[data-design="new"] .tool-invocation-name {
  font-family: var(--ax-font-mono);
  font-size: var(--ax-font-size-mono-sm);
  font-weight: 400;
}

/* Der Zustandstext. Figma: Medium 12 in der Zustandsfarbe; im Bestand
   ist das die Dauer (Begruendung oben).

   "opacity: 1" GEHOERT ZUR FARBE, nicht zur Form: Legacy blendet die
   Dauer auf 0.6 ab (webapp.css:2917), und eine halbdurchsichtige
   Zustandsfarbe waere weder Figmas Ton noch messbar gegen einen
   bekannten Grund -- ihr ΔE haenge am Wirt (Messregel 6). Ueber der
   GERASTERTEN Flaeche der Karte zusammengesetzt faellt der gruene Ton
   mit 0.6 von 10,021 auf 4,362 (dunkel) und von 4,540 auf 2,356
   (hell) -- im hellen Theme also unter die Schwelle 3,0.

   DIE SCHRIFTGROESSE STEHT HIER, OBWOHL SIE IM CHAT NICHTS AENDERT --
   und das ist der wiederkehrende Projektfehler in Spiegelform, in der
   Nachbesserung gefunden. "0.8em" auf die 15px der Blase (Task 2) sind
   bereits genau Figmas 12; ein Gegenversuch IN DER BLASE kann diese
   Deklaration also nicht belegen. Im DRITTEN Wirt sehr wohl:

     Wirt                     Wirtsgroesse        Name    Dauer
     Chat ".msg-bubble-bot"   15px (Laenge)       12      12
     ".result-card"           13,333px (Schluessel-  12   10,667
                              wort, body-Kette)

   Figma verlangt 12 fuer BEIDE Traeger. Der Name haelt es ueberall, weil
   er es ausdruecklich gesetzt bekommt; die Dauer tat es nicht. Eine
   Deklaration, die an einer Stelle unsichtbar ist, ist an einer anderen
   sehr wohl ein Nachweis -- der Gegenversuch dafuer steht in der
   Testdatei als Sonde in einer ".result-card"
   (organismsresultcard.js:204 ist der vierte Aufrufer dieses Bauteils).

   Rueckfallwert des Gewichts: 400. */
[data-design="new"] .tool-invocation-duration {
  font-size: var(--ax-font-size-mono-sm);
  font-weight: 500;
  opacity: 1;
}

/* Die Zustandsfarbe, an beiden Traegern. Rueckfallwerte: das Sinnbild
   faellt auf Legacys "--clr-success-mid" bzw. "--clr-danger", die
   Dauer auf die geerbte Textfarbe der Blase.

   GEMESSEN GEGEN DIE EIGENE FLAECHE, nicht gegen die Blase dahinter
   (Messregel 3) -- die Karte ist deckend:

     Ton                          dunkel        hell
     Legacy "--clr-success-mid"    6,105  ok     2,983  VERFEHLT
     "--ax-status-success"        10,021  ok     2,983  VERFEHLT
     "--ax-status-success-on-bg"  13,537  ok     4,540  ok
     Legacy/"--ax-status-danger"   4,640  ok     4,372  VERFEHLT
     "--ax-status-danger-on-bg"    6,313  ok     5,857  ok

   Im HELLEN Theme verfehlen BEIDE Statustoken 4,5 auf "bg/surface-2";
   im dunklen halten beide. Im hellen sind Legacys "--clr-success-mid"
   und "--ax-status-success" ueberdies DERSELBE Wert (rgb(22,163,74)) --
   webapp.css:360 mischt dort mit 0 % Schwarz.

   EINE HAELFTE DIESER VIER REGELN IST EIN WAECHTER, KEIN NACHWEIS, und
   der Gegenversuch sagt es: "--clr-danger" haengt im neuen Design auf
   "--ax-status-danger" (tokens.css:163/233), das FEHLERSINNBILD traegt
   im dunklen Theme also mit und ohne diese Regel rgb(239,68,68).
   Streicht man die Fehlerregel, aendert sich dort NUR die Dauer (3 von
   6 Werten). Im hellen Theme ist beides ein Nachweis, und beim
   Erfolgssinnbild traegt auch der dunkle Fall (Legacys color-mix mit
   78 % Schwarz ergibt rgb(58,173,100)). Gebaut ist deshalb dieselbe Konstruktion
   wie beim tuerkisen Etikett in Task 5: der Sollwert im dunklen Theme,
   die "-on-bg"-Stufe derselben Rampe als Gegenregel im hellen. Eine
   Abweichung dort, wo keine noetig ist, waere eine zweite ohne Grund
   (Rulings 10 und 12).

   Nebenbei behebt das einen Bestandsfehler: Legacys
   "--clr-success-mid" ist im hellen Theme mit 2,983 nicht nur unter
   4,5, sondern unter 3,0 -- der gruene Haken war dort auch als
   Bedienelement zu schwach.

   DIE ZWEI ZUSTAENDE SIND WEIT AUSEINANDER, und das ist die Aussage
   des Bauteils: ΔE (CIE76) 126,550 (dunkel) und 104,717 (hell) --
   Faktor 55 bzw. 46 ueber der Wahrnehmungsschwelle 2,3. Der DRITTE
   Zustand liegt bei ΔE 0,000 zum ersten; er ist im Produkt keiner
   (Befund oben). */
[data-design="new"] .tool-invocation-ok .tool-invocation-icon,
[data-design="new"] .tool-invocation-ok .tool-invocation-duration {
  color: var(--ax-status-success);
}

[data-design="new"] .tool-invocation-error .tool-invocation-icon,
[data-design="new"] .tool-invocation-error .tool-invocation-duration {
  color: var(--ax-status-danger);
}

[data-design="new"][data-theme="light"] .tool-invocation-ok .tool-invocation-icon,
[data-design="new"][data-theme="light"] .tool-invocation-ok .tool-invocation-duration {
  color: var(--ax-status-success-on-bg);
}

[data-design="new"][data-theme="light"] .tool-invocation-error .tool-invocation-icon,
[data-design="new"][data-theme="light"] .tool-invocation-error .tool-invocation-duration {
  color: var(--ax-status-danger-on-bg);
}

/* Der Chevron. Figma 149:204: "text/muted".

   Rueckfallwerte: die geerbte Textfarbe der Blase, abgeblendet auf
   0.7 (webapp.css:2843). "opacity: 1" gehoert deshalb zur Farbe, mit
   derselben Begruendung wie an der Dauer oben.

   EIN BEFUND, DER NICHT BEHOBEN WIRD, und es ist die VIERTE Stelle
   dieses Teilprojekts mit derselben Zahl (Fusszeile in Task 2,
   Quellenzeile und Ergebniskarte in Task 5, hier). "--ax-text-muted"
   haelt auf "bg/surface-2" im dunklen Theme nur 4,477 -- gerastert
   gegen die eigene Flaeche, in allen vier Wirten dieselbe Zahl, weil
   die Flaeche deckend ist; im hellen sind es 6,713. Gebaut wird
   trotzdem Figmas Wert, aus denselben zwei gemessenen Gruenden wie in
   Task 5:
     1. Der Chevron ist ein Auf-/Zu-Zeiger ("▸"/"▾"), kein Fliesstext.
        Fuer ein Bedienelement gilt 3,0 (Messregel 5), und das haelt er
        mit 1,49-facher Luft.
     2. Eine eigene Ausnahme hier ergaebe ein zweites, abweichendes
        Muted. Die Antwort gehoert in die Tokenschicht.
   Die Zeile als Ganzes wird dabei besser, nicht schlechter: der
   Chevron trug bisher "text/primary" bei 0.7 Deckkraft, also einen
   Ton, den keine Rampe fuehrt. */
[data-design="new"] .tool-invocation-caret {
  color: var(--ax-text-muted);
  opacity: 1;
}

/* Argumente und Ergebnis. Sie sind seit Task 4 Codebloecke -- Flaeche
   "bg/surface-3", 1px Rahmen, Radius 10, Innenabstand 12 kommen aus
   dessen "pre"-Basisregel und sind hier gemessen VORGEFUNDEN, nicht
   gebaut. Was dort NICHT ankommt, ist die Schrift: Legacy setzt an
   diesen beiden Klassen "font-family: monospace" (webapp.css:2921,
   (0,1,0)) und schlaegt damit ":where([data-design=new]) code"
   (0,0,1) -- und das <pre> hat gar kein <code>-Kind, an dem Task 4s
   Regel greifen koennte.

   Gebaut ist deshalb genau diese eine Deklaration: derselbe Ton
   Monospace wie in jedem anderen Codeblock der Anwendung. Der
   Rueckfallwert ist die generische Systemschrift "monospace"; gemessen
   an derselben Zeile ("Argumente: {\"kunde\": 17}") kostet der Wechsel
   14,47px Breite (172,81 statt 158,34). Der Block bricht davon nicht
   um: "scrollWidth - clientWidth" ist 0 -- bei 1280px, bei 400px und
   bei 320px eingebettet, also auch im schmalsten Wirt, den der
   oeffentliche Chatbot kennt (widgetconfig.js:8-10).

   EINE SCHRIFTAUSSAGE MIT EINER GROESSENFOLGE, und sie ist der Grund,
   warum Task 4s Reichweiten-Sonde nachgezogen werden musste: fuer ein
   Element, dessen Familie die GENERISCHE "monospace" ist, rechnet
   Chromium relative Groessen gegen 13px statt 16px. Wo die
   Groessenkette an einem SCHLUESSELWORT haengt, aendert der Wechsel auf
   eine benannte Familie deshalb auch die Groesse -- an der Sonde unter
   <body> von 8,667 auf 10,667px, und der Aussenabstand 0.15em zieht mit
   (1,3 -> 1,6px). IN DER CHATANTWORT PASSIERT DAS NICHT: dort haengt die
   Groesse an ".msg-bubble-bot { font-size: 15px }" (Task 2), also an
   einer LAENGE -- die Argumente messen mit und ohne diese Regel 12px
   (gemessen). Wo es passiert, wird die Schrift groesser, nicht kleiner.

   DIE ZEILENHOEHE BEKOMMT NUR DIE CODEGESTALT. "-body" hat zwei
   Gestalten (organismstoolinvocation.js:139-150): ein <pre> mit
   Rohtext und ein <div class="orchestration-md"> mit gerendertem
   Markdown. 18px Durchschuss sind Figmas Wert fuer eine CODEZEILE
   (Task 4, "--ax-line-height-mono-sm"); auf den Fliesstext eines
   Teilergebnisses angewandt waeren sie eine Aenderung an einem Fluss,
   fuer den es keinen Sollwert gibt. Der Selektor traegt deshalb das
   Element: "pre.tool-invocation-body" trifft die Codegestalt und laesst
   ".orchestration-md" in Ruhe.

   Der Rueckfallwert ist 24px -- geerbt von der Blase (Task 2), also
   doppelter Zeilenabstand auf 12px Schrift, und derselbe Wert, den
   Task 4 an seinen eigenen Codebloecken korrigiert hat. */
[data-design="new"] .tool-invocation-args,
[data-design="new"] .tool-invocation-body {
  font-family: var(--ax-font-mono);
}

[data-design="new"] .tool-invocation-args,
[data-design="new"] pre.tool-invocation-body {
  line-height: var(--ax-line-height-mono-sm);
}

/* ══ 07 · Chat & AI, Teil B — Task 1: Der Composer ════════════════
   Figma-Knoten 47:21. Der Bestand steht in webapp.css:5524-5540
   (".chatbot-input", fuenfzehn Deklarationen). Erzeugt wird die Klasse
   an zwei Stellen: OrganismsChatWindowInput (chatwindowinput.js:54,
   der Chat) und OrganismsFunctionAssistant
   (organismsfunctionassistant.js:119, der Assistent im
   Funktionseditor). Der zweite Verwender ist kein Versehen, sondern
   ausdruecklich so gemeint -- webapp.css:13278 sagt es in seinem
   eigenen Kommentar: "The chat input reuses the cockpit
   .chatbot-input look."

   DREI DEKLARATIONEN AUS FIGMA, ZWEI GESCHRIEBEN:

     border-radius   ERSETZT  16px -> "radius/lg" (14px).
     padding         ERSETZT  10px ringsum -> "16 12 12 16".
     border          BLEIBT   Figma sagt "1px solid border/default";
                              genau dort steht der Bestand im neuen
                              Design schon. Siehe den Block
                              "DIE DRITTE DEKLARATION" unten.

   Alles andere der fuenfzehn bleibt unberuehrt: die vier Aussenabstaende
   und "width" gehoeren "06 · Shell & Nav" (die Regel bei :2773 in
   dieser Datei, samt der teuer erkauften Begruendung ab :2680), und
   "display"/"flex-direction"/"justify-content"/"align-items"/"height"/
   "max-height"/"color"/"position" beschreiben keine Figma-Aussage
   dieses Tasks.

   ── DIE SPEZIFITAET, NACHGEMESSEN STATT ABGESCHRIEBEN ──────────────

   Der Plan begruendet die Wahl "[data-design=...]" (0,2,0) damit, dass
   ":where()" auf (0,1,0) fiele und "gegen die spaeteren beiden ueber
   die Quellenreihenfolge verloere" -- gemeint sind die drei nackten
   Resets webapp.css:5524 (Basis), :8590 und :10599 (beide in
   "@media (max-width: 640px)"). DIESE BEGRUENDUNG TRAEGT NICHT, und das
   ist gemessen: cockpit.html:16-18 laedt webapp.css ZUERST und
   components.css ZULETZT. Eine (0,1,0)-Regel von hier schlaegt bei
   Gleichstand alle drei ueber genau dieselbe Quellenreihenfolge.
   Nachgestellt im vollen Stapel bei 1280px, 800px und 600px: beide
   Fassungen liefern dieselben Werte, Zeichen fuer Zeichen.

   Geschrieben wird trotzdem (0,2,0), aber aus einem anderen Grund --
   der Teilmengen-Invariante. ":where()" ist das Werkzeug fuer eine
   BASISREGEL, die eine bestehende Legacy-Schichtung erhalten soll;
   hier gibt es keine zu erhalten: die schwereren Regeln des Bestands auf
   dieser Klasse -- "body.chat-embedded .chatbot-input" (:2192, (0,2,1)) und
   ".chatbot-input.drag-over" (:1330, (0,2,0)) -- setzen weder Radius noch
   Innenabstand. (0,2,0) ist damit die
   Fassung, die auch dann noch das Richtige tut, wenn jemand in
   webapp.css eine solche Regel ergaenzt -- und sie kostet hier nichts,
   weil sie messbar nichts anderes tut als die schwaechere.

   ── DIE SCHMALEN VIEWPORTS BLEIBEN VERDICHTET, UEBER DAS TOKEN ─────

   Unterhalb von 640px setzen webapp.css:8590 und :10599 den Radius
   bewusst auf 12px. Diese Regel schlaegt beide -- und trifft trotzdem
   denselben Wert, weil "--ax-radius-lg" selbst unter
   "@media (max-width: 768px)" auf 12px faellt (tokens.css:405).
   Gemessen bei 600px: 12px mit und ohne diese Regel. DAS IST DER
   GRUND, WARUM HIER DAS TOKEN UND KEINE ZAHL STEHT; wer "14px"
   literal schreibt, hebt die Verdichtung auf, und der Bruch waere nur
   auf einem schmalen Bildschirm zu sehen. Der Test bewacht das an vier
   Haltepunkten.

   FIGMAS 14 GILT DESHALB ERST AB 769PX, und die Bandgrenze ist
   gemessen, nicht gerechnet. Die beiden Schwellen liegen NICHT
   uebereinander: Legacy verdichtet unter 641px (webapp.css:8587,
   :10382), die Tokenschicht unter 769px (tokens.css, "@media
   (max-width: 768px)"). Dazwischen liegt ein Band, in dem KEINES der
   beiden Designs Figmas Wert zeigt:

     Viewport   altes Design   neues Design   --ax-radius-lg
       640px        12px           12px           12px
       641px        16px           12px           12px   <- Bandbeginn
       768px        16px           12px           12px   <- Bandende
       769px        16px           14px           14px

   641 bis 768px einschliesslich also. Das ist die Absicht der
   Tokenschicht (Radien auf kleinen Schirmen stauchen) und kein Defekt
   dieser Regel -- aber es heisst, dass die Aussage dieses Tasks
   "Radius 14" nur oberhalb von 768px gilt. Fuer die Spec (Task 5)
   ausdruecklich festgehalten.

   Der Innenabstand hat diese Rueckfallebene NICHT, und das ist der
   einzige Ort, an dem dieser Task etwas kostet: unterhalb von 640px
   steht der Kasten auf "box-sizing: border-box" (webapp.css:10600) und
   traegt zugleich die inline gesetzten 100px aus
   chatwindowinput.js:250. Dort sind die 100px die AUSSENhoehe, und die
   sechs zusaetzlichen Pixel Innenabstand nehmen dem Inhalt Raum: 78 ->
   70px (gemessen). Bewusst in Kauf genommen -- Figmas Innenabstand ist
   die Aussage dieses Tasks, und die Gegenregel dafuer waere eine
   zweite Sollwertquelle fuer eine Breite, die die Vorlage nicht
   beschreibt.

   ── OBERHALB VON 640PX KOSTET DER INNENABSTAND NICHTS ──────────────

   Und das ist die Widerlegung von Spec §7 #5, die "einen Rueckgang des
   Raums fuer das Textfeld von 80 auf 72px" erwartet und daran die
   Frage haengt, ob der Innenabstand unveraendert uebernommen werden
   kann. Beide Zahlen gelten nicht:

     * ".chatbot-input" ist "content-box" -- nichts in webapp.css setzt
       oberhalb von 640px "box-sizing". Die 100px sind die Hoehe des
       INHALTSkastens; ein groesserer Innenabstand macht den Kasten
       aussen groesser (122 -> 130px hoch, 622 -> 630px breit) und
       nimmt dem Inhalt nichts. Gemessen an der echten Instanz in allen
       vier Konfigurationen Design x Theme.
     * 80 war ohnehin nie der Ist-Stand: uebrig bleiben 45px -- 100px
       Inhaltskasten minus die 55px hohe Knopfreihe.

   Der Innenabstand wird deshalb unveraendert aus Figma uebernommen.

   ── DIE RECHTE KANTE, UND DER BEZUG, GEGEN DEN SIE GEMESSEN GEHOERT ─

   Der Innenabstand bewegt die rechte Aussenkante: waagerecht sind es 28
   statt 20 Pixel, und oberhalb von 640px geht der Zuwachs nach AUSSEN.
   Gegen welchen Bezug das eine Verbesserung oder eine Verschlechterung
   ist, entscheidet nicht der Vergleich alt/neu, sondern die
   NACHRICHTENSPALTE darueber (".chat-window") -- an dieser Messregel hat
   sich das Projekt schon mehrfach geschnitten. Gemessen in beiden
   Designs und beiden Themes:

                 ".chat-window"   alt    nur Innenabstand   ausgeliefert
       600px          584           584          584               584
       800px          770           782          790               782
      1280px         1250          1242         1250              1250

      600px  Der Kasten ist dort "border-box" (webapp.css:10600), die
             Aussenkante steht still, der Innenabstand waechst nach
             innen. Buendig vorher wie nachher.
     1280px  Der Composer stand 8px zu KURZ; er ist jetzt buendig mit
             der Nachrichtenspalte. Eine VERBESSERUNG -- und der Grund,
             warum der Zuwachs dort NICHT geheilt wird.
      800px  Der Composer ragt schon im ALTEN Design 12px ueber die
             Spalte hinaus; der Innenabstand allein schoebe ihn auf
             20px. Eine VERSCHLECHTERUNG -- und deshalb ist genau
             dieses Band geheilt, zurueck auf Legacys 782.

   GEHEILT IN DER 06ER-REGEL, NICHT HIER: ihr Abzug "calc(100% - 104px)"
   ist selbst eine Ableitung aus Legacys waagerechtem Innenabstand (siehe
   den Kommentar dort, dieselbe Datei). Wer den Innenabstand aendert und
   den Abzug stehen laesst, bricht die Absicht jener Regel, statt sie zu
   bewahren. 104 -> 112 stellt die rechte Kante bei 800px exakt wieder
   auf Legacys 782. "margin-left" und die Bandgrenzen bleiben unberuehrt,
   und die Zusicherung in design-shell-frames.spec.ts ("Mobil 800px")
   steht unveraendert auf Gleichheit der rechten Kante.

   ── DER ZWEITE WIRT: DER ASSISTENT IM FUNKTIONSEDITOR ──────────────

   ".chatbot-input" sitzt auch an OrganismsFunctionAssistant
   (organismsfunctionassistant.js:119). Dort ist der Kasten
   "border-box" (webapp.css:13290, ausdruecklich begruendet mit
   "Include the .chatbot-input padding + border in the 100% width"), der
   Innenabstand waechst also nach INNEN. Gemessen an einem Klon des
   Wirts (520px breite Spalte, beide Designs, beide Themes):

                          alt     neu
     Aussenbreite         520     520     border-box haelt sie fest
     Feldbreite           498     490     -8px, die einzige Folge
     Aussenhoehe (leer)   110     116
     Aussenhoehe (voll)   176     184     Feld an seinem eigenen
                                          120px-Deckel
     Innenhoehe (voll)    154     154     unveraendert
     Ueberlauf              0       0

   FOLGENLOS AUSSER DEN 8PX FELDBREITE: "min-height: 44px" des Feldes
   bindet in keinem Fall (52px leer, 120px voll), und der 220px-Deckel
   des Kastens wird auch im vollsten Zustand nicht erreicht -- 184px,
   also 36px Luft. Kein Ueberlauf, keine Beschneidung.

   ── DIE DRITTE DEKLARATION: WARUM KEINE "border-color" ─────────────

   Der Plan sieht "border-color: var(--ax-border-default)" vor. Die
   Deklaration ist TOT und deshalb nicht geschrieben: die Bruecke aus
   Schritt 1 haengt "--clr-border" unter [data-design="new"] bereits auf
   "var(--ax-border-default)" um (tokens.css:151 dunkel, :223 hell), und
   webapp.css:5536 liest genau "var(--clr-border)". Gemessen mit und
   ohne die Zeile, beide Themes: rgb(36, 34, 51) dunkel, rgb(210, 208,
   218) hell -- kein Unterschied in irgendeinem Kanal. Sie faellt damit
   unter "tote Deklarationen werden entfernt, nicht behalten". Der Test
   sichert die Farbe trotzdem zu, als Waechter ueber die Bruecke.

   Sie waere ausserdem schaedlich gewesen: ".chatbot-input--focused"
   (webapp.css:5542) setzt im Fokus "border: 1.5px solid
   var(--clr-accent)" und steht bei (0,1,0) in der FRUEHER geladenen
   Datei. Eine "border-color" von hier haette den Akzentrahmen des
   Fokuszustands lautlos zurueckgefaerbt -- eine Regression ohne
   Sollwert, fuer null Gewinn.

   ── DER EINGEBETTETE WIRT ──────────────────────────────────────────

   "body.chat-embedded .chatbot-input" (webapp.css:2192, (0,2,1)) setzt
   "width" und die beiden waagerechten Aussenabstaende; die Kundenfarben
   kommen ueber "body.chat-embedded .chatbot-input-bg" (:2231) als
   "var(--acw-input-bg, ...)". Keine der beiden Regeln beruehrt Radius
   oder Innenabstand, und diese Regel beruehrt weder Breite noch
   Flaeche: beide Achsen kreuzen sich nicht. Mit UND ohne gesetzte
   "--acw-*" gemessen; wo der Kunde eine Farbe gesetzt hat, gewinnt sie
   unveraendert. */
[data-design="new"] .chatbot-input {
  border-radius: var(--ax-radius-lg);
  padding: 16px 12px 12px 16px;
  /* TASK 3 (siehe dort): Figmas Abstand Textfeld<->Werkzeuge. Er steht
     hier, weil "gap" auf den FLEX-ELTERN gehoert -- die Begruendung, die
     Bandgrenze und die zweite, unverzichtbare Deklaration dazu
     (".button-container { margin-top: 0 }") stehen im Task-3-Abschnitt
     am Dateiende. */
  gap: var(--ax-space-4);
}

/* ══ 07 · Chat & AI, Teil B — Task 2: Flaeche, Textfeld, Kundenfarben ══
   Figma-Knoten 47:21 (Flaeche "bg/surface-1") und 47:22 (Platzhalter
   "text/muted"). Der Bestand steht in webapp.css:5580 (".chatbot-input-bg",
   eine Deklaration), :5584 (".chatbot-inputfield") und :5609
   (deren "::placeholder").

   DREI DEKLARATIONEN GESCHRIEBEN, EINE BEWUSST NICHT:

     background-color  auf ".chatbot-input-bg"      Figmas Flaeche
     background-color  auf ".chatbot-inputfield"    durchsichtig, damit
                                                    Figmas EINE Flaeche
                                                    eine bleibt
     color             auf "::placeholder"          Figmas "text/muted"
     color             auf ".chatbot-inputfield"    NICHT -- tot, siehe
                                                    unten

   ── DIE KUNDENFARBEN, UND WARUM DIE RUECKFALLKETTE DER GANZE TRICK IST ─

   "body.chat-embedded" (webapp.css:2229-2258) laesst Kunden eigene Farben
   ueber "--acw-*" in den iframe geben; publicchatbot.js:48-58 setzt sie auf
   <html>, aber NUR wenn der Kunde eine gueltige Hexfarbe in der iframe-URL
   uebergeben hat. Eine Regel, die die Flaeche unbedingt setzte, naehme dem
   Kunden seine Farbe -- und zwar unsichtbar, weil kein Test der Plattform
   "--acw-*" von sich aus setzt. Dieselbe Falle wie ".badge-success" in der
   Branding-Vorschau (05 Data, Teil B).

   "var(--acw-input-bg, var(--ax-bg-surface-1))" setzt die Vorlagenfarbe
   deshalb nur dort, wo der Kunde keine gesetzt hat. Die Regel ist damit
   eine Ergaenzung von webapp.css:2231, keine Verdraengung. Zugesichert in
   beide Richtungen, an zwei Galeriekacheln, deren gebrandete vier BEWUSST
   GRELLE Werte traegt (#ff00ff/#00ff00/#ffff00/#00ffff): ein Ueberschreiben
   kann so nicht zufaellig dem Sollwert aehneln.

   ── ZWEI SELEKTOREN, WEIL EINER IM EINGEBETTETEN WIRT NICHT ANKOMMT ────

   "[data-design=new] .chatbot-input-bg" wiegt (0,2,0). Legacys
   "body.chat-embedded .chatbot-input-bg" (webapp.css:2231) wiegt (0,2,1) --
   ein Element mehr -- und GEWINNT. Nachgemessen im vollen Stapel: mit nur
   der (0,2,0)-Fassung bleibt der eingebettete Composer auf Legacys
   "--clr-shell"-Mischung stehen, im Cockpit greift sie. Die
   Quellenreihenfolge hilft dort nicht, denn sie entscheidet erst bei
   GLEICHER Spezifitaet.

   Der zweite Selektor nennt deshalb "body" und wiegt (0,3,1). Er schlaegt
   Legacy ueber die SPEZIFITAET, nicht ueber die Ladereihenfolge -- also
   auch dann noch, wenn jemand spaeter die Dateireihenfolge aendert.
   "data-design" sitzt auf "document.documentElement" (designbootstrap.js:7),
   also auf <html>; <body> ist ein echter Nachfahre und darf im Selektor
   stehen. Eine Selektorliste statt zweier Regeln, weil beide dieselbe
   Deklaration tragen: zwei Kopien koennten auseinanderlaufen, die Liste
   kann es nicht. Jeder Selektor einer Liste traegt seine eigene
   Spezifitaet; das ist gemessen, nicht angenommen.

   ── DER COMPOSER WAR IM NEUEN DESIGN SCHON ZWEIFARBIG ──────────────────

   DER BEFUND, DEN DIESE AUFGABE NICHT GESUCHT HAT. ".chatbot-inputfield"
   ist ein <textarea>, und die Basisregel des Designsystems
   (":where([data-design=new]) textarea", :735 dieser Datei) gibt jedem
   <textarea> "--ax-bg-input" (ink/800). Der Kasten darunter stand auf
   Legacys "--clr-shell". Gemessen im Elterncommit, dunkles Theme:

     Kasten  rgb(13, 12, 22)   --clr-shell
     Feld    rgb(26, 24, 38)   --ax-bg-input

   Zwei Toene in einem Bauteil, fuer das Figma EINE Flaeche zeichnet. Die
   Flaechenregel allein haette den Abstand VERKLEINERT, aber nicht
   AUFGELOEST -- gerastert dunkel von dE76 7,226 auf 4,531, also um 37 %,
   und die Schwelle liegt bei 2,3. Der Kasten wandert dabei von
   rgb(13, 12, 22) auf rgb(18, 17, 28) und damit AUF das ink/800 des Feldes
   ZU, nicht von ihm weg. (Eine fruehere Fassung dieses Kommentars behauptete
   das Gegenteil; die Entscheidung war richtig, die Begruendung nicht --
   nachgemessen in der Abschlussrunde.)

   UND SIE HEILT NUR DUNKEL. Im hellen Theme fallen Kasten und Feld schon
   durch die Flaechenregel allein zusammen: beide stehen dann auf ink/0,
   gemessen dE76 0,000. Die "transparent"-Zeile hat dort keine Wirkung auf
   das Bild und steht nur, damit die Aussage "EINE Flaeche" nicht an einem
   Theme haengt.

   Im alten Design gibt es die Zweifarbigkeit gar nicht: dort tragen Kasten
   und Feld dieselbe "--clr-shell"-Mischung.

   Das Feld wird deshalb durchsichtig gestellt. Das ist derselbe Wert, den
   Legacy im eingebetteten Wirt laengst setzt (webapp.css:2236,
   "background: transparent") -- die Regel verallgemeinert also eine
   Entscheidung des Bestands, statt eine neue zu treffen. Und sie traegt die
   Kundenfarbe mit: das durchsichtige Feld zeigt die Flaeche des Kastens,
   und die steht bereits auf "var(--acw-input-bg, ...)". Eine zweite
   Rueckfallkette am Feld waere eine zweite Quelle fuer dieselbe Aussage.

   KEINE UMKEHRUNG EINER LEGACY-SCHICHTUNG (Spec §4 #2, gemessen): am
   Hintergrund des Feldes schichten heute "textarea" (0,0,1, --clr-shell),
   diese Datei bei :735 (0,0,1, --ax-bg-input) und
   "body.chat-embedded .chatbot-inputfield" (0,2,1, transparent). Die neue
   Regel (0,2,0) liegt DAZWISCHEN: sie schlaegt die beiden Elementregeln und
   verliert gegen den eingebetteten Wirt -- der denselben Wert setzt. Die
   Schichtung bleibt also stehen, und ihr Ergebnis aendert sich nicht.

   ── DIE VIERTE DEKLARATION: WARUM KEINE "color" AM TEXTFELD ────────────

   Der Plan sieht sie vor ("analog --acw-input-fg"). Sie ist TOT, und das
   ist dieselbe Lage wie bei Task 1s "border-color":
   ".chatbot-inputfield" liest "var(--font-color-input)" (webapp.css:5595),
   das haengt an "--clr-text-primary" (:187), und die Bruecke haengt DAS
   unter [data-design="new"] auf "var(--ax-text-primary)" um (tokens.css:159
   dunkel, :229 hell). Gemessen in allen acht Konfigurationen: rgb(232, 230,
   238) dunkel, rgb(18, 17, 28) hell -- mit und ohne die Zeile identisch.
   Sie faellt damit unter "tote Deklarationen werden entfernt, nicht
   behalten". Der Test sichert die Farbe trotzdem zu, als Waechter ueber die
   Bruecke.

   SIE WAERE AUSSERDEM EINE AUSWEITUNG GEWESEN. "--acw-input-fg" liest im
   Bestand ausschliesslich "body.chat-embedded .chatbot-inputfield"
   (webapp.css:2234) -- im Cockpit ist die Kundenschriftfarbe wirkungslos,
   und das ist Legacys Zuschnitt. Eine Regel "var(--acw-input-fg, ...)" ohne
   "body.chat-embedded" haette diese Reichweite lautlos erweitert. Der Test
   sichert beide Haelften zu: gebrandet UND eingebettet gewinnt der Kunde,
   gebrandet OHNE eingebettet gilt weiter die Vorlage.

   Die FLAECHE ist hier bewusst anders behandelt als die Schriftfarbe: sie
   traegt die Rueckfallkette auch im Cockpit-Selektor. Im Produkt ist das
   folgenlos -- publicchatbot.js setzt "--acw-*" ausschliesslich im Zweig
   "if (embedded)", also nie ohne die Klasse am <body> -- und es macht die
   beiden Selektoren zeichengleich. Zugesichert ist es trotzdem: die
   gebrandete Kachel zeigt die Kundenfarbe im Cockpit, die Kundenschrift
   dort aber nicht.

   ── DER PLATZHALTER: DAS ERSTE PSEUDOELEMENT DIESES UMBAUS ─────────────

   Spec §7 #3 stellt die Frage, ob eine "::placeholder"-Regel geschrieben
   werden soll -- Teil A hat kein Pseudoelement angefasst. ENTSCHIEDEN: ja,
   und der Ausschlag ist gemessen, nicht stilistisch.

   Der Platzhalter ist der EINZIGE Textwert, den Figma fuer das Textfeld
   nennt (47:22, "text/muted"). Legacy faerbt ihn mit "--clr-text-muted",
   und das ist im neuen Design eine Mischung aus "--ax-text-secondary" mit
   Schwarz bzw. Weiss (webapp.css:79/:341) -- die Bruecke haengt
   "--clr-text-muted" NICHT um, sie gibt "--ax-text-muted" an
   "--clr-text-faint" (tokens.css:177). Gemessen gegen die neue Flaeche:

     hell   Bestand rgb(134, 132, 146) auf Weiss   3,67   FAELLT durch 4,5
            Figma   rgb(85, 83, 106)   auf Weiss   7,42
     dunkel Bestand rgb(138, 137, 150) auf ink/900 5,43
            Figma   rgb(129, 127, 146) auf ink/900 4,80

   DIESELBE UMHAENGUNG HAT DIESES TEILPROJEKT SCHON EINMAL GEMACHT, mit
   denselben Zahlen: der Schrittzaehler des AI-Service-Assistenten (:3728 in
   dieser Datei) haengt "--clr-text-muted" auf "--ax-text-muted" um und
   notiert "7,42 statt 3,67". Die Entscheidung hier ist also keine neue
   Linie, sondern dieselbe an einem zweiten Ort.

   Im hellen Theme heilt Figmas Wert also eine WCAG-Unterschreitung, die
   heute im neuen Design steht. Im dunklen kostet er Kontrast, bleibt aber
   ueber der Schwelle -- das ist der Preis, und er ist genannt statt
   verschwiegen. Geschrieben wird ausschliesslich "color": Figmas 15/24 fuer
   den Platzhalter ist die Schriftgroesse des FELDES (Legacy: 14px, aus
   webapp.css:5586) und nicht ueber "::placeholder" zu setzen -- eine
   Groessenaenderung am Feld beschreibt dieser Task nicht.

   Wo ein Kunde eine Flaeche gesetzt hat, gilt dieser Kontrast nicht mehr --
   im alten Design genau so wenig wie im neuen. Der Bestand kennt keine
   "--acw-"-Variable fuer den Platzhalter, und dieser Task erfindet keine. */
[data-design="new"] .chatbot-input-bg,
[data-design="new"] body.chat-embedded .chatbot-input-bg {
  background-color: var(--acw-input-bg, var(--ax-bg-surface-1));
}

[data-design="new"] .chatbot-inputfield {
  background-color: transparent;
}

[data-design="new"] .chatbot-inputfield::placeholder {
  color: var(--ax-text-muted);
}

/* == 07 - Chat & AI, Teil B -- Task 5: Nur die Flaeche traegt einen Rahmen ==
   Sichtpruefungs-Befund des Anwenders: "Eingabe im Chatinput sieht mit
   Rahmen bloed aus" -- ein Doppelrahmen beim Tippen.

   GEMESSEN, NICHT ANGENOMMEN (Playwright, echte Instanz, beide Themes): im
   Ruhezustand traegt ".chatbot-inputfield" (das <textarea>) keinen Rahmen --
   "border-top-width" ist bereits "0px", weil ".chatbot-inputfield" in
   webapp.css:5696 "border: 0px" setzt und damit "border-style: none" als
   EINZIGE Regel fuer diese Eigenschaft unkontestiert gewinnt; ein Rahmen
   ohne Stil wird nicht gezeichnet, unabhaengig davon, welche Regel die
   Breite gewinnt. Der Doppelrahmen entsteht erst FOKUSSIERT: die Basisregel
   dieser Datei (":where([data-design=\"new\"]) textarea:focus-visible", :838,
   Spezifitaet 0,1,1) setzt zusaetzlich zur (wirkungslosen) Randbreite einen
   eigenen "box-shadow: var(--ax-focus-ring)" -- einen zweiten, satten Ring
   direkt um das Textfeld, INNERHALB der Flaeche, die ihrerseits schon per
   ".chatbot-input--focused" (webapp.css:5654, unveraendert, gilt in beiden
   Designs) Rahmen UND eigenen box-shadow traegt. Zwei Ringe ineinander --
   das Bild aus dem Screenshot.

   Die Regel stammt nicht aus webapp.css und ist bereits neu-design-
   spezifisch; sie bleibt deshalb unangetastet (sie bedient auch
   input/select ausserhalb des Composers). Ueberschrieben wird nur der Ring
   des Feldes, mit einer eigenen, engeren Regel bei Spezifitaet 0,3,0 --
   schlaegt 0,1,1 ueber die Spezifitaet, kein "!important" noetig. Die
   Randbreite bleibt unberuehrt: sie ist wie oben gemessen bereits
   wirkungslos, eine zusaetzliche Zeile dafuer waere unnoetig.

   Der Fokus geht dabei nicht verloren -- er wandert nicht neu, er stand
   schon immer an der FLAECHE: ".chatbot-input--focused" ist unconditional
   und wird von allen drei Wirten dieser Klasse selbst gesetzt (Klick/Tab ins
   Feld loest das 'focus'-Ereignis am <textarea> aus, der Wirt haengt daran
   die Klasse an den Container). Gemessen mit ":focus-visible" nach
   Ausklingen der Uebergangsanimation, beide Themes: die Flaeche zeigt
   weiterhin einen sichtbaren Rahmen samt Ring, nur nicht mehr doppelt.

   DREI WIRTE TRAGEN ".chatbot-inputfield", ALLE DREI PROFITIEREN: der
   Chat-Composer (chatwindowinput.js:72), der Assistent im Funktionseditor
   (organismsfunctionassistant.js:122) und das KI-Workflow-Generator-Panel
   (organismsworkflowgeneratorpanel.js:111) -- alle drei binden denselben
   Rahmen-Wirt ".chatbot-input"/".chatbot-input--focused" (chatwindowinput.js:
   177-184, organismsfunctionassistant.js:155-156,
   organismsworkflowgeneratorpanel.js:157) und zeigten denselben
   Doppelrahmen. Ein einziger Selektor auf der Feldklasse behebt alle drei,
   statt dreier wirtsspezifischer Regeln fuer denselben Befund. */
[data-design="new"] .chatbot-inputfield:focus-visible {
  box-shadow: none;
}

/* == 07 - Chat & AI, Teil B -- Task 3: Werkzeugzeile und Sendeknopf ==
   Figma-Knoten 47:23 (die Zeile), 47:24/47:32/47:37 (Symbolknoepfe) und
   47:49 (Sendeknopf). Der Bestand steht in webapp.css:5624
   (".chatbot-button"), :5646 (".chatbot-button-deactivated"), :5666
   (".chatbot-button-send"), :4019 (die Bueroklammer) und -- fuer die Fuge
   zum Textfeld -- an DREI Stellen an ".button-container" (:1518, die
   1024er-Staffel, :10750).

   -- WELCHE KNOEPFE DIESE REGEL WIRKLICH TRIFFT -----------------------

   FIGMAS DREI KNOEPFE SIND NICHT DIE KNOEPFE DES PRODUKTS (Spec 7 #6):
   Masse gelten, Anzahl nicht. Aufgenommen an der echten Instanz
   (chatwindowinput.js:73-113 und :618), alle Kinder der Zeile:

     Eingabe loeschen     (entfallen, #2055)
     Bueroklammer         LABEL in ".upload-container"  <- KEIN .chatbot-button
     Optimieren           .chatbot-button
     Dateien entfernen    .chatbot-button .chatbot-btn-secondary
     "..."-Umschalter     .chatbot-button .chatbot-more-toggle
     Anonymisierung       .chatbot-button ODER .chatbot-button-deactivated
     Diktat               .chatbot-button          (entfallen, Nachtrag/F3, 2026-09-22)
     Gedaechtnis          .chatbot-button .chatbot-btn-secondary
     Senden               .chatbot-button .chatbot-button-send

   EINE DAVON TRAEGT DIE PLANFASSUNG DER REGEL NICHT, und sie ist im
   Cockpit SICHTBAR gemessen worden -- sie waere bei 28x28 stehen
   geblieben, waehrend ihre Nachbarn auf 36 wachsen:

     .chatbot-button-deactivated  Der Anonymisierungsknopf traegt diese
        Klasse STATT ".chatbot-button", sobald die Anonymisierung zentral
        gesetzt ist -- das ist der Normalfall (chatwindowinput.js:99/:103,
        beide "else"-Zweige). Trotz des Namens ist er sichtbar.

   UND EINE BLEIBT DRAUSSEN, OBWOHL FIGMA SIE MEINT -- DER EINZIGE ECHTE
   WIDERSPRUCH DIESER AUFGABE. Die Bueroklammer ist ein <label> in
   ".upload-container", kein <button>. Sie gehoert der Vorlage nach in die
   Reihe (Figmas drei Knoepfe sind "Anhang, Mikrofon, Sonstiges" -- der
   ANHANG ist der erste davon), und der Bestand sieht das genauso:
   webapp.css:4014 gibt ihr mit dem Kommentar "Bueroklammer im
   Chatbot-Input: identisch zu .chatbot-button" dieselben 28x28 und
   denselben 7px-Radius wie den Knoepfen.

   TROTZDEM STEHT SIE NICHT IM SELEKTOR, und der Grund ist gemessen, nicht
   abgewogen: die Galerie-Aufgabe von "04 Core" hat den neuen
   Ausloeser-Stil des Datei-Uploads ausdruecklich per
   ":not(.chatbot-input .upload-container)" aus dem Composer
   herausgehalten und diese Entscheidung mit einer Zusicherung auf die
   LEGACY-GEOMETRIE festgenagelt
   (design-gallery-core.spec.ts:974 -- "behaelt seine Legacy-Geometrie
   unter data-design=new", 28x28, Radius 7px). Eine erste Fassung dieser
   Regel nahm die Bueroklammer auf; der Lauf der ganzen design-Suite
   machte GENAU DIESEN EINEN Block rot (38 statt der 37 roten Bloecke der
   Grundlast). Das ist keine veraltete Zusicherung, sondern die
   ausgesprochene Entscheidung eines anderen Teilprojekts an dessen
   eigener Testdatei -- und fremde Testdateien fasst dieses Teilprojekt
   nicht an (Task 1 hat genau das zurueckgenommen).

   FOLGE, UND SIE WAR SICHTBAR: die Bueroklammer stand mit 28x28 und
   Radius 7 zwischen Nachbarn von 36x36 und Radius 10. Der Test dieser
   Aufgabe SICHERTE DIESEN ZUSTAND ZU statt ihn zu verschweigen -- wer den
   Widerspruch aufloesen wolle, muesse die Zusicherung drueben aendern,
   und das sei eine Entscheidung der Vorlagen-Eigentuemer, nicht dieser
   Regel.

   GENAU DAS IST GESCHEHEN: der Auftraggeber hat den Widerspruch am
   2026-09-16 aufgeloest (T2, "Die Bueroklammer reiht sich ein") und die
   Zusicherung in design-gallery-core.spec.ts umschreiben lassen. Die
   Bueroklammer traegt seither 36x36 und Radius 10 wie ihre Nachbarn --
   NUR die Geometrie: Flaeche und Rahmen bleiben Legacy, der Ausschluss
   oben (":not(.chatbot-input .upload-container)") bleibt unveraendert
   stehen, und der neue Ausloeser-Stil aus "04 Core" ist hier weiterhin
   nicht gemeint. Die Regel dafuer steht direkt bei der 36er-Regel der
   Nachbarn, wenige Zeilen unterhalb dieses Blocks in diesem Abschnitt.

   Der "..."-Umschalter klappt unter 640px ein und ist im eingebetteten
   Wirt ausgeblendet (webapp.css:2209-2212) -- die Regel trifft ihn, wo er
   da ist, und mehr muss sie nicht tun. Der VoiceChat-Knopf sitzt NICHT in
   dieser Zeile (er haengt im ".chatbot-input-voiceslot" der Eingabereihe)
   und ist deshalb nicht betroffen.

   -- WARUM "36px" LITERAL UND NICHT "--ax-size-control-md" ------------

   Der Plan nennt das Token, und es TRAEGT auch 36px (tokens.css:355) --
   aber nur oberhalb von 1024px. Es wird in ZWEI Baendern gestreckt
   (tokens.css:383 und :406), und das ist gemessen:

     Viewport      --ax-size-control-md   Knopf mit Token   Sendeknopf
       >1024px            36px                 36px            38px
      769-1024px          38px                 38px            38px   gleich gross
      641-768px           44px                 44px            38px   GROESSER
       <=640px            44px                 44px            38px   GROESSER

   UNTERHALB VON 769PX KEHRT DAS TOKEN FIGMAS RANGFOLGE UM: die
   Symbolknoepfe wuerden groesser als der Sendeknopf, der in der Vorlage
   der groesste der Zeile ist. Bei 620px stieg der Ueberstand der Zeile
   unter den Kasten dabei von 10 auf 30px (gemessen). Ein Token, das die
   Aussage der Vorlage in drei von vier Baendern umdreht, ist hier das
   falsche Werkzeug -- deshalb steht Figmas Zahl literal da, genau wie die
   38 des Sendeknopfs, die der Plan selbst literal vorgibt.

   "--ax-radius-md" hat diese Falle NICHT: das Token steht in KEINEM Band
   (tokens.css ueberschreibt unter 769px nur "--ax-radius-lg" und "-xl")
   und traegt ueberall 10px. Nachgemessen bei 1280/1025/1024/769/768/641/
   620px: 10px in allen sieben.

   -- DIE FUGE ZUM TEXTFELD: "gap" ALLEIN WAERE MESSBAR FALSCH ---------

   Spec 3c fuehrt "Abstand Textfeld<->Werkzeuge 16 (space/4)" mit dem
   Vermerk "(kein gap)". Der Vermerk stimmt woertlich und fuehrt in die
   Irre: ".chatbot-input" setzt kein "gap", aber die Fuge EXISTIERT
   laengst -- als "margin-top" an ".button-container", dem Kind der
   Knopfzeile. Gemessen als Oberkante des ersten Knopfes minus Unterkante
   der Eingabereihe:

     Viewport      Fuge im Bestand   Quelle
       >1024px          20px         webapp.css:1526 (margin-top: 20px)
      641-1024px         5px         die 1024er-Staffel (margin-top: 5px)
       <=640px            4px        webapp.css:10750 (0,2,1)

   EIN BLOSSES "gap: 16" HAETTE SICH DARAUFGESETZT statt es zu ersetzen:
   36px oberhalb von 1024px (gemessen), und die Knopfreihe waere dort
   10px UNTER die Unterkante des Kastens gerutscht -- der Kasten kann
   nicht mitwachsen, seine Hoehe ist inline auf 100px gepinnt
   (chatwindowinput.js:250). Die zweite Deklaration ("margin-top: 0") ist
   deshalb keine Zutat, sondern die Bedingung dafuer, dass die erste
   Figmas Wert TRIFFT statt ihn zu addieren. Ergebnis, gemessen:

     Viewport   Fuge vorher   Fuge   Knopf-Unterkante zum Kasten
       1280px        20px       16px          -7px   (drin)
       1025px        20px       16px          -7px   (drin)
       1024px         5px     12,5px         -11px   (drin)
        769px         5px     12,5px         -11px   (drin)
        768px         5px      8,5px         -15px   (drin)
        641px         5px      8,5px         -15px   (drin)
        640px         4px      0,5px          +5px   (siehe @media unten)
        620px         4px      0,5px          +5px   (siehe @media unten)

   Die dritte Spalte ist der ausgelieferte Stand; sie steht so auch im
   Test, als Zahl und nicht als Vorzeichen. Die "Fuge"-Spalte ist der
   Stand SEIT T2 (2026-09-16, siehe unten) -- bis dahin stand hier
   16/16/16/16/12/12/4/4, siehe die naechsten beiden Absaetze.

   DIE FUGE TRAF DIE REGEL BIS T2 (2026-09-16) IN JEDEM BAND EXAKT AUF
   DEM TOKENWERT -- das ist die eigentliche Aussage der zweiten
   Deklaration, und der Test liest sie so: gemessen wird die OBERSTE
   Knopfkante gegen die Unterkante der Eingabereihe. (Die Bueroklammer
   war 28px hoch und mittig ausgerichtet, ihre Oberkante lag also 4px
   tiefer; unter 640px stand sie zufaellig an erster Stelle der Zeile,
   war dort aber wegen dieser 4px trotzdem nie die oberste Kante.)

   DAS GILT NICHT MEHR, UND DAS IST GEMESSEN, NICHT NUR UMGERECHNET. Der
   Auftraggeber hat die Klammer am 2026-09-16 auf die Geometrie ihrer
   Nachbarn gehoben (36x36, Radius 10 -- siehe die Regel wenige Zeilen
   unterhalb dieses Blocks, direkt bei der 36er-Regel der Nachbarn). Die
   UNVERAENDERTE Legacy-Regel, die der Klammer im schmalen Composer noch
   eine auf die ALTE Hoehe abgestimmte Position gibt ("@media screen and
   (max-width: 1024px) { .upload-container { height: 24px; }
   .upload-container label { margin-top: 10px; } }", webapp.css), hebt
   die jetzt 36px hohe Klammer 3,5px UEBER ihre Nachbarn -- gleichgueltig
   ob sie dort die erste sichtbare ist (<=640px) oder nicht (1024/769/
   768/641px, wo die Sekundaerknoepfe noch vor ihr stehen). Die Klammer
   wird dadurch in JEDEM Band unterhalb von 1024px zur neuen kleinsten
   Oberkante der Zeile, und die Fuge unterschreitet den Tokenwert dort
   seither um genau diese 3,5px (16 -> 12,5px, 12 -> 8,5px). Bei
   1280/1025px greift die Legacy-Regel nicht -- dort bleibt die Fuge
   exakt der Tokenwert (16px). Unter 640px galt der Tokenwert ohnehin nie
   (siehe unten); dort sinkt die ausgelieferte Fuge entsprechend von 4px
   auf 0,5px. Der Ueberstand (vierte Spalte) ist NICHT betroffen -- er
   misst die UNTERKANTE der Zeile, und die Klammer ist dort nie die
   tiefste.

   DIE BANDGRENZE DER FUGE IST 768PX: "--ax-space-4" faellt dort selbst
   auf 12px (tokens.css, "@media (max-width: 768px)"), Figmas 16 gilt also
   erst ab 769px. Das ist dieselbe Lage wie bei Task 1s "--ax-radius-lg",
   nur mit einer anderen Schwelle -- und hier ist der kleinere Wert
   zusaetzlich der bessere: er nimmt dem Ueberstand unten 4px.

   UNTER 640PX WIRD FIGMAS FUGE NICHT ERZWUNGEN -- siehe den eigenen
   "@media"-Block am Ende dieses Abschnitts. Dort ist der Kasten
   "box-sizing: border-box" (webapp.css:10600) und traegt zugleich die
   inline gepinnten 100px: jede zusaetzliche Fuge schiebt die Knopfreihe
   unter die Unterkante, statt den Kasten wachsen zu lassen.

   -- RULING 1 BINDET HIER NICHT, UND DAS IST GEMESSEN -----------------

   Der Auftrag verlangt die Form, die Task 2 erarbeitet hat: eine Regel
   mit ZWEI Selektoren, weil "body.chat-embedded .chatbot-button-send"
   (webapp.css:2238) mit (0,2,1) jede (0,2,0)-Regel schlaegt. Die Rechnung
   stimmt -- sie trifft diesen Task nur nicht, und der Gegenversuch sagt
   es klar: MIT ENTFERNTEM ZWEITEM SELEKTOR BLEIBEN ALLE VIER BLOECKE
   GRUEN, auch die des eingebetteten Wirts.

   Der Grund liegt im ersten Selektor. Er MUSS ".chatbot-input" nennen und
   wiegt damit (0,3,0) statt (0,2,0): der Sendeknopf traegt BEIDE Klassen
   ("chatbot-button chatbot-button-send", chatwindowinput.js:112) und wird
   deshalb auch von der Knopfregel darueber getroffen. Bei (0,2,0) haette
   diese Knopfregel (0,3,0) ihn auf 36x36 gezogen, und Figmas 38 waeren
   nie angekommen. Dieselben (0,3,0) schlagen Legacys (0,2,1) aber schon
   von sich aus -- in JEDEM Wirt, ohne zweiten Selektor.

   Ein zweiter Selektor waere damit eine Deklaration ohne Wirkung, und
   dieses Teilprojekt entfernt tote Deklarationen, statt sie als Waechter
   zu behalten (Task 1s "border-color", Task 2s "color"). Der Waechter
   steht stattdessen im Test: der Block zum eingebetteten Wirt misst
   Flaeche und Masse dort, und er faellt, sobald jemand ".chatbot-input"
   aus dem Selektor nimmt.

   TRAGEND BLEIBT DIE REIHENFOLGE: Knopfregel und Sendeknopfregel wiegen
   beide (0,3,0) und stehen im Gleichstand -- die Sendeknopfregel MUSS
   deshalb hinter der Knopfregel stehen, sonst gewinnen deren 36px.

   -- UND DER RADIUS DES SENDEKNOPFS IST TOT ---------------------------

   Aus derselben Doppelklasse folgt noch etwas, und auch das ist ein
   Gegenversuch, der gruen blieb: "border-radius: var(--ax-radius-md)" am
   Sendeknopf ist WIRKUNGSLOS, weil die Knopfregel darueber ihn schon
   trifft und denselben Wert traegt. Figma nennt fuer beide Knopfarten
   Radius 10 -- eine zweite Deklaration waere eine zweite Quelle fuer
   einen Wert, und die beiden koennten auseinanderlaufen. Sie ist deshalb
   nicht geschrieben; der Test liest den Radius des Sendeknopfs trotzdem,
   in allen vier Konfigurationen und an sechs Haltepunkten.

   -- DIE FLAECHE: "--clr-accent" STATT "--ax-action-primary" ----------

   DIE EINZIGE ABWEICHUNG VOM PLANTEXT, DIE ETWAS ANDERES BEDEUTET, und
   sie ist gemessen. Der Plan schreibt
   "var(--acw-send-bg, var(--ax-action-primary))". Das waere im
   ungebrandeten Fall richtig -- und naehme das ORGANISATIONS-BRANDING vom
   sichtbarsten Knopf der Anwendung: brandingapplier.js:6 setzt die
   Kundenfarbe auf "--clr-accent", und genau die ist heute der erste
   Farbstopp des Verlaufs (webapp.css:2239 und :5674). Im
   Entwicklungsstand dieses Zweigs ist das keine Theorie: "--clr-accent"
   steht dort auf #ff5500 (dunkel) bzw. #007ab0 (hell), nicht auf #009fe3.

   "var(--acw-send-bg, var(--clr-accent))" liefert BEIDES:
     ohne Branding   Die Bruecke haengt "--clr-accent" unter
                     [data-design="new"] auf "var(--ax-action-primary)" um
                     (tokens.css:153) -- gemessen rgb(0, 159, 227), also
                     Figmas "action/primary" auf den Kanal genau.
     mit Branding    Die Organisationsfarbe gewinnt, wie
                     design-branding-precedence.spec.ts es fuer ALLE vier
                     Design-x-Theme-Kombinationen verlangt.
     mit "--acw-*"   Der Kunde des Widgets gewinnt ueber beide.
   Drei Richtungen, alle drei im Test zugesichert.

   WAS DIE REGEL TATSAECHLICH AENDERT, ist damit nicht die Farbe, sondern
   die FORM der Flaeche: aus dem Verlauf wird die eine Flaeche, die Figma
   zeichnet. Und das kostet Kontrast, weil die Mitte des Verlaufs dunkler
   war als sein Anfang (gerastert, Glyphe = weiss):

     Branding dunkel   3,65 -> 3,21     Branding hell   4,46 -> 4,76
     Figmas #009fe3    2,97 -> 2,97

   FIGMAS EIGENES PAAR VERFEHLT DIE SCHWELLE: "action/on-primary"
   (#ffffff) auf "action/primary" (#009fe3) ergibt 2,97 und bleibt damit
   unter den 3,0, die fuer Bedienelemente gelten -- vor dieser Regel
   genauso wie danach. DAS IST EIN DEFEKT DER VORLAGE, keiner dieser
   Datei, und er ist hier nicht heilbar: es braeuchte ein helleres
   "action/on-primary" oder eine dunklere "action/primary", und beides
   sind Entscheidungen der Vorlagen-Eigentuemer. Fuer die Spec (Task 5)
   festgehalten.

   -- DIE DECKKRAFT GEHOERT ZUR FARBE (Teil A, Task 6) ------------------

   Bis zu diesen 2,97 kommt das Cockpit im DUNKLEN Theme aber gar nicht:
   webapp.css:862-869 setzt "opacity: 0.72" auf ".chatbot-button img", in
   einer Sammelregel fuer jedes Knopfsymbol der App (der Hover hebt sie
   auf 1, in Ruhe bleibt sie 0,72). Gerastert ueber ein Kreuz durch den
   Knopf -- der Mittelpunkt allein trifft die Glyphe NICHT, dort liegt bei
   execute.svg die Flaeche:

                        Glyphe          Kontrast
     dunkel, Figma      184,228,247       2,19  -> 255,255,255   2,97
     dunkel, Branding   255,207,184       2,27  -> 255,255,255   3,21
     hell               255,255,255       2,97     unveraendert

   "07 Chat & AI" Teil A hat denselben Fall schon entschieden (Task 6:
   "0,6 haelt hell nur 2,356 -- opacity: 1 gehoert zur Farbe"). Und das
   HELLE Theme traegt die Entscheidung im Composer bereits: die
   Primary-Icon-Regel von "04 Core" (:175 dieser Datei) setzt dort
   "filter: brightness(0) invert(1)" UND "opacity: 1" fuer jeden Knopf
   ohne Secondary-/Ghost-/Icon-Klasse -- der Sendeknopf faellt darunter.
   DIE ZEILE UNTEN IST ALSO NICHT EINE NEUE ENTSCHEIDUNG, SONDERN DIE
   FEHLENDE HAELFTE EINER VORHANDENEN: sie zieht im dunklen Theme nach,
   was im hellen laengst gilt.

   SIE HEBT DEN WERT, OHNE DIE SCHWELLE ZU ERREICHEN -- 2,19 -> 2,97 mit
   Figmas Farben. Geschrieben ist sie trotzdem, weil 2,97 nachweislich
   besser ist als 2,19 und weil die verbleibenden 0,03 der Vorlage
   gehoeren, nicht der Deckkraft. Mit der Organisationsfarbe dieses
   Zweigs reicht es sogar (3,21).

   IM EINGEBETTETEN WIRT TRIFFT DIE ZEILE NICHTS, und das ist gemessen:
   dort ist das <img> "display: none" (webapp.css:2243) und "::after"
   malt die Glyphe als Maske -- mit "opacity: 1", weil nie etwas anderes
   gesetzt wurde. Der eingebettete Wirt braucht deshalb KEINE eigene
   Zeile; er steht mit 2,97 schon dort, wo das Cockpit erst hinkommt.

   -- DIE MASKE AUF "::after" BLEIBT UNBERUEHRT (gemessen) -------------

   webapp.css:2243-2256 blendet im eingebetteten Wirt das <img> aus und
   malt das Symbol als Maske aus "--acw-send-fg"; der Wechsel
   Senden<->Stop haengt an ".chatbot-input--streaming". Diese Regel setzt
   auf "::after" NICHTS und kann die Maske deshalb nicht stoeren -- aber
   "kann nicht" ist eine Annahme, also ist es gemessen: im eingebetteten
   Wirt bleiben "content", "mask-image" (execute.svg), 18x18 und die Farbe
   ("--acw-send-fg" bzw. weiss) mit und ohne diese Regel zeichengleich, im
   Cockpit bleibt "content: none". Der Test sichert beides zu, samt des
   Wechsels auf stop.svg.

   -- WAS DIESE AUFGABE BEWUSST NICHT SCHREIBT ------------------------

   Vier Werte der Vorlage bleiben offen, alle aus demselben Grund -- sie
   brauchen Markup oder eine Regel ausserhalb dieses Bauteils:

     Glyphe 20x20 / 17x17    Die Symbole sind <img>-Elemente mit fest
     Kontur 1,75             gesetzten 18px (webapp.css:881). Die
     Glyphe "text/secondary" Konturstaerke steckt IM SVG und ist aus CSS
                             nicht erreichbar; die Farbe ebenso wenig
                             (der Bestand loest sie mit "filter:
                             brightness(0) invert(1)", nicht mit einer
                             Farbe). Eine halbe Umsetzung -- nur die
                             Groesse -- haette die Vorlage nicht erreicht
                             und die drei Fundstellen der 18px
                             auseinandergezogen.
     Knopfabstand 8          Der Bestand setzt 6px als "margin-right" an
                             der nackten "button"-Regel (webapp.css:852)
                             und 5px an der Bueroklammer. Ein echtes
                             "gap" verlangt, beide zu nullen -- und der
                             letzte Knopf jeder Gruppe verloere dabei
                             seinen rechten Einzug, was die Zeile
                             verschoebe. Fuer 2px Unterschied nicht
                             angefasst.
     Ausrichtung MIN|CENTER  Die Zeile steht auf "space-between" mit zwei
                             Gruppen (webapp.css:5616); Figmas Rahmen
                             beschreibt die LINKE Gruppe, und die steht
                             dort bereits links. Nichts zu tun, das nicht
                             die Anordnung der ganzen Zeile umbaute. */
/* BERICHTIGT (2026-09-22, Aufgabe E, Review-Fund aus Gestaltung/C): der
   Selektor stand bis zu diesem Datum auf ".chatbot-input .button-container"
   (Nachfahre, auf die ganze Eingabeflaeche gescopt) -- der Kommentar
   darunter behauptete aber bereits "Nur die direkten Kinder DER
   KNOPFZEILE". Auf den Kind-Kombinator eingeengt, damit Selektor und
   Kommentar wieder uebereinstimmen: heute folgenlos, weil unter
   ".chatbot-input" ohnehin nur die zwei Knopfgruppen von ".chatbot-buttons"
   ein ".button-container" tragen (chatwindowinput.js, "leftButtonContainer"/
   "rightButtonContainer", beide direkte Kinder von "this.buttonLine"), aber
   ein kuenftiges ".button-container" tiefer in der Eingabeflaeche bekaeme
   sonst ungewollt "width: auto". */
[data-design="new"] .chatbot-buttons > .button-container {
  margin-top: 0;
  /* Gestaltung/C (2026-09-22): die zwei Knopfgruppen teilten sich die Zeile
     bisher ueber die geerbte "width: 100%" (webapp.css:1562, unantastbar) --
     das gab beiden dieselbe Flex-Basis wie die ganze Zeile und verteilte
     einen Ueberlauf zu gleichen Teilen (dieselbe Ursache, die ".chat-regler"
     unten ausfuehrlich dokumentiert). Unauffaellig, solange die rechte
     Gruppe nur Anonymisierung und Senden trug; mit den Regler-Chips braucht
     sie jetzt deutlich mehr Platz als die linke Werkzeuggruppe. GEMESSEN:
     im Projekt-Chat (fuenf Chips: Antwortverhalten/Toolsupport/Live-Suche/
     Wissensdatenbank/Skills) drueckte die erzwungene Gleichteilung den
     ersten Chip 19,5px von der Anonymisierung weg -- die rechte Gruppe
     musste dadurch selbst bei ausreichender Gesamtbreite umbrechen. "width:
     auto" gibt beiden Gruppen ihre tatsaechliche Inhaltsbreite als
     Flex-Basis zurueck (":where(button)" bleibt unberuehrt, nur der
     Container selbst); "flex-shrink: 1; min-width: 0" erlaubt beiden bei
     echtem Platzmangel weiterhin zu schrumpfen -- darunter greift
     ".chat-regler"s eigenes "flex-wrap: wrap". Nur die direkten Kinder DER
     KNOPFZEILE, nicht global: ".button-container" wird an vielen anderen
     Stellen der Anwendung verwendet. Die "Ausrichtung MIN|CENTER"-Notiz
     oben (webapp.css:5616, "space-between") bleibt unberuehrt -- bei zwei
     Kindern draengt "space-between" sie unabhaengig von ihrer Breite an die
     beiden Raender, genau wie vor dieser Regel. */
  width: auto;
  flex-shrink: 1;
  min-width: 0;
  /* Council/K1 (2026-09-23, Befund des Anwenders "sehe nicht alle
     Auswahlmoeglichkeiten" / "kann den Modus nicht mehr wechseln"): die
     Basisregel ".button-container" (webapp.css:1562, unantastbar) traegt
     "z-index: 1". Dieser Behaelter ist ein Flex-KIND von ".chatbot-buttons"
     (chatwindowinput.js, "leftButtonContainer"/"rightButtonContainer") --
     und ein Flex-Kind mit einem z-index ungleich "auto" erzeugt einen
     EIGENEN Stapelkontext, unabhaengig von "position" (CSS Flexbox Level 1,
     5.4 "Flex Item Z-Ordering": "z-index values other than auto create a
     stacking context even if position is static"). Das Reglermenue
     (".chat-regler-menu" unten, z-index: 30) haengt seit "Gestaltung/C" an
     einem Wirt INNERHALB dieses Behaelters -- sein z-index wird deshalb
     NIE gegen Geschwister ausserhalb des Behaelters ausgewertet, sondern
     nur innerhalb dieses eingesperrten Stapelkontexts. Ob genau das den
     gemeldeten Befund erklaert (das Menue males dadurch hinter dem
     Textfeld statt darueber), liess sich am Quelltext allein nicht
     abschliessend nachvollziehen -- ".chat-container" (webapp.css:2160)
     ist selbst ein Flex-Kind mit "z-index: 5" (components.css:2965-2966
     bestaetigt den Flex-Kontext) und damit der naechste tatsaechliche
     Stapelkontext; innerhalb dessen lokaler Reihenfolge muesste ein
     Nachfahre mit explizitem, positivem z-index eigentlich VOR (oben auf)
     gewoehnlichem, unpositioniertem Inhalt wie ".chatbot-input-inputrow"
     gemalt werden, nicht dahinter. Unabhaengig davon ist die Einsperrung
     selbst ein echter, hier belegter Fehler: das Menue kann so nie gegen
     IRGENDEIN anderes Element aus dem "z-index: 5"-Stapelkontext gewinnen,
     das seinerseits ein eigenes z-index traegt (z.B. ein kuenftiges
     Chip-Menue anderswo im Chatfenster). "z-index: auto" hebt den
     Stapelkontext fuer die BEIDEN Knopfgruppen der Eingabeleiste auf, ohne
     die Basisregel selbst anzufassen (unantastbar) und ohne andere
     ".button-container"-Stellen der Anwendung zu beruehren (Selektor bleibt
     auf "> .button-container" DIESER Knopfzeile beschraenkt, siehe
     Kommentar oben). Der GRUND fuer das urspruengliche "z-index: 1"
     (webapp.css, Commit faf9e3c085 "responsive imrpovements", 2025-08-03)
     ist nicht dokumentiert -- derselbe Commit haengte im selben Atemzug
     "z-index: 10" an ".chatbot-service" und ".visibilityButton-container"
     in einer Handy-Medienabfrage an, vermutlich um Knopfreihen in der
     schmalen Ansicht ueber verschobenen Inhalt zu halten. Da diese Regel
     nur die zwei Knopfgruppen DIESER Zeile trifft (nicht die vielen
     anderen ".button-container"-Stellen, siehe Dialoge/Karten/Paginierung),
     bleibt der mobile Fall ueberall sonst unveraendert. */
  z-index: auto;
}

[data-design="new"] .chatbot-input .chatbot-button,
[data-design="new"] .chatbot-input .chatbot-button-deactivated {
  width: 36px;
  height: 36px;
  border-radius: var(--ax-radius-md);
}

/* T2 (2026-09-16): DIE BUEROKLAMMER REIHT SICH EIN -- eine gekippte
   Entscheidung, keine Korrektur.

   "04 · Core" hat diesen Wirt mit ":not(.chatbot-input .upload-container)"
   AUSDRUECKLICH vom neuen Ausloeser-Stil ausgeschlossen, und "07 · Chat & AI" B
   hat das respektiert statt es zu ueberfahren -- mit dem Satz, wer den
   Widerspruch aufloesen wolle, muesse die Zusicherung drueben aendern.
   Der Auftraggeber hat ihn am 2026-09-16 aufgeloest: die Klammer nimmt die
   Geometrie ihrer Nachbarn.

   NUR GEOMETRIE. Flaeche und Rahmen bleiben Legacy -- der neue
   Ausloeser-Stil aus "04 · Core" ist hier weiterhin NICHT gemeint, und der
   Ausschluss dort bleibt unveraendert stehen. */
[data-design="new"] .chatbot-input .upload-container label {
  width: 36px;
  height: 36px;
  border-radius: var(--ax-radius-md);
}

[data-design="new"] .chatbot-input .chatbot-button-send {
  width: 38px;
  height: 38px;
  background: var(--acw-send-bg, var(--clr-accent));
}

[data-design="new"] .chatbot-input .chatbot-button-send img {
  opacity: 1;
}

/* #2056: der VoiceChat-Knopf am Desktop so gross wie der Sendeknopf
   (38x38, Regel direkt oben); die Legacy-Regel (webapp.css, 28x28) setzt schon
   "box-sizing: border-box", der 2px-Rahmen zaehlt also mit. Unter 1025px
   bleibt er bei 48x48 -- Daumenziel auf Tablet und Handy. */
@media screen and (min-width: 1025px) {
  [data-design="new"] .chatbot-input-voiceslot .voice-control-mic {
    width: 38px;
    height: 38px;
  }
}

/* ── Model Card: NUR DIE HUELLE (07 Chat & KI, Teil B, Task 4) ─────────
   Figma 150:64 ("Model Card"), Bestand ".model-selection-card"
   (webapp.css:4418), erzeugt ausschliesslich in
   organismsmodelselectioncard.js:39 fuer organisationllmconfig.js:206.

   -- DER SCHNITT, UND WARUM ER SO ENG IST ----------------------------

   FIGMAS MODEL CARD IST NICHT DIE KARTE DES PRODUKTS. Beide heissen so,
   beide zeigen ein Modell, aber sie sind verschieden gebaut: Figma
   zeichnet 300x128 mit Symbolkachel, EINER durchgehenden Kostenspur
   (152x5, Indikator 52px) und dem vollen Satz "DSGVO-konform ·
   EU-Rechenzentrum"; das Produkt baut 230x250 mit Farbstreifen, FUENF
   einzelnen Kostenpunkten (".factor-dot"), einem DSGVO-KURZlabel
   (".dgsvo-label"), einer Reihe Faehigkeits-Chips (".cap-chip") und
   einem Fuss mit Aktiv-Schalter und "Veraltet"-Marker -- die letzten
   drei kennt Figma gar nicht.

   Die drei mittleren Bauteile sind in "05 · Data" Teil B gebaut,
   GEMESSEN UND ZUGESICHERT (".cap-chip" :6300 dieser Datei mit
   design-marker-kennzahlen.spec.ts:1330-1400; ".dgsvo-label" mit der
   Messreihe im Kommentar bei :6635). Figmas Kostenspur und Figmas
   DSGVO-Satz waeren ERSATZ dafuer, nicht Ergaenzung. Entschieden
   (Auftraggeber, 2026-09-11, Spec §2): NUR DIE HUELLE. Kostenspur,
   DSGVO-Zeile, Chips, Fuss und der Veraltet-Zustand bleiben, wie sie
   sind; dieser Block fasst sie mit keiner Deklaration an.

   NACHGEZOGEN AM 2026-09-17: der letzte Satz gilt nicht mehr fuer
   Kostenspur und DSGVO-Zeile. T4 (Entscheidung 9, Block ":14549",
   Spec docs/superpowers/specs/2026-09-17-designsystem-model-card-design.md)
   KEHRT genau diesen Punkt um und ueberschreibt ".factor-dots"/
   ".factor-dot" sowie ".dgsvo-label" fuer "[data-design=new]" mit
   eigenen Deklarationen. Chips, Fuss und der Veraltet-Zustand bleiben
   unveraendert, wie hier festgehalten -- daran aendert T4 nichts
   (Spec §2.5). Dieser Block selbst (die Huelle: Flaeche, Rahmen,
   Schatten, Hoehe, Titeltypografie) bleibt unberuehrt und gilt weiter.

   -- SCHRITT 1: DER BESTAND, GEMESSEN STATT NACHGESCHLAGEN -----------

   KEINE der drei Legacy-Variablen dieser Huelle steht in tokens.css --
   "--card-gradient", "--clr-border-accent" und "--shadow-card" kommen
   dort nicht vor. Wer daraus "unveraendert" liest, irrt: alle drei sind
   ABGELEITET, und ihre Zutaten sind ueberbrueckt. Gemessen im vollen
   Stapel an dieser Karte (1280x720, Chromium), je dunkel/hell:

     --card-gradient    alt  linear-gradient(135deg, #161b22,
                             color-mix(#161b22 50%, #1e293b 50%))
                        neu  linear-gradient(135deg, #12111c,
                             color-mix(#12111c 50%, #242233 50%))
                        hell alt #ffffff -> color-mix(#eef2ff 40%, white)
                             neu #ffffff -> color-mix(#f4f3f7 40%, white)
     --clr-border-accent  alt dunkel color-mix(#ff5500 22%, #21262d)
                          neu dunkel color-mix(#ff5500 22%, #242233)
                          alt hell   color-mix(#4f46e5 35%, white)
                          neu hell   color-mix(#007ab0 35%, white)
     --shadow-card        alt+neu dunkel 0 4px 20px rgba(255,85,0,.08)
                          alt+neu hell   0 4px 12px rgba(99,102,241,.14)

   ZWEI KORREKTUREN AN DER SPEC, beide aus dieser Messreihe:

   (1) DIE SPEC (§2) SAGT, DER DUNKLE SCHATTEN "WANDERE" von
       rgba(59,130,246,.08) nach rgba(0,159,227,.08). GEMESSEN STEHT ER IN
       DIESEM ZWEIG IN BEIDEN DESIGNS AUF rgba(255,85,0,.08) -- und das
       ist KEIN Fehler der Spec, sondern ein anderer Messgegenstand:
       ihre Tabelle beschreibt den PLATTFORMSTAND OHNE BRANDING, diese
       Messreihe den Dev-Stand MIT.
       DER MECHANISMUS IST QUELLENREIHENFOLGE, NICHT INLINE-SPEZIFITAET.
       brandingapplier.js baut einen <style id="org-branding"> und HAENGT
       ihn an <head> AN (:56), also hinter tokens.css; darin haengt es
       zwoelf Legacy-Farbwurzeln plus sieben RGB-Begleiter um, darunter
       "--clr-accent" und "--clr-accent-rgb" (:6/:24). Der dunkle Block
       waehlt ":root:not([data-theme=light])" und wiegt damit (0,2,0)
       gegen die (0,1,0) der Bruecke; der helle waehlt eigens
       "[data-design][data-theme=light]", um die (0,2,0) der Bruecke zu
       TREFFEN und den Gleichstand ueber die Ladereihenfolge zu gewinnen.
       Die Kommentare dort (:64-82) sagen ausdruecklich, dass beides so
       gewollt ist: DAS ORGANISATIONS-BRANDING SCHLAEGT DIE DESIGNBRUECKE
       MIT ABSICHT.
       Die Organisation dieses Zweigs hat NUR eine dunkle Palette
       hinterlegt -- gemessen: hell steht "--clr-accent" im alten Design
       auf Legacys #4f46e5 und im neuen auf der Bruecke (#007ab0), also
       ungebrandet. Genau deshalb faellt der Unterschied hier dunkel auf
       und hell nicht.
       Der HELLE Schatten wandert tatsaechlich nicht -- dort stimmt die
       Spec, und aus ihrem Grund ("--clr-indigo-rgb" ist nicht
       ueberbrueckt).
       Dieselbe Falle hat "05 · Data" Teil B an der Branding-Vorschau und
       Task 3 dieses Teilprojekts am Sendeknopf getroffen (:10687).
   (2) DIE SPEC (§2) SAGT, BEI "--clr-border-accent" seien "beide Zutaten
       ueberbrueckt". Das gilt nur DUNKEL (webapp.css:33,
       color-mix(--clr-accent, --clr-border)). HELL ist die zweite Zutat
       das Schluesselwort "white" (webapp.css:295), also gar keine
       Variable. Dasselbe beim zweiten Verlaufsstopp: "--clr-surface-2"
       ist dunkel ein color-mix AUS "--clr-surface-1" (webapp.css:19),
       hell aber eins aus "--clr-base" (webapp.css:281). Beide bewegen
       sich trotzdem, nur ueber eine andere Zutat als die Spec annimmt.

   -- SCHRITT 2: DER "--ax-border-soft"-DEFEKT, HIER ENTSCHIEDEN -------

   Spec §7 #7 haelt fest, dass "--ax-border-soft" als Rahmen auf sechs
   Flaechen unzeichenbar ist, und das Projekt hat den Defekt ZWEIMAL
   GEGENSAETZLICH beantwortet: Ruling 14 (Teil A, Task 4) setzt das Token
   trotzdem, Ruling 17 (Teil A, Task 6) ersetzt es. DIESER BLOCK ERBT
   KEINE DER BEIDEN ANTWORTEN, er misst.

   Gemessen wird der Farbabstand (CIE76, Schwelle 2,3) des Rahmentons
   gegen die Flaeche, die dieser Block der Karte gibt, und gegen den
   Grund, auf dem die Karte steht:

                                        dunkel    hell
     border/soft gegen bg/surface-1      4,531    9,350   zeichenbar
     border/soft gegen bg/app            8,020    4,857   zeichenbar
     bg/surface-1 gegen bg/app           3,545    4,494   (s. Schatten)

   ALSO GILT HIER RULING 14: das Token wird gesetzt. Der Defekt der
   sechs Flaechen bindet an DIESER Karte nicht, weil ihre Flaeche
   "bg/surface-1" (ink/900 dunkel, ink/0 hell) ist und "border/soft"
   ink/800 bzw. ink/100 -- zwei Stufen der Rampe, nicht dieselbe.

   UND DAS IST DER GRUND, WARUM DIE HUELLE ALS GANZES GEBAUT WIRD ODER
   GAR NICHT: gegen den HEUTIGEN Untergrund traegt derselbe Rahmen NICHT.
   Am rechten oberen Kartenrand gerastert (der Verlauf laeuft dort schon
   Richtung "--clr-surface-2", also Richtung ink/800) misst border/soft
   gegen die Verlaufsflaeche nur 1,848 -- UNTER der Schwelle. Erst die
   flache Flaeche dieses Blocks macht den Rahmen ueberall sichtbar. Wer
   die Flaechenzeile entfernte und die Rahmenzeile stehen liesse, baute
   genau den Defekt, den Spec §7 #7 beschreibt.

   -- SCHRITT 3: DER SCHATTEN FAELLT, UND DAS IST GEMESSEN ------------

   Figma zeichnet keinen; der Bestand traegt "--shadow-card"
   (webapp.css:4425), die Eigenschaft ist also an dieser Stelle
   BESTRITTEN und "box-shadow: none" keine neue Eigenschaft.

   Die Frage war, ob die Karte ohne Schatten noch als Karte lesbar ist.
   SIE IST ES, und der Bezug dafuer ist das PRODUKT, nicht die Galerie.

   IN DER GALERIE IST DER ABSTAND DER FLAECHE ZUM GRUND 0,000 -- die
   Galeriegruppe traegt selbst "bg/surface-1" (derselbe Fall, den diese
   Datei schon dreimal festgehalten hat: :7967, :8272, :8461). Das ist
   eine Eigenschaft DER KULISSE. Die Karte lebt auf
   /organisationllmconfig.html (organisationllmconfig.js:206, der einzige
   Erzeuger); dort gemessen, in beiden Themes, an einer der 140 echten
   Karten:

     Grund ".welcome"/<body>   dunkel rgb(11,10,20) = ink/950 = bg/app
                               hell   rgb(244,243,247) = ink/50 = bg/app
     dE Kartenflaeche/Grund    dunkel 3,545   hell 4,494   (Schwelle 2,3)

   Der Grund ist also "bg/app" und nicht "bg/surface-1"; die Flaeche
   traegt dort AUS EIGENER KRAFT, und der Rahmen kommt obendrauf
   (8,020 / 4,857 gegen denselben Grund). Der Schatten darf fallen.

   Er war ausserdem nie eine neutrale Tiefe, sondern ein FARBIGER Schein
   -- dunkel rgba(255,85,0,.08) in der Organisationsfarbe, hell
   rgba(99,102,241,.14) in Legacys Indigo, das im neuen Design sonst
   nirgends mehr vorkommt.

   DIE 4,531 / 9,350 DES RAHMENS GEGEN DIE FLAECHE BLEIBEN TRAGEND, und
   zwar fuer eine andere Frage: ob "--ax-border-soft" ueberhaupt
   zeichenbar ist (Schritt 2 oben). Dass der Rahmen gegen den heutigen
   VERLAUF nur 1,848 haelt, bleibt der Grund, warum Flaeche und Rahmen
   nur zusammen gebaut werden duerfen.

   -- DIE ELF GEGENVERSUCHE, KEINER BLIEB GRUEN -----------------------

   Je Deklaration einzeln entfernt (removeProperty auf der Regel, danach
   zurueckgesetzt) und der Rueckfallwert gemessen, in BEIDEN Themes --
   zweiundzwanzig Messungen, zweiundzwanzig Bewegungen:

     height          -> 250px (und der Chipkasten faellt 55 -> 46)
     background      -> rgba(0,0,0,0) + linear-gradient(135deg, ...)
     border-color    -> color(srgb 0.330118 0.177333 0.156) dunkel,
                        color(srgb 0.65 0.817451 0.891569) hell
     border-radius   -> 8px
     box-shadow      -> rgba(255,85,0,.08) 0 4px 20px dunkel,
                        rgba(99,102,241,.14) 0 4px 12px hell
     .name font-size    -> 14px
     .name line-height  -> 18px  (NICHT 16,8 -- ein Gegenversuch nimmt
                           genau EINE Deklaration, die 15px bleiben
                           stehen und Legacys Faktor 1,2 rechnet darauf)
     .provider font-size   -> 11px
     .provider line-height -> 20px
     .provider font-weight -> 400
     .provider color       -> rgb(173,171,187) dunkel / rgb(53,50,74) hell

   -- DER CHIP-UEBERLAUF, UND DIE FUENFTE ZEILE DER HUELLE -------------

   FIGMAS ZEILENHOEHE KOSTET DIE ZWEITE CHIP-ZEILE. Die Titelzeile wird
   um 9,2px hoeher (7,2 aus der Zeilenhoehe, 2 daraus, dass ".name" ein
   <p> ist -- header.js:53 -- und sein 1em-Aussenabstand mit der
   Schriftgroesse waechst). Die Karte traegt "overflow: hidden"
   (webapp.css:4431); nachgeben kann nur ".model-card-chips"
   ("flex: 1 1 auto", :4488). Mit den VIER Chips der Galeriekachel
   gemessen ("Text", "Code", "Funktionen", "Vision" --
   organismsmodelselectioncard.js:178-191 aus dem Modell in
   designgallerypage.js:2233-2236):

     altes Design                   Kasten 53, Inhalt 58, letzter Chip
                                    endet 3,2px UEBER der Unterkante
     neues Design OHNE diesen Task  Kasten 55, Inhalt 60, ebenso 3,2px
     neues Design MIT diesem Task   Kasten 46, Inhalt 60, letzter Chip
                                    ragt 6px DARUNTER -- abgeschnitten

   Der Gegenversuch (nur die zwei Titelzeilen-Regeln auf Legacys Masse
   zurueck) liefert wieder 55 / -3,2. DIE 9px SIND DIESES TASKS, nicht
   die der fremden Chipregel.

   UND ES IST KEIN GALERIE-ARTEFAKT. Auf /organisationllmconfig.html
   gemessen, an den 140 echten Karten: jede Karte mit VIER Faehigkeiten
   zeigt dort Kasten 46, Inhalt 60, Ueberstand +6 -- in beiden Themes.
   Karten mit drei Faehigkeiten bleiben einzeilig (46/46) und sind nicht
   betroffen. Im ALTEN Design passen selbst vier Chips in EINE Zeile
   (53/53): dass es im neuen zwei sind, ist die Folge der breiteren
   Chips aus "05 · Data" Teil B (11px/600 statt 10px/400, Innenabstand
   4px statt 2px) -- der ABSCHNITT dagegen ist dieser Task.

   DIE DRITTE ZAHL, UND SIE GEHOERT DIESER REGEL: "height: 250px" steht
   in derselben NACKTEN Regel (webapp.css:4420), die dieser Block ohnehin
   ueberschreibt. Sie ist damit an dieser Stelle BESTRITTEN -- anders als
   ".model-card-chips", das eine Innerei von "05 · Data" Teil B ist und
   nicht angefasst wird. Kein fremder Test nagelt die Kartenhoehe fest;
   "organisation-llm-*.spec.ts" greift "[data-testid=model-selection-card]"
   ausschliesslich nach INHALT, nie nach Geometrie.

   GEMESSEN STATT GERECHNET. Die Hoehe wurde in Schritten von 250 bis 272
   durchgefahren und je Schritt der Ueberstand des letzten Chips gelesen:

     250  Kasten 46  Ueberstand  +6   (der Stand ohne diese Zeile)
     254  Kasten 50  Ueberstand  +2
     256  Kasten 52  Ueberstand   0   (buendig -- Minimum fuer "drin")
     257  Kasten 53  Ueberstand  -1
     259  Kasten 55  Ueberstand  -3   <== gebaut
     264  Kasten 60  Ueberstand  -8   (Inhalt == Kasten, auch der
                                       Innenabstand waere sichtbar)
     272  Kasten 68  Ueberstand -16   (voller Flex-Basiswert)

   GEBAUT SIND 259, NICHT 256 UND NICHT 264, und die Wahl ist eine
   Zurechnung: 259 = Legacys 250 + die 9, die die Titelzeile dieses
   Blocks dazugebaut hat. Bei 259 steht der Chipkasten wieder auf 55 --
   exakt dem Wert "neues Design OHNE diesen Task" -- und der letzte Chip
   wieder bei -3, exakt Legacys Verhaeltnis. 256 waere das blosse
   Minimum und liesse den Chip an der Kante kleben, ein Zustand, den es
   vorher nicht gab; 264 heilte zusaetzlich ein Abschneiden des
   Innenabstands, das Legacy SELBST seit jeher hat (dort 53 gegen 58) --
   das waere eine Verbesserung ueber den Auftrag hinaus und an einer
   Zahl, die diesem Task nicht gehoert.

   DIE 259 SIND EINE ABLEITUNG, KEINE KONSTANTE. Wer "line-height" am
   Namen aendert, muss sie mitziehen -- sonst bricht er ihre Absicht,
   genau wie Ruling 4 es fuer die 104 -> 112 der 06er-Regel festgehalten
   hat. Der Test liest deshalb BEIDES: die Hoehe und den Ueberstand.

   WAS SICH SONST BEWEGT, ist gemessen und folgenlos: die Fusszeile und
   die Standard-Zeile behalten ihren Abstand zur Unterkante (-1px in
   jedem Schritt der Reihe), und da ALLE Karten der Liste dieselbe Hoehe
   tragen, bleibt das Raster von ".card-container" (flex-wrap,
   "align-items: start", 50px Fuge, webapp.css:3054) stimmig; sein
   "max-height: calc(100vh - 100px)" mit "overflow-y: auto" nimmt den
   Zuwachs als Bildlauf auf.

   IM PRODUKT NACHGEMESSEN, nicht nur in der Galerie: auf
   /organisationllmconfig.html stehen danach alle 140 Karten auf 259px,
   die mit vier Faehigkeiten auf Kasten 55 / Inhalt 60 / Ueberstand -3
   (vorher +6), die mit dreien einzeilig auf 55/55/-29 -- in beiden
   Themes, und das Raster bleibt buendig, weil jede Karte gleich
   waechst.

   -- DIE BANDGRENZEN DER BENUTZTEN TOKENS, VORHER GEPRUEFT -----------

   "--ax-radius-lg"           14px ab 769px, darunter 12px
                              (tokens.css:405). FIGMAS 14 GILT ALSO ERST
                              AB 769px -- dieselbe Grenze, die Task 1 am
                              Composer gefunden hat. Legacy steht in
                              JEDEM Band auf 8, die Karte wird also auch
                              unter 769px runder, nur nicht nach Figmas
                              Zahl. Der Test prueft 769 und 768.
   --ax-font-size-body-md     15px in JEDEM Band. Der 768er-Block
   --ax-line-height-body-md   24px   staucht display/h1..h4/body-lg,
                              body-md steht dort nicht (tokens.css:
                              391-399). Figmas 15/24 kommt ueberall an.
   --ax-font-size-label-sm    12px in JEDEM Band. Derselbe Grund; der
   --ax-line-height-label-sm  16px   768er-Block fasst keine
                              label-Groesse an.
   --ax-bg-surface-1          nur themeabhaengig, keine Bandgrenze.
   --ax-border-soft           nur themeabhaengig, keine Bandgrenze.
   --ax-text-muted            nur themeabhaengig, keine Bandgrenze.

   -- DIE FUENF ZEILEN DER HUELLE --------------------------------------

   Alle fuenf Eigenschaften stehen in der NACKTEN Legacy-Regel
   (webapp.css:4420-4425: height, background, border, border-radius,
   box-shadow) -- keine ist neu, die Subset-Frage stellt sich hier
   nicht. Geschrieben ist "border-color" und nicht "border", damit
   Breite und Stil aus Legacys Kurzform stehen bleiben: Figmas 1px solid
   ist dort schon der Wert, eine zweite Quelle dafuer koennte
   auseinanderlaufen.

   NICHT geschrieben ist "width" -- die 230px stehen daneben in derselben
   Regel, Figmas 300 beschreibt eine Karte mit anderem Inhalt (s.u.), und
   nichts an dieser Aufgabe verlangt sie.

   Spezifitaet (0,2,0) gegen Legacys (0,1,0); die Daempfungsregel
   ".model-selection-card--deprecated ..." (webapp.css:4440) setzt nur
   "opacity" und "filter" und trifft ausserdem nicht die Karte selbst,
   sondern ihre Kinder -- sie kann mit keiner dieser fuenf Zeilen in
   Beruehrung kommen.

   -- DIE ZWEI TITELZEILEN --------------------------------------------

   ".model-card-header .name"   Figma 15/24 Semi Bold, text/primary.
   Legacy (webapp.css:4456) steht auf 14/16,8/600 und "--clr-text-
   primary". ZWEI der vier Werte sind schon da und werden NICHT
   geschrieben: 600 ist Legacys eigener Wert, und die Farbe liefert die
   Bruecke (tokens.css:159/229 haengen "--clr-text-primary" auf
   "--ax-text-primary" um -- gemessen rgb(232,230,238) dunkel,
   rgb(18,17,28) hell, also Figmas text/primary auf den Kanal genau).
   Eine eigene "color"-Zeile waere wertgleich; der Test sichert
   stattdessen zu, dass die Bruecke das leistet. Dieselbe Entscheidung
   wie bei Task 1s Rahmenfarbe.

   ZWEI BEFUNDE AM TRAEGER DIESER ZEILE, beide vorbestehend und beide
   hier NICHT geheilt:
     (a) ".name" ist ein <p> (header.js:53), kein <span>. Sein
         voreingestellter Aussenabstand ist 1em und waechst mit der
         Schriftgroesse mit -- 14px -> 15px, also je 1px oben und unten.
         Das sind die 2 der 9,2px, die weiter unten im Chip-Befund
         stehen.
     (b) FIGMAS "SEMI BOLD" ERREICHT DIE GLYPHEN NICHT. Der Text steckt
         in einem <strong> (header.js:55); gemessen traegt das in BEIDEN
         Designs "font-weight: 900", waehrend der <p> darueber auf 600
         steht. Legacys 600 waren damit schon vorher nur die Angabe des
         Traegers, nicht die der Schrift. Eine Heilung hiesse, entweder
         das <strong> aus einem fremden Atom zu nehmen oder es per CSS
         zurueckzugewichten -- beides ist ein Griff ausserhalb der
         Huelle. Gemeldet, nicht gebaut.

   ".model-card-meta .provider"   Figma 12/16 Medium, text/muted.
   HIER IST DIE SUBSET-FRAGE ECHT: die nackte Legacy-Regel
   (webapp.css:4464) setzt NUR white-space, overflow und text-overflow.
   Schriftgroesse (11px) und Farbe erbt die Zeile vom Elternknoten
   ".model-card-meta" (webapp.css:4460), Gewicht und Zeilenhoehe von
   weiter oben. Alle vier Deklarationen unten sind an DIESEM Selektor
   also NEU -- zulaessig, weil die Regel "[data-design=new]"-gescopt ist
   (0,3,0) und keine Basisregel; Spec §4 #2.
   GEMESSEN, DASS KEINE LEGACY-SCHICHTUNG UMGEKEHRT WIRD: es gibt in
   webapp.css und components.css GENAU EINE Regel, die ".provider" in
   diesem Zusammenhang nennt, naemlich :4464. Es gibt nichts, was hoeher
   wiegt und ueberfahren wuerde. Und die Regel trifft bewusst NUR
   ".provider", nicht ".model-card-meta": die zweite Zeile dieses
   Elternknotens ist ".dgsvo-label", und die gehoert "05 · Data" Teil B.

   WAS DIE MUTED-FARBE KOSTET, und es ist eine bewusste Verschlechterung:
   Legacys Anbieterzeile steht auf "text/secondary" (ink/300 dunkel,
   ink/600 hell) und damit sehr hoch im Kontrast. Figma verlangt
   "text/muted". Gegen die neue Kartenflaeche gemessen:

     text/muted gegen bg/surface-1   dunkel 4,796   hell 7,416
     text/primary gegen bg/surface-1 dunkel 15,129  hell 18,705

   Beide Titelzeilen bleiben ueber WCAG 4,5. Der dunkle Wert ist mit
   4,796 der knappste der Karte -- gemessen gegen die FLAECHE, die dieser
   Block setzt, nicht gegen den Seitengrund (Messregel 3).

   -- WAS DIESER BLOCK BEWUSST NICHT SCHREIBT -------------------------

     Symbolkachel 30x30       Figma 150:64 zeichnet links eine Kachel mit
     bg/surface-2, Radius 10  Glyphe "accent/ai". Im Produkt gibt es an
     Glyphe accent/ai         dieser Stelle den 3px-FARBSTREIFEN
                              ".model-card-accent" (webapp.css:4449),
                              der den DSGVO-Zustand traegt. Die Kachel
                              zu bauen hiesse, neues Markup zu erfinden
                              und den Zustandstraeger zu ersetzen --
                              beides verbietet Spec §4 #5 bzw. §2.
     Kostenspur 152x5         Ersatz fuer ".factor-dot"/".factor-dots",
     DSGVO-Satz               Ersatz fuer ".dgsvo-label". Beide aus
                              "05 · Data" Teil B, beide zugesichert.
                              Siehe oben.
     Breite 300               Die Karte ist 230 breit und haelt darin
                              Chips, Fuss und Standard-Zeile. Figmas 300
                              beschreiben eine Karte mit anderem Inhalt;
                              nichts an dieser Aufgabe verlangt sie.
     Hoehe 128                Erst recht nicht: bei 128px Hoehe fiele
                              alles unterhalb der Titelzeile aus dem
                              "overflow: hidden" heraus. Die Hoehe geht
                              hier in die GEGENrichtung, 250 -> 259, und
                              das ist keine Figma-Zahl, sondern die
                              Nachfuehrung der Titelzeile (s.o.).

   OFFEN FUER DIE VORLAGEN-EIGENTUEMER (Spec §7 #1): gilt Figmas Karte
   als ERSATZ der Produktkarte oder als zweite, andere Karte? Bis zur
   Antwort steht hier die Huelle und sonst nichts. */
[data-design="new"] .model-selection-card {
  background: var(--ax-bg-surface-1);
  border-color: var(--ax-border-soft);
  border-radius: var(--ax-radius-lg);
  box-shadow: none;
  /* 259 = Legacys 250 + die 9, die die Titelzeile oben dazugebaut hat.
     EINE ABLEITUNG, KEINE KONSTANTE -- wer "line-height" am Namen aendert,
     muss diese Zahl mitziehen, sonst bricht er ihre Absicht. Herleitung
     und Messreihe im Kommentar oben unter "DER CHIP-UEBERLAUF". */
  height: 259px;
}

[data-design="new"] .model-card-header .name {
  font-size: var(--ax-font-size-body-md);
  line-height: var(--ax-line-height-body-md);
}

[data-design="new"] .model-card-meta .provider {
  font-size: var(--ax-font-size-label-sm);
  line-height: var(--ax-line-height-label-sm);
  font-weight: 500;
  color: var(--ax-text-muted);
}

/* -- DAS SCHMALE BAND: LEGACYS STAND SCHLAEGT FIGMAS RHYTHMUS ----------
   Unter 640px ist ".chatbot-input" "box-sizing: border-box"
   (webapp.css:10600) und traegt zugleich die inline gepinnten 100px aus
   chatwindowinput.js:250. Die Aussenhoehe steht damit fest: alles, was
   oberhalb der Knopfreihe waechst, schiebt sie UNTER die Unterkante des
   Kastens. Gemessen bei 620px, Unterkante des untersten Knopfes gegen die
   des Kastens:

     altes Design                           -1px   (drinnen)
     Stand vor diesem Task (Task 1 + 2)     +5px
     mit Fuge und 38px-Sendeknopf          +15px
     mit diesem Block                       +5px

   DIESER BLOCK GIBT GENAU DAS ZURUECK, WAS DIESER TASK GENOMMEN HAT --
   8px Fuge (12 -> Legacys 4, webapp.css:10752) und 2px Sendeknopf
   (38 -> 36, Legacys eigene Touch-Groesse aus webapp.css:10609). Die
   verbleibenden 6px zwischen +5 und Legacys -1 sind Task 1s Innenabstand
   (oben 16 statt 10) und gehoeren dessen Entscheidung, nicht dieser.

   WARUM UEBERHAUPT ZURUECKGEBEN: der Massstab in einem Band, in dem die
   Vorlage nicht darstellbar ist, ist LEGACYS STAND, nicht Figmas Zahl
   (Ruling 4 / Teil A Ruling 17). Figmas Fuge von 16 (dort ohnehin nur 12)
   und die 38 des Sendeknopfs sind Desktop-Aussagen; unter 640px steht
   ohnehin eine andere Zeile -- sie bricht um, die Cockpit-Knoepfe klappen
   hinter den "..."-Umschalter, und alle Knoepfe wachsen auf Legacys
   36px-Touch-Ziel. Der Sendeknopf reiht sich hier also in eine
   Entscheidung ein, die der Bestand fuer dieses Band schon getroffen hat.

   DER BLOCK STEHT AM ENDE, UND DAS IST TRAGEND: ein "@media" traegt keine
   Spezifitaet. Beide Regeln stehen mit den Regeln, die sie schlagen
   sollen, im GLEICHSTAND -- (0,2,0) gegen die Task-1-Regel oben in dieser
   Datei, (0,3,0) gegen die Sendeknopfregel weiter oben (Task 4 hat
   seinen Model-Card-Block dazwischengelegt; der traegt keinen
   ".chatbot-"-Selektor und beruehrt diese Schichtung nicht) -- und
   gewinnen allein ueber die Quellenreihenfolge. Wer diesen Block nach
   oben schiebt, hebt ihn auf. */
@media (max-width: 640px) {
  [data-design="new"] .chatbot-input {
    gap: 4px;
  }

  [data-design="new"] .chatbot-input .chatbot-button-send {
    width: 36px;
    height: 36px;
  }
}

/* ══ 09 · Overlays & Feedback, Teil A — die Dialogflaeche (Figma 114:48) ══

   DAS FOLGENREICHSTE BAUTEIL DIESES UMBAUS. ".dialog" entsteht im Produkt an
   EINER Stelle (dialog.js:57-58), aber "Dialog" hat 85 Unterklassen transitiv (72 direkt), verteilt auf 70 Dateien -- 61 in
   frontend/js/ui/dialogs/ und neun ausserhalb. Jede der vier Deklarationen
   unten erscheint damit auf JEDER Seite der Anwendung, sobald irgendein
   Dialog geoeffnet wird.

   DER BLOCK STEHT HINTER DEM "@media (max-width: 640px)" DARUEBER, und das
   ist unschaedlich: jener Block traegt ausschliesslich ".chatbot-*"-
   Selektoren, die beiden Regeln, die er ueber die Quellenreihenfolge schlagen
   muss, stehen weiterhin VOR ihm, und dieser Block schiebt sich zwischen
   keine der beiden. Ein "@media" traegt keine Spezifitaet -- wer diesen Block
   dort einbaut statt anhaengt, muss das nachrechnen.

   -- DER BESTAND, GEMESSEN (Elterncommit ccc93b2d3, 1280x720, Cockpit-
      Nutzer der GEBRANDETEN Entwicklungsorganisation; ungebrandet
      gegengemessen, s.u.) ----------------------------------------------

     background     linear-gradient(135deg, --clr-surface-1, --clr-surface-2)
                    dunkel  rgb(18,17,28)  -> color(srgb .1059 .1 .1549)
                    hell    rgb(255,255,255) -> color(srgb .9827 .9812 .9875)
                    backgroundColor dabei "rgba(0, 0, 0, 0)" -- GEMESSEN
     border         1px solid var(--clr-border-accent)
                    dunkel gebrandet   color(srgb .3301 .1773 .1560)
                    dunkel ungebrandet color(srgb .1101 .2412 .3518)
                    hell               color(srgb .6500 .8175 .8916)
     border-radius  8px an allen vier Ecken
     box-shadow     ZWEI Schatten:
                    dunkel rgba(0,0,0,.6) 0 8px 40px  +  Ring 0 0 0 1px
                    hell   rgba(99,102,241,.2) 0 8px 40px  +  Ring
     --overlay-bg   dunkel rgba(0,0,0,.5), hell rgba(99,102,241,.15)

   DIE HELLE PALETTE DIESER ORGANISATION SETZT KEINEN AKZENT: gebrandet und
   ungebrandet liefern im hellen Theme denselben Rahmen. Nur das dunkle Theme
   ist hier tatsaechlich gebrandet. Beide Faelle sind gemessen, damit niemand
   aus "im Hellen aendert sich nichts" schliesst, brandingapplier.js sei
   folgenlos.

   -- ERSTE ENTSCHEIDUNG: DIE KURZFORM "background" UND EINE EINFARBIGE
      BILDSCHICHT, NICHT "background-color" UND NICHT EINE NACKTE FARBE ---

   Zwei Stufen, und die zweite ist eine NACHBESSERUNG (2026-09-14): die
   erste Fassung dieses Blocks schrieb "background: var(--ax-bg-elevated)"
   und hat damit den meistgenutzten Dialogtyp der Anwendung unlesbar
   gemacht. Beide Stufen stehen hier, weil die zweite ohne die erste wie
   ein Umweg aussieht -- und dann beim naechsten Aufraeumen
   zurueckgedreht wird.

   STUFE 1, DIE KURZFORM. Legacy setzt "background: var(--card-gradient)",
   also die Kurzform mit einem VERLAUFSBILD. Eine Fassung, die nur
   "background-color" setzte, aenderte nichts Sichtbares: die Farbe laege
   UNTER dem Verlauf, und getComputedStyle meldete brav den Zielwert,
   waehrend das Auge den alten Verlauf sieht. Nur die Kurzform fasst auch
   "background-image" an. Das ist eine ECHTE ERSETZUNG -- Verlauf gegen
   Flaeche --, kein Farbwechsel.

   STUFE 2, DIE BILDSCHICHT. "UserMessage.renderUi()" setzt

       dialog.style.backgroundColor = 'white';

   als INLINE-Stil, und dieselbe Zeile steht noch zweimal in
   "userinput.js" (:235, :387). Daran haengen vierzehn Klassen --
   UserMessage, Information, Warning, ErrorMsg, UserInput, SecurityQuestion
   (die Rueckfrage, die "Dialog" bei ungesicherten Aenderungen SELBST
   oeffnet, dialog.js:265), LineInput, TextInput, SelectValue, FilleInput,
   BulkResultDialog, ExportOptionsDialog, ReorganizeContainerQuestion und
   DialogSaveChatAsDocument --, also die gesamte Bestaetigungs-, Eingabe-
   und Importfamilie.

   IM BESTAND IST DAS FOLGENLOS, und zwar aus genau einem Grund: ein
   Hintergrund-BILD liegt UEBER der Hintergrund-FARBE. Legacys Verlauf ist
   deckend, das Inline-Weiss blieb verdeckt. Eine nackte Farbe setzt
   "background-image" dagegen auf "none" -- und nimmt dem Inline-Weiss
   seine Abdeckung. Ein Inline-Stil schlaegt jede Regel; "!important" ist
   in diesem Umbau verboten, und "usermessage.js" ist gesperrter
   Produktionscode. Der einzige Hebel liegt hier.

   GEMESSEN, an einer Sonde mit den woertlichen Inline-Stilen aus
   die Inline-Stile aus "UserMessage.renderUi()", gerastert in der oberen
   rechten Ecke der Flaeche:

                              backgroundImage        gerastert      Titel   Text
     alt / dunkel             linear-gradient(135deg) rgb(26,33,45) 13,110 13,110
     alt / hell               linear-gradient(135deg) rgb(249,251,255) 15,432 15,432
     neu / dunkel, FARBE      none                   rgb(255,255,255)  1,236  2,253
     neu / dunkel, BILDSCHICHT linear-gradient(...)  rgb(26,24,38)   14,124  7,750
     neu / hell, FARBE        none                   rgb(255,255,255) 18,705 12,306
     neu / hell, BILDSCHICHT  linear-gradient(...)   rgb(255,255,255) 18,705 12,306

   1,236 ist heller Text auf weissem Grund. Die Bildschicht stellt genau
   die Eigenschaft wieder her, wegen der Legacy funktionierte, und hebt den
   Wert auf 14,124 -- den Wert, den die Regelflaeche ohnehin traegt.

   UND SIE VERAENDERT NICHTS, WO KEIN INLINE-WEISS LIEGT. Gerastert an
   allen drei Galeriekacheln, beide Themes, Farbfassung gegen Bildfassung:
   rgb(26,24,38) gegen rgb(26,24,38) dunkel und rgb(255,255,255) gegen
   rgb(255,255,255) hell -- dE 0,000, bitgleich. Ein einfarbiger Verlauf
   ist optisch eine Flaeche.

   WAS DIE BILDSCHICHT AM GERECHNETEN WERT AENDERT, und das ist der Grund
   fuer die Form der Zusicherungen: die Kurzform setzt "background-color"
   auf seinen Anfangswert zurueck, "getComputedStyle" meldet an ".dialog"
   im neuen Design also "rgba(0, 0, 0, 0)" -- genau wie im alten. DIE
   FARBE IST AB HIER NUR NOCH GERASTERT LESBAR (Messregel 2). Der Test
   sichert deshalb drei Felder getrennt zu: die Bildschicht woertlich
   ("linear-gradient(rgb(26, 24, 38), rgb(26, 24, 38))"), die durchfallende
   Farbe, und den gerasterten Punkt.

   DAS ALTE DESIGN BLEIBT UNTERSCHEIDBAR, obwohl beide Designs jetzt eine
   Bildschicht tragen: Legacys Verlauf traegt einen Winkel und zwei
   verschiedene Farbstopps ("linear-gradient(135deg, ...)"), dieser hier
   keinen Winkel und zweimal dieselbe Farbe. Die Legacy-Zusicherung prueft
   deshalb auf "135deg" und nicht mehr nur auf "linear-gradient(".

   -- ZWEITE ENTSCHEIDUNG: DER RAHMEN IST THEMEGESCOPT ------------------

   Figma verlangt "1px border/soft". "--ax-border-soft" und
   "--ax-bg-elevated" -- Figmas Rahmen und Figmas Flaeche -- sind im DUNKLEN
   Theme BEIDE "--ax-ink-800" (tokens.css:53 und :60). Hell sind sie
   verschieden (ink-0 gegen ink-100, tokens.css:101/:108).

   GEMESSEN (dE nach CIE76, gerastert auf der gesetzten Flaeche, Schwelle 2,3
   aus Messregel 5):

     Rahmen gegen Flaeche      dunkel  0,000     hell  9,350
     mit --ax-border-default   dunkel  5,334     hell 16,958

   Die Vorabpruefung ist damit BESTAETIGT, nicht uebernommen: im dunklen
   Theme ist Figmas Rahmen auf Figmas Flaeche buchstaeblich nicht vorhanden.

   Das Projekt hat denselben Defekt zweimal GEGENSAETZLICH beantwortet --
   Ruling 14 (trotzdem setzen, die Zusicherung erzwingt die Nachfuehrung)
   gegen Ruling 17 (ersetzen, sonst waere die Kante unsichtbar). Dieser Block
   erbt keine der beiden. Er misst, und die Messung faellt hier anders aus
   als an der Modellkarte, wo Ruling 14 galt: dort lag "--ax-border-soft" auf
   "bg/surface-1" und hielt mit 4,531 dunkel, hier liegt er auf "bg/elevated"
   und haelt mit 0,000 nicht. Deshalb Ruling 17s FORM -- die Abweichung nur
   dort, wo sie noetig ist:

     hell   Figmas "border/soft", unveraendert
     dunkel "--ax-border-default" (ink-700), der naechste Ton derselben Rampe

   DIE GEGENREGEL LAUTET ":not([data-theme="light"])" UND NICHT
   "[data-theme="dark"]". tokens.css fuehrt DUNKEL als Grundfassung
   ([data-design="new"], :48) und HELL als Zusatz
   ([data-design="new"][data-theme="light"], :96). Ein Dokument im dunklen
   Theme traegt das Attribut oft gar nicht; "[data-theme="dark"]" waere
   dort wirkungslos und der Rahmen wieder unsichtbar. Spezifitaet: die
   Hauptregel steht bei (0,2,0), die Gegenregel bei (0,3,0) -- ":not()"
   zaehlt die Spezifitaet seines Arguments --, sie gewinnt also unabhaengig
   von der Reihenfolge.

   -- DRITTE ENTSCHEIDUNG: DER RING FAELLT ------------------------------

   Figmas Schatten ist "0 8px 40px rgba(0,0,0,.60)" und damit BITGLEICH mit
   "--ax-shadow-dialog" (tokens.css:365); dieser Block ist dessen erster
   Verbraucher. Im dunklen Theme ist das zugleich der Bestand. Der
   Unterschied liegt im ZWEITEN Schatten des Bestands
   ("0 0 0 1px var(--clr-border-accent)") -- einem Ring neben dem
   1px-Rahmen, den Figma nicht kennt und der die Kante
   organisationsfarben faerbt.

   GEMESSEN, ob sein Wegfall die Kante schwaecht (gerastert an der linken
   Dialogkante auf halber Hoehe, Dialog ueber dem Schleier ueber der Seite):

                              dE Kante/Schleier     WCAG Kante/Schleier
     Bestand (mit Ring)       dunkel 29,9 hell 17,2   1,814 / 1,218
     neu, mit Ring            dunkel 16,2 hell 14,6   1,307 / 1,521
     neu, ohne Ring           dunkel 16,2 hell 14,6   1,307 / 1,521
     Ringpixel selbst         dunkel 20,9 hell 15,0   1,353 / 1,407

   Der Ring aendert an der Kante der Flaeche NICHTS -- er legt eine zweite,
   andersfarbige 1px-Linie daneben. Die Kante selbst traegt ohne ihn mit
   dE 16,2 (dunkel) und 14,6 (hell), weit ueber der Wahrnehmungsschwelle
   2,3. Der Ring faellt.

   ABWEICHUNG VON DER VORGABE, ausdruecklich: der Brief nennt fuer diese
   Pruefung die WCAG-Schwelle 3,0. Sie ist in dieser Palette UNERREICHBAR --
   auch der Bestand haelt sie nicht (1,814 dunkel, 1,218 hell), mit Ring so
   wenig wie ohne. Das Verhaeltnis misst Leuchtdichte, und eine dunkle Kante
   auf einem dunklen Schleier hat davon wenig, so sichtbar sie auch ist. Die
   Entscheidung faellt deshalb ueber dE, das fuer Farbtonfragen zustaendige
   Mass (Messregel 5) -- und sie faellt relativ: der Ring nimmt der Kante
   nichts. Beide Zahlenreihen stehen oben, damit ein Review die Wahl pruefen
   kann statt sie zu glauben.

   -- VIERTE ENTSCHEIDUNG: DER SCHLEIER BEKOMMT KEINE REGEL --------------

   "--overlay-bg" ist dunkel rgba(black,.5), hell rgba(indigo,.15); Figma
   liefert fuer den Schleier KEINEN Sollwert. Die 0,15 sehen schwach aus --
   gemessen sind sie es nicht (dE mit gegen ohne Schleier, gerastert am
   SEITENinhalt):

     dunkel   Gruppenflaeche  6,070     Seitengrund  3,629
     hell     Gruppenflaeche 13,156     Seitengrund 13,099

   DER HELLE SCHLEIER NIMMT DIE SEITE MEHR ZURUECK ALS DER DUNKLE, trotz
   0,15 gegen 0,50: Deckkraft ist nicht Wahrnehmung. 50 % Schwarz auf einem
   ohnehin fast schwarzen Grund (bg/app ist #0b0a14) verschiebt wenig, 15 %
   Indigo auf Weiss verschiebt viel. Eine Regel waere hier eine Erfindung
   ohne Messgrundlage; der Befund steht in der Spec, der Messwert in
   design-modal.spec.ts.

   -- JEDE DEKLARATION EINZELN WIDERLEGT (verankerte Textsabotage, je eine
      Zeile, reload dazwischen, beide Themes) ---------------------------

     ohne "background"        dunkel/hell: der Verlauf steht wieder da,
                              backgroundColor faellt auf rgba(0,0,0,0)
     ohne "border-color"      hell: color(srgb .65 .8175 .8916), also die
       (Hauptregel)           gebrandete Mischung des Bestands.
                              DUNKEL UNVERAENDERT -- dort deckt die
                              Gegenregel darunter denselben Selektor ab.
                              Die Deklaration ist damit NICHT tot, sie ist
                              der HELLE Wert; sie zu streichen naehme dem
                              hellen Theme Figmas Rahmen.
     ohne "border-radius"     dunkel/hell: 8px
     ohne "box-shadow"        dunkel/hell: zwei Schatten, mit Ring, hell
                              wieder Indigo .2
     ohne "border-color"      dunkel: rgb(26,24,38) -- die FLAECHE, der
       (Gegenregel)           Rahmen also unsichtbar. Hell unveraendert,
                              dort gilt die Regel nicht.

   Keine der fuenf Deklarationen ist tot.

   -- LECKPROBE (jede Regel einzeln entscopt, [data-design="new"] ->
      [data-design], spezifitaetserhaltend; gemessen im ALTEN Design) ----

     Hauptregel entscopt      dunkel/hell: der Verlauf verschwindet
                              (background "rgba(0,0,0,0)", bgImage "none"),
                              der Radius springt auf 14px, der Ring faellt,
                              der Rahmen faellt auf currentColor
                              (rgb(226,232,240) dunkel, rgb(30,27,75) hell)
     Gegenregel entscopt      dunkel: derselbe currentColor-Rueckfall am
                              Rahmen, alles uebrige legacy. Hell: nichts.

   ALLE VIER DEKLARATIONEN LECKEN, keine ist wertgleich mit Legacy -- es gibt
   in diesem Block keine Regel, die eine Notiz "aendert im alten Design
   nichts" braeuchte.

   DER RUECKFALL AUF "currentColor" IST DABEI SELBST EIN BEFUND: tokens.css
   fuehrt die FARBtoken nur unter [data-design="new"] (:48/:96), die
   GEOMETRIEtoken dagegen an ":root" (:315 ff.). Im alten Design ist
   "var(--ax-border-soft)" deshalb leer -- die Deklaration wird ungueltig und
   "border-color" faellt auf seinen Anfangswert currentColor --, waehrend
   "var(--ax-radius-lg)" dort sehr wohl 14px liefert. Wer eine dieser Regeln
   je entscopt, bekommt zwei verschiedene Arten von Schaden.

   -- WAS DIESER BLOCK BEWUSST NICHT SCHREIBT ---------------------------

     Breite 400/520/680       Spec 4a: 85 Dialoge sind auf die vorhandene
     Innenabstand 20/24       Geometrie gebaut, und Figma zeigt keinen
     gap 16                   einzigen mit Formularinhalt. "width",
     Zentrierung, Hoehen      "min-/max-width", "min-/max-height",
                              "position", "top", "left", "transform" und
                              "margin" werden hier NICHT gesetzt. Die
                              Zentrierung ist am 2026-09-14 auf eigene
                              Anweisung in webapp.css:1025 ff. erledigt
                              worden und ist kein offener Punkt dieses
                              Teilprojekts mehr. Innenabstand und Fuge
                              gehoeren Task 2.
     Titel 18/26              Task 2. Ein 18px-Token gibt es nicht
                              (--ax-font-size-body-lg ist 17/28); die Frage
                              wird dort entschieden, nicht hier.
     Schliessen-Knopf im Kopf Spec 4b: das Produkt hat keinen Kopfbereich,
                              das Schliessen sitzt als beschrifteter Knopf
                              in der Fusszeile. Ein Kopf-X hiesse Markup
                              und Verhalten erfinden.
     Schleier                 s.o., vierte Entscheidung.

   -- SPEZIFITAET UND NACHBARSCHAFT -------------------------------------

   Die EINZIGE Legacy-Regel, deren rechtestes Compound ".dialog" ist, ist
   webapp.css:1054 bei (0,1,0) (ueber webapp.css und components.css
   gesucht, Media-Queries und Hell-Theme-Block eingeschlossen). Es gibt
   keinen Gleichstand und nichts, was ueberfahren wuerde. Die sechs
   "!important" des Bestands liegen auf "max-height" und "overflow"
   (:1054 ff.) sowie in vier Nachfahrenregeln -- keine der vier
   Eigenschaften hier tritt gegen eines von ihnen an, und dieser Block
   schreibt selbst keines.

   Und die drei INLINE-Stile, die Dialog.renderUi() (dialog.js:59-62) auf
   jedes echte Exemplar schreibt -- "z-index: 60000", "max-height: 80%",
   "margin-top: 5%" --, beruehren keine der vier Eigenschaften. Ein
   Inline-Stil schlaegt jede Regel; dass er es hier nicht muss, ist gemessen
   und nicht angenommen. */
[data-design="new"] .dialog {
  /* EINE EINFARBIGE BILDSCHICHT, KEINE NACKTE FARBE -- und das ist keine
     Umstaendlichkeit, sondern die Eigenschaft, wegen der Legacy mit dem
     Inline-Weiss aus "UserMessage.renderUi()" funktionierte. Herleitung, die
     vierzehn betroffenen Klassen und die Messreihe (Titelkontrast 1,236
     gegen 14,124) stehen oben unter "ERSTE ENTSCHEIDUNG", Stufe 2. */
  background: linear-gradient(var(--ax-bg-elevated), var(--ax-bg-elevated));
  border-color: var(--ax-border-soft);
  border-radius: var(--ax-radius-lg);
  box-shadow: var(--ax-shadow-dialog);
}

/* Die Gegenregel zur Rahmenfrage — Begruendung, Messreihe und die Wahl von
   ":not([data-theme="light"])" statt "[data-theme="dark"]" stehen oben
   unter "ZWEITE ENTSCHEIDUNG". */
[data-design="new"]:not([data-theme="light"]) .dialog {
  border-color: var(--ax-border-default);
}

/* ══ 09 · Overlays & Feedback, Teil A — Innenabstand, Fuge und Fusszeile ══

   Fortsetzung des Blocks darueber und dieselbe Reichweite: ".dialog"
   entsteht an EINER Stelle (dialog.js:57-58), "Dialog" hat 85 Unterklassen,
   jede Zeile hier erscheint auf jeder Seite der Anwendung, sobald irgendein
   Dialog geoeffnet wird.

   -- DER BESTAND, GEMESSEN (1280x720, Kacheln modal-confirm / modal-tabs /
      modal-long, beide Designs, beide Themes; alle zwoelf Kombinationen
      liefern dieselben Zahlen) ------------------------------------------

     padding                                   20px ringsum (webapp.css:1054 ff.)
     gap an ".dialog"                          "normal", also 0
     Fuge <h4> -> ".scrollable"                0,00 px
     Fuge ".scrollable" -> ".button-container" 0,00 px
     Fuge zwischen zwei Knoepfen               6,00 px
     Innenabstand bis zum Inhalt               21 px je Seite (20 + 1px Rahmen)
     Inhaltsbreite bei 400px Dialog            358 px

   -- SCHRITT 1: EXISTIERT DIE FUGE SCHON? ZWEIMAL NEIN, EINMAL JA -------

   Die Lehre aus "07 Chat & AI" Teil B: "Legacy setzt kein gap" kann
   WOERTLICH stimmen und trotzdem in die Irre fuehren, weil die Fuge als
   "margin" an einem KIND liegt und ein blosses "gap" sich darauf addiert.
   Dort waren es 36px statt 16 und eine Knopfreihe 10px unter ihrem Kasten.
   Deshalb hier zuerst gemessen, dann geschrieben:

   1. ZWISCHEN DEN DREI TEILEN GIBT ES KEINE FUGE -- beide Abstaende sind
      0,00 px, und das ist kein Zufall, sondern erzwungen: ".dialog h4"
      setzt "margin: 0" (webapp.css:1089), ".dialog .scrollable"
      "margin: 0 !important" (:1078), ".dialog .button-container"
      "margin: 0 !important" (:1121). "gap: 16" landet hier EXAKT; eine
      zweite, zuruecknehmende Deklaration waere ueberfluessig. Gemessen mit
      der Regel: 16,00 / 16,00.

   2. IN DER FUSSZEILE GIBT ES SIE SEHR WOHL -- 6,00 px, und sie kommt aus
      "button { margin-right: 6px }" (webapp.css:844 ff.), dem NACKTEN
      Elementselektor, der jeden Knopf der Anwendung trifft. Ein blosses
      "gap: 8" ergaebe dort 14. Gemessen, nicht gerechnet: mit der dritten
      Regel unten 8,00 px, ohne sie 14,00 px. DAS IST DIE ZWEITE
      DEKLARATION, die dieser Fall verlangt, und sie gehoert in denselben
      Commit wie das "gap".

      SIE TRITT DABEI NICHT GEGEN DIE "!important" DES BESTANDS AN, und das
      ist nachgeprueft statt geglaubt: ".dialog .button-container" setzt
      "padding" und "margin" mit "!important", aber auf dem CONTAINER, nicht
      auf den Knoepfen -- und "gap" setzt es ueberhaupt nicht. Die
      Knopfregel steht bei (0,3,1), "button" bei (0,0,1) und "button.image"
      (webapp.css:869, Quelle der 40px-Hoehe) bei (0,1,1); sie gewinnt ohne
      ein eigenes "!important".

   3. EIN BEFUND, DER DIESEM TEILPROJEKT NICHT GEHOERT: die Fuge zwischen
      dem Inhalt und dem SICHTBAREN Knopf ist im Bestand -10,00 px. Der
      Knopf ist 40px hoch ("button.image") und steckt in einer 30px hohen
      Reihe (".button-container", webapp.css:1544) mit "align-items:
      center"; er ragt also 10px nach oben aus seiner eigenen Reihe heraus.
      Mit "gap: 16" wird daraus +6,00 px: die Kaestchen stehen exakt 16
      auseinander, das Auge sieht 6. Das zu beheben hiesse, Hoehe oder
      "margin-bottom" des Knopfes zu aendern -- und der Knopf gehoert
      "04 Core" (Spec 3: "Knoepfe gehoeren 04 Core"). GEMELDET, NICHT
      GEFLICKT.

   -- SCHRITT 2: WAS DER WAAGERECHTE ZUWACHS DEM INHALT NIMMT ------------

   ".dialog" traegt "box-sizing: border-box" UND "overflow: hidden
   !important"; 20 -> 24 waechst also nach INNEN. Gemessen an modal-tabs
   (400px breiter Dialog):

     Inhaltsbreite                358 -> 350 px   (-4 je Seite)
     ".tab-widget" -- die Reiterleiste, die ein Dialog TATSAECHLICH baut
                                  318 -> 310 px
     aktiver Tabkoerper           318 -> 310 px
     ".scrollable" (Hoehe)        408 -> 379 px

   KEIN UEBERLAUF ENTSTEHT: "scrollWidth - clientWidth" ist an Dialog,
   ".scrollable", Reiterleiste und Tabkoerper vorher wie nachher 0, und die
   drei Reiter stehen unveraendert nebeneinander.

   Die HOEHE nimmt nicht der Innenabstand (senkrecht +-0), sondern die neue
   Fuge: 2 x 16 px gehen an ".scrollable" -- das einzige Kind mit
   "flex: 1 1 auto; min-height: 0" (webapp.css:1078). In der Galeriekachel
   waechst modal-tabs dabei um 3px, weil der Tabkoerper eine feste Hoehe
   traegt; im echten Dialog deckelt "max-height: ... !important", und die
   32px gehen vollstaendig an den scrollenden Inhalt.

   ".dialog .container-tab-navigation" (webapp.css:1104) IST AN ALLEDEM
   NICHT BETEILIGT, und das ist ein eigener Befund: der einzige Erzeuger
   dieser Klasse ist MoleculeTabContainerNavigation, und der wird an genau
   drei Stellen gebaut -- templatecockpitnavigationaiservice.js:42,
   templatecockpitnavigationchatbot.js:236, templateprojectpanel.js:262 --,
   alle drei Cockpit-PANELE, keines davon in einem Dialog. Die Reiterleiste
   eines Dialogs ist ".tab-widget" (MoleculeTabContainer, so wie
   dialogproject.js:108 sie baut). Die Nachfahrenregeln auf
   ".dialog .container-tab" und ".dialog .container-tab-navigation" treffen
   im heutigen Produkt nichts. GEMELDET, NICHT ANGEFASST -- sie gehoeren
   diesem Teilprojekt nicht.

   -- SCHRITT 3: DER RADIUS GEGEN DIE REITERLEISTE -- KEIN BEFUND --------

   Der Radius springt in der Regel darueber von 8 auf 14, der groesste
   Radius-Sprung des Umbaus. Eine abgerundete Ecke kann nur beschneiden, was
   NAEHER als ihr Radius an der Ecke liegt. Gemessen an modal-tabs: die
   Reiterleiste sitzt 36px von links und 68px von oben innerhalb des
   Rahmens (vorher 32 / 52) -- beide Male weit ausserhalb des 14px-Bogens,
   ihr Ueberlauf bleibt 0. Allgemeiner: der Innenabstand ist in JEDEM Band
   groesser als der Radius (20/24 gegen 14, 18/20 gegen 14, 14/16 gegen 12),
   die Ecke erreicht den Inhalt also grundsaetzlich nicht.

   -- DIE BAENDER: DER INNENABSTAND IST NICHT KONSTANT ------------------

   "--ax-space-5" und "--ax-space-6" stauchen mit der Fensterbreite
   (tokens.css:380 f. und :401 ff.), "--ax-space-2" nicht. Gemessen:

     >= 1025 px   padding 20 / 24   gap 16   Fusszeile 8
     <= 1024 px   padding 18 / 20   gap 16   Fusszeile 8
     <=  768 px   padding 14 / 16   gap 12   Fusszeile 8

   Unterhalb von 1025px ist der Innenabstand also KLEINER als die 20 des
   Bestands, waagerecht wie senkrecht -- Figmas 20/24 kommen dort nicht an.
   Das ist die Absicht der Tokenschicht (Abstaende auf kleinen Schirmen
   stauchen), kein Defekt dieser Regeln, und es ist der Grund, warum hier
   Token und keine Literale stehen. Der Block "Modal: Innenabstand und Fuge
   ueber die Bandgrenzen" in design-modal.spec.ts ist der Waechter darueber;
   er faellt, sobald jemand "20px 24px" oder "16px" literal schreibt.
   Bei der FUSSZEILE waechst kein solcher Waechter: "--ax-space-2" ist in
   allen drei Baendern 8, ein literales "8px" waere dort nicht von ihm zu
   unterscheiden. Der Test sagt das ausdruecklich, statt es zu verschweigen.

   -- JEDE DEKLARATION EINZELN WIDERLEGT (verankerte Textsabotage in dieser
      Datei, je eine Zeile entfernt, Neuladen dazwischen, beide Themes) ---

     ohne "padding"        20px ringsum, Inhaltsbreite wieder 358
     ohne "gap" (16)       "normal", beide Fugen wieder 0,00
     ohne "gap" (8)        "normal", Knopffuge 0,00 -- die Knoepfe BERUEHREN
                           sich, weil die Regel darunter ihr "margin-right"
                           schon genommen hat. Die beiden gehoeren zusammen.
     ohne "margin-right"   Knopffuge 14,00 -- genau 6 + 8, die Falle aus
                           "07 Chat & AI" Teil B, hier gemessen statt
                           befuerchtet.

   Keine der vier Deklarationen ist tot.

   -- LECKPROBE (jede Regel einzeln entscopt, [data-design="new"] ->
      [data-design], spezifitaetserhaltend; gemessen im ALTEN Design) -----

     ".dialog" entscopt        Legacy bekommt padding 20/24 und gap 16,
                               Inhaltsbreite 358 -> 350
     ".button-container"       Legacy bekommt gap 8 -- und die Knopffuge
       entscopt                springt dort auf 14, weil "margin-right: 6px"
                               im alten Design stehen bleibt
     "> button" entscopt       Legacy verliert die 6px, Knopffuge 0

   Alle drei Regeln lecken; keine ist wertgleich mit Legacy, keine braucht
   die Notiz "aendert im alten Design nichts".

   -- WAS DIESER BLOCK BEWUSST NICHT SCHREIBT ---------------------------

     Geometrie              "width", "min-/max-width", "min-/max-height",
                            "position", "top", "left", "transform" und
                            "margin" auf ".dialog" -- entschieden und
                            erledigt (Spec 2a und 4a).
     Knopfhoehe und -radius Figma: 36 hoch, Radius 10. Beides gehoert
                            "04 Core"; siehe Befund 3 oben.
     Titel 18/26            Task 3.
     eigenes "!important"   Es gibt keines. Der Unittest "kein !important"
                            (tests/unit/components-css.test.js) haelt das
                            fuer die ganze Datei fest. */
[data-design="new"] .dialog {
  padding: var(--ax-space-5) var(--ax-space-6);
  gap: var(--ax-space-4);
}

[data-design="new"] .dialog .button-container {
  gap: var(--ax-space-2);
}

[data-design="new"] .dialog .button-container > button {
  margin-right: 0;
}

/* ══ 09 · Overlays & Feedback, Teil A — Titel und Fliesstext ══════════════

   Dritter Regelblock dieses Teilprojekts, dieselbe Reichweite wie die
   beiden darueber: ".dialog" entsteht an EINER Stelle (dialog.js:57-58),
   "Dialog" hat 85 Unterklassen, und der Titel ist an JEDER von ihnen
   dasselbe Element -- ein <h4>, das Dialog.setupUi() (dialog.js:71) als
   erstes direktes Kind anlegt.

   -- DER BESTAND, GEMESSEN (1280x720, Kacheln modal-confirm / modal-tabs /
      modal-long, beide Designs, beide Themes; alle zwoelf Kombinationen
      liefern dieselben Zahlen) ------------------------------------------

     ".dialog > h4"   13,3333px / 20px / 700
     ".dialog p"      13,3333px / 20px / 400, margin 0 oben, 5px unten
     Farbe beider     --clr-text-primary, geerbt von ".dialog"
                      (webapp.css:1060); dunkel rgb(232,230,238), hell
                      rgb(18,17,28) im neuen Design
     Schriftart       im neuen Design bereits Inter (tokens.css:320 ff.)

   Die 13,3333px kommen aus "body { font-size: smaller }" (webapp.css:532),
   die 20px aus "line-height: 20px" eine Zeile darunter (:533), die 700 aus
   dem Browser-Grundstil fuer <h4>. DER TITEL IST HEUTE GENAUSO GROSS WIE
   DER FLIESSTEXT und unterscheidet sich allein im Gewicht -- das ist die
   Luecke, die dieser Block schliesst.

   -- SCHRITT 1: DIE TOKENGROESSE. ES GIBT EIN 18er-TOKEN ----------------

   Brief und Spec (7, zweite gemessene Tatsache) stellen die Aufgabe so:
   "Ein 18px-Schriftgroessen-Token gibt es nicht", am naechsten liege
   "--ax-font-size-body-lg" (17px, Zeilenhoehe 28), zur Wahl stuenden
   literale 18/26, das Token 17/28 oder eine Mischung.

   DAS STIMMT FUER DIE "body"-RAMPE UND UEBERSIEHT DIE ZWEITE:

     --ax-font-size-h4     18px    tokens.css:333
     --ax-line-height-h4   26px    tokens.css:341

   Das ist Figmas 18 / 26 EXAKT, in beiden Zahlen, und es sitzt auf der
   UEBERSCHRIFTEN-Rampe -- also genau dort, wo ein <h4> hingehoert. Der
   Sollwert wird damit nicht angenaehert, sondern getroffen, und er haengt
   trotzdem an einer Bandregel. Die drei Wege des Briefs sind alle drei
   schlechter:

     literal 18px / 26px        trifft die Vorlage, haengt an keiner
                                Bandregel, waechst auf kleinen Schirmen
                                nicht mit
     --ax-font-size-body-lg     17 / 28: 1px kleiner und 2px luftiger als
                                die Vorlage, und die Zeilenhoehe 26
                                erschiene nur UNTERHALB von 769px
                                (tokens.css:399) -- also im falschen Band
     gemischt                   Groesse literal, Zeilenhoehe aus dem
                                Token: erbt beide Nachteile zur Haelfte

   Der Praezedenzfall aus "07 Chat & AI" Teil B (dort wurde literal
   gewaehlt, weil "--ax-size-control-md" unter 769px auf 44 WAECHST, also vom
   Sollwert wegfuehrt) traegt hier nicht: dort fuehrte das Token im schmalen
   Band vom Sollwert weg, hier trifft es ihn in BEIDEN Zahlen und staucht im
   schmalen Band mit, wie die Tokenschicht es ueberall tut. Ein
   Praezedenzfall ist keine Vorschrift, und die Messung geht vor.

   DAS GEWICHT ist Figmas "Semi Bold", also 600. Der Bestand steht auf 700,
   und diese 700 kommen nicht aus webapp.css, sondern aus dem
   Browser-Grundstil ("h4" ist per Grundstil fett). Gemessener
   Gegenversuch: ohne die Zeile steht dort wieder 700.

   -- SCHRITT 2: DIE BANDGRENZEN, GEPRUEFT UND BENANNT -------------------

   Von den vier benutzten Token hat GENAU EINES eine Bandgrenze, und es ist
   dieselbe Schwelle, die in Task 1 schon den Radius gestaucht hat:

     --ax-font-size-h4        18px  ab 769px    17px  bis 768px  (:393)
     --ax-line-height-h4      26px  ab 769px    24px  bis 768px  (:398)
     --ax-font-size-body-sm   13px  IN ALLEN DREI BAENDERN
     --ax-line-height-body-sm 20px  IN ALLEN DREI BAENDERN

   "--ax-font-size-body-sm" und "--ax-line-height-body-sm" werden in KEINER
   der beiden Media-Queries (tokens.css:378 und :389) neu gesetzt -- der
   Fliesstext ist damit der einzige Sollwert dieses ganzen Teilprojekts, der
   in jedem Band exakt ankommt. Innenabstand (Task 2: 20/24 nur oberhalb von
   1024px) und Radius (Task 1: 14 nur oberhalb von 768px) tun das nicht.

   Der Haltepunkt des Tests liegt deshalb AUF der Schwelle, 768 gegen 769,
   nicht daneben; der Block "Modal: Titel und Fliesstext ueber die
   Bandgrenze" in design-modal.spec.ts misst beide Seiten und sichert
   zugleich zu, dass der Fliesstext sich dort NICHT bewegt.

   -- SCHRITT 3: DIE SUBSET-LAGE, AUSDRUECKLICH BENANNT ------------------

   Der vierte blinde Fleck aus "07 Chat & AI" Teil A lautet: "irgendwo
   bestritten" heisst nicht "an dieser Stelle bestritten". Hier heisst das:

     ".dialog h4" (webapp.css:1089)   setzt NUR "flex-shrink" und "margin"
     ".dialog p"  (webapp.css:3325)   setzt NUR "margin-top" und
                                      "margin-bottom"

   "font-size", "line-height", "font-weight" und "color" sind an BEIDEN
   Stellen UNBESTRITTEN -- sie stehen dort nicht, und die gemessenen Werte
   stammen aus Vererbung (body) und aus dem Browser-Grundstil. Die Regeln
   hier sind gescopt und duerfen sie deshalb setzen; sie kehren keine
   Legacy-Schichtung um, weil es an diesen vier Eigenschaften gar keine
   gibt. "flex-shrink" und "margin" werden im Gegenzug NICHT angefasst --
   "margin" ist Geometrie (globale Randbedingung), und "flex-shrink: 0"
   haelt den Titel gegen den scrollenden Inhalt.

   -- ZWEI SELEKTORENTSCHEIDUNGEN, BEIDE GEMESSEN STATT GEAHNT ----------

   Eine Regel auf ".dialog" trifft 85 Unterklassen; eine Regel auf
   ".dialog h4" oder ".dialog p" trifft zusaetzlich JEDE Ueberschrift und
   JEDEN Absatz, den irgendein Dialog irgendwo in seinem Inhalt fuehrt. Der
   schaerfste Fall steht im Produkt: "FilleInput" (userinput.js:343 ff., der
   Import-Dialog) baut eine "MoleculeFileDropZoneSelection" IN den Dialog,
   und die bringt ein eigenes <h4> samt <p> mit -- beide haben im neuen
   Design bereits eigene Regeln (components.css:1324 und :1332). Gemessen
   an einer Sonde in genau dieser Form:

     ".dialog h4" als Nachfahre     Dropzonen-Ueberschrift 15/24 -> 18/26
       statt "> h4"                 (Gleichstand bei (0,2,1), meine Regel
                                    steht spaeter in der Datei und gewinnt)
     ".dialog p" ohne ":where()"    Dropzonen-Hinweis 12px/muted ->
                                    13px/secondary, aus demselben Grund

   BEIDES IST BEHOBEN, UND ZWAR VERSCHIEDEN, weil die Lage verschieden ist:

   1. DER TITEL BEKOMMT DEN KINDKOMBINATOR. Der Dialogtitel ist per
      Konstruktion das erste DIREKTE Kind (dialog.js:71 haengt den
      AtomDisplayHeader4 an den Dialog selbst, nicht an den Inhalt); jede
      andere Ueberschrift eines Dialogs sitzt tiefer. "> h4" trifft damit
      GENAU den Titel und nichts sonst -- die schaerfere und zugleich
      harmlosere Fassung. Gemessen: mit "> h4" bleibt die
      Dropzonen-Ueberschrift bei 15/24/600.

   2. DER FLIESSTEXT BEKOMMT ":where()". Ein <p> hat keine solche
      Sonderstellung -- der Fliesstext eines Bestaetigungsdialogs sitzt in
      "UserMessage.setupDialogUi()" (am AtomDisplayParagraph) zwei Ebenen tief,
      ein Kindkombinator traefe ihn nicht. ":where(p)" senkt die
      Spezifitaet von (0,2,1) auf (0,2,0): hoch genug, um Legacys
      ".dialog p" (0,0,2) und jeden nackten Elementselektor zu schlagen,
      niedrig genug, um jeder Bauteilregel des neuen Designs den Vortritt
      zu lassen. Das ist die Form, die das Entwicklungshandbuch fuer
      Basisregeln vorsieht (Subset-Invariante: ":where()" stellt die
      Schichtung wieder her). Gemessen: mit ":where()" bleibt der
      Dropzonen-Hinweis bei 12px/16px/500/muted.

   -- SCHRITT 4: KONTRASTE, GEGEN DIE GERASTERTE DIALOGFLAECHE ----------

   Gemessen wird gegen die FLAECHE, nicht gegen den Seitengrund und nicht
   gegen den Schleier (Messregel 3), und sie wird GERASTERT (Messregel 2) --
   Task 1 hat sie von einem Verlauf auf eine Flaeche umgestellt, und diese
   Umstellung kostet Textkontrast. Gemessen auf der NEUEN Flaeche, an allen
   drei Kacheln, gebrandet wie ungebrandet (identisch, weil
   brandingapplier.js ausschliesslich "--clr-*"-Wurzeln umhaengt und die
   "--ax-text-*" nicht kennt):

                   Flaeche            Titel     Fliesstext
     dunkel        rgb(26,24,38)      14,124    7,750
     hell          rgb(255,255,255)   18,705    12,306

   Beide Werte liegen in beiden Themes weit ueber 4,5. Der Fliesstext
   verliert durch den Wechsel auf "text/secondary" knapp die Haelfte seines
   Verhaeltnisses (14,124 -> 7,750 dunkel) und bleibt trotzdem deutlich
   ueber der Schwelle.

   -- EIN BEFUND, DER NICHT IN DIESEN BLOCK GEHOERT, ABER HIER AUFFAELLT:
      DIE BESTAETIGUNGSDIALOGE SIND IM NEUEN DESIGN DUNKEL UNLESBAR ------

   Die Kontrastmessung oben gilt fuer Dialoge, deren Flaeche aus der Regel
   kommt. "UserMessage.renderUi()" schreibt aber
   "backgroundColor = white" als INLINE-Stil -- und daran haengt die
   gesamte Bestaetigungsfamilie: UserInput, SecurityQuestion (die
   Rueckfrage, die Dialog selbst bei ungesicherten Aenderungen oeffnet,
   dialog.js:265), Information, LineInput, TextInput, SelectValue,
   FilleInput, BulkResultDialog, ExportOptionsDialog,
   ReorganizeContainerQuestion und DialogSaveChatAsDocument. Dieselbe Zeile
   steht noch zweimal in userinput.js (:235, :387).

   IM BESTAND IST DAS FOLGENLOS, WEIL DIE FLAECHE EIN VERLAUF IST: ein
   Inline-"background-color" legt sich UNTER das "background-image" der
   Regel, und "--card-gradient" ist deckend. Gemessen an einer Sonde mit
   exakt diesen Inline-Stilen:

                      backgroundImage   gerastert        Titelkontrast
     alt / dunkel     linear-gradient   rgb(26,33,45)    13,110
     alt / hell       linear-gradient   rgb(249,251,255) 15,432
     NEU / dunkel     none              rgb(255,255,255) 1,236
     neu / hell       none              rgb(255,255,255) 18,705

   Task 1 hat den Verlauf durch eine FLAECHE ersetzt ("background" als
   Kurzform, damit das Bild zurueckgesetzt wird -- richtig und noetig fuer
   Figmas "bg/elevated"). Genau dieses Zuruecksetzen nimmt dem Inline-Weiss
   seine Abdeckung: im dunklen Theme steht seitdem heller Text
   (--ax-text-primary) auf weissem Grund, Verhaeltnis 1,236.

   WARUM ES HIER NICHT BEHOBEN WIRD, und was zu tun waere:
     - Ein Inline-Stil schlaegt jede Regel. Dagegen anzutreten verlangte
       ein "!important" -- global verboten.
     - Die Zeile selbst steht in Produktionscode (usermessage.js,
       userinput.js), und der ist ausser designgallerypage.js gesperrt.
     - Der Hebel liegt in Task 1s Regel, nicht in dieser: die Flaeche
       muesste wieder als BILDschicht gemalt werden (ein einfarbiger
       Verlauf aus "--ax-bg-elevated"), dann deckt sie das Inline-Weiss ab
       wie der Bestand. Das aendert Task 1s Zusicherung "bgImage: none" und
       ist deshalb eine Entscheidung des Auftraggebers, keine dieses Tasks.
   Der Block "Modal: BEFUND -- Inline-Weiss in der Bestaetigungsfamilie" in
   design-modal.spec.ts haelt den Zustand als Zahl fest, damit er nicht
   still verschwindet oder still bleibt.

   -- WAS DIESER BLOCK BEWUSST NICHT SCHREIBT ---------------------------

     color am Titel        "--clr-text-primary" ist unter
                           [data-design="new"] bereits auf
                           "--ax-text-primary" gebrueckt (tokens.css:159
                           dunkel, :229 hell), und ".dialog" vererbt es an
                           sein direktes Kind. Figmas "text/primary" kommt
                           also schon an. Gemessen: die Zeile
                           "color: var(--ax-text-primary)" aendert an
                           keiner der zwoelf Kombinationen ein Bit -- eine
                           TOTE Deklaration.
     font-family           dito: im neuen Design steht dort bereits
                           "Inter, -apple-system, ..." (tokens.css:320 ff.)
     line-height am        "body" setzt "line-height: 20px" (webapp.css:533)
       Fliesstext          und vererbt damit eine feste Laenge -- und
                           Figmas Sollwert IST 20. Gemessen ebenfalls tot;
                           die Gleichheit ist Zufall und steht deshalb
                           hier, statt als Deklaration getarnt zu werden.
     font-weight am        Figma "Regular", der Bestand steht auf 400.
       Fliesstext          Gemessen tot.
     Geometrie             "margin" (auch am <h4> und am <p>),
                           "flex-shrink", Breiten, Hoehen, Lage --
                           entschieden und erledigt (Spec 2a und 4a).
     Schliessen-Knopf      Spec 4b: das Produkt hat keinen Kopfbereich.
     eigenes "!important"  Es gibt keines; der Unittest "kein !important"
                           (tests/unit/components-css.test.js) haelt das
                           fuer die ganze Datei fest.

   Alle vier "toten" Zeilen wurden nicht weggelassen, sondern GEMESSEN: eine
   Dateivariante MIT allen vieren liefert Zeichen fuer Zeichen dieselben
   Zahlen wie die Fassung unten (beide Designs, dunkel, an der Kachel und an
   der Sonde). Fuer das HELLE Theme deckt das die Bestandsreihe oben ab --
   dort steht der Titel schon auf rgb(18,17,28), also auf
   "--ax-text-primary", und der Fliesstext schon auf 20px/400.

   -- JEDE DEKLARATION EINZELN WIDERLEGT (verankerte Textsabotage in dieser
      Datei, je eine Zeile entfernt, Neuladen dazwischen) ---------------

     ohne Titel "font-size"     13,3333px -- der Rueckfall auf "smaller";
                                die Zeilenhoehe bleibt bei 26
     ohne Titel "line-height"   20px, Titelhoehe 26 -> 20
     ohne Titel "font-weight"   700, der Browser-Grundstil
     ohne Text "color"          rgb(232,230,238) -- text/primary, von
                                ".dialog" geerbt
     ohne Text "font-size"      13,3333px

   Keine der fuenf Deklarationen ist tot.

   -- LECKPROBE (beide Regeln entscopt, [data-design="new"] ->
      [data-design], spezifitaetserhaltend; gemessen im ALTEN Design) ----

     "> h4" entscopt        Legacy bekommt 18px / 26px / 600, Titelhoehe
                            20 -> 26
     ":where(p)" entscopt   Legacy bekommt 13px; die FARBE bleibt
                            rgb(226,232,240)

   Beide Regeln lecken; keine ist wertgleich mit Legacy. Dass die Farbe
   dabei NICHT leckt, ist derselbe Befund, den Task 1 am Rahmen gemacht hat
   und hier ein zweites Mal bestaetigt: tokens.css fuehrt die FARBtoken nur
   unter [data-design="new"] (:48/:96), die GROESSEN dagegen an ":root"
   (:330 ff.). "var(--ax-text-secondary)" ist im alten Design leer, die
   Deklaration wird ungueltig zur Rechenzeit -- waehrend
   "var(--ax-font-size-body-sm)" dort sehr wohl 13px liefert. Wer eine
   dieser Regeln je entscopt, bekommt zwei verschiedene Arten von Schaden.

   BERICHTIGT IN DER ABNAHME VON TEIL B2 (2026-09-14, nachgeschaerft im
   Abschlussreview). Hier stand bis dahin, die Deklaration werde ungueltig
   "und die Farbe bleibt geerbt". DAS IST NUR DER HALBE SATZ, UND DIE
   ANDERE HAELFTE IST DIE WICHTIGE.

   Eine zur Rechenzeit ungueltige Deklaration ("invalid at computed-value
   time") verhaelt sich wie "unset" -- und "unset" heisst zweierlei:
   VERERBTE Eigenschaften nehmen den GEERBTEN Wert, NICHT VERERBTE ihren
   ANFANGSWERT. Bei "color" (vererbt) ist der geerbte Wert die richtige
   Antwort, und genau deshalb liest sich die alte Formulierung an DIESER
   Regel wie eine Wahrheit. Sie ist aber kein Zufall und kein Sonderfall,
   sondern eine von zwei Haelften -- wer sie verallgemeinert, sagt fuer
   jede kuenftige Regel auf einem GROESSEN-Token den falschen Schaden
   voraus: "line-height: var(--leer)" behaelt die 44px des Elternteils und
   faellt NICHT auf "normal" (gegengemessen).

   Fuer die nicht vererbten Eigenschaften ist derselbe Vorgang sichtbarer
   Schaden, und Teil B2 hat ihn gemessen: entscopt bekommt die Toastkarte
   "background" -> "rgba(0, 0, 0, 0)" (durchsichtig) und "border-color" ->
   "currentColor" (Task 1). Dass es wirklich "currentColor" ist und nicht
   irgendein Grau, belegt der gebrandete Gegenversuch an einer
   Nicht-"color"-Eigenschaft: dort steht rgb(0, 255, 0), der grelle
   Marker, den setzeOrgfarbe() auf "--clr-text-primary" legt (Task 2).
   Die vollstaendige Fassung steht im Block "Toast (09 Overlays &
   Feedback, Teil B2, Task 1)" weiter unten, Leckprobe der Karten-Regel.

   -- SPEZIFITAET UND NACHBARSCHAFT -------------------------------------

     [data-design="new"] .dialog > h4        (0,2,1)
     ".dialog h4" (webapp.css:1089)          (0,0,2)   verliert
     [data-design="new"] .upload-dropzone h4 (0,2,1)   trifft den Titel
                                                       nicht (Kind)

     [data-design="new"] .dialog :where(p)   (0,2,0)
     ".dialog p" (webapp.css:3325)           (0,0,2)   verliert
     ".message-text" (webapp.css:2539)       (0,1,0)   setzt keine der
                                                       beiden Eigenschaften
     [data-design="new"] .upload-dropzone p  (0,2,1)   gewinnt, gewollt

   Kein Gleichstand, den dieser Block gewaenne, ohne es zu wollen. Die
   sechs "!important" des Bestands liegen auf "max-height"/"overflow"
   (:1054 ff.) und in vier Nachfahrenregeln -- keine der fuenf
   Eigenschaften hier tritt gegen eines von ihnen an. Und die drei
   Inline-Stile aus Dialog.renderUi() (dialog.js:59-62, z-index/max-height/
   margin-top) beruehren keine davon; das Inline-Weiss der
   Bestaetigungsfamilie sehr wohl, aber es trifft die FLAECHE, nicht den
   Text -- siehe den Befund oben.

   Ein @media-Block wird hier nicht gebraucht: beide Baender stecken in den
   Token. */
/* NACHTRAG (T2, Task 3 -- "Der Dialogtitel wandert in die Toenung"): DER
   KINDKOMBINATOR HAT EINE ZWEITE ADRESSE BEKOMMEN, UND ZWAR NOTGEDRUNGEN.

   Die Begruendung darueber sagt, der Dialogtitel sei "per Konstruktion das
   erste DIREKTE Kind". Das galt, solange ihn ausschliesslich
   "Dialog.setupUi()" anlegte. Seit Task 3 legen ihn die drei
   Meldungsfamilien (Information, Warning, ErrorMsg) eine Ebene tiefer an --
   im senkrechten Behaelter INNERHALB der getoenten ".container-message",
   weil Figmas Alert (114:102) Titel und Text gemeinsam auf der Toenung
   fuehrt. "> h4" trifft ihn dort nicht mehr.

   DER SCHADEN IST GEMESSEN, NICHT BEFUERCHTET. Am echten Dialog, neues
   Design, dunkles Theme, 1280px, mit dem verschobenen Titel und OHNE diese
   zweite Zeile:

     font-size     18px  ->  13.3333px
     line-height   26px  ->  20px
     font-weight   600   ->  700

   Das sind die Werte des BROWSER-Grundstils: ohne den Kindkombinator faengt
   den Titel gar nichts mehr auf -- ".dialog h4" (webapp.css:1089) setzt nur
   "flex-shrink" und "margin". Der Umzug haette die Titeltypografie also
   still verloren.

   WARUM DIE NACHFAHRENFORM HIER HARMLOS IST -- dieselbe Pruefung wie oben,
   nur an einem viel kleineren Wirt: ".container-message" entsteht an EINER
   Stelle ("UserMessage.setupDialogUi()") und enthaelt genau das
   Meldungsbild, den senkrechten Behaelter mit Fliesstext und das, was
   "addInputField()" dort ergaenzt. Gemessen ueber alle vierzehn Erzeuger
   der Familie: KEIN einziger setzt ein <h4> hinein -- der einzige weitere
   Titel dort ist ein <h3> ("BulkResultDialog", userinput.js:554), den
   diese Regel nicht anfasst. Die Dropzonen-Ueberschrift, wegen der oben
   der Kindkombinator gewaehlt wurde, sitzt in "FilleInput", und das baut
   gar keine ".container-message".

   SPEZIFITAET: (0,3,1) gegen die (0,2,1) der Zeile darueber -- beide
   setzen dieselben drei Eigenschaften auf dieselben Werte, ein
   Zusammentreffen gibt es nicht (ein Titel ist entweder direktes Kind oder
   im Meldungsblock, nie beides). */
[data-design="new"] .dialog > h4,
[data-design="new"] .dialog .container-message h4 {
  font-size: var(--ax-font-size-h4);
  line-height: var(--ax-line-height-h4);
  font-weight: 600;
}

/* --- Der verschobene Titel nimmt die volle Breite seiner Spalte ----------

   NACHGEMESSEN NACH DEM UMZUG, und dabei gefunden: der Titel stand nicht
   da, wo Figma ihn fuehrt. ".container-top-bottom" (webapp.css:2443)
   traegt "align-items: center" -- ein Block, den man dort hineinsetzt,
   schrumpft auf seine Inhaltsbreite und wird ZENTRIERT. Gemessen am echten
   Dialog, neues Design, dunkles Theme, 1280px:

     Titel   x=620  Breite 153   <- zentriert, schrumpfend
     Text    x=504  Breite 384   <- volle Spaltenbreite

   116px Versatz gegen den Fliesstext. Figma 114:102 fuehrt BEIDE mit
   derselben linken Kante und derselben Breite: "title" (114:105) ist
   360x24 bei x=0, "body" (114:106) 360x40 bei x=0 -- beide so breit wie
   ihr Rahmen "text" (114:104). Der Titel gehoert also auf die volle
   Spaltenbreite, links buendig mit dem Text.

   "align-self" STATT "width: 100%": beides richtet den Kasten aus, aber
   "width" muesste gegen den Innenabstand des Behaelters rechnen (10px
   ringsum, webapp.css:2445) und wieder nachgezogen werden, sobald der sich
   aendert; "stretch" ueberlaesst das dem Flex-Algorithmus. Die Eigenschaft
   ist am Titel UNBESTRITTEN -- ".dialog h4" (webapp.css:1089) setzt nur
   "flex-shrink" und "margin", einen Ausrichtungswert setzt dort nichts.

   NUR DER VERSCHOBENE TITEL, nicht der Titel oben: ein direktes Kind von
   ".dialog" streckt sich ohnehin schon (gemessen 550 = volle Dialogbreite,
   ".dialog" erbt "align-items: stretch"). Eine gemeinsame Regel waere dort
   folgenlos -- aber eine folgenlose Deklaration gehoert nicht in die
   Datei. */
[data-design="new"] .dialog .container-message h4 {
  align-self: stretch;
}

[data-design="new"] .dialog :where(p) {
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-body-sm);
}

/* --- Toast (09 Overlays & Feedback, Teil B2, Task 1) ---------------------

   Figma-Knoten 114:101 ("Toast"), Erzeuger im Produkt:
   OrganismsNotificationBanner.render() (organismsnotificationbanner.js:24-76),
   Bestand webapp.css:12792-12801. EIN Erzeuger, aber auf JEDER Cockpit-Seite
   sichtbar, sobald eine ungelesene Nachricht vorliegt.

   -- GEMESSENER BESTAND (Elterncommit 60c1e60d1, 1280x720, Cockpit-Nutzer
      der gebrandeten Entwicklungsorganisation, Kachel "toast-default") -----

     Eigenschaft     legacy/dunkel        legacy/hell        neu/dunkel
     ------------------------------------------------------------------
     Stapelbreite    360                  360                360
     Flaeche         srgb .0988/.1278/    srgb .9767/.9822/  srgb .0988/
                     .1725 (gerastert     1 (gerastert       .0933/.1459
                     25/33/44)            249/250/255)       (25/24/37)
     borderTopColor  rgb(33,38,45)        rgb(199,210,254)   rgb(36,34,51)
     borderLeftColor rgb(255,85,0)        rgb(255,85,0)      rgb(255,85,0)
                     -- die ORGANISATIONSfarbe, in allen drei Faellen
     Radius          6                    6                  6
     padding         8 / 12 / 8 / 12      dito               dito
     box-shadow      0 4px 16px rgba(0,0,0,.35), in allen drei Faellen
     Titel (strong)  13,3333 / 20 / 700, Farbe = Kartenfarbe (geerbt)
     Sub             12 / 20 / 400, Farbe "--clr-text-muted", eine
                     color-mix()-Mischung -> serialisiert als "color(srgb ...)"
     Body            13,3333 / 20 / 400, Farbe = Kartenfarbe (geerbt) --
                     ".notification-banner-body.notification-markdown", die
                     Vorschau des Nachrichtentexts. DIESER BLOCK FASST SIE
                     NICHT AN, siehe unten.
     gap (Karte)     12  -- Figmas Wert, schon im Bestand richtig
     gap (Stapel)     8  -- Figma fuehrt dazu nichts (114:101 ist EINE Karte,
                            kein Stapel); bleibt unangetastet
     max-width       calc(100vw - 32px), max-height calc(100vh - 32px)

   ZWEI BEOBACHTUNGEN AUS DIESER REIHE, beide tragen Entscheidungen unten:

   1. "--background-color-card" und "--clr-border" sind im NEUEN Design
      bereits ueber die Bruecke (tokens.css:147 ff.) umgehaengt --
      "--clr-border" zeigt dort auf "--ax-border-default" selbst. Die
      Rahmenfarbe unten ist deshalb UNGEBRANDET wertgleich mit dem Bestand
      und wird erst GEBRANDET wirksam: brandingapplier.js haengt
      "--clr-border" auf die Organisationsfarbe um (brandingapplier.js:13),
      "--ax-border-default" nicht. Die Zeile ist also kein Schmuck, sondern
      der Entzug der Organisationsfarbe vom Rahmen -- genau wie beim Modal.
      Der Gegenversuch dazu steht deshalb in der GEBRANDETEN Konfiguration.

   2. Die Flaeche ist hier KEINE Bildschicht, anders als beim Modal. Der
      Bestand setzt "background: var(--background-color-card)", eine nackte
      Farbe ohne Verlauf ("backgroundImage: none", gemessen), und kein
      Erzeuger schreibt der Karte ein Inline-Weiss vor ("UserMessage.renderUi()"
      betrifft die Dialogfamilie, nicht den Banner). Eine nackte Farbe genuegt
      also; die Zusicherung "backgroundImage bleibt none" haelt fest, dass
      sich daran nichts geaendert hat.

   -- BANDGRENZEN JEDES BENUTZTEN TOKENS (tokens.css:378/389) --------------

     --ax-radius-md        10 in ALLEN drei Baendern. Nur "lg" und "xl"
                           stauchen unter 769px (tokens.css:405) -- "md"
                           nicht. Figmas 10 kommt ueberall an.
     --ax-shadow-card      0 4px 20px rgba(0,0,0,.28) in allen Baendern;
                           steht nicht in einem @media-Block. Figmas Wert
                           woertlich.
     --ax-font-size-body-md / --ax-line-height-body-md   15 / 24, in allen
                           Baendern. Der 768er-Block stuft nur display-1 bis
                           h4 und body-lg ab, body-md nicht.
     --ax-font-size-label-sm / --ax-line-height-label-sm  12 / 16, in allen
                           Baendern; im 768er-Block ebenfalls nicht genannt.
     --ax-space-3          12 ab 769px -- UNTER 769px 10 (tokens.css:401).
     --ax-space-4          16 ab 769px -- UNTER 769px 12 (tokens.css:401).

     DAS EINZIGE TOKEN MIT BANDGRENZE IST DAMIT DER INNENABSTAND: Figmas
     12/12/12/16 kommt in ZWEI der drei Baender an (ab 1025px und im
     769-1024er Band, das space-3/space-4 gar nicht anfasst) und wird unter
     769px zu 10/10/10/12. Das ist die Absicht der Tokenschicht -- ein
     schmaler Schirm bekommt weniger Luft -- und ausdruecklich KEIN
     @media-Block hier: die Staffelung steckt schon im Token. Der eigene
     Testblock "Toast: der Innenabstand ueber die Bandgrenze" sichert beide
     Seiten der Grenze, damit die Stauchung eine gemessene Zusage ist und
     keine Ueberraschung.

   -- DIE STAPELBREITE 360 -> 380 IST EINE ENTSCHEIDUNG ------------------

     Der Stapel ist "position: fixed; top: 16px; right: 16px" und damit die
     einzige Flaeche dieses Teilprojekts, die am FENSTER haengt statt im
     Fluss zu stehen. Der Bestand deckelt sie mit
     "max-width: calc(100vw - 32px)".

     GEMESSEN, an einem echten Stapel an <body>, Breite fuer Breite:

       Fensterbreite   360er Stapel      380er Stapel (neu)
       -------------------------------------------------------
       1280            360, links 904    380, links 884
        769            360, links 393    380, links 373
        412            360, links  36    380, links  16   <- Deckel trifft
        411            360, links  35    379, links  16      genau auf
        392            360, links  16    360, links  16
        391            359, links  16    359, links  16

     DER DECKEL GREIFT BEIM NEUEN WERT AB 411px FENSTERBREITE (beim alten ab
     391). In beiden Faellen bleibt der Abstand zum linken und rechten
     Fensterrand bei genau 16px -- der Stapel laeuft NIE ueber den Rand
     hinaus, der Deckel tut also genau das, wofuer er da ist. Unter 412px
     sind alte und neue Fassung ohnehin gleich breit, weil beide am Deckel
     haengen: die Aenderung ist dort WIRKUNGSLOS, nicht schaedlich.

     KOLLIDIERT ETWAS? Nein. Der Stapel waechst ausschliesslich nach LINKS
     (der rechte Rand ist auf 16px festgenagelt), und links von ihm liegt
     Seiteninhalt, den er als Overlay mit z-index 2000 ohnehin verdeckt --
     20px mehr davon. Ein zweites fixiertes Element am oberen rechten Rand
     gibt es nicht; die Navigationsleiste steht links.

   -- TITEL UND FLIESSTEXT ------------------------------------------------

     Figma setzt Titel 15/24 Semi Bold "text/primary" und Text 12/16 Medium
     "text/secondary". Der Titel ist im Produkt ein nacktes <strong> ohne
     eigene Regel; "font-size", "line-height", "font-weight" und "color" sind
     dort also UNBESTRITTEN -- gescopt zulaessig, hier benannt (Regel 3 des
     Teilprojekts). Die Farbe ist ungebrandet wertgleich mit der geerbten
     Kartenfarbe und zieht, wie der Rahmen, erst GEBRANDET
     ("--font-color-card" haengt ueber "--clr-text-primary" an der
     Organisationsfarbe, brandingapplier.js:14).

     DIE DRITTE TEXTZEILE BLEIBT LEGACY, UND DAS IST EINE ENTSCHEIDUNG.
     ".notification-banner-body.notification-markdown" -- die Vorschau des
     Nachrichtentexts, organismsnotificationbanner.js:51 -- steht in keiner
     Regel dieses Blocks. Figmas "114:101" fuehrt genau ZWEI Textstufen
     ("Title" und "Text"), und die zweite ist hier auf die ABSENDERzeile
     gelegt, weil sie Figmas Position einnimmt. Fuer eine dritte Stufe gibt
     es in der Vorlage keinen Sollwert, und einen zu erfinden waere
     Gestaltung ohne Auftrag.

     DER PREIS IST BENANNT: die Vorschau bleibt bei 13,3333/20/400 in der
     geerbten Kartenfarbe ("text/primary") und ist damit FARBLICH
     PROMINENTER als die Absenderzeile darueber, die dieser Block auf
     "text/secondary" setzt -- und sie ist die laengste Zeile der Karte.
     Gehoert in die Sichtpruefung; die Entscheidung darueber gehoert Figma.

     An ".notification-banner-sub" sind "font-size" und "color" bestritten
     (webapp.css:12800), "line-height" und "font-weight" unbestritten.
     "font-size" steht hier NICHT: der Bestand setzt bereits 12px und
     "--ax-font-size-label-sm" ist in jedem Band ebenfalls 12 -- die
     Deklaration waere in jeder Konfiguration wertgleich, also tot, und tote
     Deklarationen werden entfernt statt behalten (gemessen, siehe den
     Testblock "die tote Deklaration").

   -- DER RAHMEN: WARUM "border-color" UND NICHT "border" -----------------

     Der Bestand traegt an der Karte ZWEI Rahmenangaben (webapp.css:12795):
     "border: 1px solid var(--clr-border)" UND
     "border-left: 4px solid var(--clr-accent)". Figmas Sollwert lautet
     "Rahmen 1px border/default" -- als KURZFORM geschrieben setzte er alle
     vier Seiten und loeschte damit den 4px-Akzent, das einzige Bauteil, das
     die Absicht der Nachricht traegt (Vorhaben B1 liefert dafuer die Klasse
     "notification-banner-card--<absicht>", noch ohne Farbe).

     Deshalb steht hier "border-color" (nur die Farbe, Breite und Stil
     bleiben aus Legacys Kurzform) und stand unmittelbar danach
     "border-left-color: var(--clr-accent)". Die zweite Zeile war KEINE
     Redundanz: ohne sie faerbte "border-color" auch die linke Kante grau.
     Nachgemessen in allen vier Konfigurationen -- eine Fassung ohne sie
     liefert borderLeftColor rgb(36,34,51) statt rgb(255,85,0), also einen
     verschwundenen Akzent.

     TASK 2 HAT GENAU DIESE EINE ZEILE ERSETZT -- durch vier gescopte
     Fassungen je Absicht, im eigenen Abschnitt unten. Die Aussagen dieses
     Absatzes bleiben stehen, weil sie erklaeren, warum "border-color" und
     nicht die Kurzform "border" dasteht; nur der Traeger der linken Kante
     ist ab Task 2 die Absicht statt der Organisation.

   -- SUBSET-INVARIANTE JE EIGENSCHAFT ------------------------------------

     ".notification-banner-stack" (webapp.css:12792) deklariert selbst
     position/top/right/z-index/display/flex-direction/gap/width/max-width/
     max-height/overflow-y. Gesetzt wird hier nur "width" -- bestritten.

     ".notification-banner-card" (webapp.css:12795) deklariert selbst
     display/justify-content/align-items/gap/background/color/border/
     border-left/border-radius/padding/box-shadow. Gesetzt werden hier
     background/border-color/border-radius/padding/box-shadow -- alle fuenf
     bestritten, keine neue Eigenschaft. ("border-left-color" stand hier bis
     Task 2 als sechste und ist in dessen Abschnitt gewandert; auch dort
     bestritten.)

     ".notification-banner-text > strong" hat im Bestand GAR KEINE Regel;
     alle vier Eigenschaften unbestritten (benannt, siehe oben).
     ".notification-banner-sub" (webapp.css:12800): "color" bestritten,
     "line-height" und "font-weight" unbestritten (benannt).

   -- LECKPROBE (jede Regel einzeln entscopt, [data-design="new"] ->
      [data-design], spezifitaetserhaltend; gemessen im ALTEN Design,
      dunkel, gebrandete Organisation) ------------------------------------

     Stapel-Regel   leckt: Breite 360 -> 380 (ein Literal, kein Token).
     Karten-Regel   leckt VOLLSTAENDIG, und das ist NICHT, was der
                    Modal-Umbau erwarten liess:
                      Radius 6 -> 10, padding 8/12/8/12 -> 12/12/12/16,
                      Schatten -> 0 4px 20px rgba(0,0,0,.28)
                        (Groessen- und Schattentoken stehen an ":root",
                         tokens.css:330 ff. -- soweit erwartet)
                      FLAECHE  srgb .0988/.1278/.1725 -> "rgba(0, 0, 0, 0)"
                      RAHMEN   rgb(33,38,45) -> rgb(226,232,240)
                    Die Legacy-Werte bleiben also NICHT stehen. Ein var()
                    ohne Wert macht die Deklaration nicht "unwirksam",
                    sondern UNGUELTIG ZUR RECHENZEIT -- die Eigenschaft
                    faellt dann auf ihren Anfangs- bzw. geerbten Wert
                    zurueck und ueberschreibt die Kaskade dabei
                    ("background" -> durchsichtig, "border-color" ->
                    "currentColor", hier die geerbte Textfarbe). Die
                    Formulierung aus dem Modal-Teilprojekt ("die
                    Deklaration wird ungueltig und die Farbe bleibt
                    geerbt") stimmt nur fuer VERERBTE Eigenschaften wie
                    "color".
                    Das ist kein Zufall und keine Eigenheit von
                    "color", sondern die Regel: eine zur Rechenzeit
                    ungueltige Deklaration verhaelt sich wie "unset" --
                    VERERBTE Eigenschaften nehmen den GEERBTEN Wert, NICHT
                    VERERBTE ihren ANFANGSWERT. Gegengemessen an einem Kind
                    mit "line-height: var(--leer)" unter einem Elternteil
                    mit "line-height: 44px": das Kind behaelt die 44px, es
                    faellt NICHT auf "normal". Fuer "background-color" und
                    "border-color" -- beide nicht vererbt -- ist derselbe
                    Vorgang sichtbarer Schaden. GEMESSEN, nicht uebernommen.
                    (Die damals mitgemessene Zeile
                    "border-left-color: var(--clr-accent)" war im alten
                    Design wertgleich mit dem Bestand, weil sie dieselbe
                    Variable benutzte. Sie steht seit Task 2 nicht mehr in
                    dieser Regel; dessen vier Nachfolger benutzen "--ax-*"-
                    Token und lecken deshalb ZERSTOEREND -- siehe die
                    Leckprobe im Abschnitt von Task 2.)
     Titel-Regel    leckt: 13,3333/20/700 -> 15/24/600. Die FARBE bleibt
                    rgb(226,232,240) -- aber nicht, weil die Deklaration
                    wirkungslos waere, sondern weil "color" VERERBT ist und
                    deshalb auf den geerbten Wert faellt; dass der hier
                    zugleich Legacys Wert ist, ist die Zufallshaelfte daran.
                    Kein Freibrief.
     Sub-Regel      leckt: 20/400 -> 16/500 UND die Farbe
                    srgb .6369/.6682/.7059 -> rgb(226,232,240): der
                    Rueckfall auf den geerbten Wert loescht hier den
                    gedaempften Ton des Bestands. Genau der Fall, den die
                    Titel-Regel nur deshalb nicht zeigt, weil ihr Bestand
                    ohnehin die geerbte Farbe war.

     Keine der vier Regeln ist wertgleich mit Legacy; entscopt richtet jede
     Schaden an, drei davon sichtbar.

   -- SPEZIFITAET UND NACHBARSCHAFT ---------------------------------------

     [data-design="new"] .notification-banner-stack       (0,2,0)
     ".notification-banner-stack" (webapp.css:12792)      (0,1,0)  verliert
     [data-design="new"] .notification-banner-card        (0,2,0)
     ".notification-banner-card" (webapp.css:12795)       (0,1,0)  verliert
     [data-design="new"] .notification-banner-text > strong (0,2,1)
       -- kein Mitbewerber im Bestand
     [data-design="new"] .notification-banner-sub         (0,2,0)
     ".notification-banner-sub" (webapp.css:12800)        (0,1,0)  verliert

     Kein "!important" im Bestand beruehrt eine dieser Eigenschaften, und der
     Erzeuger setzt keinen Inline-Stil auf Stapel oder Karte
     (organismsnotificationbanner.js schreibt ausschliesslich className,
     id, data-testid und innerHTML). Ein @media-Block wird nicht gebraucht:
     die Baender stecken in den Token. */
[data-design="new"] .notification-banner-stack {
  width: 380px;
}

[data-design="new"] .notification-banner-card {
  background: var(--ax-bg-elevated);
  border-color: var(--ax-border-default);
  border-radius: var(--ax-radius-md);
  padding: var(--ax-space-3) var(--ax-space-3) var(--ax-space-3) var(--ax-space-4);
  box-shadow: var(--ax-shadow-card);
}

/* --- Toast: die vier Absichten (Teil B2, Task 2) -------------------------

   DIESE VIER REGELN ERSETZEN GENAU EINE ZEILE VON TASK 1
   ("border-left-color: var(--clr-accent)"), sie treten nicht daneben. Task 1
   hat die Zeile ausdruecklich erhalten, damit sein eigener Commit den Akzent
   nicht voruebergehend grau ausliefert -- "border-color" oben faerbt sonst
   auch die linke Kante. Ab hier traegt die linke Kante die ABSICHT.

   DIE BREITE WIRD NICHT ANGEFASST. Die 4px kommen aus Legacys
   "border-left: 4px solid" (webapp.css:12795) und bleiben, wo sie sind;
   gesetzt wird ausschliesslich "border-left-color". Figma zeichnet den
   Akzent als Kindelement (Rechteck 3 x 20, Radius full, senkrecht zentriert)
   -- das waere Markup und damit Produktionscode, den dieses Vorhaben nicht
   schreibt (Spec 4a). Die bewusste Abweichung gehoert in die Sichtpruefung.

   -- WOHER DIE KLASSE KOMMT ----------------------------------------------

     Vorhaben B1 haengt an jede Karte GENAU EINE Zustandsklasse
     ("notification-banner-card--" + intentModifier(it.intent),
     organismsnotificationbanner.js:43). intentModifier() kennt vier Werte
     und faellt bei allem anderen auf "info" zurueck
     (notificationintent.js:21-27) -- es gibt also keine Karte ohne Klasse
     und keine mit einer fuenften. Genau deshalb darf die Bestandszeile
     ersatzlos weichen: jede Karte wird von einer der vier Regeln unten
     getroffen.

     ACHTUNG BEIM MESSEN AM PRODUKT: ein Backend, das das Feld "intent" noch
     nicht liefert, laesst intentModifier() auf "info" zurueckfallen -- dann
     sind ALLE Karten blau, und ein Test daran sichert nichts (Spec, Regel
     7). Die Galeriekachel "toast-intents" setzt die vier Klassen deshalb
     SELBST und haengt nicht am Backend; der Nachweis am echten Toast steht
     in tests/features/notifications.spec.ts (B1) und ist fuer diesen Task
     zusaetzlich gegen ein Backend nachgemessen worden, das "intent" liefert.

   -- SOLLWERTE (Spec 2b) UND IHRE ZAHLEN ---------------------------------

     Absicht   Token                    dunkel     hell
     --------------------------------------------------
     info      --ax-action-primary      #009fe3    (#009fe3)
       hell abweichend:  --ax-text-link            #007ab0
       -- Begruendung im eigenen Kommentar unten; die Klammer steht fuer den
          Sollwert der Spec, der im hellen Theme NICHT ausgeliefert wird.
       -- BERICHTIGT MIT T1 (2026-09-15, nachgetragen im Abschlussreview):
          DIE ZEILE "hell abweichend" BESCHREIBT KEINE ABWEICHUNG MEHR.
          "--ax-action-primary" steht im hellen Theme seit T1 selbst auf
          cyan/600; die Klammer "(#009fe3)" ist damit widerlegt, nicht bloss
          veraltet -- der helle Sollwert der Spec IST heute #007ab0 und wird
          ausgeliefert. Der Toast traegt hell unveraendert #007ab0, jetzt
          ueber Figmas eigenen Tokenpfad statt ueber eine Sonderregel.
          Die Sonderregel selbst ist mit T1 gefallen; an ihrer Stelle steht
          weiter unten ein "HIER STAND"-Block. Der alte Text bleibt hier
          stehen, weil er die Vorgeschichte der Zahl traegt.
          (Derselbe Vermerk steht als GEHEILT-Zusatz an Abweichung 3 in
          docs/manual/entwicklungshandbuch/14-frontend.md -- die Tabelle
          dort hat ihn bekommen, dieser Kommentar hatte ihn nicht.)
     success   --ax-status-success      #4ade80    #16a34a
     warning   --ax-status-warning      #fcd34d    #d97706
     danger    --ax-status-danger       #ef4444    #dc2626

     KEINES DER VIER TOKEN HAT EINE BANDGRENZE, und das ist gemessen und
     nicht geglaubt: bei 1280, 1024, 769, 768 und 360 liefern alle vier
     denselben Wert, "--ax-bg-elevated" (der Bezug der Kontrastmessung)
     ebenso. Kein @media-Block noetig.

   -- SCHRITT 2: JEDE FARBE GEGEN DIE FLAECHE, GERASTERT, BEIDE THEMES -----

     Schwelle 3,0 (Messregel 5) -- der Akzent ist ein Bedeutungstraeger, kein
     Text, also WCAG 1.4.11 und nicht 1.4.3.

       Theme    info    success  warning  danger
       -----------------------------------------
       dunkel   5,878   10,021   12,111   4,640
       hell     4,761    3,296    3,186   4,829

     DIE 4,761 IM HELLEN THEME SIND DAS ERGEBNIS DER NACHBESSERUNG. Der
     Sollwert der Spec ("--ax-action-primary") liefert dort 2,971 -- unter der
     Schwelle UND unter dem Bestand; die themegescopte Hellregel weiter unten
     stellt den Wert wieder her, den die Bruecke fuer diese Frage gewaehlt hat.
     Die Herleitung steht vollstaendig in ihrem eigenen Kommentar.

     BERICHTIGT MIT T1 (2026-09-15, nachgetragen im Abschlussreview): DIESE
     HELLREGEL GIBT ES NICHT MEHR, und der Satz oben verweist ins Leere. Die
     4,761 im hellen Theme stehen unveraendert, aber sie kommen heute aus dem
     FUNDAMENT: "--ax-action-primary" ist im hellen Theme seit T1 selbst
     cyan/600, die Grundregel liefert den Wert also von sich aus. Auch der
     zweite Satz ist widerlegt, nicht bloss veraltet -- der Sollwert der Spec
     liefert hell keine 2,971 mehr. An der Stelle der gefallenen Regel steht
     weiter unten ein "HIER STAND"-Block mit der vollstaendigen Herleitung und
     der zweiseitigen Messung; DORT ist die Herleitung nachzulesen, nicht mehr
     "in ihrem eigenen Kommentar". Die Zeilen oben bleiben stehen, weil sie
     erklaeren, WARUM die Zahl 4,761 und nicht 2,971 heisst.

     ZWEI WERTE HALTEN NUR KNAPP: "success" 3,296 und "warning" 3,186 im
     hellen Theme. Beide ueber 3,0, beide bleiben auf Figmas Wert -- aber sie
     haben keine Reserve, und eine hellere Flaeche als Weiss gibt es nicht.
     Gehoert in die Sichtpruefung, damit niemand sie fuer komfortabel haelt.

   -- SCHRITT 3: DIE VIER FARBEN GEGENEINANDER (der Zweck des Tasks) ------

     dE nach CIE76, gerastert, beide Themes. Zwei Absichten, die sich nicht
     unterscheiden lassen, machen den ganzen Weg von B1 durch Datenbank,
     Backend und Oberflaeche wertlos.

       Paar               dunkel   hell
       ---------------------------------
       info/success        94,5     86,7
       info/warning       115,6    110,8
       info/danger        112,1    112,3
       success/warning     69,3     91,7
       success/danger     126,6    122,4
       warning/danger      77,0     41,3   <- der kleinste Abstand

     Der kleinste Abstand ist 41,3 (Warnung gegen Gefahr im hellen Theme,
     amber/600 gegen red/600) und damit das Achtzehnfache der Schwelle 2,3.
     Nichts liegt knapp.

     DIE DREI HELLEN "info"-ABSTAENDE STEHEN HIER MIT DER HELLREGEL (cyan/600).
     Mit Figmas cyan/500 waeren es 91,5 / 117,8 / 120,1 -- die Regel rueckt
     "--info" also naeher an die drei anderen, aber der kleinste der drei
     bleibt 86,7. Der kleinste Abstand UEBERHAUPT (41,3) ist von ihr gar nicht
     beruehrt, weil "--info" daran nicht beteiligt ist. Kein Zielkonflikt
     zwischen Kontrast und Unterscheidbarkeit -- beide Zahlenreihen gemessen.

   -- GEGENVERSUCHE: KEINE DER VIER DEKLARATIONEN IST TOT -----------------

     Verankerte Textsabotage in dieser Datei, je EINE Regel entfernt,
     Neuladen dazwischen, gemessen an der Kachel "toast-intents". Die je drei
     anderen Karten bleiben dabei unveraendert -- die Meldung trifft genau
     die sabotierte:

       entfernt      neu/dunkel/gebrandet          neu/hell/ungebrandet
       ----------------------------------------------------------------
       --info        rgb(0,159,227)  -> 36,34,51   rgb(0,122,176), unveraendert
       --success     rgb(74,222,128) -> 36,34,51   rgb(22,163,74) -> 210,208,218
       --warning     rgb(252,211,77) -> 36,34,51   rgb(217,119,6) -> 210,208,218
       --danger      rgb(239,68,68)  -> 36,34,51   rgb(220,38,38) -> 210,208,218

     DER RUECKFALL IST NICHT DER BESTANDSAKZENT, sondern
     "--ax-border-default" aus "border-color" der Kartenregel -- weil die
     Bestandszeile oben ersatzlos weg ist. Vier tote Regeln waeren also vier
     graue Kanten, kein blauer Streifen. Fuer "--success", "--warning" und
     "--danger" zieht der Gegenversuch in allen vier Konfigurationen,
     gebrandet wie ungebrandet.

     FUER "--info" NICHT, UND DAS IST DIE FALLE DIESES TASKS. Die Zeile
     oben hat hell KEINE Wirkung, weil die themegescopte Hellregel darunter
     ueber die Spezifitaet gewinnt: entfernt man die Grundfassung, bleibt
     rgb(0,122,176) stehen. Jede der beiden "--info"-Zeilen zieht also in
     genau ZWEI der vier Konfigurationen -- die Grundfassung nur dunkel, die
     Hellregel nur hell. Zusammen decken sie alle vier ab; getrennt gemessen
     sieht jede zur Haelfte tot aus.

     UND UNGEBRANDET IST "--info" SEIT DER NACHBESSERUNG IN BEIDEN THEMES
     WERTGLEICH MIT DEM BESTAND. "--clr-accent" haengt im neuen Design ueber
     die Bruecke dunkel auf "--ax-action-primary" (tokens.css:153) und hell
     auf "--ax-text-link" (:257) -- die beiden neuen Regeln nennen genau
     diese zwei Token direkt. "--info" ist damit ungebrandet NIRGENDS mehr
     sichtbar und lebt ausschliesslich in den beiden GEBRANDETEN
     Konfigurationen (rgb(255,85,0) -> Tokenfarbe). Wer nur ungebrandet
     misst, haelt die Regel fuer tot -- in beiden Themes. VOR der
     Nachbesserung galt das nur fuer das dunkle; die Testdatei fuehrt
     denselben Absatz (design-toast-alert.spec.ts:468-477).

     DAS IST KEIN NEBENEFFEKT, SONDERN DIE ENTSCHEIDUNG: die linke Kante
     gehoert ab hier der ABSICHT und nicht mehr der Organisation. Dieselbe
     Art Entscheidung wie bei "border-color" und der Titelfarbe in Task 1,
     nur zugunsten einer Bedeutung statt eines Tokens.

   -- LECKPROBE (jede Regel einzeln entscopt, [data-design="new"] ->
      [data-design], spezifitaetserhaltend; gemessen im ALTEN Design) ------

     Alle vier lecken, und zwar zerstoerend: die "--ax-*"-Token sind im alten
     Design GAR NICHT definiert (getPropertyValue liefert dort den leeren
     String, gemessen). Ein var() ohne Wert macht die Deklaration ungueltig
     zur Rechenzeit -- "border-left-color" faellt dann auf seinen Anfangswert
     "currentColor" zurueck und ueberschreibt die Kaskade dabei.

       entscopt      legacy/dunkel/ungebrandet     legacy/dunkel/gebrandet
       ----------------------------------------------------------------
       --info        rgb(59,130,246) -> 226,232,240   rgb(255,85,0) -> 0,255,0
       --success     dito                             dito
       --warning     dito                             dito
       --danger      dito                             dito

     Die zweite Spalte ist der Beweis, dass der Rueckfall wirklich
     "currentColor" ist und nicht irgendein Grau: rgb(0,255,0) ist der grelle
     Marker, den setzeOrgfarbe() auf "--clr-text-primary" legt -- also die
     geerbte TEXTfarbe der Karte. Entscopt bekaeme das alte Design damit
     einen Akzentstreifen in Schriftfarbe statt rgb(59,130,246) bzw. der
     Organisationsfarbe. Jeweils nur die entscopte Karte ist betroffen, die
     drei anderen bleiben auf dem Bestandswert.

     Die Zustandsklassen selbst stehen im alten Design genauso im DOM -- B1
     haengt sie an, ganz gleich welches Design gewaehlt ist. Nur die Marke
     [data-design="new"] haelt die Farben drueben. Der Testblock "die
     Absichtsklassen faerben im alten Design nichts" ist der Dauerwaechter
     dazu, in beide Richtungen (ungebrandet der Bestandsakzent, gebrandet die
     Organisationsfarbe -- fuer alle vier Karten gleich).

   -- SUBSET-INVARIANTE UND SPEZIFITAET -----------------------------------

     ".notification-banner-card--info" und die drei Geschwister haben im
     Bestand GAR KEINE Regel (B1 hat die Klassen bewusst ohne CSS geliefert).
     Die Subset-Frage stellt sich damit nicht gegen diese Selektoren, sondern
     gegen ".notification-banner-card" (webapp.css:12795), und die dort
     deklarierte Eigenschaft ist "border-left" -- BESTRITTEN, keine neue.

     [data-design="new"] .notification-banner-card--<absicht>   (0,2,0)
     [data-design="new"] .notification-banner-card              (0,2,0)

     GLEICHE SPEZIFITAET, also entscheidet die REIHENFOLGE: die vier Regeln
     stehen unmittelbar HINTER der Kartenregel und schlagen deren
     "border-color" auf der linken Kante. Wer sie nach oben schoebe, bekaeme
     vier graue Kanten. Ein "!important" ist dafuer nicht noetig und steht
     deshalb nicht da; im Bestand beruehrt keines diese Eigenschaft, und der
     Erzeuger setzt keinen Inline-Stil (er schreibt nur className, id,
     data-testid und innerHTML).

     EINE KARTE KANN NUR EINE DER VIER KLASSEN TRAGEN (siehe oben), die vier
     Regeln konkurrieren also nie untereinander; ihre Reihenfolge
     zueinander ist gleichgueltig und folgt der Spec. */
[data-design="new"] .notification-banner-card--info {
  border-left-color: var(--ax-action-primary);
}

/* --- "--info" IM HELLEN THEME: DIE SONDERREGEL IST ENTFALLEN
   (T1, 2026-09-15) ---

   HIER STAND:
     [data-design="new"][data-theme="light"] .notification-banner-card--info {
       border-left-color: var(--ax-text-link);
     }
   Der Block wird umgeschrieben, nicht geloescht: sonst erklaerte er eine
   Regel, die es nicht mehr gibt, und die Frage wuerde ein zweites Mal
   gestellt.

   WARUM ES SIE GAB: die Grundregel darueber nimmt "--ax-action-primary",
   und das war im hellen Theme cyan/500. Der Toast-Akzent fiel damit von
   4,761 (Bestand nach Schritt 1) auf 2,971 gegen "bg/elevated" (Weiss) --
   unter die 3,0 fuer Bedienelemente und unter den Bestand. Kein verfehlter
   Sollwert, sondern ein Rueckschritt. Die Regel holte ueber
   "--ax-text-link" (cyan/600) die 4,761 zurueck. Im dunklen Theme gab es
   sie nie: dort traegt Figmas action/primary einwandfrei (5,878 gegen
   "bg/elevated").

   WARUM SIE FAELLT: T1 hat "--ax-action-primary" im hellen Theme selbst
   auf cyan/600 geheilt (tokens.css:127). Die Grundregel liefert damit
   genau den Wert, den diese Regel herstellen sollte -- der Rueckschritt,
   gegen den sie gebaut war, existiert nicht mehr.

   ZWEISEITIG GEMESSEN, BEVOR SIE FIEL (Galerie-Kachel "toast-default",
   ".notification-banner-card--info", "border-left-color", Marke #ff5500):
                        mit dieser Regel   ohne sie
     dunkel ungebrandet rgb(0,159,227)     rgb(0,159,227)
     dunkel gebrandet   rgb(0,159,227)     rgb(0,159,227)
     hell   ungebrandet rgb(0,122,176)     rgb(0,122,176)
     hell   gebrandet   rgb(0,122,176)     rgb(0,122,176)
   Viermal dasselbe, und die gebrandete Spalte ist der Teil, der zaehlt:
   eine wertgleiche Deklaration kann trotzdem wirken, wenn sie eine
   brandbare Wurzel gegen ein festes Token tauscht. Hier tut sie das nicht
   -- beide Seiten sind "--ax-"-Tokens, und brandingapplier.js haengt
   ausschliesslich "--clr-"-Wurzeln um (:6-17).

   WAS SICH AN DEN ABSTAENDEN AENDERT: NICHTS. "--info" traegt im hellen
   Theme weiterhin cyan/600, die dE-Abstaende der vier Absichten bleiben
   wie gemessen, und der kleinste von ihnen (41,31, Warnung gegen Gefahr)
   war an "--info" ohnehin nicht beteiligt.

   AUFBEWAHRT, WEIL MEHRFACH GEBRAUCHT -- die Herleitung "HELL POSITIV,
   DUNKEL MIT :not(...)": designbootstrap.js:13/22 setzt "data-theme"
   IMMER, hell wie dunkel; teamstheme.js:17/19 setzt "data-theme=light"
   nur fuer hell und ENTFERNT das Attribut sonst. Hell ist also immer
   positiv markiert, dunkel nicht immer. Eine HELL-Regel schreibt deshalb
   positiv ("[data-theme=light]"), eine DUNKEL-Regel
   ":not([data-theme=light])".
   BELEGSTELLEN FUER DIE DUNKLE FORM, nachgezogen mit T1: der
   Diagrammbalken war bis dahin die naechstgelegene -- seine Scopung ist
   mit T1 gefallen, der Verweis ginge ins Leere. Es gibt sie weiterhin an
   ".tool-invocation" (:9978) und zweimal am Dialog (:11520 mit der
   ausgeschriebenen Herleitung, :11678 mit der Regel). */

[data-design="new"] .notification-banner-card--success {
  border-left-color: var(--ax-status-success);
}

[data-design="new"] .notification-banner-card--warning {
  border-left-color: var(--ax-status-warning);
}

[data-design="new"] .notification-banner-card--danger {
  border-left-color: var(--ax-status-danger);
}

[data-design="new"] .notification-banner-text > strong {
  color: var(--ax-text-primary);
  font-size: var(--ax-font-size-body-md);
  line-height: var(--ax-line-height-body-md);
  font-weight: 600;
}

[data-design="new"] .notification-banner-sub {
  color: var(--ax-text-secondary);
  line-height: var(--ax-line-height-label-sm);
  font-weight: 500;
}

/* --- Alert: die getoente Flaeche je Absicht (09 Overlays & Feedback,
   Teil B2, Task 3) ------------------------------------------------------

   Figma-Knoten 114:142 ("Alert", Stil INLINE -- der Block steht im
   Fliesstext eines Dialogs, nicht als seitenbreites Band). Gegenstueck im
   Produkt ist ".container-message" (webapp.css:2524), und die entsteht an
   EINER Stelle: "UserMessage.setupDialogUi()".

   DER MEISTGENUTZTE DIALOGTYP DER ANWENDUNG. "UserMessage" hat DREIZEHN
   Unterklassen ueber die extends-Ketten, mit sich selbst also VIERZEHN
   Klassen -- Information, Warning, ErrorMsg,
   UserInput, SecurityQuestion, LineInput, TextInput, SelectValue,
   FilleInput, BulkResultDialog, ExportOptionsDialog,
   ReorganizeContainerQuestion, DialogSaveChatAsDocument und UserMessage
   selbst. Jede Zeile hier erscheint im Cockpit UND auf den
   Administrationsflaechen.

   -- DER BESTAND, GEMESSEN (am ECHTEN Dialog, nicht an der Kachel:
      Information/Warning/ErrorMsg ueber einen dynamischen Import von
      usermessage.js auf der Galerieseite geoeffnet, 1280x720, beide
      Designs, beide Themes) ---------------------------------------------

     padding        0 ringsum          -- ".container-message" setzt keinen
     background     rgba(0,0,0,0)      -- und keine Flaeche
     border         0px none           -- und keinen Rahmen
     border-radius  0                  -- und keinen Radius
     box-sizing     content-box        -- kein universeller Reset in dieser
                                          Anwendung (components.css:2414)
     gap            20px                  webapp.css:2530
     width          100%, gemessen 550 = Breite von ".dialog .scrollable"

   VIER DER FUENF EIGENSCHAFTEN SIND HIER UNBESTRITTEN (Spec 3a, Regel 3
   des Teilprojekts): "padding", "background", "border" und
   "border-radius" stehen an ".container-message" nicht -- eine gescopte
   Regel darf sie setzen, muss es aber benennen. Genau das tut dieser
   Absatz. "gap" ist die einzige BESTRITTENE: Legacy setzt 20, Figma 12.

   -- DIE FUENFTE EIGENSCHAFT, DIE DER AUFTRAG NICHT AUFZAEHLT:
      "box-sizing" -- UND SIE IST NICHT OPTIONAL ---------------------------

     ".container-message" ist "width: 100%" im content-box-Modell. Figmas
     Innenabstand und Rahmen legen sich darin NEBEN die 100%, nicht hinein.
     Gemessen am echten Dialog, verankerte Textsabotage, nur diese eine
     Zeile entfernt:

       mit "box-sizing: border-box"   Breite 550, scrollWidth 550,
                                      clientWidth 550 -> Ueberlauf 0
       ohne die Zeile                 Breite 584, scrollWidth 584,
                                      clientWidth 550 -> Ueberlauf 34

     34 = 16 + 16 Innenabstand + 1 + 1 Rahmen. Und ".dialog .scrollable"
     traegt "overflow: hidden !important" (webapp.css:1078): der Ueberlauf
     wird nicht gescrollt, sondern ABGESCHNITTEN -- die rechten 34px des
     Alerts samt seinem rechten Rahmen waeren weg. Die Zeile ist also keine
     Zutat, sondern die Bedingung dafuer, dass Innenabstand und Rahmen
     ueberhaupt zeigbar sind. "box-sizing" steht an ".container-message"
     ebenfalls nicht -- auch sie ist unbestritten, und hiermit benannt.

   -- SCHRITT 1: GREIFT ":has()" IM PRODUKT? GEMESSEN, NICHT ANGENOMMEN ---

     Es gibt keine Markierung im DOM, an der eine Regel je Absicht ansetzen
     koennte: Information, Warning und ErrorMsg unterscheiden sich
     ausschliesslich im "src" ihres Bildes (die Konstruktoren von
     Information, Warning und ErrorMsg).

       CSS.supports("selector(:has(img))")            true
       c.matches(':has(img[src$="msg_warn.png"])')    true  (nur am Warning)

     WIE DER "src" IM DOM WIRKLICH AUSSIEHT -- die eigentliche Frage:

       img.getAttribute("src")   "../images/msg_warn.png"
       img.src                   "http://127.0.0.1:8181/images/msg_warn.png"

     Ein CSS-Attributselektor liest das ATTRIBUT, nicht die IDL-Eigenschaft,
     also den relativen Pfad. "$=" wuerde hier allerdings BEIDES tragen --
     beide Zeichenketten enden auf denselben Dateinamen. Das ist der Grund,
     warum der Selektor ueber das Ende geht und nicht ueber "=": eine
     Gleichheitspruefung haenge am relativen Pfad und braeche, sobald
     jemand das Bild von woanders holt. Der Wert kommt aus
     ImageElementFactory.generateImage() (image.js:51), die "image.src = src"
     setzt -- das Setzen der IDL-Eigenschaft schreibt die Zeichenkette
     unveraendert ins Attribut zurueck.

   -- DIE REICHWEITE: ALLE VIERZEHN ERZEUGER, EINZELN GEOEFFNET UND
      GEMESSEN -- UND ES SIND MEHR ALS DIE DREI DER SPEC ----------------

     Die Spec (3c) nennt drei Dialogklassen. Gemessen sind es SIEBEN Wege in
     die Toenung, weil der Selektor am SYMBOL haengt und nicht an der Klasse.
     Jede der vierzehn Klassen wurde mit ihrem EIGENEN Konstruktor
     geoeffnet und gemessen (neu/dunkel). DIE TABELLE HAT FUENFZEHN ZEILEN
     FUER VIERZEHN KLASSEN: "BulkResultDialog" steht zweimal, weil seine
     Toenung mit dem Ergebnis wechselt -- eine Klasse, zwei Zustaende.

       Klasse                        src              Toenung
       ----------------------------------------------------------------
       Information                   msg_info         info
       Warning                       msg_warn         warnung
       ErrorMsg                      msg_error        gefahr
       UserMessage (leerer Pfad)     msg_info         info
       SecurityQuestion              msg_warn         WARNUNG  <- neu
       ReorganizeContainerQuestion   msg_warn         WARNUNG  <- neu
       BulkResultDialog ohne Fehler  msg_info         INFO     <- neu
       BulkResultDialog mit Fehlern  msg_warn         WARNUNG  <- neu
       UserInput                     msg_question     keine
       LineInput                     msg_question     keine
       TextInput                     msg_question     keine
       SelectValue                   msg_question     keine
       ExportOptionsDialog           msg_question     keine
       DialogSaveChatAsDocument      -- kein Meldungsblock --
       FilleInput                    -- kein Meldungsblock --

     DIE VIER MIT "neu" SIND DER BEFUND:
       UserMessage-Ktor      "UserMessage" faellt bei LEEREM Bildpfad auf
                              "msg_info.png" zurueck.
       userinput.js:96        "SecurityQuestion" UEBERSCHREIBT den geerbten
                              "msg_question.png" mit "msg_warn.png" -- das
                              ist die Rueckfrage, die "Dialog" bei
                              ungesicherten Aenderungen selbst oeffnet
                              (dialog.js:275-276). Ein EINGABEdialog, der ab hier
                              eine Warnung TOENT.
       userinput.js:643       "ReorganizeContainerQuestion" erbt das.
       userinput.js:536-537   "BulkResultDialog" waehlt sein Bild nach dem
                              Ergebnis -- seine Toenung WECHSELT mit dem
                              Inhalt.

     IST DAS RICHTIG SO? Gemessen und bejaht: in jedem der vier Faelle traegt
     der Dialog das Symbol bereits, die Toenung sagt also nichts Neues,
     sondern dasselbe noch einmal. Einen Selektor ueber die KLASSE gibt es im
     DOM nicht (Spec 3b), und einer, der SecurityQuestion ausnaehme, muesste
     eine Warnung ENTfaerben, die das Produkt selbst als Warnung zeichnet.
     Es gehoert trotzdem in die Sichtpruefung -- die Rueckfrage bei
     ungesicherten Aenderungen ist der haeufigste dieser vier.

     UND SIEBEN KLASSEN BLEIBEN UNGETOENT -- sieben getoent, sieben nicht,
     zusammen die vierzehn. Fuenf davon ueber das Fragesymbol:
     "msg_question.png" hat seinen
     einzigen Erzeuger in userinput.js:27, der Eingabefamilie. Gemessen an
     einem echten UserInput, beide Themes:

       padding 0/0 * gap 20px * background rgba(0,0,0,0) * border 0px none
       * border-radius 0 * box-sizing content-box

     Also Zeichen fuer Zeichen der Bestand. Der Selektor trifft sie nicht,
     weil er die drei Meldungsbilder AUFZAEHLT statt ".container-message"
     allgemein zu nehmen -- das ist der Grund fuer den "src"-Weg. Zwei
     weitere ("FilleInput" userinput.js:345 und "DialogSaveChatAsDocument")
     ueberschreiben setupDialogUi() und bauen den Meldungsblock gar nicht
     erst. Der Testblock "Alert: die Toenung folgt dem Symbol, nicht der
     Klasse" haelt alle fuenfzehn Zeilen fest -- vierzehn Klassen, davon
     "BulkResultDialog" in seinen beiden Zustaenden.

   -- SCHRITT 2: DIE FLAECHE GEGEN DAS INLINE-WEISS ----------------------

     "UserMessage.renderUi()" schreibt
     "backgroundColor = white" als INLINE-Stil auf den DIALOG. Genau daran
     hat der Modal-Umbau die schwerste Regression dieses Vorhabens getragen
     (Titelkontrast 1,236); seither ist die Dialogflaeche eine BILDSCHICHT
     ("linear-gradient" aus zwei gleichen Stopps, components.css im Block
     "Teil A -- die Dialogflaeche"), die das Inline-Weiss abdeckt.

     DIESE FLAECHE HIER LIEGT AUF EINEM KIND, also darueber. Gemessen
     (gerastert, am echten Dialog, beide Themes) statt angenommen:

       Theme    Dialog inline   Dialog backgroundImage      .container-message
       ---------------------------------------------------------------------
       dunkel   "white"         linear-gradient(...)         rgb(51,38,12)
       hell     "white"         linear-gradient(rgb(255,255, rgb(254,243,199)
                                255), rgb(255,255,255))

     (Die Beispielzeilen zeigen die Warnung; der Testblock prueft alle drei
     Absichten. Die dunkle Bildschicht wurde als "faengt mit
     linear-gradient( an" gemessen, ihr genauer Stoppwert ist Gegenstand des
     Modal-Blocks und nicht dieses.)

     Die gerasterte Farbe der getoenten Flaeche ist in ALLEN sechs Faellen
     (drei Absichten x zwei Themes) Zeichen fuer Zeichen das deklarierte
     Token -- das Inline-Weiss des Elternteils kommt nirgends durch. Der
     Testblock "Alert: die Flaeche liegt ueber dem Inline-Weiss" misst beide
     Schichten im selben Durchgang, damit die Aussage eine Beziehung bleibt
     und nicht zwei unabhaengige Zahlen.

   -- SCHRITT 3: DIE TEXTFARBE -- GEMESSEN UND DESHALB NICHT GESCHRIEBEN --

     Figma setzt Titel "text/primary" und Text "text/secondary" AUF die
     getoente Flaeche; die Tokenschicht fuehrt zusaetzlich
     "--ax-status-*-on-bg" genau dafuer. Beide Paare gemessen, gerastert,
     beide Themes, Schwelle 4,5:

       Absicht   Theme    text/secondary      "-on-bg"
       --------------------------------------------------
       info      dunkel    6,548               9,231
       warnung   dunkel    6,548              12,255
       gefahr    dunkel    7,441               6,062
       info      hell     10,846               7,530
       warnung   hell     11,051               6,367
       gefahr    hell     10,074               5,296

     BEIDE PAARE HALTEN DIE 4,5 IN ALLEN SECHS FAELLEN, und in VIER von
     sechs ist "text/secondary" sogar das kontrastreichere. Es ist
     ausserdem Figmas Wahl und steht bereits da: der Modal-Umbau hat
     ".dialog :where(p)" auf 13/20 "text/secondary" gesetzt, und
     ".message-text" (webapp.css:2539) setzt keine Farbe. Gemessen kommt an
     der Meldung rgb(173,171,187) dunkel und rgb(53,50,74) hell an.

     DESHALB STEHT HIER KEINE FARBREGEL. Eine Deklaration, die nichts
     aendert, gehoert nicht in die Datei; eine, die etwas aendert, ohne dass
     ein Sollwert es verlangt, erst recht nicht. Die Zusicherung auf die
     4,5 steht trotzdem im Test -- sie ist eine Zusage, ganz gleich aus
     welcher Datei die Farbe kommt.

     DER TITEL LAG GAR NICHT AUF DER GETOENTEN FLAECHE. Gemessen (Stand
     Teil B2): ".container-message".contains(".dialog > h4") ist false --
     der Dialogtitel ist ein Geschwister von ".scrollable"
     (dialog.js:81-82), die Toenung sitzt eine Ebene tiefer. Auf der
     Flaeche lagen nur das Bild und der Fliesstext. Figmas Alert fuehrt
     Titel UND Text darauf; das anzugleichen waere Markup. Gehoert in die
     Sichtpruefung.

     NACHTRAG (T2, Task 3): DIE SICHTPRUEFUNG HAT ES ENTSCHIEDEN, das
     Markup ist gebaut. Fuer die drei Meldungsfamilien (Information,
     Warning, ErrorMsg) haengt der Titel jetzt IM senkrechten Behaelter
     der ".container-message" -- die Zeile oben ist damit die Beschreibung
     des Bestands VOR Task 3, nicht mehr die Lage. Die Eingabefamilie und
     jede Klasse ohne Meldungsblock behalten ihren Titel oben. Gebaut in
     "UserMessage.setupUi()"/"setupDialogUi()"; die Folge fuer den
     Kindkombinator steht am Block ".dialog > h4".

   -- SCHRITT 4: DER ABSTAND 20 -> 12, UND WAS ER WIRKLICH TUT -----------

     Der Auftrag liest die Zeile als "das 100x100-Bild rueckt naeher an den
     Text". Das stimmt -- aber fuer den TEXT ist sie das Gegenteil einer
     Verengung. Gemessen am echten Dialog, je eine Zeile sabotiert:

       volle Fassung            Textbreite 384
       ohne "gap: 12"  (also 20) Textbreite 376   -> der kleinere Abstand
                                                     GIBT dem Text 8px
       ohne "padding"            Textbreite 416
       Bestand (ohne alles)      Textbreite 410

     Die Bilanz ist -26px (410 -> 384): Innenabstand und Rahmen nehmen 34,
     der kleinere Abstand gibt 8 zurueck. UMGEBROCHEN WIRD DESHALB NICHT
     ANDERS -- gemessen an vier Texten (kurz/mittel/grenzfall/lang) in
     beiden Fassungen: 1/3/2/4 Zeilen, vorher wie nachher, Texthoehe
     20/60/40/80 unveraendert. Der Block waechst um 26px in der HOEHE
     (100 -> 126), nicht in der Zeilenzahl. Ein Text, dessen letzte Zeile
     naeher als 26px an die rechte Kante reicht, bekaeme eine Zeile dazu --
     das ist Arithmetik, kein Messergebnis, und "white-space: pre-wrap"
     sowie "word-break: break-word" (webapp.css:2539) bleiben unberuehrt.

   -- BEFUND: DER RAHMEN HAELT IM HELLEN THEME DIE 3,0 NICHT --------------

     Gerastert, an der linken Kante, gegen BEIDE Nachbarn (Messregel 3 --
     ein Rahmen hat zwei):

       Theme    Absicht   gegen die Toenung   gegen die Dialogflaeche
       ---------------------------------------------------------------
       dunkel   info       4,966               5,878
       dunkel   warnung   10,232              12,111
       dunkel   gefahr     4,456               4,640
       hell     info       2,619 X             2,971 X
       hell     warnung    2,861 X             3,186
       hell     gefahr     3,953               4,829

     DIE 2,971 IST DIESELBE ZAHL, DIE TASK 2 AM TOAST GEHEILT HAT --
     cyan/500 gegen Weiss, von tokens.css:240-257 dort ausdruecklich
     verworfen. Sie kommt hier ueber den Sollwert "Rahmen 1px
     action/primary" zurueck.

     GEMELDET, NICHT ERSETZT -- und der Unterschied zu Task 2 ist gemessen:
     dort war es ein RUECKSCHRITT (der Akzent fiel von 4,761 auf 2,971 und
     war das EINZIGE Bauteil, das die Absicht trug). Hier gibt es im
     Bestand ueberhaupt keinen Rahmen, der Wert steigt also von "nichts"
     auf 2,6 bis 4,8; und die Absicht wird zusaetzlich vom 100x100-Symbol
     und vom Farbton der Flaeche getragen, die beide unveraendert bleiben.
     Der Sollwert der Spec (3c) nennt die drei Token woertlich; ihn ohne
     Auftrag zu verlassen waere eine zweite Abweichung ohne Not.

     EINE ZEILE JE ABSICHT WUERDE ES HEILEN, falls der Auftraggeber das
     will -- die "-on-bg"-Token sind genau dafuer da und schon gerechnet:
     cyan/700 haelt 7,530 gegen die Toenung und 8,544 gegen Weiss,
     amber/800 6,367 und 7,090, red/700 5,296. Der Testblock nagelt die
     sechs Werte mit der Zahl fest, damit die Entscheidung nicht still
     verschwindet.

   -- GEGENVERSUCHE: KEINE DER ACHT DEKLARATIONEN IST TOT -----------------

     Verankerte Textsabotage, je EINE Zeile entfernt, Neuladen dazwischen,
     gemessen am echten Information-Dialog (neu/dunkel):

       entfernt            Rueckfall                        Textbreite
       ---------------------------------------------------------------
       (volle Fassung)     --                                  384
       box-sizing          content-box, Breite 584,            418
                           UEBERLAUF 34 (s.o.)
       padding             0px / 0px                           416
       gap                 20px -- Legacys Wert                376
       border-width        3px -- NICHT 0. "medium" ist der    380
                           Anfangswert von "border-width",
                           und "border-style: solid" steht
                           weiter da: der Rahmen wird DICKER,
                           nicht unsichtbar.
       border-style        none, und die Breite faellt         386
                           damit auf 0px
       border-radius       0px                                 384
       background          rgba(0,0,0,0) -- die Toenung        384
                           verschwindet ganz
       border-color        rgb(232,230,238) --                 384
                           "currentColor", also die
                           TEXTfarbe des Dialogs

     DER "border-width"-RUECKFALL WAR EINE UEBERRASCHUNG und ist der Grund,
     warum diese Reihe gemessen und nicht aufgeschrieben wurde: wer "ohne
     die Zeile ist der Rahmen weg" erwartet, liest hier 3px. Nur das
     Entfernen von "border-style" nimmt ihn wirklich.

     Die letzte Zeile ist zugleich der Beleg dafuer, warum die gemeinsame
     Regel "border-width"/"border-style" schreibt und NICHT die Kurzform
     "border": die Kurzform setzte "border-color" auf "currentColor", und
     zwar mit derselben Spezifitaet (0,3,1) wie die drei Absichtsregeln --
     die Farbe haenge dann an der REIHENFOLGE der Regeln. Mit den beiden
     Langformen fasst die gemeinsame Regel "border-color" gar nicht an, und
     die Reihenfolge ist gleichgueltig.

   -- LECKPROBE (alle VIERZEHN Deklarationen entscopt, [data-design="new"] ->
      [data-design], spezifitaetserhaltend; gemessen im ALTEN Design, an
      allen drei echten Dialogen, beiden Themes und beiden Markenzustaenden
      -- AM AUSGELIEFERTEN STAND, nicht an einer Kandidatenfassung) -------

       Zustand                       Ergebnis
       ------------------------------------------------------------------
       gescopt, legacy (alle 12      padding 0/0, gap 20, radius 0,
       Kombinationen)                Rahmen 0px none, background
                                     rgba(0,0,0,0), box-sizing content-box
                                     -> Zeichen fuer Zeichen der Bestand
       entscopt, legacy/dunkel, un-  padding 12/16, gap 12, radius 10,
       gebrandet                     Rahmen 1px solid rgb(226,232,240),
                                     background rgba(0,0,0,0)
       entscopt, legacy/hell, un-    dito, Rahmen rgb(30,27,75)
       gebrandet
       entscopt, legacy, GEBRANDET   dito, Rahmen rgb(0,255,0)
       (beide Themes)

     DIE ERSTE FASSUNG DIESER REIHE LIEF AN DER KANDIDATENFASSUNG (die
     gemeinsame Regel trug damals die Kurzform "border: 1px solid"), und das
     stand hier auch so. Mit der Nachbesserung ist sie am AUSGELIEFERTEN
     Stand nachgefahren -- mit den beiden Langformen und den zwei
     Hellregeln. Ergebnis unveraendert; die Begruendung, warum beide Wege
     zum selben Wert fuehren, steht weiterhin unten.

     ALLE VIERZEHN ZUSAMMEN ENTSCOPT ERGEBEN DEN SCHADEN OBEN. Getragen
     wird er von den SECHS GEOMETRIEZEILEN der gemeinsamen Regel: sie
     lecken einzeln, weil ihre Token an ":root" stehen und im alten Design
     sehr wohl Werte liefern (tokens.css:330 ff.).

     DIE ACHT FARBZEILEN LECKEN NUR IM VERBUND, und das ist ausdruecklich
     keine Verallgemeinerung wert: "--ax-action-primary-bg" und Geschwister
     sind im alten Design gar nicht definiert, ein var() ohne Wert macht die
     Deklaration ungueltig zur Rechenzeit, und die Eigenschaft faellt auf
     ihren ANFANGSWERT zurueck -- "background" auf "rgba(0,0,0,0)",
     "border-color" auf "currentColor". GENAU DAS IST IM BESTAND ABER
     OHNEHIN DER WERT: ".container-message" hat dort weder Flaeche noch
     Rahmen. EINZELN entscopt sind die sechs Farbzeilen der drei
     Absichtsregeln und die zwei Hellregeln im alten Design also
     WIRKUNGSLOS. Zerstoerend werden sie erst, wenn die gemeinsame Regel
     mitleckt und dem Rahmen ueber "border-width"/"border-style" eine
     sichtbare Breite gibt.

     Die dritte Zeile der Tabelle ist dann der Beweis, dass der Rueckfall
     wirklich "currentColor" ist und nicht irgendein Grau: rgb(0,255,0) ist
     der grelle Marker, den setzeOrgfarbe() auf "--clr-text-primary" legt --
     also die geerbte TEXTfarbe. Das alte Design bekaeme einen gerahmten,
     gerundeten, eingerueckten Kasten OHNE Toenung, mit einem Rahmen in
     Schriftfarbe.

     DIE ZWEI HELLREGELN LECKEN MIT, lassen sich in dieser Messung aber
     nicht von ihren Grundfassungen unterscheiden: entscopt sind im hellen
     Theme BEIDE ungueltig, und beide fallen auf denselben "currentColor".
     Das ist keine Luecke, sondern die Aussage -- wer eine der vierzehn
     entscopt, bekommt denselben Schaden wie jede andere ihrer Gruppe.

     Der Testblock "Alert: das alte Design bleibt unveraendert" ist die
     Gegenrichtung dazu, "Alert: die Hellregel ... drei Theme-Zustaende"
     der Waechter ueber die Designmarke der zwei neuen Zeilen.

   -- BANDGRENZE: EINE, UND ES IST DIESELBE WIE BEIM TOAST ---------------

     Gemessen bei 1280 / 1024 / 769 / 768 / 360:

       --ax-space-3   12 12 12 | 10 10   Bandgrenze bei 768 (tokens.css:401)
       --ax-space-4   16 16 16 | 12 12   dito
       --ax-radius-md 10 in allen fuenf Breiten -- KEINE Bandgrenze
       die sechs Farbtoken  in allen fuenf Breiten gleich

     Figmas 12/16 und 12 kommen damit in zwei der drei Baender an und
     stauchen unter 769px auf 10/12 und 10 -- die Absicht der Tokenschicht.
     Kein "@media"-Block; die Staffelung steckt im Token.

   -- MARKE: GEBRANDET UND UNGEBRANDET SIND IDENTISCH --------------------

     Alle sechs Faelle (drei Absichten x zwei Themes) liefern gebrandet
     Zeichen fuer Zeichen dieselben Werte wie ungebrandet -- Flaeche,
     Rahmen, Textfarbe und der gerasterte Punkt. brandingapplier.js haengt
     ausschliesslich "--clr-*"-Wurzeln um (:5-18), dieser Block benutzt
     ausschliesslich "--ax-*". Anders als beim Toast wird der Organisation
     hier auch NICHTS entzogen: ".container-message" trug im Bestand weder
     Flaeche noch Rahmen, es gab keine Organisationsfarbe zu verlieren.
     Gemessen wird trotzdem in allen vier Konfigurationen (Regel 6) -- die
     Gleichheit ist die Aussage.

   -- SPEZIFITAET UND REIHENFOLGE ----------------------------------------

     [data-design="new"] .container-message:has(img[src$="..."])   (0,3,1)
       ":has()" nimmt die Spezifitaet seines staerksten Arguments, und
       "img[src$=...]" ist (0,1,1).
     ".container-message" (webapp.css:2524)                        (0,1,0)
       verliert -- das ist die einzige Legacy-Regel, gegen die "gap"
       antritt.
     Die gemeinsame Regel und die drei Absichtsregeln sind GLEICH
     spezifisch (0,3,1); sie beruehren aber keine gemeinsame Eigenschaft
     (s.o., "border-width"/"border-style" gegen "border-color"), die
     Reihenfolge ist also gleichgueltig und folgt der Spec.
     Ein Dialog traegt genau EIN Bild; die drei Absichtsregeln koennen sich
     nie gegenseitig treffen -- gemessen an allen drei Klassen.
     Kein "!important" (der Unittest tests/unit/components-css.test.js haelt
     das fuer die ganze Datei fest), und die Inline-Stile von
     UserMessage.renderUi() liegen auf dem DIALOG, nicht auf der
     ".container-message" -- gegen ein Inline tritt hier nichts an.

   -- WAS DIESER BLOCK BEWUSST NICHT SCHREIBT ---------------------------

     color               siehe Schritt 3 -- gemessen unnoetig
     Symbolgroesse       Figmas 16x16 gegen 100x100 im Produkt. Das zu
     und Symbolfarbe     aendern waere eine Umgestaltung des Dialogs, kein
                         Umlackieren (Spec 3b, Entscheidung des
                         Auftraggebers); und die vier PNGs sind 300x300,
                         Farbtyp 2 ohne Alphakanal -- eine CSS-Maske ergaebe
                         ein einfarbiges Quadrat.
     "Erfolg"            hat in der Dialogfamilie keinen Erzeuger. Figma
                         fuehrt ihn, das Produkt nicht -- kein Grund, eine
                         Klasse zu erfinden.
     align-items         Legacys "start" haelt das 100x100-Bild und den
                         Text oben buendig. Figma fuehrt dazu nichts. */
[data-design="new"] .container-message:has(img[src$="msg_info.png"], img[src$="msg_warn.png"], img[src$="msg_error.png"]) {
  /* "box-sizing" ist die fuenfte, vom Auftrag nicht aufgezaehlte
     Eigenschaft -- ohne sie laeuft der Alert 34px aus dem ".scrollable"
     heraus und wird dort abgeschnitten. Herleitung oben. */
  box-sizing: border-box;
  padding: var(--ax-space-3) var(--ax-space-4);
  gap: var(--ax-space-3);
  /* Zwei Langformen statt der Kurzform "border": die Kurzform setzte
     "border-color" auf "currentColor" und machte die Absichtsfarbe von der
     Regelreihenfolge abhaengig. Begruendung und Messung oben. */
  border-width: 1px;
  border-style: solid;
  border-radius: var(--ax-radius-md);
}

[data-design="new"] .container-message:has(img[src$="msg_info.png"]) {
  background: var(--ax-action-primary-bg);
  border-color: var(--ax-action-primary);
}

[data-design="new"] .container-message:has(img[src$="msg_warn.png"]) {
  background: var(--ax-status-warning-bg);
  border-color: var(--ax-status-warning);
}

[data-design="new"] .container-message:has(img[src$="msg_error.png"]) {
  background: var(--ax-status-danger-bg);
  border-color: var(--ax-status-danger);
}

/* --- Der Rahmen im hellen Theme: die "-on-bg"-Token statt Figmas
   Statusfarbe (Nachbesserung zu Task 3, Form von Ruling 17) ---------------

   DIE DREI ZEILEN DARUEBER HALTEN IM HELLEN THEME DIE 3,0 NICHT -- nicht
   alle. Gerastert an der linken Kante, halbe Hoehe, gegen BEIDE Nachbarn
   (ein Rahmen hat zwei, Messregel 3):

     Theme    Absicht   gegen die Toenung   gegen die Dialogflaeche
     ---------------------------------------------------------------
     dunkel   info       4,966               5,878
     dunkel   warnung   10,232              12,111
     dunkel   gefahr     4,456               4,640
     hell     info       2,619  X            2,971  X
     hell     warnung    2,861  X            3,186
     hell     gefahr     3,953               4,829

   DIE 2,971 IST DIESELBE ZAHL, DIE TASK 2 AM TOAST GEHEILT HAT, und das ist
   kein Zufall: wieder cyan/500 gegen eine helle Flaeche. tokens.css:240-257
   hat genau diesen Wert ausgerechnet und verworfen.

   -- WARUM GEHEILT WIRD, OBWOHL ES KEIN RUECKSCHRITT IST -----------------

     Anders als beim Toast ist der Rahmen hier NICHT der alleinige Traeger
     der Absicht: die Toenung und das 100x100-Symbol tragen sie mit, und im
     Bestand gibt es ueberhaupt keinen Rahmen -- der Wert steigt von "nichts"
     auf 2,6 bis 4,8. Das war der Einwand, und er ist richtig. Geheilt wird
     trotzdem, aus drei Gruenden (Entscheidung des Auftraggebers):

       1. Die Heilung kostet eine Zeile, und das Token existiert genau fuer
          diese Flaechen.
       2. Dieses Projekt hat dieselbe Frage zweimal zugunsten der
          Sichtbarkeit entschieden (Ruling 17 aus "07 Chat & AI" und die
          Nachbesserung zu Task 2). Ein drittes Mal anders zu entscheiden,
          ohne dass sich die Lage unterscheidet, machte die Linie
          unberechenbar.
       3. Ein Rahmen, den man nicht sieht, ist kein Rahmen -- dann waere
          Weglassen ehrlicher, und das will Figma nicht.

   -- DIE ROLLENVERSCHIEBUNG, AUSDRUECKLICH BENANNT ----------------------

     "--ax-status-*-on-bg" und "--ax-action-primary-on-bg" sind fuer TEXT
     auf der getoenten Flaeche gedacht; hier tragen sie einen RAHMEN. Das
     ist eine Rollenverschiebung und keine Selbstverstaendlichkeit.

     SIE IST BEGRUENDET, NICHT ENTSCHULDIGT: tokens.css:240-257 zieht die
     Rollengrenze nicht zwischen "Text" und "Nicht-Text", sondern zwischen
     FLAECHE und duenner Linie -- "duenne Randlinien/Rings" zaehlt der
     Absatz dort ausdruecklich zur Textrolle und begruendet damit, warum
     "--clr-accent" im hellen Theme auf "--ax-text-link" zeigt. Ein
     1px-Rahmen ist genau so eine duenne Linie: er braucht dieselbe
     Dunkelheit wie Text, weil er aus derselben geringen Flaeche dieselbe
     Unterscheidbarkeit holen muss. Task 2 hat dieselbe Verschiebung am
     Toast-Akzent benannt (dort "--ax-text-link" fuer einen 4px-Streifen);
     dies ist die zweite, und sie steht hier, damit sie nicht als
     Gedankenlosigkeit gelesen wird.

   -- NUR HELL, UND NUR ZWEI DER DREI ABSICHTEN -------------------------

     NUR HELL: im dunklen Theme haelt jede der sechs Messungen die 3,0
     (4,456 im schlechtesten Fall). Eine Abweichung dort, wo keine noetig
     ist, waere eine zweite ohne Grund -- dieselbe Form wie Ruling 17.

     NUR ZWEI DER DREI: "gefahr" haelt auch hell (3,953 / 4,829) und bleibt
     deshalb auf Figmas "--ax-status-danger". Das ist die woertliche Lesart
     von "nur dort, wo es noetig ist" und vermeidet eine dritte Abweichung
     ohne Not.

     DER PREIS DAVON IST EINE GEMISCHTE RAMPE: im hellen Theme steht der
     Rahmen bei info auf cyan/700, bei warnung auf amber/800 und bei gefahr
     auf red/600. Drei Absichten, zwei Tokenrollen. Gemessen ist das
     unauffaellig -- alle drei liegen zwischen 3,9 und 8,5, also im selben
     Band --, aber es ist eine bewusste Uneinheitlichkeit und gehoert in die
     Sichtpruefung. Waere Einheitlichkeit wichtiger als Sparsamkeit,
     bekaeme "gefahr" "--ax-status-danger-on-bg" (red/700, 5,296 / 6,470);
     die Zahl steht hier, damit die Entscheidung eine Zeile kostet.

   -- WARUM "[data-theme=light]" POSITIV UND NICHT ":not(...)" -----------

     Belegt, nicht angenommen -- dieselben zwei Stellen wie bei Task 2:

       designbootstrap.js:13/22  setzt "data-theme" IMMER, hell wie dunkel
       teamstheme.js:17/19       setzt "data-theme=light" fuer hell und
                                 ENTFERNT das Attribut fuer dunkel/Kontrast
                                 ("The cockpit's default theme is Dark (no
                                 attribute set). The 'light' value is the
                                 only one that gets the attribute.")

     HELL IST IMMER POSITIV MARKIERT, DUNKEL NICHT IMMER. Eine HELL-Regel
     muss deshalb positiv schreiben; ein ":not([data-theme=dark])" traefe im
     Teams-Wirt auch das dunkle Cockpit. Das Dunkle steht in den
     Absichtsregeln darueber, die gar keinen Theme-Scope tragen und damit
     BEIDE dunklen Faelle decken -- mit gesetztem Attribut und ohne.

     Nachgemessen in drei Zustaenden, am echten Dialog:
       data-theme="light"      info rgb(0,81,122)   warnung rgb(146,64,14)
       data-theme="dark"       info rgb(0,159,227)  warnung rgb(252,211,77)
       Attribut GANZ ENTFERNT  info rgb(0,159,227)  warnung rgb(252,211,77)
     Der dritte Fall ist der Teams-Wirt und der eigentliche Beweis.

   -- SPEZIFITAET --------------------------------------------------------

     [data-design="new"][data-theme="light"] .container-message:has(...)
                                                               (0,4,1)
     [data-design="new"] .container-message:has(...)            (0,3,1)

     Die Hellregeln gewinnen ueber die Spezifitaet, nicht ueber die
     Stellung -- sie stuenden auch weiter oben richtig. Sie stehen trotzdem
     unmittelbar hinter ihren Grundfassungen, damit beide Zeilen zusammen
     gelesen werden. "background" fassen sie NICHT an: die Toenung bleibt in
     beiden Themes Figmas "<absicht>-bg".

   KEIN BRANDING beteiligt: beide Token sind "--ax-*", und
   brandingapplier.js haengt ausschliesslich "--clr-"-Wurzeln um. Gebrandet
   und ungebrandet liefern denselben Wert -- gemessen.

   -- WAS DAS AN DEN ZAHLEN AENDERT (gerastert, hell) --------------------

     Absicht   gegen die Toenung      gegen die Dialogflaeche
     ----------------------------------------------------------
     info      2,619 -> 7,530         2,971 -> 8,544
     warnung   2,861 -> 6,367         3,186 -> 7,090
     gefahr    3,953 (unveraendert)   4,829 (unveraendert)

     Keiner der sechs Werte bleibt unter 3,0 -- kein Zielkonflikt. */
[data-design="new"][data-theme="light"] .container-message:has(img[src$="msg_info.png"]) {
  border-color: var(--ax-action-primary-on-bg);
}

[data-design="new"][data-theme="light"] .container-message:has(img[src$="msg_warn.png"]) {
  border-color: var(--ax-status-warning-on-bg);
}

/* --- Kartenbild (05 Data, Abschluss, Task 1) -----------------------------

   FIGMA "Card / Agent" (51:191), Kind "avatar": Hoehe 132, Radius 10
   ("radius/md"). Die Kartenhuelle selbst ist bereits gebaut -- sie entsteht
   ueber "AtomContainerSingleCard" und damit ueber die generische Klasse
   ".card", die "04 Core" umgestellt hat (oben, ab ".card"). Offen war genau
   EINE Klasse: ".cockpit-agent-image" (webapp.css:3236).

   -- DIE FLAECHE WIRD NICHT GEBAUT --------------------------------------

     Figmas Avatar ist ein PLATZHALTER: ein Verlauf mit einer 38px-Glyphe
     darin. Das Produkt zeigt an derselben Stelle das ECHTE Bild der
     Organisation bzw. des Agenten. Eine Verlaufsflaeche darueberzulegen
     hiesse, das Bild zu verdecken. Vergleichbar sind allein Hoehe und
     Radius -- und von den beiden traegt, gemessen, nur die Hoehe eine
     Aenderung (siehe "DER RADIUS AENDERT NICHTS" weiter unten).

   -- ACHT ERZEUGER, SELBST NACHGEZAEHLT ---------------------------------

     Die Spec nennt acht; es sind acht, und die Liste stimmt:

       organismsagentcard.js:74               Agentenkarte (Figmas Vorlage)
       organismsaiservicecard.js:44           AI-Service-Karte
       organismsaiservicemanagercard.js:37    AI-Service-Karte (Manager)
       organismfavoritesaiservicecard.js:46   AI-Service-Karte (Favoriten)
       organismscontainercard.js:61           Container-Karte, festes Bild
                                              "./images/datacontainer.jpg"
       organismsmarketplacecard.js:44         Marktplatz-Karte
       organismsorganisationcard.js:48        Organisationskarte
       cockpitagentselect.js:105              Agentenauswahl im Cockpit --
                                              KEINE Karte

     Die ersten sieben haengen ihr Bild in eine ".card-info" innerhalb einer
     ".card"; der achte nicht. Diese Trennung ist der Grund fuer beide
     Gegenregeln weiter unten.

   -- SCHRITT 2: WAECHST DAS BILD ODER NUR DER LEERRAUM? -----------------

     "object-fit: contain" PASST EIN, es fuellt nicht. Eine hoehere Flaeche
     macht ein Bild mit abweichendem Seitenverhaeltnis NICHT groesser --
     sie fuegt Leerraum hinzu. Gemessen wurde deshalb die TATSAECHLICH
     gezeichnete Bildflaeche, nicht die Elementbox: aus naturalWidth/
     naturalHeight und der Box faellt der contain-Massstab exakt aus
     min(Boxbreite/nw, Boxhoehe/nh).

     DIE BOX IST IN ALLEN SIEBEN KARTENWIRTEN 200 BREIT (".card-info",
     webapp.css:4604) -- "04 Core" laesst die Kartenbreite unangetastet und
     setzt den Innenabstand auf "--ax-space-5" = 20px, also denselben Wert
     wie der Bestand. Die Box ist damit 200x120 (Verhaeltnis 1,667) und
     wird 200x132 (Verhaeltnis 1,515).

       Bild                        120er Box        132er Box
       ------------------------------------------------------------
       quadratisch (1201x1200)     120,1 x 120,0    132,1 x 132,0  +10 %
       breit       ( 900x300)      200,0 x  66,7    200,0 x  66,7  gleich
       hoch        ( 300x900)       40,0 x 120,0     44,0 x 132,0  +10 %

       Leerraum quadratisch         9 588 px2        8 961 px2
       Leerraum breit              10 667 px2       13 067 px2

     DIE GRENZE IST DAS SEITENVERHAELTNIS DER BOX. Ein Bild breiter als
     1,515:1 ist breitenbegrenzt und waechst NICHT mit; nur sein Leerraum
     waechst. Alles darunter ist hoehenbegrenzt und waechst um genau 10 %.

     UND JETZT DER BEZUG, DER DIE FRAGE ENTSCHEIDET: alle drei Bilder, die
     die Plattform SELBST ausliefert, sind quadratisch --
     "datacontainer.jpg" 1201x1200, "auxi-standard-app.jpg" 1201x1200,
     "auxi-custom-app.jpg" 1200x1200 (aus den JPEG-Kopfdaten gelesen). Der
     Standardfall waechst also. Kleiner wirkt das Bild ausschliesslich bei
     einem HOCHGELADENEN Bild breiter als 1,515:1, und auch dort wird es
     nicht kleiner, sondern bleibt gleich gross in mehr Leerraum.

     ERGEBNIS: die 132 sind eine VERBESSERUNG fuer jedes Bild bis 1,515:1
     (alle ausgelieferten) und eine GESTALTUNGSENTSCHEIDUNG zugunsten von
     mehr Leerraum fuer breitere. Die Spec hatte den zweiten Fall als den
     wahrscheinlichen angenommen; gemessen ist er der Sonderfall. In die
     Sichtpruefung gehoert er trotzdem, mit einem bewusst breiten
     Agentenbild.

   -- DER RADIUS AENDERT NICHTS, UND DAS IST DER BEFUND -------------------

     Die Spec fuehrt "Bestand 5". Das ist der Wert der NACKTEN Regel und in
     keinem der acht Wirte der gerechnete:

       ".card-info img { border-radius: 10px }"   webapp.css:4615  (0,1,1)

     schlaegt ".cockpit-agent-image" (0,1,0) in allen SIEBEN Kartenwirten --
     gemessen 10px, nicht 5px. Figmas 10 STEHEN DORT ALSO SCHON. Und der
     achte Wirt liegt im Produkt ausnahmslos in ".chatbot-service-panel"
     (templatecockpitnavigationbase.js:79/81 haengt ihn an
     "AtomContainerNavPanel", atomcontainernavpanel.js:19), wo
     webapp.css:5146 mit (0,2,0) 12px setzt.

     DIE 5px SIND IM PRODUKT NIRGENDS SICHTBAR. Die Deklaration unten ist
     deshalb kein sichtbarer Umbau, sondern eine VERANKERUNG: der Radius
     kommt kuenftig aus "--ax-radius-md" statt aus einem Zufall der
     Kaskade, und ein kuenftiger Wirt ausserhalb einer Karte bekaeme 10
     statt 5. Sie steht hier, weil sie in der Teilmenge der nackten Regel
     liegt und Figma sie nennt -- nicht, weil sie heute etwas bewegt. Wer
     eine sichtbare Wirkung erwartet, findet sie nur im Leck-Block des
     Tests, und zwar am Cockpit-Auswahlfeld.

   -- ".cockpit-result-image" WIRD MITGEZOGEN (Schritt 3) ----------------

     webapp.css:3244 traegt DIESELBEN VIER WERTE und hat GENAU EINEN
     Erzeuger: organismsaiserviceresultcard.js:36, die Ergebniskarte des
     Reiters "Ergebnisse" (templateresults.js:77). Figma kennt dafuer kein
     Gegenstueck -- mitgezogen wird sie trotzdem, aus drei gemessenen
     Gruenden und nicht aus Symmetrie:

       1. SIE SITZT IM SELBEN BAUTEIL. Auch sie haengt in einer
          ".card-info" einer ".card"; ihr Radius ist damit ebenfalls schon
          10px. Figmas "avatar" ist der Bildplatz DER KARTE, nicht der der
          Agentenkarte.
       2. DER BESTAND BEHANDELT BEIDE ALS EINS. Die Schmalband-Regel
          webapp.css:10493 nennt beide Klassen in EINER Selektorliste und
          gibt ihnen dieselben 40x40; ebenso webapp.css:10479 fuer die
          Umsortierung. Eine der beiden auszulassen hiesse, diese
          Gleichsetzung in genau einer Eigenschaft zu brechen.
       3. DIE FOLGE WAERE SICHTBAR. Ergebniskarten und Agentenkarten sind
          im Cockpit benachbarte Seiten mit derselben Kartenform; 120
          neben 132 waere eine Unregelmaessigkeit ohne Anlass.

   -- DIE EINE GEGENREGEL -- UND DIE, DIE ES NIE GEBRAUCHT HAT ----------

     Das ist der eigentliche Umbau dieses Tasks. "components.css" laedt NACH
     "webapp.css" (alle Seiten-Koepfe: webapp, tokens, components), und die
     Grundregel unten liegt bei (0,2,0):

       1. ".chatbot-service-panel .cockpit-agent-image" (webapp.css:5146)
          liegt EBENFALLS bei (0,2,0) -- und ist trotzdem KEIN Gegner,
          weil dieser Wirt gar nicht von Klassen regiert wird.
          Der einzige Erzeuger der Klasse INNERHALB des Panels
          (cockpitagentselect.js:105) ist zugleich der einzige der acht,
          der eine DOM-Id vergibt: "agentImage". Dort gilt damit
          "#agentImage" (webapp.css:3228) bei (1,0,0) -- 36x36 und
          Radius 5 --, und EINE ID SCHLAEGT JEDE ZAHL VON KLASSEN. Die
          sieben Kartenerzeuger uebergeben "" (organismsagentcard.js:74
          und die sechs Geschwister); es trifft also genau diesen einen.
          GEMESSEN AM ECHTEN COCKPIT, alle vier Konfigurationen: 36x36,
          Radius 5, "object-fit: cover" -- alt wie neu unveraendert.
          "object-fit" kommt dabei sehr wohl aus 5146, denn "#agentImage"
          deklariert es nicht.
          DAS KORRIGIERT DIE ERSTE FASSUNG DIESES BLOCKS, und die
          Korrektur ist der Grund, warum hier nur noch EINE Gegenregel
          steht. Jene Fassung nannte "62x62 -> 62x132" und leitete daraus
          eine Gegenregel ab, die "height: 62px" und "border-radius: 12px"
          restaurierte. Die Zahlen stammen aus dem Galerie-Nachbau, der
          den Panelinhalt bewusst OHNE Id klont
          (designgallerypage.js:2779) -- DORT stimmten sie. Am
          Produktwirt hat die Gegenregel nie einen Wert bewegt:
          zweiseitig gemessen, mit ihr und ohne sie NULL Abweichungen
          ueber alle vier Konfigurationen. Sie ist entfernt.
          DIE LEHRE GEHOERT DAZU: ein Wirt, den nur ein Nachbau belegt,
          ist nicht gemessen. Die Spezifitaetsrechnung hatte jede Klasse
          gezaehlt und die eine ID uebersehen, die daneben stand.
          DIESELBE STELLE HAT EIN ZWEITES GESCHWISTER, und auch das ist
          KEIN Gegner: webapp.css:9607 fuehrt
          "[data-theme=\"light\"] .chatbot-service-panel .cockpit-agent-image"
          bei (0,3,0) mit "border-color" und "box-shadow". Es verliert
          gegen nichts von hier -- die Grundregel erreicht das Panel
          ohnehin nicht.
       2. "@media (max-width: 640px) { .cockpit-agent-image,
          .cockpit-result-image { ... height: 40px ... } }"
          (webapp.css:10493) liegt bei (0,1,0). Eine Media-Query erhoeht die
          Spezifitaet NICHT -- die Grundregel unten schluege sie und machte
          das Kartenbild im Schmalband wieder 132 statt 40 hoch. Gemessen
          bei 360px Fensterbreite, bevor die Gegenregel stand: 40 -> 132.

     DIE VERBLIEBENE GEGENREGEL RESTAURIERT WOERTLICH, sie gestaltet
     nicht: die 40 ist die Zahl des Bestands. Dieselbe Form wie bei den
     drei Identitaets-Markern an ".card" weiter oben (Befund
     "Important 3"). Sie nimmt keine Eigenschaft an, die ihre
     Legacy-Vorlage nicht selbst deklariert.

   -- TEILMENGE JE EIGENSCHAFT -------------------------------------------

     Grundregel   {height, border-radius}
       gegen ".cockpit-agent-image"  {width, height, object-fit,
                                      border-radius}      -- Teilmenge
       gegen ".cockpit-result-image" {dieselben vier}      -- Teilmenge
     (Eine Panel-Regel steht hier nicht mehr. Der Panel-Wirt gehoert
      "#agentImage" (1,0,0) und ist von keiner Regel dieser Datei
      erreichbar -- siehe Punkt 1 oben.)
     Schmalband   {height, border-radius}
       gegen der 640er-Regel         {width, height, object-fit,
                                      border-radius, flex-shrink}
                                                          -- Teilmenge

     "width" und "object-fit" bleiben in allen drei Faellen bewusst beim
     Bestand: Figma misst fuer die Breite nichts (der Platzhalter fuellt
     seine Karte) und "cover" im Panel ist eine Entscheidung des Panels.

   -- KEIN BANDWECHSEL AN "--ax-radius-md" -------------------------------

     tokens.css:352 setzt "--ax-radius-md: 10px" auf blankem ":root". Der
     1024er Bandblock (:378) fasst GAR KEINEN Radius an; allein der 768er
     (:389) stuft "--ax-radius-lg" und "--ax-radius-xl" herunter
     (tokens.css:405). Gemessen bei 1280, 1024, 769, 640 und 360:
     durchgaengig 10px. Die 132 sind ein Literal und haben ohnehin keins.

   -- KEIN BRANDING BETEILIGT --------------------------------------------

     Beide Werte sind Zahlen bzw. ein "--ax-"-Token; brandingapplier.js
     haengt ausschliesslich "--clr-"-Wurzeln um. Gebrandet und ungebrandet
     liefern denselben Wert -- gemessen in allen vier Konfigurationen.

   -- LECKPROBE, JE EIGENSCHAFTSART GELESEN ------------------------------

     Beide Eigenschaften sind NICHT vererbt; ein leeres var() liesse sie
     also auf den ANFANGSWERT fallen (0 bzw. auto), nicht auf den geerbten
     Wert. HIER WIRD DAS NICHT SCHLAGEND, und das ist gemessen, nicht
     angenommen: "--ax-radius-md" steht auf blankem ":root" (tokens.css:330
     ff.) und gilt auch im alten Design. Entscopt lecken die Deklarationen
     deshalb mit ihrem VOLLEN Wert, nicht mit dem Anfangswert -- wer die
     Leckprobe an einer Eigenschaft aus einem "[data-design=new]"-Token
     gelernt hat, sagte hier das Falsche voraus.

     JEDE REGEL EINZELN ENTSCOPT ("[data-design=new]" -> "[data-design]",
     spezifitaetserhaltend) und im ALTEN Design gemessen, bei 1280 und 360:

       entscopt      Karte      Ergebnis   Auswahlfeld   Sidebar
       -----------------------------------------------------------------
       (nichts)      120/10px   120/10px   120/ 5px      62/12px
       Grundregel    132/10px   132/10px   132/10px      132/10px
       Panelregel    unveraendert in allen vier Wirten
       Schmalband    unveraendert bei 1280; bei 360 faellt die Sidebar
                     von 62 auf 40

     DIE GRUNDREGEL LECKT SICHTBAR, UND ZWAR UEBERALL -- auch in die
     Sidebar, weil sie entscopt auch deren (0,2,0)-Regel ueber die Stellung
     schlaegt. DIE PANELREGEL LECKT UNSICHTBAR, und das ist kein Mangel des
     Gegenversuchs, sondern der Beweis, dass sie eine Restaurierung ist:
     sie setzt genau die Werte, die Legacy dort ohnehin rechnet. DIE
     SCHMALBANDREGEL leckt nur in EINEM Band und nur in EINEM Wirt -- die
     Bandfassung derselben Lehre, die dieses Projekt sonst an "nur in einem
     Theme" und "nur gebrandet" gelernt hat.

     DIE DREI DECLARATIONEN EINZELN VERANKERT SABOTIERT (je genau eine,
     woertlicher Text, nie ueber das CSSOM): 132->131, radius-md->9px,
     40->41. Jede der drei bewegt genau einen gemessenen Wert und keine
     andere. Keine ist Schmuck.

     ZWEI WEITERE STANDEN HIER EINMAL (62->61 und 12->11) und bestanden
     dieselbe Probe -- aber im Galerie-Nachbau, nicht am Produktwirt. Am
     echten Cockpit bewegten sie nichts. Der Unterschied zwischen jenen
     beiden und den drei oben ist der ganze Inhalt von Punkt 1: eine
     Sabotageprobe belegt nur den Wirt, an dem sie gemessen wurde. */
[data-design="new"] .cockpit-agent-image,
[data-design="new"] .cockpit-result-image {
  height: 132px;
  border-radius: var(--ax-radius-md);
}

/* HIER STAND "Gegenregel 1" -- die Cockpit-Sidebar. Sie ist entfernt,
   weil sie nie etwas bewegt hat: der Panel-Wirt traegt "id=agentImage"
   und wird von "#agentImage" (webapp.css:3228, (1,0,0)) regiert. Wer
   sie wieder einsetzen will, lese Punkt 1 des Blocks oben -- und messe
   am echten Cockpit, nicht in der Galerie. */

/* DIE GEGENREGEL -- das Schmalband. Sie hiess "Gegenregel 2", solange
   es eine erste gab. Gleichstand bei (0,2,0) mit der
   Grundregel; diese Regel steht spaeter in der Datei und gewinnt darueber.
   Die Media-Query selbst traegt keine Spezifitaet bei -- genau das ist der
   Grund, warum die Regel ueberhaupt noetig ist.

   NUR DIE HOEHE, UND DAS IST EINE MESSUNG, KEINE SPARSAMKEIT. Die
   640er-Regel des Bestands setzt auch "border-radius: 6px" -- gerechnet
   wird der Wert aber in KEINEM der acht Wirte: in den sieben Kartenwirten
   schlaegt ".card-info img" (0,1,1) ihn auch im Schmalband (gemessen bei
   640 und 360: 10px, nicht 6px), und der achte liegt im Panel, dessen
   Regel (0,2,0) ebenfalls gewinnt (12px). Die 6px sind damit genauso tot
   wie die 5px der nackten Regel.

   WUERDE SIE HIER RESTAURIERT, WAERE DAS KEINE RESTAURIERUNG, SONDERN EINE
   AENDERUNG: die Gegenregel laege bei (0,2,0) und schluege ".card-info
   img" -- das Kartenbild im Schmalband fiele von 10 auf 6. Genau dieser
   Fehlschlag ist in der ersten Fassung dieses Tasks gemessen worden
   (640px, neu: 6px statt 10px) und hat die Deklaration wieder entfernt.
   Ohne sie gilt im Schmalband die Grundregel mit "--ax-radius-md" = 10px
   -- derselbe Wert, den Legacy dort rechnet. */
@media (max-width: 640px) {
  [data-design="new"] .cockpit-agent-image,
  [data-design="new"] .cockpit-result-image {
    height: 40px;
  }
}

/* C2c-1/Task 7: der Agenten-Avatar in der Kopfzeile verlor beim Umzug
   (Task 1) seinen Bildzuschnitt -- ein Produktfehler, den dieser Task
   behebt, nicht dokumentiert.

   URSACHE: die schuetzende Regel ".chatbot-service-panel .cockpit-agent-image"
   (webapp.css:5232, (0,2,0), "object-fit: cover") erfasst nur den Panelkopf.
   "_buildTopbarSlot()" (templatecockpitnavigationbase.js) haengt dieselbe
   Klasse "OrganismsCockpitAgentSelect" seit Task 1 aber in
   ".cockpit-topbar-agent" -- der Slot der Kopfzeile (cockpittopbar.js) --,
   nicht mehr in ".chatbot-service-panel". Dort greift die Panelregel nicht,
   und "object-fit" faellt auf die nackte Klasse ".cockpit-agent-image"
   zurueck (webapp.css:3322, (0,1,0), "contain").

   GEMESSEN (Schritt 1, echtes Chromium, /cockpit.html, neues Design, Rolle
   "user"): "object-fit: contain" statt "cover" -- Breite und Hoehe bleiben
   unberuehrt bei 36x36, weil "#agentImage" (webapp.css:3314, (1,0,0)) sie
   traegt und eine ID von keiner Klassenzahl geschlagen wird; "object-fit"
   deklariert die ID-Regel aber nicht.

   BERICHTIGT 2026-09-21 (Abschlusspruefung, Fund I3): hier stand "deshalb
   kippt genau diese EINE Eigenschaft". Das war zu wenig behauptet. Die
   Panelregel (webapp.css:5232) setzt neben "object-fit" auch "border:
   1.5px solid rgba(weiss,0.10)" und "box-shadow: 0 2px 12px rgba(schwarz,
   0.35)", im hellen Theme (webapp.css:9746) nochmals "border-color" und
   "box-shadow"; auch die greifen am neuen Wirt nicht mehr.
   NACHGEMESSEN, BEIDE WIRTE, BEIDE THEMES (/cockpit.html):
     Kopfzeile: border "0px none", box-shadow "none", 36x36, Radius 5px
     Panel:     border "1px solid rgba(0,0,0,0.1)" (hell) bzw.
                rgba(255,255,255,0.1) (dunkel),
                box-shadow "rgba(...) 0 2px 8px" (hell) / "0 2px 12px"
                (dunkel), 38x38 (36 + 2x1.5px Rahmen), Radius 5px
   ENTSCHIEDEN: nur "object-fit" wird zurueckgeholt, Rahmen und Schatten
   nicht. Die zwei Eigenschaften sind kein Schaden, sondern ein Wirtwechsel:
   sie heben im Panel eine Bildkachel von dessen EIGENER Flaeche ab
   (".chatbot-service-panel" hat einen eigenen Hintergrund; die Panelregel
   rechnet zudem mit 62px Kantenlaenge, die erst "#agentImage" auf 36
   zurueckholt). Die Kopfzeile ist transparent gemessen ("rgba(0, 0, 0, 0)",
   siehe Spec-Test "Die Kopfleiste ist 72px hoch ..."), da steht das Bild
   auf dem Seitenhintergrund -- ein 1,5px-Schleier plus 12px-Schatten auf
   einem 36px-Bild waere dort eine neue Gestaltungsentscheidung ohne
   Figma-Beleg, nicht die Wiederherstellung einer alten. "object-fit"
   dagegen ist FUNKTIONAL: "contain" staucht ein nicht-quadratisches
   Agentenbild in den Rahmen und laesst Leerstreifen stehen.
   Wer Rahmen und Schatten doch will, trifft damit eine Entscheidung fuer
   die Sichtpruefung, nicht eine Fehlerbehebung -- deshalb steht sie hier
   ausdruecklich als offener Punkt und nicht als stille Auslassung.

   DIE GEGENREGEL: ".cockpit-topbar-agent .cockpit-agent-image" liegt mit dem
   Design-Merker bei (0,3,0) und schlaegt damit sowohl die nackte Klasse
   (0,1,0) als auch die Schmalband-Regel oben (0,1,0) -- bei jeder
   Fensterbreite, eine einzige Regel statt einer zweiten Kopie im
   640px-Block. Sie restauriert woertlich denselben Wert, den die Panelregel
   fuer den anderen Wirt schon setzt, keine neue Gestaltungsentscheidung. */
[data-design="new"] .cockpit-topbar-agent .cockpit-agent-image {
  object-fit: cover;
}

/* ── Diagrammhuelle — Figma "Chart Shell" 122:283, Variante
   "Type=Bar, Legend=False" (122:233). 05 · Data, Abschluss, Task 2. ──────────

   EIN WIRT, NACHGEZAEHLT: "MoleculeBarChart" wird im ganzen Frontend genau
   einmal erzeugt (organismspersonalusage.js:72, Profilreiter "Mein
   Verbrauch"); der zweite Treffer auf "new MoleculeBarChart" ist die
   Galeriekachel dieses Tasks. Die vier ".usage-chart*"-Klassen haben damit
   keinen zweiten Wirt, in dem eine Regel hier unbemerkt etwas anderes faerbt.

   VON VIER SOLLWERTEN WIRD EINER GEBAUT, EINER VERANKERT UND ZWEI NICHT --
   und das ist das Ergebnis der Messung am Figma-Knoten, nicht Sparsamkeit.
   Die drei Nicht-Aenderungen stehen unten je einzeln mit ihrer Zahl. */

/* 1 · DIE BALKENFARBE — die einzige echte Aenderung dieses Tasks.

   Figma bindet jeden Balken an "series/1" (gemessen am Knoten 122:240:
   boundVariables.fills = "series/1", #009fe3). Die Tokenschicht fuehrt die
   Familie bereits: "--ax-chart-series-1" ... "-6" (tokens.css:370-375), und
   "--ax-chart-series-1" ist "--ax-cyan-500" = #009fe3. Sie steht auf blankem
   ":root", und Figmas Sammlung "Chart" hat nur EINEN Modus ("Mode 1") --
   die Serienfarben sind in beiden Themes dieselbe Farbe. Deshalb ist diese
   Regel bewusst NICHT themescoped.

   DER PREIS, UND ER IST GEMESSEN, NICHT VERMUTET: "--clr-accent-soft"
   (webapp.css:45/307) ist "color-mix(--clr-accent 55%, white)" im Dunkeln und
   "color-mix(--clr-accent 88%, black)" im Hellen -- eine GEBRANDETE Wurzel.
   Diese Regel entzieht dem Diagramm die Organisationsfarbe. Gemessen an der
   Galeriekachel, vier Konfigurationen, VOR dieser Regel:

       neu/dunkel  ungebrandet  rgb(115, 202, 240)   gebrandet  rgb(255, 162, 115)
       neu/hell    ungebrandet  rgb(  0, 107, 155)   gebrandet  rgb(224,  75,   0)

   NACH dieser Regel steht in allen vier Zellen rgb(0, 159, 227). Die Regel
   aendert also AUCH ungebrandet etwas (die "-soft"-Mischung mit Weiss bzw.
   Schwarz ist nicht Figmas Serienfarbe) -- sie ist damit nicht bloss ein
   Branding-Entzug, sondern zuerst eine Farbkorrektur.

   DER KONTRAST IST DER ZWEITE PREIS, UND IM HELLEN THEME IST ER ZU HOCH --
   DESHALB GILT DIESE REGEL NUR IM DUNKELN. Gerastert statt gerechnet, und
   zwar NICHT wegen eines Verlaufs -- ".config-card" traegt eine FLACHE
   Flaeche (webapp.css:7669, "background: var(--clr-surface-2)", gemessen
   "background-image: none" in allen vier Konfigurationen). Der Grund ist
   ein anderer und steht so auch im Test: "--clr-surface-2" ist ein
   "color-mix()" (webapp.css:19 bzw. :281) und serialisiert als
   "color(srgb ...)"; eine Zahlensuche darauf ist fuer kontrast()
   unbrauchbar -- genau der Fehlgriff, der design-chat-composer.spec.ts
   einmal 1,08 statt 5,43 gekostet hat (Messregel 7). Gemessen an einem
   Balken gegen die Flaeche der ".config-card", in der das Diagramm im
   Produkt sitzt, ungebrandet:

                 altes     NEUES DESIGN       Figmas
                 Design    ohne diese Regel   series/1     gebaut
       dunkel    8,102     9,335              5,770        5,770
       hell      7,176     5,643              2,855        5,643
   DIESE TABELLE IST DER STAND BIS T1 (gerastert, 1280x720). Sie bleibt
   stehen, weil die Herleitung darunter auf ihr aufsetzt; was heute
   ausgeliefert wird, steht in der zweiten Tabelle unter "NEU
   ENTSCHIEDEN".

   DREI SPALTEN, NICHT ZWEI -- UND DIE MITTLERE IST DER RICHTIGE BEZUG
   (Messregel 3). "--clr-accent-soft" ist "color-mix(--clr-accent ...)", und
   Schritt 1 hat "--clr-accent" laengst umgehaengt: der Balken hat im neuen
   Design SCHON eine andere Farbe als im alten, bevor diese Regel etwas tut.
   Wer gegen die erste Spalte misst, vergleicht mit einem Stand, den im
   neuen Design niemand sieht. Beide Zahlen der ersten Fassung dieses
   Kommentars ("dunkel 8,102 -> 5,770", "hell haelt 7,176") waren genau
   dieser Fehler und sind nachgemessen korrigiert.

   WAS DARAUS FOLGT, in beide Richtungen:
     * DUNKEL ist ein GROESSERER Rueckschritt als gedacht -- 9,335 -> 5,770,
       nicht 8,102 -> 5,770. Bleibt trotzdem klar ueber der Schwelle.
     * HELL haelt 5,643, nicht 7,176. Die Entscheidung aendert das nicht:
       Figmas 2,855 waere ein Rueckschritt von 5,643 auf unter 3,0.

   Die helle Zahl ist keine Vorlagenluecke, die man hinnimmt: ein Balken ist
   zum Verstehen des Inhalts noetig, also gilt fuer ihn die 3,0. Figmas Wert
   dort zu uebernehmen waere eine VERSCHLECHTERUNG AN EINEM DATENZEICHEN,
   und zwar unter die Schwelle.

   DIE URSACHE LIEGT IN DER VORLAGE, NICHT IN DIESER REGEL: Figmas Sammlung
   "Chart" hat GENAU EINEN MODUS ("Mode 1", am Knoten gemessen). Der helle
   Modus ist dort nie durchgerechnet worden -- #009fe3 auf Figmas eigenem
   "bg/surface-2" hell (#f4f3f7) rechnet 2,689, auf "bg/surface-1" hell
   (#ffffff) 2,971.

   (BERICHTIGT IM ABSCHLUSSREVIEW: hier stand "2,61" fuer die weisse
   Flaeche. Das war arithmetisch unmoeglich -- "bg/surface-1" hell IST
   #ffffff (tokens.css:98 -> --ax-ink-0, :19), und Weiss liefert von allen
   hellen Flaechen den HOECHSTEN Kontrast; #f4f3f7 haelt ja schon 2,689.
   Die richtige Zahl steht seit Schritt 1 im Baum, tokens.css:252:
   "cyan/500 gegen weisses surface-1 (Light, neues Design) haelt nur
   2.971". Eine gerechnete Zahl kippt, eine gemessene nicht -- hier hat es
   den Kommentar erwischt, der genau das anderswo predigt.)

   DAS IST DER DRITTE FALL DESSELBEN MUSTERS nach Figmas Sendeknopf (2,97)
   und dem hellen Toast-Akzent (2,971) -- UND MIT DER BERICHTIGTEN ZAHL IST
   ES DREIMAL DIESELBE: alle drei sind "action/primary" (#009fe3) gegen
   #ffffff, und alle drei liegen bei 2,97. Das macht das Muster staerker,
   nicht schwaecher: es ist nicht dreimal knapp danebengegangen, sondern
   EINE ungerechnete Stelle der Vorlage, die an drei Bauteilen auftaucht.
   Mit drei Faellen ist es kein Einzelfall mehr, sondern eine Frage an die
   Vorlagen-Eigentuemer. Der Befund gehoert nach Spec 6 -- die Dokumentation
   ist Task 3 dieses Teilprojekts.

   ENTSCHIEDEN (Auftraggeber, Nachbesserung zu Task 2): THEMEGESCOPT, nach
   der Form von Ruling 17 -- die Abweichung NUR DORT, WO SIE TRAEGT. Dunkel
   bekam Figmas Serienfarbe, hell behielt, was die Bruecke lieferte.

   NEU ENTSCHIEDEN (Auftraggeber, T1, 2026-09-15): DIE THEME-SCOPUNG
   FAELLT. Der Balken nimmt Figmas Serienfarbe in BEIDEN Themes. Der Grund
   fuer die Scopung war eine Zahl, und die Zahl gibt es nicht mehr:
   "--ax-chart-series-1" hatte nur einen (dunklen) Wert, weil Figmas
   Sammlung "Chart" GENAU EINEN MODUS hat, und dieser Wert (cyan/500)
   rechnete hell 2,855 gegen die Kartenflaeche -- unter der 3,0 fuer ein
   Datenzeichen. T1 hat der Serienfarbe einen hellen Wert gegeben
   (cyan/600, tokens.css:160); damit haelt sie hell 4,577 und die Scopung
   schuetzt nichts mehr.

   DIE ZAHLEN VON HEUTE, alle vier in EINER Reihe gemessen (T1,
   2026-09-15, an der ".config-card"-Sonde; Farben per getComputedStyle,
   Verhaeltnis nach derselben Formel wie
   tests/features/design-contrast.spec.ts -- eine andere Messreihe als die
   gerasterte Tabelle oben, deshalb steht sie getrennt):
                    Balken                          Kartenflaeche      Kontrast
     dunkel, vorher rgb(0,159,227)                  srgb .1059/.10/.1549  5,794
     dunkel, jetzt  rgb(0,159,227)                  dieselbe              5,794
     hell,   vorher srgb 0/.42102/.607373           srgb .9827/.9812/.9875 5,623
     hell,   jetzt  rgb(0,122,176)                  dieselbe              4,577
   Hell faellt also von 5,623 auf 4,577 und bleibt deutlich ueber der 3,0
   fuer ein Datenzeichen; Figmas eigener Wert (cyan/500) haette dort 2,856
   gehalten und die Schwelle gerissen -- genau deshalb bekam die
   Serienfarbe in T1 einen eigenen hellen Wert, statt dass die Scopung
   bleibt.

   DER PREIS, UND ER IST EIN ANDERER ALS VORHER. Die frueher hier
   genannte Uneinheitlichkeit -- "das Branding wirkt auf den Balken nur
   noch im hellen Theme" -- ENTFAELLT. An ihre Stelle tritt: DER BALKEN
   TRAEGT IN KEINEM THEME MEHR DIE ORGANISATIONSFARBE. Ungebrandet wie
   gebrandet steht dort jetzt dieselbe Serienfarbe; gemessen an der
   ".config-card"-Sonde mit Marke #ff5500:
                        vorher (themegescopt)  jetzt (entscopt)
     dunkel ungebrandet rgb(0,159,227)         rgb(0,159,227)
     dunkel gebrandet   rgb(0,159,227)         rgb(0,159,227)
     hell   ungebrandet srgb 0/.42102/.607373  rgb(0,122,176)
     hell   gebrandet   srgb .88/.29333/0      rgb(0,122,176)
   Das ist vom Auftraggeber ausdruecklich in Kauf genommen und kein
   Nebenbefund: eine Organisation, die ihre Farbe setzt, sieht sie am
   Diagramm nicht mehr. Der Gewinn ist die Einheitlichkeit, die die
   Scopung gekostet hatte -- eine Farbe, die in einem Theme die
   Organisationsfarbe traegt und im anderen nicht, war die schlechtere von
   beiden Welten. Gehoert benannt und in die Sichtpruefung, nicht unter
   den Teppich.

   WARUM DER ENTZUG RICHTIG IST: Figmas "series/*" ist eine EIGENE
   Sammlung ("Chart"), getrennt von "Theme", und ihre sechs Farben sind
   Cyan/Violett/Amber/Teal/Magenta/Cyan-hell -- eine Reihenfolge, die
   auseinanderhaltbar bleiben muss. Eine Organisationsfarbe darin waere
   die erste Reihe, die sich beim naechsten Mehrreihen-Diagramm mit einer
   der fuenf anderen beissen kann. Das Fundament kennt diesen Gedanken
   bereits: "--clr-voice-thinking: var(--ax-cyan-500)" (tokens.css:195)
   traegt woertlich den Kommentar "fixed primitive, not the brandable
   --clr-accent chain".

   DIE UEBRIGEN FUENF SERIENFARBEN HABEN WEITERHIN KEINEN HELLEN WERT.
   Das ist folgenlos, solange es genau einen Verbraucher gibt
   ("new MoleculeBarChart" kommt einmal vor, organismspersonalusage.js:72);
   faellig werden sie gemeinsam, sobald ein Mehrreihen-Diagramm entsteht.
   Wer dieses Diagramm baut, faengt hier an.

   TEILMENGE: "background" ist die einzige Farbeigenschaft, die Legacys
   ".usage-chart-bar" (webapp.css:13768) selbst deklariert. "width",
   "height" und "border-radius" bleiben unberuehrt -- der Radius aus Grund 3
   unten, die Hoehe, weil "MoleculeBarChart.fill()" sie je Balken inline
   setzt. */
[data-design="new"] .usage-chart-bar {
  background: var(--ax-chart-series-1);
}

/* 2 · DIE ACHSENBESCHRIFTUNG — eine Verankerung, keine Aenderung.

   BEFUND ZUERST: Figma hat gar keine Achsenbeschriftung. Der Knoten 122:233
   enthaelt "chart title", vier "gridline", 18 Balken und "axis" -- kein
   einziges Textfeld an der Achse (nachgezaehlt am Knoten). Die Werte
   "12/16 Medium text/secondary" stammen von der LEGENDE (122:226, gemessen:
   fontSize 12, lineHeight 16px, Inter Medium, fills -> "text/secondary"),
   und die Legende baut dieses Teilprojekt ausdruecklich nicht.

   GEBAUT WIRD DESHALB NUR, WAS OHNEHIN GILT: "font-size" steht in Legacy auf
   12px (webapp.css:13782) und in der Tokenschicht auf denselben 12px
   ("--ax-font-size-label-sm", tokens.css:336). Die Deklaration verschiebt
   keinen Pixel; sie haengt den Wert an die Skala, statt ihn als Literal
   stehen zu lassen -- dieselbe Entscheidung wie beim Bildradius in Task 1.

   "color" WIRD BEWUSST NICHT GESETZT, und das ist die Kehrseite von Grund 1
   oben. Gemessen im neuen Design, ungebrandet: die Beschriftung steht
   bereits auf rgb(173, 171, 187) im Dunkeln und rgb(53, 50, 74) im Hellen --
   WOERTLICH Figmas "text/secondary" (#adabbb / #35324a), weil Schritt 1
   "--clr-text-secondary" laengst umgehaengt hat. Ein
   "color: var(--ax-text-secondary)" aendert ungebrandet also NICHTS und
   naehme gebrandet der Organisation eine Farbe weg, die
   brandingapplier.js ausdruecklich anbietet ("textSecondary",
   brandingapplier.js:15). Das waere ein Entzug ohne Gegenwert -- anders als
   beim Balken, wo der Entzug eine Farbkorrektur BEZAHLT.

   "line-height" (16) und "font-weight" (Medium/500) fehlen aus zwei
   Gruenden: Legacys Regel deklariert beide nicht (Teilmenge), und ihre
   Figma-Quelle ist die Legende, nicht die Achse.

   ".usage-chart-empty" STEHT MIT DA, weil Legacy beide Klassen in EINER
   Selektorliste fuehrt (webapp.css:13780/13781). Eine auszulassen braeche
   diese Gleichsetzung in genau einer Eigenschaft -- derselbe Grund, aus dem
   Task 1 ".cockpit-result-image" mitgezogen hat. */
[data-design="new"] .usage-chart-axis-label,
[data-design="new"] .usage-chart-empty {
  font-size: var(--ax-font-size-label-sm);
}

/* 3 · DER BALKENRADIUS BLEIBT — Figma zeichnet ihn genauso.

   Spec 3c fuehrt "oben 4 (Figma zeichnet Rechtecke ohne Radius; zu
   pruefen)", der Brief "Figma zeichnet Rechtecke". BEIDES IST FALSCH, und
   zwar nachmessbar: Knoten 122:240 ("bar 1.1") hat
   topLeftRadius/topRightRadius/bottomRightRadius/bottomLeftRadius =
   2 / 2 / 0 / 0 -- Zeichen fuer Zeichen Legacys "border-radius: 2px 2px 0 0"
   (webapp.css:13771). Gemessen im Browser in allen vier Konfigurationen:
   2px/2px/0px/0px.

   Es gibt hier also NICHTS zu bauen. Aus der ABWESENHEIT eines Radius in
   einer Knotenliste auf "Rechteck" zu schliessen, war der dritte
   Namens-/Abwesenheits-Fehlschluss dieses Umbaus (nach "--ax-font-size-h4"
   und "--ax-series"); Figmas Knotentyp heisst "rounded-rectangle" fuer jedes
   Rechteck, mit und ohne Radius.

   4 · DIE ACHSENLINIE WIRD NICHT GEBAUT — Befund, keine Aufgabe.

   Figma legt unter den Plot ein Rechteck "axis" (122:258), 400 x 1,
   gefuellt mit "border/default" (#242233 dunkel / #d2d0da hell). Es liegt
   bei y = 188 INNERHALB des Plots, und alle 18 Balken enden ebenfalls bei
   y = 188: die Linie ist die GRUNDLINIE, auf der die Balken stehen.

   Im Produkt gibt es dafuer keine Stelle. ".usage-chart-axis" ist der
   Flex-Container der beiden Tagesbeschriftungen und liegt ALS GESCHWISTER
   unter ".usage-chart". Gemessen, in allen acht Konfigurationen identisch:

       Balken-Grundlinie ... Oberkante ".usage-chart-axis":  8,00 px Abstand

   Die 8 px sind ".usage-chart"s eigenes "padding: 8px 0" (webapp.css:13757;
   "height: 120px" ist dort content-box, das Element misst 136). Ein
   "border-top" auf ".usage-chart-axis" zeichnete die Linie also 8 px UNTER
   den Balken -- die Balken schwebten darueber. Das ist keine Grundlinie
   mehr, sondern ein Trenner.

   ZWEI WEGE, SIE DOCH ZU ERZWINGEN, BEIDE VERWORFEN:
     a) "border-top" trotzdem schreiben. Kostet 8 px Versatz gegen Figma UND
        ist eine NEUE Eigenschaft gegenueber der nackten Regel (Legacys
        ".usage-chart-axis" setzt nur "display" und "justify-content") --
        unbestreitbar durch jede Legacy-Regel.
     b) zusaetzlich "padding-bottom: 0" auf ".usage-chart". Das saesse
        buendig (die Balken behielten ihre Groesse, weil die Spalten
        "height: 100%" der 120px-Inhaltsbox sind), ist aber eine
        Layoutaenderung, die kein Sollwert verlangt: die Tagesbeschriftungen
        ruecken 8 px nach oben.

   Die Linie braucht ein Element an der Grundlinie, und das gibt es nur mit
   neuem Markup. Dieses Teilprojekt erfindet keins. Der Befund gehoert nach
   Spec 6 (Task 3), damit er beim naechsten Umbau des Molekuels zur Hand
   ist.

   EBENFALLS NICHT GEBAUT, weil im Produkt ohne Gegenstueck: Gitterlinien
   (Figma: vier Rechtecke in "border/soft"), Legende (sechs Eintraege,
   Punkt 10 x 10), mehrere Reihen (dafuer liegen "--ax-chart-series-2" bis
   "-6" bereit), Linie und Ring, der eigene Kartenrahmen (Figmas
   "bg/surface-1" + "border/soft" + Radius 14 + Titel 18/26 -- im Produkt
   sitzt das Diagramm in einer ".config-card", und die ist eine andere
   Karte als Figmas Diagrammrahmen). */

/* ═══════════════════════════════════════════════════════════════════════
   T3 · DER SEITENABSTAND
   Spec: docs/superpowers/specs/2026-09-16-designsystem-seitenabstand-design.md
   Entscheidung 2 der zwoelf vom 2026-09-15: "Nehme immer den gleichen
   Abstand."

   DER ABSTAND LIEGT UM DEN INHALT, NICHT UM DIE SEITE. Eine fruehere
   Fassung der Spec setzte EINE Regel auf ".welcome" ("eine Regel, eine
   Wurzel"). Sie ist zurueckgezogen, und der Grund ist gemessen:
   ".navbar2" (webapp.css:3496) und ".chatbot-service" (:5485) tragen
   Rand und 10px-Radius NUR oben, rechts und unten -- ihre linke Flanke
   ist eckig und randlos, weil sie die Fensterkante IST. Oben und unten
   stehen beide Leisten laengst frei ("margin-top: 25px", "height:
   calc(100vh - 50px)"); links kleben sie, und zwar FERTIG GEZEICHNET.
   Ein seitliches Padding auf ".welcome" haette genau diese eine Flanke
   freigestellt -- auf jeder Seite der Anwendung. Der Auftraggeber hat am
   2026-09-16 entschieden: die Leisten bleiben an der Kante, den Abstand
   traegt die Inhaltsspalte.

   DREI ADRESSEN, EINE ROLLE. Das Produkt hat zwei Seitenfamilien und
   drei Formen von Inhaltsspalte:
     1. Standardseiten (82 von 97): ".container-top-bottom" als direktes
        Kind von ".welcome" (AtomContainerPage.renderUi()).
     2. Cockpit-Stapelseiten: derselbe Container eine Ebene tiefer, neben
        der Leiste im waagerechten Container.
     3. Cockpit-Chat: ".chat-container" (templatechatwindow.js:114).

   SUBSET-INVARIANTE. Adressen 1 und 2 sind TEILMENGEN: die nackte
   Legacy-Regel ".container-top-bottom" (webapp.css:2437) setzt
   "padding: 10px", diese Regel setzt zwei seitliche Anteile davon.
   ADRESSE 3 IST EINE ERGAENZUNG und wird hiermit benannt:
   ".chat-container" (webapp.css:2106) deklariert KEIN padding. Beleg
   dafuer, zweiseitig, in design-seitenabstand.spec.ts ("Cockpit-Chat:
   von null auf 24 px").

   DER KINDKOMBINATOR IST TRAGEND. Die generische Klasse
   ".container-top-bottom" bleibt UNBERUEHRT -- sie stapelt ueberall im
   Produkt senkrecht und ist seit "T2" der Elternknoten des
   Dialogtitels. Wer sie nackt anspraeche, aenderte jeden Dialog mit.
   ".welcome > .container-top-bottom" ist im Bestand bereits die
   etablierte Adresse fuer die Inhaltsspalte (BERICHTIGT 2026-09-16,
   Fixwelle 1: fuenfzehn Regeln in webapp.css sprechen sie so an,
   nachgezaehlt -- nicht zwoelf). Dialoge haengen an <body>, nicht in
   ".welcome", und sind damit strukturell ausser Reichweite -- belegt,
   nicht behauptet ("Dialoge sind unberuehrt").

   SENKRECHT BLEIBT SENKRECHT. Gesetzt werden ausschliesslich
   "padding-left" und "padding-right". Die 10px oben und unten bleiben
   stehen; eine Kurzform "padding: 24px" haette sie mehr als verdoppelt.

   DER WERT IST DAS TOKEN, NICHT "24px". "--ax-space-6" ist in der Skala
   bereits gestaffelt (tokens.css:441 -> 24, :483 -> 20 ab 1024px,
   :504 -> 16 ab 768px) und liefert das Bandverhalten mit. Gemessen am
   Element, nicht am Token ("Die drei Baender").

   BOX-SIZING NUR AM CHAT, UND DAS IST GEMESSEN. Es gibt in diesem Repo
   kein globales "* { box-sizing: border-box }", und alle drei Wirte
   stehen auf "width: 100%" im Content-Box-Modell. Fuer die ersten
   beiden Adressen bleibt das ohne Folgen: sie sind FLEX-KINDER, und
   die Flex-Rechnung zieht Innenabstaende in der Aussengroesse ab --
   BERICHTIGT 2026-09-16 (Fixwelle 1): gemessen ist das nur fuer Adresse
   1, in "Standardseite: nichts laeuft ueber", scrollWidth gegen
   clientWidth am Elternknoten, in allen drei Baendern, ohne Abweichung.
   Fuer Adresse 2 gilt dieselbe Formel, aber nur bei der Standardbreite
   1280px, in "Cockpit-Stapelseite: dieselben 24 px eine Ebene tiefer"
   (design-seitenabstand.spec.ts) -- die vorherige Fassung dieses
   Kommentars behauptete faelschlich, "Cockpit: nichts laeuft ueber"
   deckte auch Adresse 2 ab; dieser Testfall misst ausschliesslich
   Adresse 3 (".chat-container").
   Der Weg ueber den Elternknoten ist noetig, weil ".welcome"
   "overflow-x: hidden" traegt (webapp.css:1585): ein Ueberlauf waere
   hier STUMM.

   ".chat-container" ist die Ausnahme, und die ist gemessen, nicht
   vermutet: unterhalb 1024px wird sie "position: absolute"
   (webapp.css:6587) und verlaesst den Fluss. Bei 1024px meldete das
   Element "right" 1064 gegen eine Sichtbreite
   ("document.documentElement.clientWidth") von 1024 -- ein Ueberlauf
   von genau 40px, der Summe der beiden 20px-Seitenabstaende dieser
   Bandstufe. Der Elternknoten blieb dabei STUMM (scrollWidth 1024
   gegen clientWidth 1024): ein absolut positioniertes Kind zaehlt nur
   dann in "scrollWidth" seines Elternknotens, wenn dieser selbst
   positioniert ist, und das ist er hier nicht. Deshalb steht
   "box-sizing: border-box" ausschliesslich auf dieser Regel.

   SPEZIFITAET. (0,3,0) bzw. (0,4,0) gegen (0,1,0) der generischen
   Klasse und (0,2,0) von ".welcome > .container-top-bottom"
   (webapp.css:1590, setzt dort ohnehin kein padding). components.css
   laedt nach webapp.css. Am konkreten Wirt nach IDs, Inline-Styles und
   "!important" gesucht -- "#profile-content" (webapp.css:1990) setzt
   kein padding. BERICHTIGT 2026-09-16 (Fixwelle 1): "sonst nichts
   gefunden" war FALSCH. "#myimpact-content" (webapp.css:1932-1942)
   setzt sehr wohl "padding-left"/"padding-right: 20px", bei
   ID-Spezifitaet (1,0,0) -- das schlaegt Adresse 2 oben (0,4,0)
   unabhaengig von der Ladereihenfolge, und die Seite behielt den alten
   20px-Abstand komplett, unterhalb 768px sogar MEHR als die
   gestaffelten 16px des Tokens. Behoben mit einer eigenen,
   ID-adressierten vierten Regel (Ruling 14) statt einer dokumentierten
   Ausnahme -- Entscheidung 2 ("nehme immer den gleichen Abstand")
   laesst keine Ausnahme zu. Beleg, zweiseitig, in
   design-seitenabstand.spec.ts ("Meine Wirkung: dieselben 24 px trotz
   ID-Regel bei #myimpact-content").
   ═══════════════════════════════════════════════════════════════════ */
[data-design="new"] .welcome > .container-top-bottom,
[data-design="new"] .welcome > .container-left-right-top-aligned > .container-top-bottom {
  padding-left: var(--ax-space-6);
  padding-right: var(--ax-space-6);
}

[data-design="new"] .welcome > .container-left-right-top-aligned > .chat-container {
  padding-left: var(--ax-space-6);
  padding-right: var(--ax-space-6);
  /* ERGAENZUNG gegenueber der nackten Legacy-Regel, und sie ist gemessen:
     bei 1024px meldete das Element right 1064 gegen die Sichtbreite
     (document.documentElement.clientWidth) 1024. Ohne diese Zeile laeuft
     der Wirt ueber, und ".welcome" schneidet den Ueberlauf wegen
     "overflow-x: hidden" (webapp.css:1585) STUMM ab -- es gaebe keinen
     Scrollbalken, nur fehlenden Inhalt. Unterhalb 1024px ist der Chat
     "position: absolute" (webapp.css:6587) und ausser Fluss; der
     Elternknoten selbst blieb dabei bei scrollWidth 1024 gegen
     clientWidth 1024 STUMM, weil ein absolut positioniertes Kind nur
     dann in dessen "scrollWidth" zaehlt, wenn der Elternknoten selbst
     positioniert ist. */
  box-sizing: border-box;
}

/* VIERTE REGEL, ERGAENZT 2026-09-16 (Fixwelle 1). "#myimpact-content"
   (webapp.css:1932-1942) traegt eine eigene ID und setzt dort eigenes
   "padding-left"/"padding-right: 20px" bei Spezifitaet (1,0,0) -- das
   schlaegt Adresse 2 oben (0,4,0), unabhaengig davon, welche Regel zuletzt
   laedt. Eine ID-Kollision ist mit einer Klassenregel nicht zu gewinnen;
   die einzige Moeglichkeit, "denselben Abstand" (Entscheidung 2) hier
   durchzusetzen, ohne die ID in webapp.css anzufassen, ist eine ebenso
   ID-adressierte Regel. */
[data-design="new"] .welcome > .container-left-right-top-aligned > #myimpact-content {
  padding-left: var(--ax-space-6);
  padding-right: var(--ax-space-6);
}

/* #2011: Adresse 2 ist in der Cockpit-Huelle ein RASTER-Kind, kein
   Flex-Kind -- "width: 100%" (webapp.css .container-top-bottom) plus die
   24px-Seitenabstaende oben ergaben im Content-Box-Modell einen stummen
   Ueberlauf nach rechts (gemessen auf /editprofile.html: Kopf und Karten
   24-26px ueber dem Fensterrand, bei 1440 und 940px). Dieselbe Abhilfe wie
   bei ".chat-container". */
[data-design="new"] .welcome > .container-left-right-top-aligned > .container-top-bottom {
  box-sizing: border-box;
}

/* ═══════════════════════════════════════════════════════════════════════
   T4 · DIE MODEL CARD
   Spec: docs/superpowers/specs/2026-09-17-designsystem-model-card-design.md
   Entscheidung 9 der zwoelf vom 2026-09-15 -- sie KEHRT die Entscheidung
   "nur die Huelle" vom 2026-09-11 UM.

   OHNE JEDE MARKUP-AENDERUNG. Saemtliche Bauteile, die Figma "ersetzt",
   stehen im Baum bereits und bekommen nur eine andere Gestalt. Der
   3px-Streifen WIRD die Kachel, die fuenf Punkte WERDEN die Spur (Task 3),
   der DSGVO-Punkt ist ein Pseudo-Element (Task 3). Deshalb ist das alte
   Design gar nicht beruehrt und es gibt keinen unsichtbaren Knoten je
   Design.

   DER BEFUND, DER DAS ERLAUBT: die alte Spec verwarf die Kachel mit dem
   Argument, sie ersetze "einen Zustandstraeger durch eine Dekoration" --
   der Streifen trage den DSGVO-Zustand. Das traegt nicht: das Label sagt
   ihn IN WORTEN (organismsmodelselectioncard.js:164, drei Texte) und
   traegt zusaetzlich eine Zustandsklasse fuer die Farbe. Der Streifen ist
   ein REDUNDANTER Traeger und darf fallen.
   ═══════════════════════════════════════════════════════════════════════ */

/* Die Huelle. "height: auto" nimmt die feste Hoehe der bisherigen Regel
   (components.css:11700) ausdruecklich zurueck; "min-height" setzt genau
   denselben Wert als UNTERGRENZE. Damit schrumpft keine Karte, und der
   ganze Gewinn liegt darin, dass laengerer Inhalt nicht mehr im
   "overflow: hidden" (webapp.css:4457) verschwindet.

   Die 259 sind NICHT neu gewaehlt: sie stehen seit "07 · Chat & AI" B in
   dieser Datei und sind dort als Ableitung ausgewiesen -- Legacys 250 plus
   die 9, die die umgestellte Titelzeile dazugebaut hat.

   Das Raster ist die ganze Anordnung: Kachel in Zeile 1 Spalte 1, Kopf in
   Zeile 1 Spalte 2, alles Uebrige ueber beide Spalten. Der Baum bleibt
   unberuehrt.

   Der seitliche Innenabstand wandert von den Kindern auf die Karte --
   sonst saesse die Kachel innerhalb des Kopf-Innenabstands und die Spalten
   liefen auseinander. Legacys Kinder tragen ihn mit 12px
   (webapp.css:4481/4497/4509); "--ax-space-3" ist derselbe Wert. */
[data-design="new"] .model-selection-card {
  /* DIE RANDBOX IST HIER PFLICHT, UND SIE IST EINE AUSNAHME VON DER
     SUBSET-INVARIANTE: die Legacy-Grundregel (webapp.css:4444) setzt
     "box-sizing" NICHT, diese Regel schon. Der Grund ist gemessen, nicht
     gemutmasst: Legacys Karte deklariert "width: 230px" und misst 232px,
     weil der 1px-Rahmen links und rechts dazukommt. Ohne "border-box"
     traegt "width: 300px" hier 300 + 2x12px Innenabstand + 2x1px Rahmen
     = 326px -- Figmas Zahl waere dann nirgends sichtbar. Mit "border-box"
     ist die deklarierte Zahl die gemessene. Dieselbe Loesung wie bei
     ".chat-container" in T3. */
  box-sizing: border-box;
  width: 300px;
  height: auto;
  /* 261 = die 259 der Ableitung (Legacys 250 Inhaltshoehe plus die 9 der
     Titelzeile, components.css:11700) PLUS die 2px Rahmen, die mit
     "border-box" jetzt in derselben Zahl stecken. Die Ableitung bleibt
     unveraendert, nur ihr Bezugsrahmen wechselt von der Inhalts- auf die
     Randbox. */
  min-height: 261px;
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  column-gap: var(--ax-space-2);
  align-content: start;
  padding-left: var(--ax-space-3);
  padding-right: var(--ax-space-3);
}
[data-design="new"] .model-selection-card > * {
  grid-column: 1 / -1;
}
[data-design="new"] .model-card-header,
[data-design="new"] .model-card-factor,
[data-design="new"] .model-card-chips {
  padding-left: 0;
  padding-right: 0;
}

/* GEGENSTUECK zur Randabstands-Verlagerung oben (Ruling 8, final-review.md
   B1): die Karte traegt seit der Regel oben "padding-left/right:
   var(--ax-space-3)", aber ".model-card-footer" und
   ".model-card-default-row" tragen weiterhin ihre EIGENE dunkle Flaeche
   plus ihr eigenes "padding: 8px 12px" (webapp.css:4531-4537 / :4546-4553)
   -- sie wurden absichtlich NICHT entpolstert, sonst saesse ihr Text am
   Kartenrand. Ohne Ausgleich enden beide Streifen 12px vor beiden
   Kartenraendern, waehrend Legacys Streifen (dort traegt die Karte keinen
   eigenen Innenabstand) randbuendig laufen. Ein negativer Aussenabstand in
   derselben Breite wie der Karten-Innenabstand zieht die Flaeche wieder bis
   zur Kante; der Text bleibt durch das eigene "padding" an derselben Stelle
   wie in Legacy. AUSNAHME VON DER SUBSET-INVARIANTE: die Legacy-Grundregeln
   setzen kein "margin" auf diesen Elementen, diese Regel schon -- genau
   dafuer, wie oben begruendet. */
[data-design="new"] .model-card-footer,
[data-design="new"] .model-card-default-row {
  margin-left: calc(-1 * var(--ax-space-3));
  margin-right: calc(-1 * var(--ax-space-3));
}

/* Die Symbolkachel. DIE DREI VARIANTEN STEHEN NAMENTLICH DA, und das ist
   kein Beifang: ".model-card-accent.compliant" und ihre zwei Geschwister
   (webapp.css:4476-4478) wiegen (0,2,0) und setzen "background". Eine
   Regel allein auf ".model-card-accent" laege ebenfalls bei (0,2,0) und
   gewaenne nur ueber die Ladereihenfolge -- ein Gleichstand, und der ist
   in diesem Projekt schon einmal teuer geworden. Mit der Variantenklasse
   steht diese Regel bei (0,3,0) und gewinnt zaehlbar.

   Die Glyphe ist fuer ALLE Modelle dieselbe: "llmprovider" fuehrt kein
   Symbol, eines je Anbieter waere erfunden. "model.svg" ist das vorhandene
   Symbol fuer genau dieses Bauteil. */
[data-design="new"] .model-card-accent,
[data-design="new"] .model-card-accent.compliant,
[data-design="new"] .model-card-accent.conditional,
[data-design="new"] .model-card-accent.noncompliant {
  grid-column: 1;
  grid-row: 1;
  width: 30px;
  height: 30px;
  border-radius: var(--ax-radius-md);
  background: var(--ax-bg-surface-2) url("../images/model.svg") no-repeat center / 18px 18px;
}
[data-design="new"] .model-card-header {
  grid-column: 2;
  grid-row: 1;
}

/* Die Kostenspur. DIE FUENF PUNKTE WERDEN DIE SPUR -- kein neues Markup.
   Legacy zeichnet sie als 6x6-Kreise mit 3px Abstand (webapp.css:4502-4504);
   hier werden daraus fuenf gleich breite, lueckenlose Segmente von 5px
   Hoehe. Fuenf lueckenlose Segmente in zwei Farben SIND eine durchgehende
   Spur mit Indikator, und die Grenze zwischen "an" und "aus" liegt exakt
   dort, wo der Indikator endet. Der Anteil stimmt damit ohne jede Rechnung,
   weil "_factorDots()" (organismsmodelselectioncard.js:172) ihn schon
   bestimmt -- die CSS erfindet keine Zahl.

   Figmas 152px sind fuer eine 300er-Karte gezeichnet; gebaut wird die Spur
   RELATIV ("flex: 1"), damit sie in den Baendern nicht ueberlaeuft.

   ".factor-dot.on" wiegt bei Legacy (0,2,0); diese Regel steht bei (0,3,0)
   und gewinnt zaehlbar, nicht ueber die Ladereihenfolge. */
[data-design="new"] .factor-dots {
  flex: 1;
  gap: 0;
}
[data-design="new"] .factor-dot {
  flex: 1;
  width: auto;
  height: 5px;
  border-radius: 0;
  background: var(--ax-bg-surface-2);
}
[data-design="new"] .factor-dot.on {
  background: var(--ax-accent-ai);
}
[data-design="new"] .factor-dot:first-child {
  border-top-left-radius: var(--ax-radius-full);
  border-bottom-left-radius: var(--ax-radius-full);
}
[data-design="new"] .factor-dot:last-child {
  border-top-right-radius: var(--ax-radius-full);
  border-bottom-right-radius: var(--ax-radius-full);
}

/* Die DSGVO-Zeile. Figma gibt ihr eine eigene Zeile mit einem 7px-Punkt.
   Beides ohne Markup: die Zeile entsteht, indem ".model-card-meta" eine
   Spalte statt einer Zeile wird (Legacy: "display: flex; justify-content:
   space-between", webapp.css:4486), der Punkt ist ein Pseudo-Element.

   "currentColor" ist hier tragend und kein Stilmittel: das Label traegt
   seine Zustandsfarbe bereits ueber ".dgsvo-label.compliant" und die zwei
   Geschwister (webapp.css:4492-4494). Der Punkt erbt sie damit, OHNE dass
   es drei weitere Regeln braucht -- und er folgt ihr auch dann noch, wenn
   jemand die Zustandsfarben aendert.

   FIGMAS ZWEITER HALBSATZ WIRD NICHT GEBAUT. Die Vorlage schreibt
   "DSGVO-konform · EU-Rechenzentrum"; fuer den zweiten Teil gibt es im
   Produkt KEIN Datum. Er waere erfunden. */
[data-design="new"] .model-card-meta {
  flex-direction: column;
  align-items: flex-start;
}
[data-design="new"] .dgsvo-label {
  display: inline-flex;
  align-items: center;
  gap: var(--ax-space-1);
}
[data-design="new"] .dgsvo-label::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   T5 · DIE BADGE-FAMILIE DES WORKFLOW-EDITORS
   Spec: docs/superpowers/specs/2026-09-18-designsystem-badge-familie-workfloweditor-design.md
   Entscheidung 8 der zwoelf vom 2026-09-15.

   WARUM DIE KLASSE NAMENTLICH NEBEN DER GRUNDFORM STEHT, und warum das
   keine Zierde ist: "workfloweditor.css" wird von aiprocesseditor.html:17
   und aiprocessstepeditor.html:17 NACH components.css:16 geladen. Eine
   Regel, die hier bei gleicher Spezifitaet steht, VERLIERT -- nicht
   inhaltlich, sondern allein wegen der Reihenfolge. ".wf-badge.badge-ai"
   wiegt (0,3,0) gegen die (0,1,0) der dunklen und die (0,2,0) der hellen
   Bestandsregeln und gewinnt aus eigener Kraft. Gleichstand ist kein Sieg.

   WARUM KEINE THEME-UNTERSCHEIDUNG: die Bestandsregeln brauchen zwanzig
   Zeilen, weil sie je Theme eigene Farben mischen (workfloweditor.css:264-275
   dunkel, :634-644 hell). Die Rastertokens tragen ihre Themewerte selbst
   (tokens.css:78-93 dunkel, :144-159 hell) -- aus zwanzig Regeln werden
   sechs. (2026-09-18 berichtigt: hier stand "sieben"; Ruling 6 hat
   ".badge-fn" nachtraeglich zu ".badge-http"/".badge-mcp" gesellt.)

   DIE ZUORDNUNG GRUPPIERT, SIE IDENTIFIZIERT NICHT. Das Kuerzel im Badge
   (AI, FN, HTTP, MCP, VID, ORCH, END, IF, UI, ?) unterscheidet die
   Schritttypen bereits eindeutig; die Farbe sagt, WOZU ein Schritt
   gehoert. Die Trennlinie zwischen Violett und Tuerkis ist NICHT "intern
   gegen extern" -- AI-Schritte rufen genauso einen fremden Anbieter. Sie
   lautet: ruft der Schritt ein Modell, das die Plattform verwaltet, oder
   einen Endpunkt, den der Ablaufautor selbst eingetragen hat?

   SUBSET-INVARIANTE: jede Regel unten setzt ausschliesslich "background"
   und "color" -- genau die zwei Eigenschaften, die die Legacy-Regeln
   ebenfalls setzen. Groesse, Radius und Schriftschnitt bleiben bei der
   Grundform ".wf-badge" (workfloweditor.css:255). Dieses Vorhaben aendert
   Farbe, nicht Gestalt.
   ═══════════════════════════════════════════════════════════════════════ */

/* Ein Modell arbeitet. "VideoTranslation" steht hier, obwohl ein externer
   Dienst die Arbeit tut: der Ablaufautor waehlt dort kein Ziel, sondern
   eine Sprache. ".badge-orchestration" verlaesst damit sein Sonder-Indigo
   (webapp.css:59, eine Mischung aus den Wurzeln ZWEIER anderer Gruppen --
   der Grund, warum es nie zu einer von ihnen gehoerte). */
[data-design="new"] .wf-badge.badge-ai,
[data-design="new"] .wf-badge.badge-orchestration,
[data-design="new"] .wf-badge.badge-video {
  background: var(--ax-accent-ai-bg);
  color: var(--ax-accent-ai-on-bg);
}

/* Der Ablauf ruft Code, kein Modell -- eigener Code oder ein fremder
   Endpunkt, den der Ablaufautor selbst eingetragen hat. HIER LOEST SICH DIE
   DOPPLUNG AUF, die dieses Vorhaben ausgeloest hat: ".badge-http" verlaesst
   die Akzentfarbe und ist nicht laenger zeichengleich mit ".badge-ai"
   (workfloweditor.css:264 gegen :269).

   Ruling 6 (2026-09-18): ".badge-fn" traegt jetzt dieselbe Farbe wie
   ".badge-http"/".badge-mcp" statt einer eigenen. Alle 21 Paare der
   urspruenglichen sieben Gruppen wurden durchgerechnet -- ein Tausch der
   Toene haette jede gefundene Kollision nur verschoben, weil beide Toene im
   Satz blieben. Eine Gruppe musste ihren Ton abgeben. Der Auftraggeber hat
   "gruppieren, nicht identifizieren" gewaehlt: das Kuerzel im Badge
   (FN/HTTP/MCP) unterscheidet ohnehin eindeutig, die Trennlinie, die im
   Editor wirklich zaehlt, ist Modell gegen Code -- und die bleibt scharf.
   WAS DADURCH VERLOREN GEHT: die Farbe unterscheidet nicht mehr zwischen
   unserem eigenen Code und einem fremden Endpunkt; ".badge-fn" und
   ".badge-http"/".badge-mcp" sehen jetzt absichtlich gleich aus.
   "--ax-action-primary-*" wird von dieser Familie damit bewusst nicht mehr
   benutzt.

   BERICHTIGUNG (2026-09-18, Ruling 7): hier stand, Cyan/Tuerkis sei das
   EINZIGE Paar unter der Schwelle gewesen -- das war falsch, gerechnet mit
   geschaetzten statt den echten Hexwerten. Tatsaechlich lagen ZWEI Paare
   unter der Schwelle 10: Cyan/Tuerkis bei dE 5,906 dunkel und 7,976 hell
   und ".badge-fn" gegen ".badge-unknown" bei dE 8,525 (nur hell, im dunklen
   unauffaellig bei 13,388). Das Zusammenlegen loest trotzdem beide auf, weil
   es die Cyan-Gruppe als Ganzes aufhebt -- die zweite Kollision verschwindet
   dabei als Nebenwirkung, nicht als Absicht. Das engste der verbleibenden
   15 Paare liegt danach bei dE 14,758 (dunkel) und 13,154 (hell). */
[data-design="new"] .wf-badge.badge-fn,
[data-design="new"] .wf-badge.badge-http,
[data-design="new"] .wf-badge.badge-mcp {
  background: var(--ax-accent-knowledge-bg);
  color: var(--ax-accent-knowledge-on-bg);
}

/* Der Ablauf wartet auf einen Menschen. VORBEREITET, NICHT IN BETRIEB: der
   Schritttyp "UserInteraction" (steptyperegistry.js:17) kommt im gesamten
   Backend nicht vor -- gezaehlt, 0 Treffer in backend/**\/*.go. Die Regel
   steht hier, weil die Registry ihren Vorrat selbst so begruendet ("Future
   types -- registered now so the badge CSS is ready when they are
   implemented"). Sichtbar ist sie nur in der Galerie-Kachel. */
[data-design="new"] .wf-badge.badge-ui {
  background: var(--ax-status-warning-bg);
  color: var(--ax-status-warning-on-bg);
}

/* Der Ablauf verzweigt. ".badge-if" ist ebenfalls VORBEREITET: die Registry
   vergibt fuer "Condition" ausschliesslich "badge-cond"
   (steptyperegistry.js:18), der Aliasname aus workfloweditor.css:266 hat
   keinen Erzeuger. Beide stehen hier, damit sie nicht auseinanderlaufen,
   falls doch einmal jemand "badge-if" vergibt. */
[data-design="new"] .wf-badge.badge-if,
[data-design="new"] .wf-badge.badge-cond {
  background: var(--ax-status-success-bg);
  color: var(--ax-status-success-on-bg);
}

/* DIE EINE AUSNAHME, UND SIE IST BEGRUENDET, NICHT VERGESSEN.
   ".badge-end" behaelt die SATTE Flaeche statt der Toenung. Der
   Beenden-Schritt ist der einzige, der den Ablauf abbricht -- er darf beim
   Ueberfliegen einer langen Schrittliste herausstechen. Die Lautstaerke ist
   hier Information, nicht Zierde. Entscheidung 8 hat Figmas vollflaechige
   Variante verworfen; sie ueberlebt an genau der Stelle, an der sie etwas
   aussagt.
   WER DIESE REGEL ALS SCHLAMPEREI LIEST und sie aufs Toenungsraster zieht,
   nimmt dem Abbruch seine Stimme. Der Waechter dagegen heisst "END ist
   lauter als die getoenten Gruppen" in
   tests/features/design-workfloweditor-badges.spec.ts.

   Ruling 5 (2026-09-18): die Flaeche ist "--ax-red-600", ein PRIMITIV,
   kein semantisches Token -- absichtlich. Dem Rastersystem fehlt ein
   gesaettigtes Gefahren-Flaechen-Token. Es fuehrt "--ax-status-danger"
   (ein Vordergrund) und "--ax-status-danger-bg" (eine Toenung), aber keine
   satte Flaeche, die Weiss traegt. Gemessen: Weiss auf red-500 (dunkel =
   "--ax-status-danger") haelt 3,763 -- unter der Schwelle 4,5. Auf red-600
   haelt es 4,829. Im hellen Theme ist "--ax-status-danger" ohnehin schon
   red-600, dort aendert sich also nichts. Wer hier auf "--ax-status-danger"
   zurueckstellt, macht den Beenden-Schritt im dunklen Theme unlesbar. */
[data-design="new"] .wf-badge.badge-end {
  background: var(--ax-red-600);
  color: var(--ax-text-on-accent);
}

/* Unbekannter Typ -- der Rueckfall aus getStepType() (steptyperegistry.js:31).
   Er faerbt jeden Schritttyp, den ein aelterer oder neuerer Server schickt
   und dieses Frontend nicht kennt. */
[data-design="new"] .wf-badge.badge-unknown {
  background: var(--ax-text-muted-bg);
  color: var(--ax-text-muted-on-bg);
}

/* GEGENREGEL ZUM LECK DER <link>-ZEILE (2026-09-18, Abschlussreview Befund 1 /
   Ruling 10) -- DIE EINZIGE REGEL DIESES BLOCKS OHNE "[data-design=\"new\"]".
   Spec 2.4 und das Handbuch behaupteten "null Traeger" fuer die elf
   Nicht-"wf-"-Selektoren aus workfloweditor.css. Das stimmte fuer zehn davon,
   aber nicht fuer den ERSTEN: "workfloweditor.css:14" lautet
   ".welcome > .container-top-bottom" -- und ihr EIGENER Kommentar haelt sie
   faelschlich fuer "only loaded on aiprocesseditor.html". Die Galerie erzeugt
   diese Struktur aber ebenfalls: "ContainerElementFactory.generatePageContainer()"
   (container.js:73) gibt der Seite die Klasse "welcome", und
   "DesignGalleryPage.setupUi()" (designgallerypage.js) baut darunter
   "new AtomContainerVertical(this, \"gallery-root\")" -- macht per
   "generateVerticalContainer()" (container.js:130-132) die Klasse
   "container-top-bottom" mit "id=\"gallery-root\"". Die Zeilen-14-Regel
   trifft also exakt "#gallery-root", obwohl sie das nicht soll.
   GEMESSEN am selben Knoten, einmal mit und einmal ohne die "<link>"-Zeile in
   "designgallery.html" (Playwright, "agent-admin", danach wiederhergestellt):
     - "height"/"max-height": MIT 670px ("calc(100vh - 50px)"), OHNE 695px
       ("calc(100vh - 25px)", so wie "webapp.css:1590" es fuer jede andere
       ".welcome > .container-top-bottom"-Seite vorsieht). Das ist der
       gesamte Schaden.
     - "overflow-y", "display", "flex-direction": in BEIDEN Messungen
       identisch ("auto", "flex", "column") -- das setzt bereits die generische
       ".container-top-bottom"-Basisregel ("webapp.css:2437"), workfloweditor.css:14
       schreibt hier nur denselben Wert nochmal. Kein zusaetzlicher Schaden.
   Diese Regel stellt darum ausschliesslich "height"/"max-height" wieder her.
   SPEZIFITAET: "#gallery-root" gibt "(1,1,0)" gegen "(0,2,0)" der Leckregel --
   das gewinnt unabhaengig von der Ladereihenfolge, nicht nur, weil
   "components.css" hier zufaellig zuerst laedt. Deshalb die ID und nicht die
   Klasse "container-top-bottom" (die traegt jeder Dialogtitel mit, siehe
   Kopfkommentar oben).
   DESIGNUNABHAENGIG, weil das Leck es ist: "workfloweditor.css:14" traegt kein
   "[data-design]"-Attribut und wirkt in Legacy wie in New gleichermassen,
   sobald die "<link>"-Zeile laedt.
   DIESE REGEL GEHOERT GELOESCHT, SOBALD DIE "<link>"-ZEILE AUS
   "designgallery.html" VERSCHWINDET (oder "workfloweditor.css:14" selbst auf
   die Editor-Seiten gescopt wird) -- sie hat dann keinen Anlass mehr. */
.welcome > #gallery-root {
  height: calc(100vh - 25px);
  max-height: calc(100vh - 25px);
}

/* ═══════════════════════════════════════════════════════════════════════
   C1 · DIE COCKPIT-HUELLE
   Spec: docs/superpowers/specs/2026-09-18-cockpit-huelle-design.md

   NICHT GESCOPT, WIE DER PLAN ES WOLLTE -- BERICHTIGT: der Plan begruendete
   hier, alle Klassen dieses Blocks seien neu und ein "[data-design]"-Praefix
   deshalb Zierde ohne Wirkung. `npm run test:unit` widerspricht dem:
   tests/unit/components-css.test.js ("components.css enthaelt ausschliesslich
   Regeln des neuen Designs") verlangt den Marker MECHANISCH auf jedem
   Selektor, unabhaengig davon, ob das alte Design einen Traeger dafuer hat --
   Ausnahmen stehen dort einzeln und benannt in einer eigenen Liste
   ("AUSNAHMEN"), nicht stillschweigend im CSS. Jeder Selektor unten traegt
   deshalb "[data-design=\"new\"]" -- an der Laufzeitwirkung aendert das
   nichts (die Knoten existieren im alten Design ohnehin nicht), am Testlauf
   sehr wohl.

   Masse aus Figma (DE - Chat - Conversation, 264:10065), Farben gegen die
   Rastertokens aufgeloest:
     Leiste 276 breit, Innenabstand 12/12/16, Fuge 8   -> space-3/4/2
     Eintrag 252x36, Radius 10                          -> radius-md
     Flaeche der Leiste   #12111c                       -> bg-surface-1
     Flaeche aktiv        #1a1826                       -> bg-surface-2
     Schrift aktiv        #e8e6ee                       -> text-primary
     Schrift inaktiv      #adabbb                       -> text-secondary

   DIE SCHRIFTGROESSE IST DIE EINE ABWEICHUNG: Figma fuehrt 14px, die Skala
   kennt 13 und 15. Gewaehlt ist 15 (body-md), wie Entscheidung 2 es beim
   Seitenabstand vorgemacht hat -- die naechstgelegene Stufe nehmen, statt
   die Skala um einen Sonderwert zu erweitern.
   ═══════════════════════════════════════════════════════════════════════ */

/* Abschluss-Fixwelle (2026-09-22, C1): "overflow-y: auto" stand hier vorher
   -- und macht die Leiste damit SELBST zu einer Beschneidungsbox, denn die
   Spezifikation berechnet "overflow-x" bei einseitig gesetztem "auto" auf
   "visible" ebenfalls zu "auto" (siehe die ausfuehrliche Herleitung 40
   Zeilen weiter unten bei ".chatbot-service", derselbe Fehler, hier eine
   Ebene tiefer). Eingeklappt (64px) schneidet das den Hover-Tooltip jedes
   Eintrags ab (Tooltip-Box ~60...151px, siehe dort).
   GEFAHRLOS ENTFERNT, gemessen und nicht angenommen: ".cockpit-sidebar-history"
   (weiter unten) traegt bereits "flex: 1; min-height: 0; overflow-y: auto"
   -- sie ist die einzige Stelle in dieser Spalte, deren Inhalt die
   verfuegbare Hoehe ueberschreiten kann (der Chatverlauf), und sie faengt
   das selbst ab. Kopf, Eintraege, Fach und Fuss haben feste, kurze Hoehen
   und wachsen nicht. Ohne eigenes "overflow" clippt diese Leiste also
   nichts mehr -- der Tooltip kann ungehindert ueber ihren Rand ragen. */
[data-design="new"] .cockpit-sidebar {
  width: 276px;
  flex-shrink: 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: var(--ax-space-2);
  padding: var(--ax-space-4) var(--ax-space-3) var(--ax-space-3);
  background: var(--ax-bg-surface-1);
}

/* Aufgabe A1 (2026-09-22, Befund 1+2): Organisationslogo links, Minimieren-
   Chevron rechts -- bis hierher war ".cockpit-sidebar-brand" ein leerer
   Platzhalter (28px hoch, ohne eigenes Layout), cockpitsidebar.js fuellt ihn
   seither mit Logo und Knopf. */
[data-design="new"] .cockpit-sidebar-brand {
  height: 28px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

[data-design="new"] .cockpit-sidebar-logo {
  height: 24px;
  width: auto;
  max-width: 140px;
  object-fit: contain;
}

[data-design="new"] .cockpit-sidebar-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: var(--ax-radius-sm);
  background: transparent;
  color: var(--ax-text-secondary);
  cursor: pointer;
  flex-shrink: 0;
}

[data-design="new"] .cockpit-sidebar-toggle svg {
  width: 16px;
  height: 16px;
}

[data-design="new"] .cockpit-sidebar-toggle:hover {
  background: var(--ax-bg-hover);
}

[data-design="new"] .cockpit-sidebar-item {
  display: flex;
  align-items: center;
  height: 36px;
  padding: 0 var(--ax-space-3);
  box-sizing: border-box;
  border-radius: var(--ax-radius-md);
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-body-md);
  font-weight: 500;
  text-decoration: none;
  flex-shrink: 0;
  /* Bezugsrahmen fuer den Hinweispunkt (Task 6, cockpitsidebar.js
     "showStatusDot()") -- ".status-dot" (webapp.css) positioniert sich
     absolut GEGEN diesen Eintrag, wie sie es bei einem Reiter-Knopf schon
     tut. */
  position: relative;
  /* Aufgabe A2 (2026-09-22): Fuge zwischen Symbol und Beschriftung -- beide
     stehen seither in eigenen Kindknoten, siehe cockpitsidebar.js
     "_eintrag()". */
  gap: var(--ax-space-2);
}

/* Aufgabe A2 (2026-09-22): jeder Eintrag traegt ein Symbol (Figma zeigt sie
   durchgaengig). 18px, mittig im 36px hohen Eintrag -- dieselbe Groesse wie
   die Symbole der alten Symbolleiste ("chip" in cockpitnavigation.js, dort
   ueber die aeussere 40x40-Flaeche skaliert statt ueber eine eigene
   Groessenangabe am svg). */
[data-design="new"] .cockpit-sidebar-item-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

[data-design="new"] .cockpit-sidebar-item-icon svg {
  width: 18px;
  height: 18px;
}

[data-design="new"] .cockpit-sidebar-item-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

[data-design="new"] .cockpit-sidebar-item:hover {
  background: var(--ax-bg-hover);
}

[data-design="new"] .cockpit-sidebar-item.active {
  background: var(--ax-bg-surface-2);
  color: var(--ax-text-primary);
  font-weight: 600;
}

[data-design="new"] .cockpit-sidebar-more {
  display: flex;
  align-items: center;
  height: 36px;
  padding: 0 var(--ax-space-3);
  box-sizing: border-box;
  border: 0;
  border-radius: var(--ax-radius-md);
  background: transparent;
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-body-md);
  font-family: inherit;
  cursor: pointer;
  flex-shrink: 0;
  /* Nachtrag/N1 (2026-09-23): Bezugsrahmen fuer den gespiegelten Hinweispunkt
     (cockpitsidebar.js "_setMehrAnzeigenDot()") -- dieselbe Technik wie
     ".cockpit-sidebar-item" oben ("position: relative" fuer ".status-dot",
     webapp.css), hier bisher nicht noetig, weil der Knopf zuvor keinen
     absolut positionierten Nachfahren hatte. */
  position: relative;
}

[data-design="new"] .cockpit-sidebar-divider {
  height: 1px;
  margin: var(--ax-space-2) 0;
  border: 0;
  background: var(--ax-border-soft);
  flex-shrink: 0;
}

/* Der Platz fuer den Chatverlauf. C2 fuellt ihn; sein "flex: 1" ist hier
   schon noetig, damit die Nutzerkarte am Fuss klebt, sobald sie kommt. */
[data-design="new"] .cockpit-sidebar-history {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

/* Sichtpruefung/Task 1 (2026-09-22, am Wirt gemessen): der Verdacht aus dem
   Aufgabenbrief (lange Titel ohne Umbruchpunkt) traf NICHT zu -- Task 7 hat
   das bereits per "text-overflow: ellipsis" geloest (Regel bei
   ".cockpit-sidebar-history .container-left-right-spacebetween > li" weiter
   unten). Der tatsaechliche Ueberlauf kommt von ".list-container"
   (webapp.css:6560, unangetastet, gilt unscoped fuer jede Liste): es traegt
   "margin-left: 2px" UND "width: 100%" -- macht "#sidebar-history-list"
   dadurch 2px breiter als sein Wirt. Gemessen (echtes Chromium): Wirt
   scrollWidth 254 vs. clientWidth 252, "#sidebar-history-list" reicht bis
   x=266 bei einem Wirt bis x=264 -- exakt die 2px Ueberstand aus dem Test.
   Der Rand wird hier auf 0 zurueckgenommen, statt den Ueberlauf per
   "overflow-x: hidden" nur zu verstecken: Letzteres liesse die 2px zu
   breite Liste bestehen (nur den Wirt daran hindern, selbst zu scrollen)
   und waere an der falschen Stelle riskant -- ein "overflow-x: hidden" auf
   dem falschen Knoten hat in diesem Baum schon einmal ein schwebendes
   Zeilenmenue abgeschnitten (siehe Handbuch "transform bricht schwebende
   Menues"). Das "..."-Menue dieser Zeilen ist hier zwar sicher (es portet
   sich per JavaScript nach "document.body", siehe
   moleculemenudropdownsmall.js showMenu()), aber die Korrektur an der
   Ursache braucht diese Vorsicht gar nicht erst. */
/* AUFGABE L3 (2026-09-23): der Abstand vom Kopf der Leiste zum ersten
   Verlaufseintrag war zu gross. Gemessen: er kommt NICHT von der
   Ueberschrift (".chat-history-group-header" traegt in diesem Kontext gar
   kein "margin", siehe Regel weiter unten), sondern zu gleichen Teilen aus
   ZWEI Eigenschaften des unscoped ".list-container" (webapp.css:6560, gilt
   fuer jede Liste der Plattform): "margin-top: 10px" (Aussenabstand der
   Box in ihrem Flex-Elternteil ".cockpit-sidebar-history") UND
   "padding-top: 10px" (Innenabstand der Liste selbst) -- zusammen 20px.
   Beide gehoeren hier ueberschrieben, nicht nur eine: eine allein wuerde
   den Abstand nur halbieren.
   Sollwert 8px = "var(--ax-space-2)", derselbe "Fuge"-Token, den diese
   Karte bereits fuer ihren eigenen Trenner verwendet (".cockpit-sidebar-
   divider", weiter oben, "margin: var(--ax-space-2) 0") -- keine neue
   Zahl, sondern der im Bauteil selbst schon belegte Abstandswert.
   Beide Eigenschaften wirken nur auf den ERSTEN, obersten Rand der Liste
   (sie stehen einmal am Container, nicht je Eintrag) -- der Abstand
   ZWISCHEN zwei Gruppenkoepfen entsteht dadurch nicht mit weg, er kam
   ueber diese beiden Eigenschaften nie zustande.
   Wirkt sich nicht auf den Fuss der Leiste aus: ".cockpit-sidebar-history"
   behaelt "flex: 1" (Regel oben), an der Groesse, die der Leiste insgesamt
   zusteht, aendert sich nichts -- nur der Innenraum am oberen Rand
   schrumpft. */
[data-design="new"] .cockpit-sidebar-history .list-container {
  margin-left: 0;
  margin-top: 0;
  padding-top: var(--ax-space-2);
}

/* C2b/Task 3 (2026-09-21): Figmas Verlaufszeile hat GENAU EIN Kind, einen
   Textknoten (Knoten 66:3915). Das "..."-Menue, das
   MoleculeCommandListItem automatisch mitbringt, waere dort also zu viel --
   ersatzlos streichen hiesse aber fuenf Funktionen verlieren (Umbenennen,
   Ausblenden, Word, PDF, In Projekt verschieben). Es erscheint deshalb erst
   im Ueberfahr-Zustand, den die Vorlage gar nicht zeichnet: sie wird nicht
   verletzt, sondern dort ergaenzt, wo sie schweigt.

   KORREKTUR AM AUFGABENBRIEF (Bericht Korrektur 1): der Brief sah
   "[id$=\"-icon\"]" vor. Die tatsaechliche Zeilenstruktur haengt an die vom
   Aufrufer vergebene id zusaetzliche Suffixe an (MoleculeCommandListItem.
   setupUi() -> "new MoleculeMenuDropDownSmall(this, this.id+\"-icon\", ...)"
   -> Molecule.renderUi()/AtomContainer.renderUi() haengt "-container" an
   (atomcontainer.js:403), AtomContainerDropDown haengt nochmal
   "-menucontent" an (atomcontainerdropdown.js:13)) -- KEIN Element im Baum
   traegt eine id, die auf "-icon" endet. ".dropdown"
   (atomcontainerdropdown.js:17) ist der stabile Anker: er umschliesst das
   Icon UND das Popover, unabhaengig von der (dynamischen, chat-spezifischen)
   id der Zeile.

   ".list-container > *" waere ebenfalls falsch: MoleculeList.addGroupHeader()
   haengt die Gruppenkoepfe als eigene direkte Kinder ein
   (moleculelist.js:77) -- die Regel traefe dann auch sie.
   ".container-left-right-spacebetween" (die Zeile selbst,
   moleculecommandlistitem.js:71) grenzt korrekt auf Zeilen ein.

   "visibility" statt "display": der Knopf behaelt seinen Platz, die Zeile
   springt beim Ueberfahren nicht um -- am Wirt gemessen, siehe Bericht.

   ":focus-within" ist hier VORSORGE, nicht die Behebung eines bestehenden
   Mangels (Bericht Korrektur 2): MoleculeMenuDropDownSmall.addEvents()
   haengt ausschliesslich mouseover/mouseleave an (kein Klick-, kein
   Tastatur-Handler), und weder ".dropdown" noch das Icon tragen ein
   "tabindex" -- das Menue ist in BEIDEN Designs heute nur mit der Maus
   erreichbar. Diese Regel nimmt also niemandem etwas weg; sie liegt bereit
   fuer den Tag, an dem das Molekuel fokussierbar wird.

   NACHBESSERUNG 1 (2026-09-21, am Wirt gemessen): "visibility" allein hatte
   keine Box zum Zeigen. Legacys ".dropdown" (webapp.css:5039, unangetastet)
   traegt "width: 20px; margin-right: 30px". Das passt in der breiten
   Panel-Liste des alten Designs, aber in der 276px schmalen Seitenleiste
   schrumpft die Flexbox-Kette darauf zusammen -- gemessen am echten
   Vor-Fix-Stand (Commit 6103a1ecd), erste Verlaufszeile:
     .dropdown           { width: 0,  height: 24 }
     .molecule (Wrapper)  { width: 20, height: 24 }
     img.settings-icon   { width: 24, height: 24 }  -- natuerliche Groesse,
                            quillt aus der 0px-Box heraus, rechte Kante bei
                            270, Zeilenkante bei 266 -- Ueberstand +4px.
   (Korrigiert 2026-09-21, Nachbesserung 2: hier stand zunaechst Ueberstand
   "+6"/Zeilenkante "264" -- das war eine Messung NACH einem Hover, der die
   Zeile selbst um 2px verschiebt. Der echte Vor-Fix-Wert, direkt gegen
   Commit 6103a1ecd gemessen, ist +4. Der Kantenvergleich im Test vergleicht
   beide Kanten live und haengt an keinem der beiden Zahlenwerte.)
   Playwrights "toBeVisible()" verlangt eine nichtleere Box -- bei
   "width: 0" faellt das unabhaengig von "visibility". Und das Symbol quillt
   sichtbar ueber die Zeile hinaus -- ein echter Layoutfehler, nur in der
   schmalen Leiste sichtbar, den C2b durch das Umziehen des Molekuels
   hierher eingefuehrt hat.

   NACHBESSERUNG 2 (2026-09-21, drei Messreihen am Wirt, siehe Bericht):
   (a) jede Deklaration einzeln auf ihren Legacy-Wert zurueckgesetzt und
   molW/dropW/Ueberstand erneut gemessen, gegen den geheilten (5-Deklarationen-)
   Zustand: ".dropdown{flex-shrink:0}" UND ".molecule{width:24px}" liessen
   den Ueberstand je EINZELN bei 0. (b) eine per injiziertem CSS
   nachgestellte Vorstufe widersprach der echten Messung (molW 50 statt 20)
   -- eine rekonstruierte Kaskade ist kein Beleg, nur der echte Vorzustand
   zaehlt. (c) gegen den echten Vor-Fix-Commit 6103a1ecd gemessen (Zahlen
   oben): ".molecule" schrumpft dort auf 20 (statt auf 24 zu huggen), weil
   es als Kind der ZEILE (".container-left-right-spacebetween",
   "flex-direction: row" -- dort ist die Breite die HAUPTACHSE) selbst dem
   Flex-Shrink der Zeile unterliegt.

   DIE LEHRE DIESER RUNDE: aus "(a) zeigt beide Zeilen je EINZELN entbehrlich"
   folgt NICHT "beide ZUSAMMEN entbehrlich" -- (a) hat nur Einfaktor-
   Perturbationen gegen die 5-Deklarationen-Basis gemessen, nie die
   Kombination "beide fehlen gleichzeitig". Eine erste Fassung dieser Regel
   strich beide Zeilen genau auf diesen (fehlerhaften) Schluss hin; der
   tatsaechliche Gate-Lauf gegen die Drei-Deklarationen-Kombination zeigte
   sofort wieder einen Ueberstand (268 statt der geforderten <=264) --
   ".molecule" ohne eigene Bremse UND ohne von ".dropdown" mitgezogen zu
   werden, schrumpft doch. Wer eine Deklaration streicht, muss die
   tatsaechlich auszuliefernde Kombination messen, nicht nur die
   Einzelwirkung gegen die volle Basis.

   Von den beiden tragfaehigen Einzelloesungen wird ".molecule{width:24px}"
   ausgeliefert, NICHT ".dropdown{flex-shrink:0}": Letzteres wirkt zwar
   (dieselbe Messung (a) zeigt es), aber niemand -- weder Koordinator noch
   Pruefer noch dieser Kommentar -- kann benennen, WARUM: ".dropdown" ist
   selbst Kind von ".molecule" ("flex-direction: column"), dort ist die
   Breite die KREUZACHSE, und "flex-shrink" regelt nach Spezifikation nur
   die HAUPTACHSE (hier: Hoehe). Eine Zeile mit unerklaerter Wirkung ist
   schlechter als ein etwas breiterer, aber benennbarer Selektor.

   ":has(> .dropdown)" schliesst die Sorge, dass eine blanke
   ".molecule"-Breitenregel ein kuenftiges zweites, andersartiges Kind
   derselben Zeile (".molecule" ist die allgemeine Ruecklfallklasse JEDER
   Molekuel-Unterklasse ohne eigene Klasse) still mitklemmen wuerde --
   Praezedenzfall im selben Baum: ".molecule:has(> .chunk-img-carousel)"
   (webapp.css:10967). Am Wirt bestaetigt: der Selektor GREIFT -- der
   Kantenvergleich im Gate-Test besteht nur, wenn genau dieser Wrapper
   "width: 24px; flex-shrink: 0" bekommt, und der gruene Lauf belegt das.
   Ein heutiger Gegenbeweis (ein ".molecule" OHNE ".dropdown"-Kind in
   derselben Zeile, das die Regel faelschlich mittreffen wuerde) existiert
   in dieser Zeile nicht -- MoleculeCommandListItem.setupUi() erzeugt
   ".molecule" ausschliesslich als Wrapper von MoleculeMenuDropDownSmall,
   nur wenn Kontextmenuebefehle vorliegen -- die Absicherung durch ":has()"
   ist deshalb heute strukturell ungetestet vorsorglich, nicht durch einen
   Negativfall am Wirt belegt. */
[data-design="new"] .cockpit-sidebar-history .container-left-right-spacebetween > .molecule:has(> .dropdown) {
  flex-shrink: 0;
  width: 24px;
}

[data-design="new"] .cockpit-sidebar-history .container-left-right-spacebetween .dropdown {
  visibility: hidden;
  width: 24px;
  margin-right: 0;
}

[data-design="new"] .cockpit-sidebar-history .container-left-right-spacebetween:hover .dropdown,
[data-design="new"] .cockpit-sidebar-history .container-left-right-spacebetween:focus-within .dropdown,
[data-design="new"] .cockpit-sidebar-history .container-left-right-spacebetween .dropdown:has(> .dropdown-trigger[aria-expanded="true"]) {
  visibility: visible;
}

/* #2015: seit dem Ticket greift ":focus-within" oben tatsaechlich -- die
   Textzeile ist fokussierbar, der Ausloeser ist ein <button>. Der Fokus
   blendet damit nur den KNOPF ein, nicht das Menue: das oeffnet erst eine
   Aktion (Enter/Leertaste/Pfeil ab), wie mit der Maus erst das Ueberfahren
   des Knopfs, nicht das der Zeile. Die dritte Zeile haelt den Knopf
   sichtbar, solange sein Menue offen ist: das Menue haengt dann als Portal
   an <body>, die Zeile verliert ":focus-within", und ein unsichtbarer
   Knopf koennte den Fokus beim Schliessen nicht zurueckbekommen. */

/* #2015: Fokusring in der Farbe des neuen Designs. "outline" statt des
   "box-shadow"-Rings der Knopf-Basisregel: der Ring liegt nach innen
   (Versatz -2px) und wird von der schmalen, scrollenden Seitenleiste nicht
   abgeschnitten. */
[data-design="new"] .dropdown .dropdown-trigger:focus-visible,
[data-design="new"] .command-list-item-action:focus-visible {
  outline-color: var(--ax-border-accent);
  box-shadow: none;
}

/* Der fokussierte Menueeintrag bekommt dieselbe Flaeche wie beim
   Ueberfahren (Regel "[data-design=new] .dropdown-content-small a:hover"
   oben); "[data-design=new] .dropdown-content-small a" (0,2,1) setzte sie
   sonst auf "transparent". */
[data-design="new"] .dropdown-content-small a:focus-visible {
  background-color: var(--ax-bg-hover);
  outline-color: var(--ax-border-accent);
  outline-offset: -2px;
  box-shadow: none;
}

/* ZUSAMMENGELEGT 2026-09-21 (Abschlusspruefung C2b, Befund M-5): die
   Deklarationen fuer diesen Selektor lagen in ZWEI Bloecken -- "flex: 1"
   aus Task 4 (Nachbesserung 3, Kommentar unmittelbar darunter) und die
   Einzeiligkeit aus Task 7 (weiter unten, ohne eigenen Kommentar, direkt
   hinter der Zeilenregel). Beide Herleitungen stehen jetzt beieinander
   ueber EINEM Block an dieser Stelle. An den Werten aendert sich nichts,
   und an ihrer Wirkung auch nicht: zwischen der alten und der neuen
   Position liegt keine weitere Regel, die eine dieser vier Eigenschaften
   fuer diesen Selektor setzt -- es gibt also keinen Gleichstand, den die
   Quelltextreihenfolge entscheiden koennte.

   NACHBESSERUNG 3 (2026-09-21, am Wirt gemessen, Fund des Auftraggebers):
   "MoleculeCommandListItem.addEvents()" haengt den Klick an "this.listElement",
   also an das "<li>" (AtomDisplayListItem) -- und das ist per
   ".container-left-right-spacebetween { display:flex; justify-content:
   space-between }" nur so breit wie sein Text, nicht die Zeile. Gemessen
   VOR dieser Regel (Auftraggeber, 2026-09-21): Zeile x=14..266 (Mitte
   x=140), "<li>" x=16..40 -- 24px breit. Rund 90% der 252px breiten Zeile
   waren damit klicktot: ein Klick auf die Zeilenmitte (wo ein Nutzer UND
   Playwright hinzielen) traf ins Leere. "MoleculeCommandListItem" bleibt
   unangetastet (geteiltes Molekuel, altes Design bleibt Byte fuer Byte
   gleich) -- die Breite wird rein ueber CSS nachgezogen: "flex:1" laesst
   das "<li>" den verfuegbaren Platz bis zum (24px breiten, "flex-shrink:0"
   tragenden) "..."-Menue ausfuellen.
   GEMESSEN NACH dieser Regel (2026-09-21, design-cockpit-verlauf.spec.ts,
   "Zeilenbreite-Messung"-Konsolenzeile im gruenen Lauf): "<li>" x=16..242
   -- 226px breit (Zeile weiterhin x=14..266, Mitte x=140 -- jetzt
   INNERHALB des "<li>"). Die verbleibenden 24px (242..266) sind das
   "..."-Menue, bewusst ausgespart.
   Die Zeile ist 55px hoch, das "<li>" bricht bei laengeren Titeln auf zwei
   Zeilen um ("white-space: normal", unveraendert) -- ob die Figma-Zeile
   stattdessen einzeilig mit Auslassungspunkten sein soll, ist eine
   Designfrage fuer Task 7, hier nur festgehalten, nicht entschieden.
   ENTSCHIEDEN (Task 7, siehe die Zeilenregel weiter unten): einzeilig mit
   Auslassungspunkten -- die drei Deklarationen dafuer stehen jetzt in
   diesem Block. "min-width: 0" ist dabei noetig, weil "flex: 1" oben ein
   Flex-Kind sonst nach der CSS-Vorgabe "min-width: auto" von seinem Inhalt
   aufdruecken laesst und "overflow"/"text-overflow" ignoriert. */
[data-design="new"] .cockpit-sidebar-history .container-left-right-spacebetween > li {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* C2b/Task 7 (2026-09-21, am Wirt gemessen, siehe Bericht): Aussehen nach
   Vorlage (Knoten 66:3915) -- Gruppenkopf 252x36 mit Text bei x=12, Zeile
   252x36 mit Text bei x=12, aktive Zeile mit Fuellung rgb(36, 34, 51).

   Gruppenkopf ("Heute"/"Gestern"/...): bis hierher voellig ungestylt (die
   Klasse traegt ausserhalb der Kommandopalette keine unscoped Basisregel,
   siehe Kommentar an ".cockpit-search-section .chat-history-group-header"
   weiter unten). Ueber "height"+"flex" auf die von der Vorlage verlangten
   36px gebracht (die 34px der Kommandopalette sind dagegen aus IHREM
   Innenabstand hergeleitet, 16+14+4 -- ein anderer Figma-Knoten, eine andere
   Herleitung), Groesse gedaempft wie ein Abschnittskopf.

   KORRIGIERT (2026-09-21, echter Testlauf): hier stand zunaechst dieselbe
   Grossschreibung/Sperrung wie bei ".cockpit-search-section
   .chat-history-group-header" -- ABGESCHRIEBEN von jenem Knoten (66:4114),
   nicht am eigenen Knoten (66:3915) belegt. Playwrights "allInnerTexts()"
   liest den GERENDERTEN Text (CSS-"text-transform" eingerechnet, anders als
   "textContent") -- der bestehende Test "Der Verlauf steht in der
   Seitenleiste, mit Gruppenkoepfen" vergleicht wortgetreu gegen "Heute"/
   "Gestern"/"Diese Woche"/"Älter" und schlug mit Grossschreibung prompt fehl
   ("unbekannter Gruppenkopf in [GESTERN, ÄLTER]"). Kein Beleg aus der
   Vorlage rechtfertigte die Uebernahme; entfernt statt den Test zu biegen. */
[data-design="new"] .cockpit-sidebar-history .chat-history-group-header {
  display: flex;
  align-items: center;
  height: 36px;
  padding: 0 var(--ax-space-3);
  box-sizing: border-box;
  color: var(--ax-text-muted);
  font-size: var(--ax-font-size-label-caps);
  line-height: var(--ax-line-height-label-caps);
}

/* Zeile: dieselbe Herleitung wie ".cockpit-sidebar-item" (Task 1, oben) --
   36px, Text vertikal zentriert. Die Basis
   (".chatbot-service .container-left-right-spacebetween", webapp.css:6112)
   setzt keine Hoehe und "padding: 0 0" -- hier ueberschrieben.

   Vorher 55px hoch, der Titel brach bei laengeren Namen um ("white-space:
   normal", der Browser-Vorgabewert, nie explizit gesetzt). Die Vorlage
   verlangt 36px -- das ist mit einem zweizeiligen Titel nicht vereinbar,
   deshalb hier einzeilig mit Auslassungspunkten: "min-width: 0" ist noetig,
   weil das "<li>" "flex: 1" traegt (Regel oben) -- ohne "min-width: 0"
   ignoriert ein Flex-Kind "overflow"/"text-overflow" und wird stattdessen
   von seinem Inhalt aufgedrueckt (CSS-Flexbox-Vorgabe "min-width: auto").

   NACHBESSERUNG 1 (Task 7, Fix-Runde 1, am Wirt gemessen -- Koordinator-
   Fund): links "var(--ax-space-3)" (12px) gesetzt und gemessen, kam der
   Text-Einzug bei 14px an, nicht 12. Ursache: dieselbe Basisregel
   (webapp.css:6112-6119) traegt "border-left: 2px solid transparent" --
   unveraendert, sie ist der Anker fuer die bestehende Hover-Hervorhebung
   ("border-left-color: var(--clr-accent)", webapp.css:6121, unscoped, greift
   also auch hier). Bei "box-sizing: border-box" zieht dieser Rahmen 2px vom
   Innenraum ab, UNABHAENGIG von "padding-left": der Text landet bei
   Rahmen(2) + Innenabstand(12) = 14px. Die Vorlage verlangt 12 -- links
   deshalb um genau die Rahmenbreite gekuerzt statt den (bestehenden,
   unangetasteten) Rahmen zu entfernen: "calc(var(--ax-space-3) - 2px)" =
   10px, macht 2 + 10 = 12. Rechts bleibt "var(--ax-space-3)" (12px), dort
   gibt es keinen Rahmen, der etwas abzoege. Der Rahmen selbst (und damit die
   bestehende Hover-Hervorhebung) bleibt unangetastet -- Task 7 aendert nur,
   was die Vorlagentreue verlangt, nicht das bestehende Hover-Verhalten. */
[data-design="new"] .cockpit-sidebar-history .container-left-right-spacebetween {
  height: 36px;
  padding: 0 var(--ax-space-3) 0 calc(var(--ax-space-3) - 2px);
  box-sizing: border-box;
  border-radius: var(--ax-radius-md);
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-body-md);
  /* Die ganze Zeile oeffnet den Eintrag (MoleculeCommandListItem haengt den
     Klick an die Zeile), und der Hover faerbt sie ueber die volle Breite ein
     (Regel weiter unten). Der Zeiger stand aber nur ueber dem Text auf
     "pointer" -- gemessen: Zeile 12..264, "<li>" 24..228. Die Innenabstaende
     links und rechts sahen damit tot aus, obwohl sie es nicht sind. */
  cursor: pointer;
}

/* (Die Einzeiligkeit des "<li>" stand hier bis 2026-09-21 in einem zweiten
   Block fuer denselben Selektor; sie liegt jetzt beim "flex: 1" aus Task 4
   weiter oben -- Abschlusspruefung C2b, Befund M-5.) */

/* Die aktive Zeile -- der einzige Zustand, den die Vorlage farblich
   auszeichnet (Knoten 66:3915). "--ax-bg-hover" ist dasselbe Token, das
   diese Datei fuer Hover-/Aktiv-Flaechen ohnehin schon durchgaengig
   benutzt (siehe Kommentar "Warum '--ax-bg-hover' und nicht eine der
   Flaechen aus Task 1" weiter oben in dieser Datei) und loest im dunklen
   Theme zu genau "--ax-ink-700" = rgb(36, 34, 51) auf -- der von der
   Vorlage geforderte Wert, am Wirt bestaetigt. Im hellen Theme traegt es
   "--ax-ink-100" -- die Vorlage kennt nur einen (dunklen) Beleg, das helle
   Aequivalent folgt derselben Farbleiter wie jede andere Aktiv-/Hover-
   Flaeche der Seitenleiste. */
[data-design="new"] .cockpit-sidebar-history .sidebar-history-active {
  background-color: var(--ax-bg-hover);
}

/* Der Ueberfahr-Zustand (2026-09-21, Abschlusspruefung C2b, Befund M-3).
   Er war bis hierher legacy-getoent: ".chatbot-service
   .container-left-right-spacebetween:hover" (webapp.css:6120-6123,
   unangetastet) setzt "background-color: var(--clr-surface-1)" und
   "border-left-color: var(--clr-accent)" -- zwei "--clr-*"-Wurzeln, also
   genau das, was dieses Vorhaben abloest. WEN das betrifft, sind die
   INAKTIVEN Zeilen: sie bekamen beim Ueberfahren im neuen Design
   "--ax-bg-surface-1" (rgb(18, 17, 28), ueber die Bruecke tokens.css:187)
   und einen Rahmen in "--ax-action-primary" (rgb(0, 159, 227),
   tokens.css:191) -- Werte aus der Legacy-Leiter, nicht aus der Vorlage.
   Diese Regel setzt an ihre Stelle "--ax-bg-hover" und einen transparenten
   Rahmen.

   BERICHTIGT 2026-09-21 (Nachpruefung der Abschlusspruefung, Befund N-2).
   ALTFASSUNG DIESES ABSATZES (ueberholt): "Und die Regel griff in der
   Seitenleiste MIT: sie steht bei (0,3,0) und schlug damit die Aktiv-Regel
   darueber ((0,3,0), aber frueher in der Kaskade) -- die aktive Zeile
   verlor beim Ueberfahren ihre Vorlagenfarbe."
   GRUND: die Herleitung stand verkehrt herum. Beide Regeln liegen bei
   (0,3,0) -- die Aktiv-Regel direkt darueber
   ("[data-design=new] .cockpit-sidebar-history .sidebar-history-active",
   Attribut + zwei Klassen) und die Legacy-Hover-Regel (zwei Klassen +
   Pseudoklasse). Bei Gleichstand entscheidet die Quelltextreihenfolge, und
   components.css wird NACH webapp.css geladen (cockpit.html:16 und :18) --
   die Aktiv-Regel gewann also ohnehin. Die aktive Zeile hat ihre
   Vorlagenfarbe beim Ueberfahren nie verloren. Die Regel hier bleibt
   trotzdem, weil ihr echter Zweck der oben beschriebene ist: den INAKTIVEN
   Zeilen die Legacy-Wurzeln nehmen.

   Diese Regel steht bei (0,4,0) und gewinnt damit gegen die Legacy-Regel,
   ohne "!important" und ohne webapp.css anzufassen. Gegen die Aktiv-Regel
   gewinnt sie ebenfalls -- gewollt, siehe naechster Absatz.

   WARUM DERSELBE WERT WIE FUER DIE AKTIVE ZEILE: die Vorlage (Knoten
   66:3915) zeichnet nur EINEN ausgezeichneten Zustand, den aktiven. Fuer
   einen eigenen Ueberfahr-Farbwert gibt es keinen Beleg. Zwei Token zu
   erfinden hiesse, eine Vorlagenaussage zu behaupten, die es nicht gibt --
   und weil diese Regel spezifischer ist als die Aktiv-Regel, wuerde ein
   anderer Wert der aktiven Zeile beim Ueberfahren ihre Farbe nehmen. Sie
   teilen sich deshalb "--ax-bg-hover", dasselbe Token, das diese Datei
   fuer Ueberfahr- und Aktivflaechen ohnehin durchgaengig benutzt.

   Der linke Rahmen bleibt transparent: die Zeilenregel weiter oben rechnet
   mit genau 2px transparentem Rahmen ("padding-left: calc(... - 2px)"),
   damit der Text bei 12px sitzt. Ein eingefaerbter Rahmen beim Ueberfahren
   waere ein zweiter, in der Vorlage nicht vorgesehener Auszeichner. */
[data-design="new"] .cockpit-sidebar-history .container-left-right-spacebetween:hover {
  background-color: var(--ax-bg-hover);
  border-left-color: transparent;
}

/* Der Zustandstext ("Noch keine Chats" / "Verlauf nicht erreichbar")
   bekommt denselben Einzug wie eine Zeile (12px, "--ax-space-3") und eine
   gedaempfte Farbe -- er ist keine Zeile, aber er steht an ihrer Stelle. */
[data-design="new"] .cockpit-sidebar-history-state {
  padding: var(--ax-space-2) var(--ax-space-3);
  color: var(--ax-text-muted);
  font-size: var(--ax-font-size-body-md);
}

/* Der Fuss: traegt seit Nachtrag/F4 (2026-09-22) nur noch "Agent Manager"
   (nur Administratoren) -- der Design-Umschalter ist ins Avatar-Menue der
   Kopfzeile gezogen (cockpittopbar.js), siehe dessen Klassenkommentar.
   UEBERHOLT: bis zu diesem Datum stand hier die Begruendung fuer
   ".cockpit-sidebar-chip" (Ruling 9, 2026-09-18) -- die Regel selbst ist
   mit dem Umschalter entfallen (keine andere Stelle nutzte die Klasse,
   siehe Bericht). Die Fuss-Regel bleibt bestehen: fuer Rollen ohne
   Agent-Manager-Recht ist der Fuss dann nur eine leere, abgetrennte
   Flaeche -- design-cockpit-verlauf.spec.ts prueft ihn trotzdem strukturell
   (fixer Flex-Anker, sichtbar/im Bild), unabhaengig vom Inhalt.
   BERICHTIGT (Abschluss-Fixwelle, 2026-09-22, M1): bis hierher stand hier
   auch "design-cockpit-kopfleiste.spec.ts" -- deren eigene Zusicherung
   wurde von Nachtrag/F4 selbst auf "toHaveCount(0)" (KEIN designToggleBtn
   im Fuss) umgebaut, eine NEGATIVE Pruefung, die auch ohne Fuss gruen
   bliebe. Nur die Verlauf-Spec traegt die Begruendung wirklich. */
[data-design="new"] .cockpit-sidebar-footer {
  flex-shrink: 0;
  padding-top: var(--ax-space-2);
  border-top: 1px solid var(--ax-border-soft);
}

/* C2c-1/Task 2 (2026-09-21): Die Huelle als Gitter.
   Bis hierher war der Behaelter eine waagerechte Flexbox mit bis zu drei
   Kindern: Navigationsspalte (".chatbot-service"), Sichtbarkeitsknopf
   (".visibilityButton-container", nicht auf jeder Seite vorhanden) und
   Inhaltsvorlage. Seit Task 1 kommt die Kopfzeile (".cockpit-topbar") als
   weiteres Kind dazu -- als Flex-Geschwister staende sie NEBEN der
   Navigation statt UEBER dem Inhalt.
   Zwei Zeilen, zwei Spalten: die Seitenleiste haelt Spalte 1 ueber beide
   Zeilen, die Kopfzeile sitzt in Zeile 1 / Spalte 2, alles Uebrige in
   Zeile 2 / Spalte 2. Das alte Design bleibt Flexbox -- diese Regel greift
   nur unter [data-design="new"].

   GEMESSEN (Step 1, echtes Chromium, Rolle "user", 1280px, vier Seiten:
   /cockpit.html, /cockpitfavorites.html, /projects.html,
   /project.html?projectId=<zur Laufzeit ermittelt>): auf allen vier ist die
   Kinderliste gleich aufgebaut -- Navigationsvorlage, Kopfzeile,
   Sichtbarkeitsknopf, Inhaltsvorlage (deren Klasse wechselt:
   ".chat-container" auf Chat/Projekt/Projekte, ".aiservice-container" auf
   Favoriten). Laut Quelltext bauen sechs weitere Cockpit-Seiten (Profil,
   Mein Impact, Benachrichtigungen, Intervall-Services, persoenliche
   WissensDB, Projekt-Chunks/WissensDB) keinen Sichtbarkeitsknopf -- dort nur
   Navigation, Kopfzeile, Inhalt.

   DESHALB KEINE KLASSENLISTE FUER "ALLES UEBRIGE": die Inhaltsvorlage traegt
   je Seite eine andere Klasse bzw. Id, und der Sichtbarkeitsknopf fehlt auf
   einigen Seiten ganz. Eine Aufzaehlung aller Inhaltsklassen waere auf den
   ungemessenen Seiten geraten, keine Messung. Der Gegenselektor
   ":not(.chatbot-service):not(.cockpit-topbar)" trifft stattdessen JEDES
   Kind, das nicht Navigation oder Kopfzeile ist -- unabhaengig von Zahl und
   Klasse -- und deckt damit Sichtbarkeitsknopf und Inhaltsvorlage in einer
   Regel ab.

   UEBERLAGERUNG: Sichtbarkeitsknopf und Inhaltsvorlage bekommen beide die
   Zelle Zeile 2 / Spalte 2 zugewiesen.
   BERICHTIGT 2026-09-21 (Abschlusspruefung, Fund M1) -- DIE URSPRUENGLICHE
   BEGRUENDUNG LAS IHRE EIGENE MESSUNG FALSCH HERUM. Hier stand, die
   0x0-Messung von ".visibilityButton-container" belege eine "leere Box, die
   nichts ueberlagert". Nachgemessen (echtes Chromium, /cockpit.html, neues
   Design): das Element traegt "display: none !important" (webapp.css:6536;
   die Regel ".visibilityButton-container" oeffnet bei 6535) -- ein solches Element erzeugt GAR KEINE Box, ist damit kein
   Gitterkind und belegt keine Zelle. Die 0x0-Messung belegte also nicht
   "leer", sondern "nicht vorhanden". Damit macht der ":not()"-Zweig dieser
   Regel FUER DEN SICHTBARKEITSKNOPF heute keinen messbaren Unterschied; auch
   die Nachpruefung zu Task 2, die annahm, der Knopf belege zufaellig
   Zeile 2/Spalte 2, beruhte auf dieser Fehldeutung.
   DIE REGEL BLEIBT TROTZDEM, UND ZWAR FUER DIE INHALTSVORLAGE: sie ist der
   einzige Ort, an dem "alles Uebrige" ueberhaupt eine Zelle zugewiesen
   bekommt. Ohne sie haengt die Platzierung an der Einhaengereihenfolge der
   Seiten-Objekte und an der Zahl der Kinder -- die Auto-Platzierung wuerde
   den Inhalt in die naechste freie Zelle schieben, sobald ein weiteres
   sichtbares Kind dazukommt oder eine Seite ihre Kinder anders anhaengt. Der
   Gegenselektor deckt dabei weiterhin jede Inhaltsklasse ab, ohne sie
   aufzaehlen zu muessen (die Klasse wechselt je Seite, siehe oben).

   DIE HOEHENGRENZE (ergaenzt 2026-09-21, Abschlusspruefung, Fund C1):
   "grid-template-rows: auto 1fr" allein genuegt NICHT, weil der Behaelter
   ohne bestimmte Hoehe dasteht -- ".welcome" ist "display: flex"
   (webapp.css:1601) mit "align-items: start" (:1600), streckt ihn also
   nicht. Bei unbestimmtem freiem Raum waechst "1fr" auf den
   max-content-Beitrag seines Kindes, statt es zu begrenzen; und die
   Inhaltsflaechen rechnen alle mit der VOLLEN Fensterhoehe
   (".chat-container" "height: calc(100vh - 25px)" webapp.css:2163,
   ".aiservice-execution-container"/".aiservice-container"
   "calc(100vh - 50px)" :2472/:2483, ".welcome > .container-top-bottom"
   :1611, "#myimpact-content" :1998, "#profile-content" :2046). Vor C2c-1
   steckte die Kopfzeile INNERHALB von ".chat-container"; seit Task 2 ist sie
   eine zusaetzliche Zeile DARUEBER, und niemand entlastete den Inhalt darunter.
   GEMESSEN VORHER (echtes Chromium, Rolle "user", 1280x720, neues Design):
     /cockpit.html          innerHeight 720, Behaelter 792, Ueberstand +72
     /cockpitfavorites.html innerHeight 720, Behaelter 792, Ueberstand +72
     /projects.html         innerHeight 720, Behaelter 792, Ueberstand +72
     /cockpitresults.html   innerHeight 720, Behaelter 792, Ueberstand +72
     /cockpitaiserviceexecution.html                 742, Ueberstand +22
     Gitterzeilen "72px 720px", ".welcome" 720 hoch mit "overflow-y: hidden"
     -- die 72px wurden STUMM abgeschnitten, samt dem unteren Rand des
     Chatfensters. Im ALTEN Design zur selben Zeit: Behaelter 720,
     Inhaltsunterkante 720, kein Ueberstand -- der Fehler gehoert allein
     dem neuen Design.
   DREI ZEILEN, DREI AUFGABEN:
   1. "height: 100%" gibt dem Behaelter ueberhaupt erst eine bestimmte Hoehe
      (Prozent von ".welcome", das "height: 100vh" traegt -- gemessen 720 bei
      innerHeight 720). Prozent statt "100vh", damit die Regel der Huelle
      folgt und nicht dem Fenster, falls ".welcome" je tiefer beginnt.
   2. "minmax(0, 1fr)" erlaubt der zweiten Zeile, unter ihren
      max-content-Beitrag zu schrumpfen; ein blosses "1fr" hat als
      Mindestwert "auto" und schrumpft nicht.
   3. Die Inhaltsflaeche darf ihre eigene "100vh"-Hoehe in dieser Zeile nicht
      mehr durchsetzen -- "height: auto" plus "align-self: stretch" laesst
      stattdessen das Gitter die Hoehe bestimmen. "stretch" ist noetig, weil
      der Gitterbehaelter selbst "align-items: start" traegt (webapp.css:2587,
      in seiner eigenen Regel ".container-left-right-top-aligned", :2582-2588)
      und die Gitterregel hier das nicht zurueckstellt -- die Zeile wird sonst
      nicht gefuellt.
      BERICHTIGT 2026-09-21 (Nachpruefung, Fund N1): hier stand, ".welcome"
      VERERBE sein "align-items: start" (webapp.css:1600). Das ist falsch --
      "align-items" ist keine vererbte Eigenschaft. Der wirksame Wert kommt
      aus der eigenen Regel des Behaelters, siehe oben. Die Wirkung war
      richtig beschrieben, der Mechanismus nicht, und die Verwechslung war
      gefaehrlich: wer spaeter "align-items: start" an ".welcome" entfernt,
      faende unter dem alten Verweis keinen Zusammenhang und striche
      "align-self: stretch" als ueberfluessig. Deshalb sichert der Test
      "Die Huelle bleibt im Fenster" jetzt auch eine UNTERGRENZE zu: die
      Randbox des Inhalts endet genau an der Behaelterunterkante.
      AM BESTAND FALSIFIZIERT, nicht behauptet -- mit entferntem
      "align-self: stretch" gemessen (1280x720, neues Design):
      /cockpitfavorites.html Randbox-Unterkante 336 statt 720 (die Zeile
      bleibt 648 hoch, der Inhalt fuellt sie nur bis zu seiner Inhaltshoehe),
      waehrend beide Unterkanten-Pruefungen gruen blieben. /cockpit.html
      (753) und /myimpact.html (792) fallen dagegen schon in die obere
      Pruefung -- dort waechst der Inhalt statt zu schrumpfen. Erst beide
      Richtungen zusammen decken den Rueckbau ab.
      "min-height: 0" laesst die Flaeche kleiner
      werden als ihr Inhalt, damit deren eigenes "overflow: auto/hidden"
      wieder greift, statt nach unten hinauszuwachsen. "height: auto" steht
      dabei in einer EIGENEN, bewusst schwaecher adressierten Regel -- die
      Begruendung dort.
   Die "100vh"-Hoehen in webapp.css bleiben unangetastet; sie gelten
   weiterhin fuer das alte Design und fuer jede Seite ohne diese Huelle. */
[data-design="new"] .welcome > .container-left-right-top-aligned {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto minmax(0, 1fr);
  height: 100%;
}

[data-design="new"] .welcome > .container-left-right-top-aligned > .chatbot-service {
  grid-column: 1;
  grid-row: 1 / span 2;
}

[data-design="new"] .welcome > .container-left-right-top-aligned > .cockpit-topbar {
  grid-column: 2;
  grid-row: 1;
}

[data-design="new"] .welcome > .container-left-right-top-aligned > :not(.chatbot-service):not(.cockpit-topbar) {
  grid-column: 2;
  grid-row: 2;
  align-self: stretch;
  min-height: 0;
}

/* DIE HOEHENFREIGABE STEHT ABSICHTLICH IN EINER EIGENEN, SCHWAECHER
   ADRESSIERTEN REGEL. ":where()" zaehlt immer 0, diese Regel liegt damit bei
   (0,3,0) statt bei den (0,5,0) der Regel darueber -- gewollt: sie muss die
   generischen Klassen schlagen (".chat-container", ".aiservice-container",
   ".welcome > .container-top-bottom": (0,1,0) bzw. (0,2,0)), sich aber von
   einer genaueren Adresse zurueckholen lassen. Das braucht der Schmalband-
   Block am Dateiende: unterhalb 1024px sind drei dieser Flaechen
   "position: absolute" (webapp.css:6674/:6680/:6687; die Regeln oeffnen bei
   6673/:6679/:6686) und damit AUSSER FLUSS
   -- das Gitter bestimmt ihre Hoehe dort gar nicht mehr, und sie holen sich
   ihre Legacy-Hoehe mit (0,4,0) zurueck, ohne dass hier ein
   Spezifitaets-Klimmzug noetig waere. */
[data-design="new"] .welcome > .container-left-right-top-aligned > :where(:not(.chatbot-service, .cockpit-topbar)) {
  height: auto;
}

/* ZWEITE ADRESSE FUER DIESELBE HOEHENFREIGABE -- dieselbe Falle wie beim
   Seitenabstand weiter oben (Regel an "#myimpact-content", Fixwelle 1):
   "#myimpact-content" (webapp.css:1998) und "#profile-content" (:2046)
   setzen ihre "height: calc(100vh - 25px)" unter ID-Spezifitaet (1,0,0) und
   schlagen damit jede Klassenregel, unabhaengig von der Ladereihenfolge.
   "align-self"/"min-height" kommen weiterhin von der Regel darueber --
   nur "height" braucht eine ebenso ID-adressierte Gegenregel. Ihr
   "max-height: calc(100vh - 25px)" bleibt stehen und bindet nie: die zweite
   Gitterzeile ist immer "100vh - 72px" hoch, also kleiner.
   GEMESSEN NACHHER (1280x720, neues Design): /editprofile.html
   "#profile-content" 72..720 (648 hoch), /myimpact.html "#myimpact-content"
   97..720 (623 hoch, plus sein eigener 25px-Aussenrand) -- beide Seiten
   Ueberstand 0. */
[data-design="new"] .welcome > .container-left-right-top-aligned > #myimpact-content,
[data-design="new"] .welcome > .container-left-right-top-aligned > #profile-content {
  height: auto;
}

/* GEMESSEN (Step 3, echtes Chromium): ohne diese Zeile stand ".chatbot-service"
   bei y=25, ".cockpit-topbar" bei y=0 -- 25px auseinander, obwohl beide
   dieselbe Gitterzeile (Zeile 1) belegen. Ursache ist "margin-top: 25px" auf
   ".chatbot-service" (webapp.css:5578 -- BERICHTIGT 2026-09-21,
   Abschlusspruefung, Fund M7: hier stand 5571, das ist die OEFFNENDE
   Regelzeile ".chatbot-service {"; die Deklaration "margin-top: 25px"
   selbst steht bei 5578), aus der Zeit, als die Seitenleiste
   als freischwebende, abgerundete Karte UNTER einer Luecke stand -- es gab
   damals keine Kopfzeile daneben, die auf derselben Hoehe beginnen musste.
   Seit die Kopfzeile Zeile 1 / Spalte 2 belegt (oben), verlangt Figma "auf
   derselben Hoehe" (Task 2, Step 3 des Aufgabenbriefs) -- die geerbte
   Randregel widerspricht dem jetzt direkt. Nur "margin-top" wird genullt,
   nicht Rahmen/Ecken-Radius/Hoehe: die bleiben unveraendert, das faellt der
   Panel-Aufloesung in C2c-2 zu (siehe Task-4-Brief: "Das Panel selbst
   bleibt"), nicht dieser Aufgabe. */
[data-design="new"] .chatbot-service {
  margin-top: 0;
}

/* Aufgabe A1 (2026-09-22, Befund 3): "Volle Hoehe" -- HIER geloest, was der
   Kommentar oben ("nicht Rahmen/Ecken-Radius/Hoehe... nicht dieser Aufgabe")
   ausdruecklich zurueckstellte. ".chatbot-service" traegt aus derselben
   freischwebenden-Karten-Zeit noch eine um 50px verkuerzte Hoehe
   ("height: calc(100vh - 50px)", webapp.css), einen Rahmen oben/rechts/unten
   und einen Eckradius rechts oben UND rechts unten (je 10px, webapp.css).
   Figma zeigt die Seitenleiste ohne jedes davon, buendig mit allen drei
   Fensterkanten.
   "height: 100%" nutzt dieselbe Gitterzelle wie unten ("grid-row: 1 / span 2"
   auf ".chatbot-service", Block "Die Huelle als Gitter") -- deren Elternknoten
   ".container-left-right-top-aligned" traegt bereits "height: 100%" (von
   ".welcome", "height: 100vh"), die Zelle selbst also die volle
   Fensterhoehe -- oben schon 0 (siehe "margin-top" hier druber), unten reicht
   sie damit bis zur Fensterkante.
   "border: 0" nimmt alle drei Legacy-Rahmenlinien auf einmal: eine
   Seitenleiste, die oben/unten an der Kante steht, aber seitlich weiter einen
   Rahmen traegt, waere ein neuer, unbelegter Zwischenzustand -- Figma zeigt
   keinen. "border-radius: 0" nimmt beide Ecken, nicht nur die vom Anwender
   benannte rechts oben: eine verbliebene Rundung unten rechts liefe ins
   Leere, sobald die Karte dort ohnehin an der Fensterkante steht. */
[data-design="new"] .chatbot-service {
  height: 100%;
  border: 0;
  border-radius: 0;
}

[data-design="new"] .cockpit-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ax-space-3);
  height: 72px;
  padding: 0 var(--ax-space-6);
  box-sizing: border-box;
  flex-shrink: 0;
}

/* Kopfzeile/L2 (2026-09-23, Befunde 2+4+5 des Anwenders): "display: flex"
   fehlte hier als BASISREGEL -- auf der Projektseite haengen seit dieser
   Aufgabe VIER Geschwister direkt in diesem Wirt (Projektwahl, "Neuer
   Chat", Projekteinstellungen, "+"), nicht mehr nur die EINE Agenten-/
   Projektwahl wie bisher. Ohne "display: flex" waere jedes Div-/
   Knopf-Geschwister ein eigener Block -- die drei Knoepfe fielen dann
   UNTER die Auswahl statt daneben, und "auf einer Hoehe" (Befund 5) waere
   ohne gemeinsame Zeile gar nicht moeglich. "align-items: center"
   zentriert die vier Geschwister vertikal (Befund 4); "gap" ist derselbe
   Wert wie ".cockpit-topbar-controls" rechts daneben. Fuer die
   Agentenseite (nur EIN Kind) aendert das nichts: ein Flex-Wirt mit einem
   Kind sitzt optisch wie ein Block-Wirt mit einem Kind. */
[data-design="new"] .cockpit-topbar-agent {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--ax-space-2);
}

/* BERICHTIGT (Abschluss-Fixwelle, 2026-09-22, H1 -- Bruch zwischen
   Nachtrag/F5 und Nachtrag/F1, siehe Bericht). Nachtrag/F5 hat nur
   ".container-cockpit-agent" (das INNERE Element) nach links geruemt --
   dieser Wirt behielt "flex: 1" und zog weiterhin JEDEN uebrigen Platz an
   sich. Weil ".container-cockpit-agent" seit F5 aber "width: fit-content"
   traegt, landete der gezogene Platz als LEERFLAECHE rechts NEBEN der
   Agentenwahl, innerhalb des Wirts -- und die Geschwisterspans Modell/
   Standort/Routing (nach diesem Wirt im Markup, cockpittopbar.js) blieben
   dadurch am RECHTEN Ende der Kopfzeile haengen, direkt vor den Funktionen,
   statt neben dem Agentennamen zu stehen.
   GEMESSEN (echtes Chromium, 1280x720, /cockpit.html, neues Design, Rolle
   "user", VOR dieser Korrektur): Abstand Agentenwahl-Modelltext 380px bei
   991px Kopfzeilenbreite (design-cockpit-nachtrag.spec.ts, Abschluss-
   Fixwelle/H1) -- NICHT die paar Pixel des Kopfzeilen-"gap", sondern die
   nahezu volle freie Breite.
   GEPRUEFT UND VERWORFEN: "flex: 0 1 auto" direkt an ".cockpit-topbar-agent"
   (Vorschlag des Abschlussreviews) allein reicht NICHT -- ".cockpit-topbar"
   traegt "justify-content: space-between" (oben); ohne einen wachsenden
   Flex-Posten verteilt das die freiwerdende Breite als GLEICHE Luecken
   zwischen ALLEN vier Geschwistern (Wirt/Modell/Standort/Funktionen), nicht
   als EINE Luecke vor den Funktionen -- Agent und Modell staenden dann
   selbst auseinandergezogen. Erst zusammen mit "margin-left: auto" an
   ".cockpit-topbar-controls" (unten) verschwindet dieser Nebeneffekt: ein
   Auto-Rand verbraucht die GESAMTE freiwerdende Breite an genau dieser
   Stelle, noch VOR "justify-content" (CSS Flexbox, Abschnitt 8.1) -- fuer
   "space-between" bleibt dann nichts mehr zu verteilen.
   NUR auf Agentenseiten (":has(.container-cockpit-agent)"): die
   Projektwahl direkt darunter braucht das GEGENTEIL -- ihr Wirt
   ".container-cockpit-project" hat kein eigenes "width", er fuellt sich
   normal ueber die Breite des Elternblocks; design-cockpit-kopfleiste
   .spec.ts:588 ("die Auswahl nutzt die Zeile", ">180px") verlangt deshalb
   ausdruecklich, dass der WIRT weiterhin "flex: 1" traegt und die volle
   Breite fuellt. Ohne dieses Scoping wuerde die Projektwahl auf 180px
   zurueckfallen (siehe deren eigener Wirt-Kommentar unten).
   BERICHTIGT (Aufgabe G1, 2026-09-23): das ZIEL dieser Regel -- "Modell
   soll NEBEN dem Agentennamen stehen" -- gilt seit G1 nicht mehr, der
   Anwender wollte die Modellinformation ausdruecklich bei den Funktionen
   rechts (siehe cockpittopbar.js "setupUi()"). Die Regel selbst bleibt
   trotzdem stehen: sie haelt die Agentenwahl kompakt (Nachtrag/F5), und
   genau das braucht auch G1 weiterhin -- nur die Begruendung "damit Modell/
   Standort/Routing nicht rechts haengen" ist ueberholt, seit G1 haengen sie
   dort ABSICHTLICH. */
/* BERICHTIGT (Kopfzeile/L2, 2026-09-23, Befund 1: "Projektauswahl so gross
   wie die Agentenauswahl, nicht groesser"): der Absatz unmittelbar darueber
   ("NUR auf Agentenseiten... die Projektwahl direkt darunter braucht das
   GEGENTEIL") beschrieb einen Auftrag ("die Auswahl nutzt die Zeile"), den
   der Anwender mit diesem Befund ausdruecklich umgekehrt hat -- er gilt
   seither NICHT mehr. Die Projektwahl bekommt deshalb denselben
   Wirt-Mechanismus wie die Agentenwahl: ".cockpit-topbar-agent" schrumpft
   auf den Inhalt, statt sich per "flex: 1" zu strecken. Ohne diese
   Erweiterung wuerde die Projektwahl weiterhin die gesamte linke
   Kopfzeilenhaelfte fuellen, ganz gleich, was an ihrem eigenen Innenleben
   (die vier Gegenregeln weiter unten) geaendert wird. */
[data-design="new"] .cockpit-topbar-agent:has(.container-cockpit-agent),
[data-design="new"] .cockpit-topbar-agent:has(.container-cockpit-project) {
  flex: 0 1 auto;
}

/* Aufgabe B, Befund 1 (2026-09-22, GEMESSEN): woher die Breite der
   Agentenwahl kommt. ".container-cockpit-agent" (Wirt der Testid
   "cockpit-agent-select", cockpitagentselect.js "renderUi()") traegt eine
   UNGESCOPTE Grundregel ("width: 100%", webapp.css:2652-2658) -- in der
   Kopfzeile stretcht sie sich damit auf die volle Breite des Wirts direkt
   darueber (".cockpit-topbar-agent", "flex: 1"), obwohl Agentenbild und
   Auswahl ("cockpit-service-input", ebenfalls ungescopt, feste 180px,
   webapp.css:2372) zusammen nur einen Bruchteil davon brauchen.
   GEMESSEN (echtes Chromium, 1280x720, /cockpit.html, neues Design, Rolle
   "user") VOR dieser Regel: Verhaeltnis Auswahlbreite/Kopfzeilenbreite 0.753
   (siehe design-cockpit-figma.spec.ts, Aufgabe B, dortiger erster --
   fehlgeschlagener -- Lauf: "Received: 0.7532795156407669").

   BEWUSST NICHT ueber ".cockpit-topbar-agent" selbst geloest (z. B. per
   "display: flex; justify-content: flex-end"): derselbe Wirt traegt auf
   den Projektseiten ".container-cockpit-project" (siehe die vier
   Gegenregeln direkt unter dieser), und DEREN Test ("Die Projektwahl in
   der Kopfleiste hat einen Wirt mit eigenen Regeln",
   design-cockpit-kopfleiste.spec.ts:543) verlangt ausdruecklich das
   GEGENTEIL -- "die Auswahl nutzt die Zeile" (">180px", stretcht also
   ueber die volle Wirtbreite). Ein "display: flex" auf dem gemeinsamen
   Wirt haette diesen Test gebrochen: der Block-Wirt stretcht seine Kinder
   heute per "width: auto"-Vererbung (normales Blockverhalten), ein
   Flex-Wirt saesse seine Kinder stattdessen an ihrem Inhalt aus. Die
   Regel unten aendert deshalb NUR die Agentenwahl selbst: "width:
   fit-content" nimmt ihr die 100%-Streckung. "die Funktionen sammeln sich
   auf der rechten Seite" bleibt davon unberuehrt (".cockpit-topbar-controls"
   ist ein eigener, unveraenderter Flex-Nachbar). Spezifitaet (0,3,0) gegen
   die ungescopte Grundregel (0,1,0).

   BERICHTIGT (Nachtrag/F5, 2026-09-22): bis zu diesem Datum stand hier
   zusaetzlich "margin-left: auto" -- es schob den jetzt schmalen Block an
   den rechten Rand des Wirts, "rechtsbuendig" nach dem urspruenglichen
   Auftrag von Aufgabe B ("schmaler und rechtsbuendig"). Der Anwender hat
   diesen Auftrag praezisiert: "rechtsbuendig" galt den FUNKTIONEN, nicht
   der Agentenwahl -- die steht links, waehrend Modell/Routing-Text und die
   Funktionen weiterhin rechts sitzen. "margin-left: auto" entfernt, "width:
   fit-content" (schmaler, gemessen 75,3prozent -> deutlich darunter, siehe
   Aufgabe B) bleibt -- die Zusicherung "schmal" gilt unveraendert weiter,
   nur "rechtsbuendig" nicht mehr. Ohne eigenes "margin-left" faellt der
   Block auf das normale Blockverhalten zurueck (margin-left: 0) und steht
   damit am linken Rand des Wirts. */
[data-design="new"] .cockpit-topbar-agent .container-cockpit-agent {
  width: fit-content;
  margin-left: 0;
}

/* Aufgabe G1 (2026-09-23): ".cockpit-topbar-modell" (Sichtpruefung/Task 3,
   2026-09-22 -- der sekundaere Text neben der Agentenwahl: Modellname,
   Routing-Chip, seit Nachtrag/F1 auch der jetzt wieder entfernte
   Datenstandort) entfaellt HIER ersatzlos -- die Modellinformation zieht zu
   den Funktionen rechts und braucht dort eine Chip-Form, keinen reinen
   Fliesstext mehr. Der nur EINE verbliebene Nutzer war "standortEl", und
   der ist mit der Anzeige selbst weg (siehe cockpittopbar.js,
   Konstruktor-Kommentar an "this.modellEl"). Ersatz: ".cockpit-topbar-
   modell-chip" bei ".cockpit-topbar-chip" weiter unten -- derselbe Zweck
   (Modell/Routing, sekundaerer Text), neue Form, neuer Ort im Markup
   (rechts statt neben der Agentenwahl). */

/* DIE PROJEKTWAHL IN DER KOPFZEILE (ergaenzt 2026-09-21, Abschlusspruefung,
   Fund I2) -- dieselbe Fehlerklasse wie der Avatar-Fund weiter oben, nur
   fuer den ganzen Wirt statt fuer eine Eigenschaft.

   "OrganismsCockpitProjectSelect" rendert ".container-cockpit-project".
   JEDE Regel, die diesen Behaelter kennt, ist panelgebunden
   (webapp.css:11687 Wirt, :11706 Auswahl, :11712 Knopf, :11726 Knopfbild;
   components.css:3085 Innenabstand) -- eine ungescopte Regel gibt es nicht.
   Seit Task 3 haengt derselbe Organismus aber in ".cockpit-topbar-agent",
   und dort greift keine davon. Die Agentenwahl kam ohne eigene Regel durch,
   weil ihr Behaelter ".container-cockpit-agent" eine UNGESCOPTE Grundregel
   hat (".container-cockpit-agent", webapp.css:2652-2658: "width: 100%"
   :2653, "margin-top: 10px" :2654, "display: flex" :2655,
   "flex-direction: row" :2656, "align-items: center" :2657) -- die
   Projektwahl hat keine.

   GEMESSEN VORHER (echtes Chromium, 1280x720, /projects.html, neues Design,
   Rolle "user"; zum Vergleich der Panel-Wirt im alten Design):
     Wirt      Kopfzeile "display: block"   | Panel "flex", "gap: 8px"
     Auswahl   180px breit, 11px Schrift,   | 127px (flex 1 1 auto),
               "margin: 10px 0 10px 20px"   | 12px Schrift, "margin: 0"
     "+"-Knopf 56x42, "padding: 9px 16px"   | 36x36, "padding: 0"
     Knopfbild 24x24                        | 18x18
   In der Kopfzeile fiel die Auswahl also auf ".cockpit-service-input"
   zurueck (feste 180px, die bei langen Projektnamen abschneiden, und ein
   unmotivierter 20px-Linksrand mitten in einer 24px-Kopfzeile), und aus dem
   Symbolknopf wurde ein breiter Textknopf.

   DIE VIER GEGENREGELN bauen die Struktur des Panel-Wirts nach -- Zeile,
   zentriert, mit Abstand; Auswahl waechst, Knopf bleibt quadratisch --,
   NICHT seine Masse: der Knopf ist hier 42x42 statt 36x36, weil die Auswahl
   in der Kopfzeile gemessen 42px hoch ist (im Panel 30px) und ein
   Symbolknopf so hoch sein muss wie das Feld daneben. 18x18 fuer das Bild
   ist woertlich der Panelwert (webapp.css:11726): dieselbe Rolle, dieselbe
   Groesse. Der Abstand ist "--ax-space-2" (8px) -- derselbe Wert, den der
   Panel-Wirt als "gap" fuehrt und den ".cockpit-topbar-controls" rechts
   daneben bereits nutzt.
   Spezifitaet (0,3,0) gegen (0,1,0) der generischen Klassen; die
   Panelregeln (0,2,0) treffen diesen Wirt gar nicht erst.

   BERICHTIGT (Kopfzeile/L2, 2026-09-23, Befund 1): "order: 1" ist NEU --
   der Wirt ist seither nicht mehr das einzige Kind von ".cockpit-topbar-
   agent" (siehe Befund 2 unten), "order" haelt ihn trotzdem an erster
   Stelle, unabhaengig von der tatsaechlichen Einfuegereihenfolge (die
   Projektwahl rendert asynchron, siehe cockpittopbar.js "setupUi()"). */
[data-design="new"] .cockpit-topbar-agent .container-cockpit-project {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--ax-space-2);
  order: 1;
}

/* BERICHTIGT (Kopfzeile/L2, 2026-09-23, Befund 1): "flex: 1 1 auto" liess
   die Auswahl bis zu diesem Datum jede freie Breite des Wirts fuellen --
   GENAU das Verhalten, das der Anwender jetzt umgekehrt haben wollte ("so
   gross wie die Agentenauswahl, nicht groesser", design-cockpit-kopfleiste
   .spec.ts hielt das bisher als "die Auswahl nutzt die Zeile" fest, dort
   ebenfalls berichtigt). "flex: 0 1 auto" nimmt ihr den Wachstumszwang
   (Grow 0), erlaubt aber weiterhin das Schrumpfen unter Platznot -- die
   Auswahl faellt jetzt auf ihre inhaltsbestimmte Breite zurueck, denselben
   Mechanismus, den "#agentselect" (webapp.css:2379, "width: 100%" in einem
   seit Nachtrag/F5 "width: fit-content"-Wirt) fuer die Agentenwahl schon
   traegt. */
[data-design="new"] .cockpit-topbar-agent .cockpit-project-select-input {
  flex: 0 1 auto;
  min-width: 0;
  width: auto;
  margin: 0;
}

/* Aufgabe M3 (2026-09-23, Anwender: "Die unterschiedlichen Hoehen
   (Projektauswahlbox und Buttons) sehen nicht gut aus, die Hoehe muss
   einheitlich sein.") -- ZWEITER ANLAUF: Kopfzeile/L2 (Regeln direkt oben
   und unten) hat bereits alle KNOEPFE der Kopfzeile auf eine gemeinsame
   Hoehe (31px) gebracht, dabei aber die Auswahlbox selbst nicht angefasst
   -- sie ist ein <select>, kein <button>, jede der L2-Regeln zielt aber auf
   ".cockpit-project-add-btn"/".cockpit-topbar-chip".
   URSACHE (GEPRUEFT, nicht vermutet): die globale Formularregel
   ":where([data-design=\"new\"]) select" (components.css, "Formulare"-
   Block weiter oben) setzt "min-height: var(--ax-size-field-md)" -- 42px
   (tokens.css). Ohne eigene Hoehenregel bleibt die Auswahl bei dieser
   Untergrenze haengen, waehrend die Knoepfe daneben seit L2 31px hoch sind.
   Genau der aus L2 bekannte Wert (dortiger Kommentar: "DAMALS 42px hohe
   Auswahl") -- L2 hat den Knopf verkleinert, nicht die Auswahl.
   TRIFFT BEIDE AUSWAHLFELDER DER KOPFZEILE: ".cockpit-service-input" ist
   die gemeinsame Klasse von Projektwahl (".cockpit-project-select-input",
   cockpitprojectselect.js) UND Agentenwahl ("#agentselect",
   cockpitagentselect.js) -- eine Regel statt zwei, dieselbe Quelle,
   dieselbe Form, kein Sonderfall fuer eine der beiden Seiten.
   "min-height: 0" ist noetig, nicht nur "height: 31px" allein: CSS "min-
   height" schlaegt ein kleineres "height" IMMER (unabhaengig von
   Spezifitaet/Kaskade), die globale 42px-Untergrenze muss deshalb
   ausdruecklich auf 0 zurueckgesetzt werden, sonst bliebe die Auswahl trotz
   "height: 31px" bei 42px haengen. "box-sizing: border-box" ist bereits
   Teil derselben globalen "select"-Regel (siehe oben) -- keine zweite
   Deklaration noetig, "height: 31px" ist deshalb bereits die volle
   Aussenhoehe inklusive Rahmen, wie bei ".cockpit-topbar-chip" (unten). */
[data-design="new"] .cockpit-topbar-agent .cockpit-service-input {
  height: 31px;
  min-height: 0;
}

/* BERICHTIGT (Kopfzeile/L2, 2026-09-23, Befund 4: "alle Knoepfe gleich
   gross"): 42x42 stammte aus dem Massvergleich mit der DAMALS 42px hohen
   Auswahl (siehe GEMESSEN oben) -- diese Aufgabe bringt die Auswahl auf
   Agentenwahl-Groesse zurueck (Befund 1) und alle Knoepfe der Kopfzeile auf
   eine gemeinsame Hoehe: 31px, dieselbe wie ".cockpit-topbar-chip" ("Chat
   sichern", Projekteinstellungen, "Neuer Chat", Avatar -- siehe dort).
   42px bleibt NICHT bestehen: eine zweite Knopfgroesse in derselben Zeile
   waere genau der Befund, den Aufgabe L2 beheben soll. Das Knopfbild
   bleibt 18x18 (unveraendert, passt weiterhin in die kleinere Box). "order:
   4" haelt den Knopf an letzter Stelle der linken Gruppe -- er haengt seit
   dieser Aufgabe als Geschwister direkt in ".cockpit-topbar-agent"
   (cockpitprojectselect.js "addEvents()"), nicht mehr nur im eigenen Wirt
   ".container-cockpit-project"; der Selektor bleibt trotzdem ein
   Nachfahren-Selektor (kein direktes-Kind-">"), er trifft die Klasse an
   jeder Tiefe. */
[data-design="new"] .cockpit-topbar-agent .cockpit-project-add-btn {
  flex: 0 0 auto;
  width: 31px;
  height: 31px;
  padding: 0;
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  order: 4;
}

[data-design="new"] .cockpit-topbar-agent .cockpit-project-add-btn img {
  width: 18px;
  height: 18px;
}

/* Kopfzeile/L2 (2026-09-23, Befund 2: "Neuer Chat" und Projekteinstellungen
   linksbuendig zwischen Projektwahl und "+"): beide Knoepfe haengen bereits
   an der richtigen Stelle im DOM (cockpittopbar.js "setzeNeuerChatKnopf()"/
   "setzeProjekteinstellungenKnopf()", je in "this.agentSlot" ==
   ".cockpit-topbar-agent") -- diese beiden Regeln legen nur noch die
   sichtbare Reihenfolge zwischen den vier linken Elementen fest, ueber
   Testid statt Klasse (beide teilen sich ".cockpit-topbar-chip" mit den
   rechten Funktionsknoepfen, eine Klassenregel wuerde die treffen). */
[data-design="new"] .cockpit-topbar-agent [data-testid="btn-new-chat"] {
  order: 2;
}

[data-design="new"] .cockpit-topbar-agent [data-testid="projekt-einstellungen"] {
  order: 3;
}

/* "margin-left: auto" (Abschluss-Fixwelle, 2026-09-22, H1): verbraucht die
   GESAMTE freiwerdende Kopfzeilenbreite an dieser Stelle, noch VOR
   "justify-content" (siehe ".cockpit-topbar-agent:has(...)" oben fuer die
   volle Begruendung) -- ohne diesen Rand wuerde "justify-content:
   space-between" dieselbe Breite als gleiche Luecken zwischen ALLEN
   Geschwistern verteilen und Agent/Modell auseinanderziehen. Auf
   Projektseiten (Wirt bleibt "flex: 1") ist bereits keine Breite mehr
   uebrig -- dort bewirkt dieser Rand nichts. */
[data-design="new"] .cockpit-topbar-controls {
  display: flex;
  align-items: center;
  gap: var(--ax-space-2);
  flex-shrink: 0;
  margin-left: auto;
}

/* 2026-09-22 (Sichtpruefung/Task 2, GEMESSEN): die Basisregel
   (":where([data-design=\"new\"]) button", oben in dieser Datei) setzt
   "display: inline-flex" ohne "align-items" -- bewusst, siehe deren eigener
   Kommentar ("ersatzlos entfernt, kein Legacy-Gegenstueck"), das darf hier
   nicht nachgeholt werden (Subset-Invariante der Basisregel). Ohne eigenes
   "align-items" faellt der Textknoten als anonymes Flex-Kind auf den
   Anfang der Querachse zurueck: am Wirt gemessen lag der Text alle drei
   Kopfzeilen-Chips ("Chat sichern", Sprache, Theme) rund 1-2px unter dem
   oberen und rund 14-15px ueber dem unteren Rand -- deutlich ausserhalb der
   Mitte. Diese Klasse ist keine Basisregel, sondern ein Zweck-Bauteil --
   "align-items: center" hier ist deshalb kein Verstoss gegen die
   Subset-Invariante. */
[data-design="new"] .cockpit-topbar-chip {
  height: 31px;
  padding: 0 var(--ax-space-3);
  border: 1px solid var(--ax-border-soft);
  border-radius: var(--ax-radius-full);
  background: transparent;
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-label-sm);
  font-family: inherit;
  cursor: pointer;
  align-items: center;
}

/* Aufgabe G1 (2026-09-23): Modell-/Routing-Chip rechts bei den Funktionen
   (cockpittopbar.js "setzeModell()"/"setzeRouting()", Testid
   "cockpit-modell"/"cockpit-routing") -- Ersatz fuer das entfallene
   ".cockpit-topbar-modell" (siehe dessen frueheren Standort weiter oben,
   bei ".cockpit-topbar-agent:has(...)"). Traegt IMMER zusammen mit
   ".cockpit-topbar-chip" (oben): der Grundlook (Rand, Pille, Innenabstand)
   kommt von dort, hier nur das, was ein reiner Info-Knoten zusaetzlich
   braucht bzw. NICHT will.
     display: inline-flex -> ".cockpit-topbar-chip" bekommt "display:
       inline-flex" bisher nur ueber die Knopf-Basisregel
       (":where([data-design=\"new\"]) button", oben in dieser Datei) --
       der Modell-/Routing-Chip ist aber ein "<span>", kein "<button>"
       (reiner Info-Text, kein Klick), braucht das deshalb hier selbst.
     cursor: default -> ueberschreibt den geerbten Zeigerfinger von
       ".cockpit-topbar-chip" (dort richtig, die anderen drei Chips --
       "Chat sichern", Projekteinstellungen, Avatar -- sind klickbar).
       Gleiche Spezifitaet (0,2,0), spaeter in der Datei -> gewinnt.
     min-width/overflow/text-overflow/white-space -> derselbe Schutz wie
       zuvor an ".cockpit-topbar-modell" (Abschluss-Fixwelle/H2,
       2026-09-22): ohne "min-width: 0" schrumpft ein Flex-Kind nie unter
       seine min-content-Breite, "text-overflow: ellipsis" greift dann nie.
       Der Modellname selbst ist kurz und fest, aber ohne diesen Schutz
       koennte ein langer Name die Kopfzeile aufbrechen lassen.
     border-color: var(--stufe-farbe, ...) -> die Datensouveraenitaetsstufe
       (cockpittopbar.js "_setzeStufenfarbe()") ueberschreibt NUR die
       Randfarbe, nicht die Flaeche -- ein Dauerzustand ist keine
       Handlungsaufforderung, dieselbe Ueberlegung wie bei
       ".chat-regler-knopf" (siehe dort, "Rand statt Flaeche"). Ohne
       gesetzte Stufe (kein Provider/kein bekannter Wert, siehe
       cockpitagentselect.js "setModel()") faellt der Rand auf denselben
       Wert zurueck wie jeder andere Chip ("--ax-border-soft") -- keine
       geratene Farbe. Kontrast der drei Randfarben gegen den
       Kopfzeilengrund in beiden Themes: siehe Bericht zu Aufgabe G1
       (design-kopfleiste-souveraenitaet.spec.ts misst live -- alle drei
       Stufen, beide Themes).
       BERICHTIGT (Fix-Runde, 2026-09-23): "_setzeStufenfarbe()" setzt seither
       "--ax-status-*-on-bg" statt der PLAIN-Marken "--ax-status-*" -- die
       plain "success"/"warning" verfehlten die 3:1-Schwelle gegen
       "--ax-bg-app" im hellen Theme (2,98:1 / 2,88:1, siehe dortiger
       Kommentar fuer die volle Herleitung). Dieselbe Chip-Regel hier bleibt
       unveraendert, sie liest nur, was in "--stufe-farbe" steht.
     box-sizing: border-box -> GEMESSEN (Gate-Lauf 2026-10-02): die 31px aus
       ".cockpit-topbar-chip" schliessen bei den Knoepfen den Rand ein (die
       Knopf-Basisregel setzt "border-box"), beim "<span>" nicht -- der Chip
       stand mit 33px zwischen 31px hohen Knoepfen. */
[data-design="new"] .cockpit-topbar-modell-chip {
  display: inline-flex;
  box-sizing: border-box;
  cursor: default;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-color: var(--stufe-farbe, var(--ax-border-soft));
}

/* Aufgabe N5 (2026-09-23, Anwender-Befund: "ein leerer Rahmen vor 'Routing
   aktiv'"): "display: inline-flex" oben (Spezifitaet 0,2,0) schlaegt die
   native UA-Regel "[hidden] { display: none }" (0,1,0) -- derselbe Kniff wie
   ".cockpit-chat-sichern-menu[hidden]"/".cockpit-avatar-menu[hidden]"/
   ".cockpit-sidebar-item[hidden]" (alle oben in dieser Datei): kein
   "!important", stattdessen die hoehere Spezifitaet (0,3,0) hier.
   cockpittopbar.js "setzeModell()"/"setzeRouting()" setzen "hidden" auf
   diesem Knoten, sobald kein Modellname feststeht (der Knoten selbst bleibt
   im DOM -- ein elternloser Knoten liesse "insertAdjacentElement()" beim
   Routing-Chip sonst wieder als stillen No-Op scheitern, siehe
   cockpittopbar.js "setupUi()"). */
[data-design="new"] .cockpit-topbar-modell-chip[hidden] {
  display: none;
}

/* #2020: der Routing-Chip ("⚡ Routing aktiv") sah mit Rahmen und Pille wie
   ein Knopf aus, ist aber reine Information. Ohne Rahmen liest er sich als
   Statustext; Hoehe und Innenabstand bleiben (".cockpit-topbar-chip"), damit
   die Kopfzeile auf einer Linie bleibt. "cursor: default" kommt schon von
   ".cockpit-topbar-modell-chip". (0,2,0), spaeter in der Datei -> schlaegt
   die Randfarbe von ".cockpit-topbar-modell-chip". */
[data-design="new"] .cockpit-topbar-info {
  border-color: transparent;
  color: var(--ax-text-secondary);
}

/* 2026-09-22 (C2c-2/Task 8): Uebergangs-Wirt der Zeitersparnis-Zeile in der
   Kopfzeile (cockpittopbar.js "setupUi()", der Block, der
   "zeitersparnisSlot"/"zeitersparnisWirt" baut), bis ein spaeterer Task
   (C2d) sie endgueltig in den Leistenfuss der Seitenleiste verschiebt. Nur
   eine Hoehen-/Ausrichtungsleine fuer die 72px hohe Kopfzeile -- die Kachel
   selbst (".kpi-tile", oben in dieser Datei) bleibt unveraendert. "overflow:
   hidden" ist eine reine Vorsichtsmassnahme, kein gemessener Ueberlauf: sie
   verhindert nur, dass die Kopfzeile aufbrechen koennte, sollte ein
   Sprachtext einmal laenger ausfallen als bisher beobachtet. */
[data-design="new"] .cockpit-topbar-timesaving {
  display: flex;
  align-items: center;
  max-height: 56px;
  overflow: hidden;
}

[data-design="new"] .cockpit-topbar-timesaving .timesaving-row {
  margin: 0;
}

/* Sichtpruefung/Task 3 (2026-09-22): die kompakte Zeitersparnis --
   "MoleculeTimeSavingRow" mit "kompakt=true" (moleculetimesavingrow.js).
   Nur Sinnbild und Stundenwert, die Worterklaerung sitzt als title-Attribut
   am Knoten (Hover) statt als eigene Beschriftung -- deshalb kein Aequivalent
   zu ".kpi-label" hier. "cursor: pointer" fehlt der eigenen Klasse (anders als
   der vollen Zeile, ".timesaving-row" traegt es unscoped in webapp.css), weil
   der Knoten NICHT ".timesaving-row" heisst -- eine eigene Klasse, kein
   Alias. */
[data-design="new"] .timesaving-row-kompakt {
  display: flex;
  align-items: center;
  cursor: pointer;
}

[data-design="new"] .timesaving-row-kompakt .kpi-value {
  font-size: var(--ax-font-size-label-sm);
  font-weight: 600;
}

/* #2050: der Knopf "In Wissensdatenbank speichern" (bis dahin der Export-Knopf
   aus #2020 mit Aufklappmenue) traegt Datenbank-Symbol plus Beschriftung
   (cockpittopbar.js "setzeSicherungsBefehl()"). Das Menue samt seinen
   Regeln (".cockpit-chat-sichern-menu"/"-option") ist entfallen. */
[data-design="new"] .cockpit-chat-sichern-knopf {
  gap: var(--ax-space-1);
  white-space: nowrap;
}

[data-design="new"] .cockpit-chat-sichern-knopf svg {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
}

/* Die Sammelregel ":where([data-design=new]) button:hover:not(:disabled)"
   (0,2,1) faerbt NUR den Hintergrund (Primaerton) und liesse die graue
   Schrift darauf stehen. Diese Regel (0,3,0) setzt beide Eigenschaften.
   (#2050: ein offener Zustand existiert ohne Menue nicht mehr.) */
[data-design="new"] .cockpit-chat-sichern-knopf:hover {
  background: var(--ax-bg-hover);
  color: var(--ax-text-primary);
}

/* Unterhalb 1024px nur das Symbol -- die Kopfzeile traegt dort schon
   Modell, Zeitersparnis und Avatar. Der Name bleibt ueber "aria-label"
   erhalten. Unterhalb 640px weicht der ganze Knopf ins Avatar-Menue. */
@media (max-width: 1024px) {
  [data-design="new"] .cockpit-chat-sichern-text {
    display: none;
  }
}

/* Sichtpruefung/Task 3 (2026-09-22): das Avatar-Menue -- "Alles Persoenliche"
   (Sprache, Erscheinung, Profil, Abmelden), Entscheidung des Auftraggebers.
   Dasselbe Muster wie das fruehere Menue "Chat sichern" (#2050 entfallen)
   (Task 2 korrigiert): eigene Anker-/Aufklapp-/Options-Regeln statt einer der
   Bibliotheksmenues, siehe cockpittopbar.js "_baueAvatarMenu()" fuer die
   Begruendung. Nicht dieselben Klassen wiederverwendet: ".cockpit-chat-
   sichern-option" traegt eine eigene, von "aiprocessstepeditor-pdf.spec.ts"
   direkt gepruefte Bedeutung ("Menue Chat sichern") -- eine geteilte Klasse
   fuer zwei inhaltlich verschiedene Menues waere keine Ersparnis, nur eine
   neue Kopplung. */
[data-design="new"] .cockpit-avatar {
  position: relative;
}

/* #2024: Avatar-Knopf mit Initialen-Kreis (AtomDisplayInitials) statt "👤".
   Linker Innenabstand kleiner, damit der Kreis in der 31px-Pille sitzt.
   EIGENE :hover-Regel: sonst greift die Sammelregel
   ":where(...) button:hover:not(:disabled)" (0,2,1) gegen
   ".cockpit-topbar-chip" (0,2,0) und legt die Primaerflaeche unter den
   Knopf -- der Kreis (selbst Primaerflaeche) verschwaende darin und der
   Pfeil ("--ax-text-secondary") verloere seinen Kontrast. (0,4,0) schlaegt
   sie ohne !important. */
[data-design="new"] .cockpit-topbar-chip.cockpit-avatar-btn {
  gap: var(--ax-space-1);
  padding-left: 3px;
}

[data-design="new"] .cockpit-topbar-chip.cockpit-avatar-btn:hover:not(:disabled) {
  background: var(--ax-bg-hover);
}

[data-design="new"] .atom-initials {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 23px;
  height: 23px;
  border-radius: var(--ax-radius-full);
  background: var(--ax-action-primary);
  color: var(--ax-action-on-primary);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

[data-design="new"] .cockpit-avatar-menu {
  position: absolute;
  top: calc(100% + var(--ax-space-1));
  right: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  min-width: 200px;
  background: var(--ax-bg-elevated);
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-md);
  box-shadow: var(--ax-shadow-card);
  padding: var(--ax-space-1);
}

/* Dieselbe Falle wie frueher ".cockpit-chat-sichern-menu[hidden]" (Task 2,
   GEMESSEN): ohne diese Zeile schlaegt die Klassenregel ("display: flex",
   Spezifitaet 0,2,0) die native UA-Regel "[hidden] { display: none }"
   (0,1,0), unabhaengig von der Ladereihenfolge. Kein "!important" --
   stattdessen die hoehere Spezifitaet (0,3,0). GEGENGEPRUEFT (Sichtpruefung/
   Task 3): Zeile entfernt, "Das Avatar-Menue fuehrt Sprache, Erscheinung,
   Profil und Abmelden" faellt sofort an der ersten Zusicherung
   ("not.toBeVisible()") -- das Menue bleibt trotz "hidden" sichtbar. */
[data-design="new"] .cockpit-avatar-menu[hidden] {
  display: none;
}

/* MOBIL/A (2026-09-26): ".cockpit-avatar-menu-mobil-option" -- die
   Sicherungsbefehle, die unterhalb 640px flach im Avatar-Menue stehen
   (cockpittopbar.js "_sicherungsZeile()"). Sie sind Eintraege DESSELBEN
   Menues und tragen deshalb dieselbe Zeilenform; eine eigene Klasse
   bekommen sie trotzdem, weil zwei Bestandstests
   ("design-shell-parts.spec.ts", AVATAR_ROW/"avatarMenuRhythm()") die
   ERSTEN ZWEI ".cockpit-avatar-menu-option" der Liste messen -- oberhalb
   des Haltepunkts sind die mobilen Zeilen "display: none" und haetten
   dort als Messobjekt nur Nullen geliefert. */
[data-design="new"] .cockpit-avatar-menu-option,
[data-design="new"] .cockpit-avatar-menu-mobil-option {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--ax-space-2) var(--ax-space-3);
  border: none;
  border-radius: var(--ax-radius-sm);
  background: transparent;
  color: var(--ax-text-primary);
  font-family: inherit;
  font-size: var(--ax-font-size-label-sm);
  cursor: pointer;
}

[data-design="new"] .cockpit-avatar-menu-option:hover,
[data-design="new"] .cockpit-avatar-menu-mobil-option:hover {
  background: var(--ax-bg-hover);
}

/* #2049: die Zeile "Modus" -- Text links, der Hell/Dunkel-Switch
   (AtomThemeSwitch) rechts. Die Zeile ist ein <div>, kein <button> --
   ohne "border-box" addiert sich das Innenpolster auf "width: 100%", und
   die Zeile ragt rechts aus dem Menue. Kein Hover: klickbar ist nur der
   Switch selbst. */
[data-design="new"] .cockpit-avatar-menu-option.cockpit-avatar-menu-modus {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ax-space-3);
  cursor: default;
}

[data-design="new"] .cockpit-avatar-menu-option.cockpit-avatar-menu-modus:hover {
  background: transparent;
}

/* #2049: AtomThemeSwitch -- Spur mit Sonne (hell, links) und Mond (dunkel,
   rechts); der Knopf liegt unter dem aktiven Symbol. Spur 56x28 (border-
   box, 1px Rahmen -> 54px innen), Knopf 22px mit 2px Rand: Verschiebung
   54-22-2-2 = 28px. */
[data-design="new"] .atom-theme-switch {
  position: relative;
  flex-shrink: 0;
  box-sizing: border-box;
  width: 56px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-full);
  background: var(--ax-bg-input);
  cursor: pointer;
}

[data-design="new"] .atom-theme-switch:focus-visible {
  outline: 2px solid var(--ax-action-primary);
  outline-offset: 2px;
}

[data-design="new"] .atom-theme-switch-knopf {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--ax-action-primary);
  transform: translateX(0);
  transition: transform 120ms ease-out;
}

[data-design="new"] .atom-theme-switch[aria-checked="true"] .atom-theme-switch-knopf {
  transform: translateX(28px);
}

[data-design="new"] .atom-theme-switch-symbol {
  position: absolute;
  top: 2px;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ax-text-secondary);
  transition: color 120ms ease-out;
}

[data-design="new"] .atom-theme-switch-symbol svg {
  width: 14px;
  height: 14px;
}

[data-design="new"] .atom-theme-switch-hell {
  left: 2px;
}

[data-design="new"] .atom-theme-switch-dunkel {
  right: 2px;
}

[data-design="new"] .atom-theme-switch[aria-checked="false"] .atom-theme-switch-hell,
[data-design="new"] .atom-theme-switch[aria-checked="true"] .atom-theme-switch-dunkel {
  color: var(--ax-text-on-accent);
}

/* Nachbesserung (2026-09-22, C-2): Trennlinie zwischen den persoenlichen
   Zielen (Profil, Persoenliche Wissensdatenbank, Wiederh. Services,
   Nachrichten, Nachrichten verwalten, Support) und Sprache/Erscheinung/
   Abmelden -- dieselbe Regel wie ".cockpit-sidebar-divider" (siehe dort). */
[data-design="new"] .cockpit-avatar-menu-divider {
  height: 1px;
  margin: var(--ax-space-2) 0;
  border: 0;
  background: var(--ax-border-soft);
  flex-shrink: 0;
}

/* NICHT IM PLAN, ABER NOTWENDIG (waehrend des eigenen Testlaufs gefunden):
   ".cockpit-sidebar-item[hidden]" bleibt ohne diese Regel SICHTBAR. Die
   native UA-Regel "[hidden] { display: none }" und die Autorenregel
   "[data-design=\"new\"] .cockpit-sidebar-item { display: flex; ... }"
   (oben) stehen bei GLEICHER Spezifitaet (0,2,0 gegen 0,1,0 -- der
   Design-Marker zaehlt mit) gegeneinander -- bei einem Gleichstand
   gewinnt ohnehin die Autorenregel gegen die UA-Regel unabhaengig von der
   Ladereihenfolge, hier zusaetzlich per hoeherer Spezifitaet. cockpitsidebar.js
   setzt "hidden" auf die Fach-Eintraege (Favoriten/Ergebnisse) und erwartet,
   dass sie dadurch aus der ersten Ebene verschwinden -- ohne diese Zeile
   zaehlt Test 2 der Spec-Datei sie faelschlich zur ersten Ebene. webapp.css
   kennt denselben Kniff bereits fuer ".help-chat-panel[hidden]" (:12705). */
[data-design="new"] .cockpit-sidebar-item[hidden] {
  display: none;
}

/* ENTFERNT (2026-09-22, C2c-2/Task 8): hier standen zwei Breitenregeln,
   ".chatbot-service:has(> .cockpit-sidebar):has(~ :where(#chatwindow))..."
   auf "width: 660px" und ihr Gegenstueck ohne Chatfenster auf "480px".
   Begruendung damals: "das Panel ist auf JEDER der sechs Seiten weiterhin
   da und braucht Platz" (Chat-Historie/Details/CTA bzw. Agenten- oder
   Projektwahl). Task 8 baut das Panel im neuen Design nicht mehr -- die
   Begruendung gilt seit C2c-1 (Kopfzeile ersetzt den Panelkopf) ohnehin
   nicht mehr vollstaendig und jetzt gar nicht mehr. Ohne eigene Breite
   gilt fuer ".chatbot-service" wieder die Grundregel
   "[data-design=\"new\"] .chatbot-service { width: 289px; }" (oben, Block
   "06 Shell & Nav - Task 2: Sidebar") -- unveraendert fuer ALLE sechs
   Seiten, da keine von ihnen mehr ein Panel danebenstellt, das mehr
   Platz braeuchte. */

/* ── Der eingeklappte Zustand ──────────────────────────────────────────
   UEBERHOLT (2026-09-22, Aufgabe A2): hier stand bis zu diesem Datum, dass
   AUCH das neue Design unterhalb der Umbruchbreite die Symbolleiste zeigt
   -- additiv gebaut (templatecockpitnavigationbase.js, Task 4), nur per CSS
   verborgen, wenn sie nicht galt. Diese Begruendung entfaellt: die
   Seitenleiste klappt seit A2 SELBST ein, die Symbolleiste wird im neuen
   Design gar nicht mehr gebaut (sie bleibt dem alten Design vorbehalten).

   ZWEI WEGE IN DENSELBEN ZUSTAND, deshalb zwei Stellen mit dementselben
   Eigenschaftensatz statt einem gemeinsamen Selektor (eine Media-Bedingung
   laesst sich mit einer Klassenbedingung nicht "oder"-verknuepfen, ohne den
   Block zu wiederholen):
     1. Die Klasse ".cockpit-sidebar--eingeklappt" (cockpitsidebar.js) --
        von aussen schaltbar ("toggleEingeklappt()", A1 haengt spaeter den
        Minimieren-Knopf daran) und ueberlebt einen Seitenwechsel per
        localStorage, wie "DesignPreference" es vormacht. Gilt bei JEDER
        Fensterbreite.
     2. Die Umbruchbreite selbst (Media-Block unten, unbedingt) -- dieselbe
        Schwelle wie zuvor. WARUM 1024: es ist die Stufe, die das Produkt
        bereits fuehrt und die zwischen Figmas beiden Stuetzstellen (1440
        und 834) liegt (siehe GEMESSEN-Notiz von Task 4, unveraendert
        gueltig: die 276px breite Seitenleiste ueberliefe die schmalere
        Spalte knapp unterhalb 1025px).

   ZIELBREITE 64PX: dieselbe Breite, die die alte Symbolleiste hier trug
   (design-shell-frames.spec.ts, "Nav-Rail: neue Geometrie im neuen
   Design"). */
[data-design="new"] .cockpit-sidebar--eingeklappt {
  width: 64px;
}

[data-design="new"] .cockpit-sidebar--eingeklappt .cockpit-sidebar-item {
  justify-content: center;
  padding: 0;
}

/* Abschluss-Fixwelle (2026-09-22, C2, Blocker): ".cockpit-sidebar-item--fach"
   stand bis hierher mit in dieser Liste -- eingeklappt UND unterhalb 1024px
   waren "Live-Websuche", "Favoriten" und "Ergebnisse" (im Fach, siehe
   templatecockpitnavigationbase.js:438/496/497) damit fuer den Anwender
   UNERREICHBAR, ohne Ersatz. Vor A2 fuehrte die alte Symbolleiste Favoriten
   und Ergebnisse dort als eigene Knoepfe -- kein Ziel darf schlechter
   erreichbar sein als vorher. Entschieden: eigene Symbole statt Aufklapp-
   menue -- dieselbe Optik wie jeder andere Eintrag, kein neuer
   Interaktionsmechanismus noetig, und ".cockpit-sidebar-item" traegt die
   Kollaps-Regel (justify-content/padding, oben) bereits fuer JEDEN Eintrag
   einschliesslich der Fach-Eintraege. Die Regel unten hebt zusaetzlich das
   "hidden"-Attribut auf, das cockpitsidebar.js beim geschlossenen "Mehr
   anzeigen"-Zustand setzt -- eingeklappt gilt "Mehr anzeigen" nicht mehr,
   der Knopf dafuer bleibt weiterhin ausgeblendet (unten). */
[data-design="new"] .cockpit-sidebar--eingeklappt .cockpit-sidebar-item-label,
[data-design="new"] .cockpit-sidebar--eingeklappt .cockpit-sidebar-more,
[data-design="new"] .cockpit-sidebar--eingeklappt .cockpit-sidebar-history {
  display: none;
}

[data-design="new"] .cockpit-sidebar--eingeklappt .cockpit-sidebar-item--fach[hidden] {
  display: flex;
}

/* Aufgabe A1 (2026-09-22, Befund 2): der Kopf traegt jetzt Logo und
   Chevron (siehe oben, ".cockpit-sidebar-brand") -- bei 64px ist kein Platz
   fuer beide. Das Logo weicht, der Chevron bleibt als einziger Weg zurueck
   sichtbar und dreht sich um (zeigt dann nach rechts, "ausklappen" statt
   "einklappen"). */
[data-design="new"] .cockpit-sidebar--eingeklappt .cockpit-sidebar-logo {
  display: none;
}

[data-design="new"] .cockpit-sidebar--eingeklappt .cockpit-sidebar-brand {
  justify-content: center;
}

[data-design="new"] .cockpit-sidebar--eingeklappt .cockpit-sidebar-toggle svg {
  transform: rotate(180deg);
}

/* ENTFERNT (Nachtrag/F4, 2026-09-22): hier stand bis zu diesem Datum die
   Ueberlaufkorrektur fuer den Design-Umschalter im eingeklappten Fuss
   (".cockpit-sidebar--eingeklappt .cockpit-sidebar-chip", "width: 100%" +
   Innenabstand/Zentrierung gegen einen "<button>", der sich als
   "inline-flex"-Kasten an seinem eigenen Inhalt statt an der 40px breiten
   Fussspalte ausrichtete -- siehe A2-/Aufgabe-E-Bericht). Der Umschalter
   ist ins Avatar-Menue der Kopfzeile gezogen (cockpittopbar.js) und keine
   ".cockpit-sidebar-chip" mehr -- die Klasse hat repoweit keinen Nutzer
   mehr (gegengeprueft), die Korrektur ist damit gegenstandslos. Der Fuss
   traegt jetzt nur noch ".cockpit-sidebar-item"-Eintraege (Agent Manager),
   die die Kollaps-Regeln oben bereits abdecken. */

/* Nachtrag aus dem A2-Bericht ("Kein Hover-Tooltip fuer die eingeklappte
   Seitenleiste"): ohne Beschriftung ist ein blosses Symbol nicht mehr
   benennbar. Dasselbe Muster wie die alte Symbolleiste
   (".nav-rail .rail-btn[data-tip]:hover::before", webapp.css) -- "left: 100%"
   statt eines festen Pixelmasses, weil die Eintragsbreite hier von der
   Fensterbreite abhaengt (Klasse bei 64px, Medienabfrage unten ebenso).
   Nur im eingeklappten Zustand: bei ausgeklappter Leiste steht die
   Beschriftung schon da, ein zusaetzlicher Tooltip waere doppelt. */
/* Sichtpruefung 2026-09-23 (Anwender: "wenn ich in die mobile Ansicht
   wechsle, versucht man wieder die Texte zu den Menuepunkten einzublenden.
   das darf nicht sein"): die Beschriftungen selbst sind unterhalb 1024px
   ausgeblendet -- der Text, der dort trotzdem erschien, stammt aus DIESER
   Tooltip-Regel. Auf einem Zeigegeraet ist sie richtig und ausdruecklich
   gewuenscht (Aufgabe A1: "ohne Beschriftung ist ein blosses Symbol nicht
   mehr benennbar"); auf einem BERUEHRUNGSGERAET gibt es kein Ueberfahren,
   sondern nur das Antippen -- und ein Tippen setzt dort einen Hover-Zustand,
   der bis zur naechsten Beruehrung haengen bleibt. Der Tooltip klappte
   dadurch beim Antippen eines Menuepunkts auf, genau im Moment des
   Seitenwechsels.

   "@media (hover: hover)" fragt nicht die Fensterbreite ab, sondern ob das
   Hauptzeigegeraet ueberhaupt schweben kann -- die einzige Bedingung, die
   hier zaehlt. Ein schmales Fenster auf einem Rechner mit Maus behaelt den
   Tooltip (und braucht ihn, die Leiste ist dort 64px schmal); ein Tablet
   oder Telefon bekommt ihn nicht mehr. Die Geraeteansicht der
   Entwicklerwerkzeuge meldet ebenfalls "hover: none", der Befund ist dort
   also nachvollziehbar. */
@media (hover: hover) {
  [data-design="new"] .cockpit-sidebar--eingeklappt .cockpit-sidebar-item[data-tip]:hover::before {
    content: attr(data-tip);
    position: absolute;
    left: 100%;
    top: 50%;
    transform: translateY(-50%);
    margin-left: var(--ax-space-2);
    background: var(--ax-bg-surface-2);
    border: 1px solid var(--ax-border-soft);
    color: var(--ax-text-primary);
    font-size: var(--ax-font-size-label-sm);
    font-weight: 500;
    padding: 4px 9px;
    border-radius: var(--ax-radius-sm);
    white-space: nowrap;
    z-index: 200;
    pointer-events: none;
  }
}

@media (max-width: 1024px) {
  /* Dieselben Eigenschaften wie ".cockpit-sidebar--eingeklappt" oben, hier
     unbedingt auf die blanke Klasse angewandt -- siehe die Erklaerung
     "ZWEI WEGE" im Kommentar darueber. */
  [data-design="new"] .cockpit-sidebar { width: 64px; }

  [data-design="new"] .cockpit-sidebar .cockpit-sidebar-item {
    justify-content: center;
    padding: 0;
  }

  /* Abschluss-Fixwelle (2026-09-22, C2, Blocker): zweite Adresse derselben
     Berichtigung wie oben (".cockpit-sidebar--eingeklappt .cockpit-sidebar-
     item-label/-more/-history") -- ".cockpit-sidebar-item--fach" bleibt
     unterhalb 1024px erreichbar, siehe dort fuer die Begruendung. */
  [data-design="new"] .cockpit-sidebar .cockpit-sidebar-item-label,
  [data-design="new"] .cockpit-sidebar .cockpit-sidebar-more,
  [data-design="new"] .cockpit-sidebar .cockpit-sidebar-history {
    display: none;
  }

  [data-design="new"] .cockpit-sidebar .cockpit-sidebar-item--fach[hidden] {
    display: flex;
  }

  /* Aufgabe A1: zweite Adresse derselben drei Regeln wie oben
     (".cockpit-sidebar--eingeklappt .cockpit-sidebar-logo/-brand/-toggle
     svg") -- siehe dort fuer die Begruendung. */
  [data-design="new"] .cockpit-sidebar .cockpit-sidebar-logo {
    display: none;
  }

  [data-design="new"] .cockpit-sidebar .cockpit-sidebar-brand {
    justify-content: center;
  }

  [data-design="new"] .cockpit-sidebar .cockpit-sidebar-toggle svg {
    transform: rotate(180deg);
  }

  /* ENTFERNT (Nachtrag/F4, 2026-09-22): zweite Adresse derselben jetzt
     entfernten Regel oben (".cockpit-sidebar--eingeklappt .cockpit-sidebar-
     chip") -- siehe dort fuer die Begruendung. */

  /* Zweite Adresse derselben Absicherung wie oben -- siehe dort. */
  @media (hover: hover) {
    /* MOBIL/S2 (2026-09-26): ":not(.cockpit-sidebar--schublade-offen)"
       ergaenzt. In der offenen Schublade traegt jeder Eintrag seine
       Beschriftung wieder -- ein Schwebe-Hinweis daneben waere derselbe
       Text zweimal, und er stuende ausserhalb der Schublade auf dem
       abgedunkelten Grund. EINGEENGT statt eine dritte Regel daneben:
       tests/unit/components-css.test.js bewacht, dass es genau ZWEI
       Tooltip-Adressen gibt, und diese Zahl soll stimmen bleiben. */
    [data-design="new"] .cockpit-sidebar:not(.cockpit-sidebar--schublade-offen) .cockpit-sidebar-item[data-tip]:hover::before {
      content: attr(data-tip);
      position: absolute;
      left: 100%;
      top: 50%;
      transform: translateY(-50%);
      margin-left: var(--ax-space-2);
      background: var(--ax-bg-surface-2);
      border: 1px solid var(--ax-border-soft);
      color: var(--ax-text-primary);
      font-size: var(--ax-font-size-label-sm);
      font-weight: 500;
      padding: 4px 9px;
      border-radius: var(--ax-radius-sm);
      white-space: nowrap;
      z-index: 200;
      pointer-events: none;
    }
  }

  [data-design="new"] .cockpit-topbar { padding: 0 var(--ax-space-4); }

  /* ENTFERNT (Sichtpruefung/Task 3, 2026-09-22): hier stand bis zu diesem
     Datum "[data-design=\"new\"] #langToggleBtn, [data-design=\"new\"]
     #themeToggleBtn { display: none; }" (ergaenzt 2026-09-21, Abschluss-
     pruefung Fund I1) -- damals noetig, weil beide Ids unbedingt sichtbare
     Knoepfe der Kopfzeile waren und unterhalb 1024px doppelt neben der
     Symbolleiste (".rail-langToggleBtn"/".rail-themeToggleBtn") gestanden
     haetten. Seit Task 3 ("Alles Persoenliche im Avatar-Menue") tragen
     Sprache und Theme im Avatar-Menue der Kopfzeile gar keine eigene Id mehr
     (Testids "avatar-lang-toggle"/"avatar-theme-toggle", cockpittopbar.js --
     "#langToggleBtn"/"#themeToggleBtn" gehoeren seither ausschliesslich der
     Symbolleiste) -- verborgen per "[hidden]", bis man den Avatar anklickt,
     bei JEDER Fensterbreite. Diese Regel waere jetzt SCHAEDLICH statt nur
     ueberfluessig: sie wuerde die beiden Eintraege auch dann ausblenden,
     wenn das Avatar-Menue unterhalb 1024px absichtlich geoeffnet ist --
     Sprache und Theme waeren dort nicht mehr erreichbar.
     UEBERHOLT (2026-09-22, Aufgabe A2): der letzte Satz hier ("Die
     Symbolleiste behaelt ihre eigenen 'rail-*'-Knoepfe unveraendert ...")
     bezog sich auf die additive Symbolleiste des neuen Designs, die es seit
     A2 nicht mehr gibt.
     UEBERHOLT (2026-09-22, Nachtrag/F4): der letzte Satz hier ("Im neuen
     Design bleibt der Design-Umschalter jetzt im Fuss der Seitenleiste
     ('#designToggleBtn', cockpitsidebar.js) ...") gilt nicht mehr -- der
     Umschalter ist ins Avatar-Menue der Kopfzeile gezogen (cockpittopbar.js)
     und traegt "#designToggleBtn" dort weiter. Erreichbar bleibt er ueber
     denselben Weg wie Sprache/Erscheinung: das Avatar-Menue steht bei JEDER
     Fensterbreite offen, unabhaengig vom eingeklappten Zustand der
     Seitenleiste. */

  /* DIE AUSFUEHRUNGSKARTE SCHOB SICH UNTER DIE KOPFZEILE (ergaenzt
     2026-09-21, Abschlusspruefung, Fund I1).
     Unterhalb 1024px sind die drei Inhaltsflaechen "position: absolute" mit
     "top: 50px" (webapp.css:6675/:6681/:6688; die Regeln oeffnen bei
     6673/:6679/:6686 -- aus der Zeit der 50px hohen
     "navbar2") und haben keinen positionierten Vorfahren -- sie liegen also
     relativ zum Dokument, unbeeindruckt vom Gitter oben. Die Kopfzeile
     belegt y = 0..72.
     GEMESSEN (echtes Chromium, 900x800, neues Design, Rolle "user"):
       .chat-container            top 75  (kein Ueberlapp: "margin-top: 25px",
                                   webapp.css:2162, schiebt die Randbox auf 75)
       .aiservice-container       top 75  (dito, "margin: 25px auto", :2477)
       .aiservice-execution-container top 50, Kopfzeile bis 72
                                  -> 22px MITTEN IN DER KOPFZEILE, sie wird
                                     uebermalt. Ihr "margin: 0 auto" (:2466)
                                     hat nichts, was sie nach unten schiebt.
     Nur die dritte ist betroffen; die ersten beiden bleiben deshalb
     unangetastet (Chirurgie-Regel). Im ALTEN Design zur selben Zeit: top 50
     ohne Kopfzeile daneben -- kein Ueberlapp, der Fund gehoert allein dem
     neuen Design.
     DIE HOEHE MUSS MIT: bliebe sie bei "calc(100vh - 50px)", schoebe das
     tiefere "top" die Unterkante um dieselben 22px unter die Fensterkante
     (gemessen alt: Unterkante 800 bei innerHeight 800, also exakt buendig).
     72px ist die gemessene Hoehe der Kopfzeile -- dieselbe Zahl wie in
     "[data-design=\"new\"] .cockpit-topbar" oben, und schmal unveraendert
     (nur der Innenabstand wechselt dort).

     WARUM ALLE DREI HIER STEHEN, OBWOHL NUR EINE EINEN FEHLER HAT: die
     Hoehenfreigabe des Gitters ("height: auto", C1, weiter oben) trifft
     diese drei Flaechen auch hier, wo sie AUSSER FLUSS sind und das Gitter
     ihre Hoehe gar nicht mehr bestimmt -- gemessen wurden sie dadurch
     inhaltsgross (Chatfenster 557 statt 775). Das waere eine
     Layoutaenderung am schmalen Geraet, die C1 nicht gewollt hat und die
     niemand gemessen hat. Die zwei unbetroffenen Flaechen bekommen deshalb
     ihre Legacy-Hoehe woertlich zurueck (webapp.css:2163 bzw. :2483); dass
     sie damit wie vor C2c-1 unter die Fensterkante reichen (Chatfenster
     850 bei innerHeight 800), ist ein VORBESTEHENDER Zustand -- im alten
     Design zur selben Zeit gemessen: identisch 850. Nicht von diesem Plan
     verursacht, deshalb hier nicht mitbehoben.
     Spezifitaet (0,4,0) gegen (0,3,0) der Hoehenfreigabe oben und (0,1,0)
     der Legacy-Regeln im selben Band. */
  /* BERICHTIGT (2026-09-26, CHAT/H2, Befund des Anwenders mit Bild: "wenn
     ich eine Antwort im Chatfenster erhalten habe, wird danach das Chat
     Input Widget nicht mehr vollständig angezeigt"). HIER STAND:
         [data-design="new"] .welcome > .container-left-right-top-aligned
             > .chat-container { height: calc(100vh - 25px); }
     Ihre Begruendung steht vollstaendig im Block darueber und lautete:
     die drei Inhaltsflaechen sind unterhalb 1024px "position: absolute"
     und AUSSER FLUSS, das Gitter bestimmt ihre Hoehe nicht mehr, also
     machte die Hoehenfreigabe aus C1 sie inhaltsgross (gemessen 557 statt
     775). Dass sie damit unter die Fensterkante reichen, wurde
     ausdruecklich als "VORBESTEHENDER Zustand" hingenommen.

     DIESE PRAEMISSE GILT NICHT MEHR. Mobil-Schritt 1 (Commit 844fb76db,
     2026-09-25) hat genau diese Behaelter im neuen Design wieder in den
     Fluss geholt ("position: static", Block weiter unten in dieser
     Datei) -- sie SIND jetzt Rasterkinder, und die Hoehenfreigabe wirkt
     wieder so, wie C1 sie gemeint hat.

     Und der hingenommene Ueberstand ist kein Schoenheitsfehler: GEMESSEN
     (390x800) lag der Composer nach ein paar Antworten bei 737..864, also
     64px UNTER dem Fensterrand -- seine Knopfzeile war nicht mehr
     erreichbar. Sichtbar wurde es erst NACH einer Antwort, weil
     "justify-content: center" den Composer bei kurzem Gespraech in die
     Mitte des zu hohen Behaelters stellte.

     ".aiservice-container" darunter behaelt seine Zeile vorerst: derselbe
     Einwand trifft sie zwar auch, aber sie ist nicht gemeldet und nicht
     gemessen (Chirurgie-Regel). */

  [data-design="new"] .welcome > .container-left-right-top-aligned > .aiservice-container {
    height: calc(100vh - 50px);
  }

  [data-design="new"] .welcome > .container-left-right-top-aligned > .aiservice-execution-container {
    top: 72px;
    height: calc(100vh - 72px);
  }
}

/* ══ Cockpit C2a/Task 6 — die Kommandopalette (Suchdialog) ══════════════════

   Figma "Chat · Search — DE · Dark", Knoten 66:3887. Erzeuger:
   DialogCockpitSearch (dialogcockpitsearch.js), Aufrufer der
   Seitenleisteneintrag "Suchen" und Strg+K (templatecockpitnavigationbase.js).
   Nur das neue Design -- das alte kennt den Dialog gar nicht, dort schaltet
   der Eintrag weiter den Live-Websuche-Modus.

   -- DER WIRT: ":has()" TRAEGT ------------------------------------------
   Gemessen am laufenden Dialog (design-cockpit-suche.spec.ts, Tests
   "Kommandopalette: Aussehen nach Vorlage (Theme dark/light)"): der zweite
   Zweig "[data-testid=\"cockpit-search-list\"]" trifft zuverlaessig, auch
   BEVOR eine Suche laeuft (MoleculeList traegt die Testid schon beim
   Rendern, vor jedem Treffer). Keine Ausweichklasse noetig.

   -- BREITE: 2026-09-21 KORRIGIERT, JETZT AUS FIGMA -----------------------
   2026-09-20: hier stand "min(640px, ...)" aus einer eigenen Schaetzung
   ohne Figma-Zugriff (keine autoritative Quelle im Repository, die
   generische ".dialog"-Regel mit "width: 80%" ist fuer eine Kommandopalette
   klar zu breit). Der Auftraggeber hat den Knoten inzwischen selbst
   nachgemessen: "command palette" (66:4104) ist 660px breit. Auf 660
   korrigiert, gedeckelt gegen schmale Fenster wie zuvor.

   -- INNENABSTAND: 2026-09-21 AUF 0 GESETZT, RANDVOLL WIE DIE VORLAGE -----
   Fuenf Kind-Frames der Vorlage (Kopfzeile, Abschnittskopf, Trefferzeile,
   Abstand vor der Fusszeile, Fusszeile) messen ALLE exakt 660px -- also
   genau die Breite des Palette-Rahmens selbst, ohne jeden seitlichen
   Abstand. Das ist bei fuenf unabhaengigen Messungen kein Zufall, sondern
   randvolles Layout: jeder Abschnitt spannt die volle Palettenbreite, sein
   eigener Innenabstand (falls vorhanden) steckt in der Abschnittsregel
   selbst, nicht hier. Die generische ".dialog"-Regel (padding 20/24,
   components.css, Block "09 Overlays") gilt deshalb fuer DIESEN Dialog
   NICHT -- hier ueberschrieben. "gap" ebenso auf 0: die generischen 16px
   zwischen JEDEM Kindpaar (auch um das leere ".button-container") passen
   nicht zu der einen, gezielten 8px-Fuge vor der Fusszeile (Vorlagenknoten
   66:4180) -- die setzt stattdessen "margin-top" direkt an der Fusszeile
   (unten). Der abgerundete Rahmen bleibt trotzdem sauber: ".dialog" traegt
   bereits "overflow: hidden !important" (webapp.css:1090), das schneidet
   randvolle Kinder automatisch auf die Rahmenrundung zurueck.

   -- MAXIMALE HOEHE: NICHT HIER GESETZT, NUR GEERBT ----------------------
   ".dialog" selbst deckelt "max-height" bereits mit "!important"
   (webapp.css:1085, "calc(100vh - 50px) !important") -- fuer JEDEN Dialog,
   unabhaengig vom Design. Eigenes "!important" ist in dieser Datei per
   Unit-Test verboten (components-css.test.js, "kein !important"), ein
   NICHT-wichtiges "max-height" hier waere also unbekaempft wirkungslos.
   Die Palette erbt deshalb denselben Deckel wie jeder andere Dialog und
   NICHT die 622px, die die Vorlage fuer den Palette-Rahmen zeigt -- gemessen
   und zugesichert wird der tatsaechlich geerbte Wert, keiner neu gesetzt.
   Dieser Absatz bleibt unveraendert richtig: NUR "max-height" ist gemeint.
   Fuer "min-height" siehe den naechsten Absatz -- die beiden Deckel wurden
   in der ersten Fassung faelschlich als EIN Paket behandelt.

   -- MINDESTHOEHE: 2026-09-21 (Abschlusswelle, Fund I4) NEU ZURUECKGENOMMEN
   Hier stand bis dahin nichts -- ".dialog" traegt "min-height: min(500px,
   calc(100vh - 50px))" (webapp.css:1084, KEIN "!important", anders als
   "max-height" oben) fuer JEDEN Dialog, und Task 6 hatte das bewusst
   uebernommen ("Die Palette erbt deshalb denselben Deckel wie jeder andere
   Dialog", Absatz oben) -- richtig gedacht fuer eine Mindesthoehe, die bei
   FORMULARDIALOGEN Sinn ergibt. Fund I4 der Abschlusspruefung zeigte aber:
   bei wenigen Treffern (gemessen mit zwei: ein Chat, ein Service) erzwingt
   die Mindesthoehe 500px, obwohl der Inhalt (Kopfzeile 60 + zwei knappe
   Abschnitte + Fusszeile 40 + Innenabstand) deutlich weniger braucht --
   ".scrollable" (webapp.css:1096, "flex: 1 1 auto") bzw. darin
   ".list-container" (webapp.css:6559, "flex: 1") absorbieren die Differenz
   als LEERRAUM unterhalb der letzten Trefferzeile. Gemessen: aus den 8px
   Abstand der Vorlage vor der Fusszeile wurden dadurch rund 132px --
   deutlich mehr, als allein die beiden im Fund I4 zuerst benannten Regeln
   erklaeren (rund 38px, siehe deren eigener Kommentar unten). Die Vorlage
   misst die Palette INHALTSGROSS (660 x 622 bei ACHT Trefferzeilen plus
   Koepfen und Fusszeile, Ruling 11 oben) -- eine Kommandopalette ist kein
   Formulardialog mit fester Mindesthoehe, sie soll bei zwei Treffern kurz
   und bei vielen lang sein, gedeckelt nur nach oben (das "max-height" des
   Absatzes darueber, unveraendert). "min-height: 0" hebt NUR die geerbte
   Mindesthoehe fuer DIESEN Dialog auf -- kein "!important" noetig, die
   Basisregel traegt selbst keins. */
[data-design="new"] .dialog:has(.cockpit-search-section),
[data-design="new"] .dialog:has([data-testid="cockpit-search-list"]) {
  background: var(--ax-bg-elevated);
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-lg);
  width: min(660px, calc(100vw - var(--ax-space-12)));
  min-height: 0;
  padding: 0;
  gap: 0;
}

/* 2026-09-21 (Abschlusspruefung, Fund I4): ZWEI GEERBTE REGELN hoben die
   Vorlagentreue der PALETTENLAGE teilweise auf, obwohl Task 6 oben jeden
   Einzelkasten (Kopfzeile, Abschnittskopf, Trefferzeile, Fusszeile) exakt
   nach Vorlage vermessen hatte -- gemessen wurde dort nie die LAGE dieser
   Kaesten zueinander:

   1. ".list-container" -- die Traeger-Klasse von "MoleculeList"
      (moleculelist.js:57), erzeugt fuer "this.liste" in "setupDialogUi()"
      (dialogcockpitsearch.js) -- bringt UNGESCOPT "margin-left: 2px;
      margin-top: 10px; margin-bottom: 20px; padding-top/-bottom: 10px" mit
      (webapp.css:6559 ff., Spezifitaet 0,1,0). Die Vorlage zeigt die
      Trefferliste randvoll (siehe "INNENABSTAND"-Begruendung oben) und
      direkt unter dem Suchfeld -- mit der geerbten Regel stand sie
      stattdessen 2px eingerueckt und begann 20px darunter. Eng auf die
      Testid DIESER EINEN Liste gescopt (0,2,0), schlaegt ".list-container"
      ohne "!important".

   2. ".button-container" (webapp.css:1139, Dialog-Fusszeile fuer Knoepfe) --
      "dialog.js", "setupUi()" legt sie UNBEDINGT an ("new
      AtomContainerButton(this, "")"), auch wenn dieser Dialog nie einen
      Knopf hineinsetzt. Die Basisregel ".button-container" (webapp.css:1562,
      0,1,0) traegt "height: 30px"; ".dialog .button-container"
      (webapp.css:1139) nullt zwar "padding"/"margin" mit "!important",
      NICHT aber die Hoehe. Aus den 8px Abstand, den die Vorlage vor der
      Fusszeile zeigt (Knoten 66:4180, siehe Fusszeile-Kommentar unten),
      wurden dadurch rund 38px tote Flaeche. Eng auf DIESEN Dialog gescopt
      (0,4,0), schlaegt ".button-container" ohne "!important".

   Beide Regeln sind reine LAGE-Korrekturen; kein Wert hier ist neu erfunden
   -- ".list-container" wird auf 0 zurueckgenommen (randvoll, wie die
   Wirt-Regel oben es fuer jeden Kind-Frame der Vorlage schon festhaelt),
   der leere Knopfbehaelter wird unsichtbar (0 statt 30px).

   2026-09-21, BERICHTIGT (Abschlusswelle, erste Pruefung dieses Fundes):
   hier stand "der verbleibende Abstand vor der Fusszeile ist danach genau
   deren eigenes margin-top (8px) -- nichts sonst" und "rund 58px tote
   Flaeche". Beides war zum Pruefzeitpunkt plausibel hergeleitet, aber am
   Wirt NICHT nachgemessen -- die Messung (erster Playwright-Lauf dieser
   Welle) ergab 132px statt 8px, nicht die hier zuerst vermuteten ~58.
   Ursache war ein DRITTER, hier nicht genannter Faktor: die geerbte
   "min-height" der Dialogfamilie, siehe deren eigener, ebenfalls
   berichtigter Kommentar in der Wirt-Regel oben ("MINDESTHOEHE"). Mit deren
   Ruecknahme sind es jetzt wirklich nur noch die ~38px dieser beiden
   Regeln, die die Fusszeile von der letzten Trefferzeile trennten -- und
   die verschwinden durch die Neutralisierung hier vollstaendig; der
   verbleibende Abstand ist danach das eigene "margin-top:
   var(--ax-space-2)" der Fusszeile (8px, siehe dort) -- nichts sonst.
   Zugesichert wird das ueber "boundingBox()" in "design-cockpit-suche.spec.ts"
   ("Kommandopalette: Aussehen nach Vorlage", Abschnitt "LAGE"), nicht ueber
   die CSS-Eigenschaften selbst -- eine Zusicherung auf "margin-top: 8px"
   allein haette weder diesen Fund noch die "min-height" gefangen. */
[data-design="new"] [data-testid="cockpit-search-list"] {
  margin: 0;
  padding: 0;
}

[data-design="new"] .dialog:has(.cockpit-search-section) .button-container,
[data-design="new"] .dialog:has([data-testid="cockpit-search-list"]) .button-container {
  height: 0;
}

/* Kopfzeile (Figma-Knoten 66:4105, 660x60): Behaelter fuer Suchfeld und
   esc-Chip. "position: relative" ist der Bezugsrahmen fuer den absolut
   positionierten Chip (Knoten 66:4112) -- ohne ihn positionierte sich der
   Chip gegen das naechste positionierte Vorfahrenelement, hier ".dialog"
   selbst, und landete an dessen Ecke statt an der Kopfzeile. */
[data-design="new"] .cockpit-search-header {
  position: relative;
  height: 60px;
  flex-shrink: 0;
}

[data-design="new"] [data-testid="cockpit-search-input"] {
  width: 100%;
  height: 60px;
  box-sizing: border-box;
  /* SICHTPRUEFUNG 2026-09-25: Platz fuer esc-Chip UND Schliessen-Knopf, damit
     langer Text nicht unter ihnen verschwindet. Summe aus Rand (16) +
     Knopf (28) + Zwischenraum (8) + Chip (35) + Zwischenraum (8). */
  padding-right: calc(var(--ax-space-4) + 28px + var(--ax-space-2)
                      + 35px + var(--ax-space-2));
}

/* SICHTPRUEFUNG 2026-09-25: Chromium rendert fuer "input[type=search]" ein
   eigenes Loeschkreuz. Neben dem neuen Schliessen-Knopf standen damit ZWEI
   Kreuze nebeneinander -- eines leert das Feld, eines schliesst den Dialog.
   Gleiches Zeichen, verschiedene Bedeutung, 8px auseinander: das ist keine
   Wahl, sondern eine Falle. Das native Kreuz weicht; geleert wird ueber die
   Tastatur, und der Dialog wird ohnehin bei jedem Oeffnen neu gebaut.
   Eng auf dieses Feld gescopt -- die uebrigen Suchfelder der Anwendung
   behalten ihres (webapp.css vergibt ihm eigens einen Hover). */
[data-design="new"] [data-testid="cockpit-search-input"]::-webkit-search-cancel-button {
  display: none;
}

/* esc-Chip (Figma-Knoten 66:4112, 35x21, rechts bei x=609/y=20 innerhalb
   der 660 breiten Kopfzeile -- rechter Abstand also 660-609-35 = 16px).
   Rein anzeigend: das Escape-Verhalten existiert bereits in
   "_tastendruck()" (dialogcockpitsearch.js). 2026-09-20/Task 6 liess ihn
   zunaechst aus, weil weder das Brief-Geruest noch die
   Diagnose-Vorgabe von Schritt 2 ihn vorsahen und es kein DOM-Element
   dafuer gab -- 2026-09-21 vom Auftraggeber als eigener Vorlagen-Knoten
   bestaetigt und nachgetragen (dialogcockpitsearch.js, "_escChipBauen()"). */
/* SICHTPRUEFUNG 2026-09-25: der Chip raeumt die Ecke fuer den
   Schliessen-Knopf und rueckt um dessen Breite plus einen Zwischenraum nach
   links. Als "calc" aus Marken statt als feste 52px, damit er der
   Abstandsskala folgt (die Marken schrumpfen unterhalb einer Fensterbreite,
   siehe tokens.css).
   DER RAHMEN wechselt von "--ax-border-soft" auf "--ax-border-default": im
   dunklen Modus war "soft" auf erhoehtem Grund praktisch unsichtbar, der
   Chip schwebte konturlos. Das fiel vorher nicht auf, weil er allein stand
   -- neben einem Knopf mit sichtbarem Rahmen saehen die beiden sonst wie
   zwei verschiedene Dinge aus. */
[data-design="new"] .cockpit-search-esc-chip {
  position: absolute;
  top: 20px;
  right: calc(var(--ax-space-4) + 28px + var(--ax-space-2));
  width: 35px;
  height: 21px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-sm);
  color: var(--ax-text-muted);
  font-size: var(--ax-font-size-label-sm);
}

[data-design="new"] .cockpit-search-section-body {
  display: flex;
  flex-direction: column;
}

/* 2026-09-21 (Abschlusspruefung, Fund M2): OHNE eigene Regel standen die drei
   Zustandstexte ("Suche laeuft ...", "Nichts gefunden", "Suche nicht
   erreichbar" -- gesetzt direkt als "textContent" DIESES Elements, siehe
   "_abschnitt()"/"_fuellen()"/"_ausfall()" in dialogcockpitsearch.js) buendig
   am linken Palettenrand UND in der Primaerfarbe, waehrend Trefferzeilen
   ("cockpit-search-row" unten) 12px Einzug haben und gedaempft sind.
   ":not(:has(.cockpit-search-row))" trifft NUR den Text-Zustand: sobald
   echte Trefferzeilen als Kinder stehen, greift die Regel nicht mehr --
   sonst wuerde der Einzug der Zeilen mit ihrem EIGENEN "padding: 0
   var(--ax-space-3)" verdoppelt und die volle Breite ihrer Hover-Flaeche
   (randvoll, siehe Trefferzeile-Kommentar unten) um 12px eingezogen. */
[data-design="new"] .cockpit-search-section-body:not(:has(.cockpit-search-row)) {
  padding: 0 var(--ax-space-3);
  color: var(--ax-text-muted);
}

/* Abschnittskopf ("CHATS" / "AI-SERVICE-ERGEBNISSE"): "_abschnitt()"
   (dialogcockpitsearch.js) nutzt dafuer dieselbe Klasse wie die
   Chatverlauf-Gruppenkoepfe ("Heute" / "Aelter") -- ABSICHTLICH, siehe deren
   eigener Kommentar dort. Die Klasse traegt in diesem Repository aber KEINE
   unscoped Basisregel (nur zwei Stellen scopen sie eng auf
   ".chatbot-service-panel ... #chat-history" bzw. "#service-history",
   webapp.css:9920/10033) -- innerhalb der Kommandopalette waere der Kopf
   ohne eigene Regel vollstaendig ungestylter Fliesstext. Kein Widerspruch
   zum Geruest aus dem Aufgabenbrief (das diese Regel nicht zeigte): die
   "kleinen, gedaempften Ueberschriften" sind ausdruecklicher Teil der
   Vorlagenbeschreibung. Eng auf ".cockpit-search-section" gescopt, damit die
   beiden bestehenden Stellen unberuehrt bleiben.

   Innenabstand 2026-09-21 korrigiert: oben stand "var(--ax-space-3)" (12px),
   macht mit der Zeilenhoehe (14px) und dem unteren Abstand (4px) 30px
   Gesamthoehe. Die Vorlage (Knoten 66:4114) misst 34px -- oben auf
   "var(--ax-space-4)" (16px) angehoben, 16+14+4 = 34. */
[data-design="new"] .cockpit-search-section .chat-history-group-header {
  padding: var(--ax-space-4) var(--ax-space-3) var(--ax-space-1);
  color: var(--ax-text-muted);
  font-size: var(--ax-font-size-label-caps);
  line-height: var(--ax-line-height-label-caps);
  text-transform: uppercase;
  letter-spacing: .04em;
}

/* 2026-09-21 korrigiert: "border-radius" und senkrechter Innenabstand
   (vorher "var(--ax-space-2) var(--ax-space-3)", ergab mit der
   Zeilenhoehe 40px Gesamthoehe) sind entfallen bzw. ersetzt. Grund: die
   Vorlage (Knoten 66:4116) misst die Trefferzeile 660px breit -- randvoll
   wie die Palette selbst (siehe Wirt-Regel oben), keine seitliche Fuge, in
   der eine eigene Randrundung sichtbar waere. Eine Zeile mit
   "border-radius" haette an beiden Raendern kleine, unbegruendete
   Rundungs-Kerben gezeigt. Die Gesamthoehe kommt jetzt direkt aus der
   Vorlage (54px) statt aus dem Innenabstand hergeleitet zu werden. */
[data-design="new"] .cockpit-search-row {
  display: flex;
  align-items: center;
  color: var(--ax-text-primary);
  text-decoration: none;
  padding: 0 var(--ax-space-3);
  line-height: var(--ax-line-height-body-md);
  min-height: 54px;
}

/* Die Hervorhebung der Tastaturfuehrung UND der Maus-Hover sind DASSELBE
   Aussehen -- wer mit der Maus faehrt und wer mit den Pfeilen laeuft, sieht
   denselben Zustand. Zwei verschiedene Hervorhebungen gleichzeitig waeren
   verwirrend. */
[data-design="new"] .cockpit-search-row:hover,
[data-design="new"] .cockpit-search-row.cockpit-search-active {
  background: var(--ax-bg-hover);
}

/* 2026-09-21 korrigiert, zwei Funde gegen die Vorlage (Knoten 66:4181,
   660x40, Text bei x=20/y=12):
   1. Waagerechter Innenabstand: vorher "var(--ax-space-3)" (12px) auf
      allen vier Seiten. Die Textposition x=20 verlangt links/rechts
      "var(--ax-space-5)" (20px); oben/unten bleibt bei 12px richtig
      (y=12 trifft exakt, und 12+16(Zeilenhoehe)+12 = 40 = die gemessene
      Gesamthoehe -- unveraendert).
   2. Abstand VOR der Fusszeile fehlte ganz: die Vorlage zeigt dafuer einen
      eigenen 8px-Knoten (66:4180, 660x8) zwischen Trefferliste und
      Fusszeile. Der generische ".dialog"-Gap (16px zwischen JEDEM
      Kindpaar) ist am Wirt oben auf 0 gesetzt (siehe dortiger Kommentar)
      -- die 8px kommen jetzt gezielt als "margin-top" hier her,
      "var(--ax-space-2)" trifft exakt. */
[data-design="new"] .cockpit-search-footer {
  display: flex;
  justify-content: space-between;
  color: var(--ax-text-muted);
  padding: var(--ax-space-3) var(--ax-space-5);
  font-size: var(--ax-font-size-label-sm);
  line-height: var(--ax-line-height-label-sm);
  flex-shrink: 0;
  margin-top: var(--ax-space-2);
}

/* 2026-09-22 (Fix-Runde 1 zu C2c-2/Task 6, Fund N-3): die Ueberlagerung
   "Ai-Services in Arbeit" (dialoglaufendedienste.js) erbt denselben Deckel
   wie jeder andere Dialog -- ".dialog" traegt "min-height: min(500px,
   calc(100vh - 50px))" (webapp.css:1084, KEIN "!important"). Gemessen:
   1024x500px bei "Derzeit alles abgeschlossen" (ein Kopfzeilenlabel plus
   eine Zeile Text plus der Knopfreihe aus Fix-Runde 1/I-4) -- eine halbe
   Bildschirmhoehe Leerraum. Dasselbe Problem, das C2a fuer
   "DialogCockpitSearch" schon neutralisieren musste (Regeln oben,
   "MINDESTHOEHE"-Kommentar) -- hier dasselbe Mittel: "min-height: 0" hebt
   NUR die geerbte Mindesthoehe fuer DIESEN Dialog auf, ohne "!important",
   die Basisregel traegt selbst keins. Anders als bei der Kommandopalette
   bleibt ".button-container" HIER unangetastet -- Fix-Runde 1/I-4 fuellt
   sie mit einem echten "Schliessen"-Knopf, ein "height: 0" wie beim
   Suchdialog (der nie einen Knopf hineinsetzt) wuerde ihn unsichtbar
   machen. */
[data-design="new"] .dialog[data-testid="laufende-dienste-dialog"] {
  min-height: 0;
}

/* Council/K2 (2026-09-23): derselbe Deckel wie bei "laufende-dienste-dialog"
   direkt darueber, aus demselben Grund und mit demselben Mittel -- die
   Gremiumsauswahl (dialoggremium.js) erbt sonst ebenfalls "min-height:
   min(500px, calc(100vh - 50px))" von ".dialog" (webapp.css:1084, KEIN
   "!important"), obwohl ihr Inhalt (Kopfzeile plus eine kurze Personenliste
   plus Knopfreihe) deutlich weniger braucht -- der Anwender hat ausdruecklich
   "ein kleiner Dialog" verlangt. "min-height: 0" hebt NUR die geerbte
   Mindesthoehe fuer DIESEN Dialog auf, ohne "!important", die Basisregel
   traegt selbst keins. */
[data-design="new"] .dialog[data-testid="gremium-dialog"] {
  min-height: 0;
}

/* ══ C2c-2/Task 9 — die Reglerleiste (chatregler.js) ══════════════════════
   Die Leiste selbst hing seit C2c-2/Task 1 an ".chatbot-input" (gap:
   var(--ax-space-4), Task 3) -- IHR ABSTAND zu Eingabezeile und Knopfreihe
   war damit schon immer korrekt (gemessen: Chat- und Projektseite, beide
   Themes, je 16px zu beiden Nachbarn). Die Leiste TRUG BISHER ABER GAR
   KEINE EIGENE REGEL: ".chat-regler" blieb ein unbestyltes "display:block"
   (chatregler.js baut seine Knoten roh, ohne Klassenkommentar dazu), und
   ".chat-regler-knopf"/".chat-regler-option" waren nackte "<button>" --
   erbten damit ungebremst die Primary-CTA-Farbe der Basisregel (oben,
   ":where([data-design=\"new\"]) button"). Gemessen (echtes Chromium): zwei
   Regler-Knoepfe standen ohne jede Fuge nebeneinander, beide knallblau wie
   ein Sende-Knopf, obwohl sie nur einen Dauerzustand anzeigen (dasselbe
   Vorbild wie der Anonymisierungs-Knopf, siehe Klassenkommentar). Hier
   nachgezogen, NUR das Fehlende:

     .chat-regler           -> Flex-Zeile mit Fuge (der Leiste fehlte genau
                                das, was ".cockpit-topbar-controls" (oben)
                                fuer die Kopfzeile schon hat)
     .chat-regler-knopf      -> Chip-Optik wie ".cockpit-topbar-chip" (Rand
                                statt Flaeche -- ein Dauerzustand ist keine
                                Handlungsaufforderung)
     .chat-regler-menu/
     .chat-regler-optionen/
     .chat-regler-option     -> dieselbe Karten-/Zeilen-Optik wie das
                                Vorbild ".cockpit-chat-sichern-menu" (siehe
                                oben, Task 5)

   DIE LAGE DES MENUES (2026-09-22, bis "Gestaltung/C" unten): chatregler.js
   haengte Knopf und Menue als FLACHE GESCHWISTER an dieselbe Leiste (kein
   eigener Wirt je Regler wie beim "Chat sichern"-Menue, das genau EIN
   Knopf/Menue-Paar hat). Das Menue blieb deshalb IM FLUSS: "flex-basis:
   100%" erzwang fuer JEDES offene Menue eine eigene, volle Zeile in der
   umbrechenden Flex-Leiste. Bekannte, zweimal vertagte Einschraenkung: bei
   mehreren gleichzeitig offenen Menues wanderten nachfolgende Knoepfe eine
   Zeile tiefer, und ein einzelnes offenes Menue blaehte die Eingabeflaeche
   sichtbar auf -- SIEHE "Gestaltung/C" unten, dort eingeloest.

   2026-09-22 (Sichtpruefung/Task 4): ".chat-regler" ist seither selbst ein
   Flex-KIND von ".chatbot-buttons" (chatregler.js "_stelleSicherGerendert()"
   haengt den Container jetzt HINEIN statt DAVOR), nicht mehr eine eigene
   Zeile in voller Breite. ".chat-regler-knopf" heisst seither
   ".chat-regler-chip" (Chip-Optik plus jetzt auch Chip-Rolle: Symbol +
   Kurzwert statt "Beschriftung: Wert", siehe chatregler.js).

   UEBERHOLT (2026-09-22, Gestaltung/C -- Befund 1 des Anwenders vom
   Folgetag): die drei Absaetze oben beschreiben ".chat-regler" als eigenes
   drittes Flex-Kind NEBEN den beiden Knopfgruppen, inklusive der
   "flex-shrink: 0" + Media-Block-Loesung gegen den damaligen Ueberlauf. Die
   Leiste zieht seither in die RECHTE Knopfgruppe um, zur Anonymisierung
   (chatwindowinput.js, "rightButtonContainer") -- der Wirt ist jetzt ein
   ".button-container" (webapp.css:1562, KEIN eigenes "flex-wrap"), nicht
   mehr ".chatbot-buttons" direkt. Deshalb GEMESSEN neu statt die alten
   Werte weiterzutragen: ".chat-regler" bekommt "flex-shrink: 1; min-width:
   0" jetzt UNBEDINGT (keine 1024px-Schwelle mehr noetig) -- die rechte
   Gruppe traegt jetzt selbst potenziell vier Chips plus zwei Knoepfe ohne
   eigenes Umbrechen, und nur ein schrumpfbares ".chat-regler" kann bei
   Platzmangel auf sein eigenes "flex-wrap: wrap" ausweichen (mehrzeilig
   INNERHALB der 30px hohen, aber ueberlaufend gemalten Gruppe -- derselbe
   bereits akzeptierte Vertikal-Ueberlauf wie bei den 36px-Knoepfen
   ("[data-design=\"new\"] .chatbot-input .chatbot-button", oben in dieser
   Datei) in der 30px hohen Box), statt die ganze Gruppe waagerecht
   ueberlaufen zu lassen. GEGENGEPRUEFT gegen die
   Ueberlauf-Zusicherungen aus Task 4 (design-cockpit-sichtpruefung.spec.ts,
   "Die Knopfzeile laeuft im schmalen Fenster nicht waagerecht ueber", beide
   Chatflaechen, 900/375px) -- siehe Taskbericht fuer die tatsaechlichen
   Messwerte nach dem Umzug.

   "align-items: center" statt "flex-start" (Befund 2 des Anwenders): mit dem
   Umzug ins Fluss-Layout der rechten Gruppe war der urspruengliche Grund
   fuer "flex-start" (mehrzeiliges Verhalten bei offenem, IM FLUSS stehendem
   Menue -- siehe Vor-Gestaltung/C-Absaetze oben) ohnehin hinfaellig: das
   Menue steht seit "Gestaltung/C" unten "position: absolute" und traegt
   nichts mehr zur Zeilenhoehe von ".chat-regler" bei. */
[data-design="new"] .chat-regler {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ax-space-2);
  flex-shrink: 1;
  min-width: 0;
}

/* Gestaltung/C: eigener Wirt je Regler (Klasse "chat-regler-item",
   chatregler.js "setzeRegler()") -- verankert das Menue direkt an SEINEM
   eigenen Knopf, statt es lose im Fluss der ganzen Leiste treiben zu lassen.
   Dasselbe Muster wie ".cockpit-chat-sichern"/".cockpit-avatar" (oben in
   dieser Datei): die Klasse traegt nur die Verankerung. */
[data-design="new"] .chat-regler-item {
  position: relative;
}

[data-design="new"] .chat-regler-chip {
  height: 31px;
  padding: 0 var(--ax-space-3);
  border: 1px solid var(--ax-border-soft);
  border-radius: var(--ax-radius-full);
  background: transparent;
  color: var(--ax-text-secondary);
  font-family: inherit;
  font-weight: 400;
  font-size: var(--ax-font-size-label-sm);
  /* Gestaltung/C, Befund 2 (GEMESSEN wie schon bei ".cockpit-topbar-chip"
     oben, dieselbe Ursache): die Basisregel fuer Knoepfe setzt
     "display: inline-flex" ohne "align-items" (deren eigener Kommentar
     verbietet das dort, Subset-Invariante der Basisregel) -- der Textknoten
     faellt als anonymes Flex-Kind sonst auf den Anfang der Querachse
     zurueck, sichtbar oben statt mittig im 31px hohen Chip. Diese Klasse
     ist keine Basisregel, sondern ein Zweck-Bauteil -- "align-items:
     center" hier ist deshalb kein Verstoss gegen die Subset-Invariante. */
  align-items: center;
}

[data-design="new"] .chat-regler-chip:hover:not(:disabled) {
  background: var(--ax-bg-hover);
}

/* Gestaltung/C: das Menue haengt jetzt "position: absolute" an seinem
   eigenen Wirt (".chat-regler-item" oben) statt "flex-basis: 100%" im
   Fluss -- siehe Klassenkommentar in chatregler.js ("DIE LAGE DES
   MENUES"). Dasselbe Muster wie ".cockpit-chat-sichern-menu"/
   ".cockpit-avatar-menu" (oben in dieser Datei), inklusive derselben,
   dort ausfuehrlich dokumentierten Falle: "display: flex" hier
   (Spezifitaet 0,2,0) schlaegt sonst die native UA-Regel
   "[hidden] { display: none }" (0,1,0) -- die Regel direkt darunter holt
   "[hidden]" mit hoeherer Spezifitaet (0,3,0) zurueck, ohne "!important".

   Abschluss-Fixwelle (2026-09-22, H4, Blocker): "top: calc(100% + ...)"
   stand hier vorher -- WOERTLICH aus ".cockpit-chat-sichern-menu"/
   ".cockpit-avatar-menu" uebernommen, deren Wirt in der KOPFLEISTE sitzt,
   wo "nach unten oeffnen" richtig ist. Die Regler-Chips sitzen dagegen in
   der LETZTEN Zeile der Eingabeflaeche, am UNTEREN Rand des Fensters -- ein
   Menue mit acht Antwortverhalten ist ~270px hoch und oeffnete dort aus
   dem sichtbaren Bereich HERAUS. Beide Cockpit-Vorlagen setzen zudem
   "document.body.style.overflowY = \"hidden\"" (templatecockpitnavigation-
   chatbot.js/-aiservice.js) -- ein Herunterscrollen zum Menue ist also
   nicht moeglich, die Auswahl war unbenutzbar. "bottom" statt "top" oeffnet
   das Menue stattdessen NACH OBEN, ueber den Chip -- bei allen vier Reglern
   und beiden Chatflaechen (dieselbe Klasse, kein eigener Selektor je
   Regler), gegen "window.innerHeight" zugesichert (siehe Testdatei). */
[data-design="new"] .chat-regler-menu {
  position: absolute;
  bottom: calc(100% + var(--ax-space-1));
  right: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  min-width: 220px;
  background: var(--ax-bg-elevated);
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-md);
  box-shadow: var(--ax-shadow-card);
  padding: var(--ax-space-1);
  /* Council/K1 (2026-09-23), Deckel gegen den naechsten Fall: das
     Antwortverhalten kann inzwischen SIEBEN Optionen fuehren (Kurz/Detail/
     Referat/Automatisch, dazu je nach Freischaltung Deep Thinking/Council/
     Orchestrierung) statt der vier bis acht, fuer die "bottom" oben schon
     einmal nachgezogen wurde -- und beim Council-Regler haengt zusaetzlich
     noch die Gremiumsauswahl in dasselbe Menue (chatregler.js, "getMenu()").
     Nach oben geoeffnet waechst das Menue in Richtung Fensterkante; auf
     einem kurzen Bildschirm ist "document.body.style.overflowY: hidden"
     (siehe Kommentar oben) weiterhin gesetzt, ein Herunterscrollen zum
     abgeschnittenen Rest bleibt also unmoeglich. "max-height" mit eigenem
     "overflow-y" haelt das Menue deshalb IMMER innerhalb eines nutzbaren
     Bereichs -- 320px reichen fuer sieben Zeilen "chat-regler-option" plus
     Innenabstand; "calc(100vh - 160px)" faengt zusaetzlich den kurzen
     Bildschirm ab (Platz fuer Kopfzeile/Composer bleibt reserviert), "min()"
     nimmt den jeweils kleineren der beiden Werte. */
  max-height: min(320px, calc(100vh - 160px));
  overflow-y: auto;
}

[data-design="new"] .chat-regler-menu[hidden] {
  display: none;
}

[data-design="new"] .chat-regler-optionen {
  display: flex;
  flex-direction: column;
}

[data-design="new"] .chat-regler-option {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--ax-space-2) var(--ax-space-3);
  border: none;
  border-radius: var(--ax-radius-sm);
  background: transparent;
  color: var(--ax-text-primary);
  font-family: inherit;
  font-weight: 400;
  font-size: var(--ax-font-size-label-sm);
}

[data-design="new"] .chat-regler-option:hover {
  background: var(--ax-bg-hover);
}

/* ===================================================================
   Sichtpruefung 2026-09-23, Befund P4/P5: die Verwaltungszeile des
   Projektdialogs (dialogproject.js "setupDialogUi()", Reiter
   "Stammdaten": "Wissensdatenbank" + "Projekt loeschen"). Sie ist dort
   an die ERSTE Stelle gezogen, weil sie am Ende des Formulars unterhalb
   der Faltkante stand und der Anwender beide Funktionen fuer fehlend
   hielt. Damit sie dort als eigener Block liest und nicht als erste
   Formularzeile missverstanden wird, bekommt sie eine Trennlinie nach
   unten -- dieselbe weiche Randmarke wie die Chips der Kopfzeile.
   "Projekt loeschen" rutscht per "margin-left: auto" an das rechte
   Ende: eine unwiderrufliche Handlung soll nicht direkt neben der
   harmlosen liegen, wo sie verklickt werden kann. Die Zeile traegt
   zusaetzlich "container-left-right" (display: flex) -- das "gap" hier
   wirkt deshalb. */
[data-design="new"] .project-verwaltung-row {
  gap: var(--ax-space-2);
  margin-bottom: var(--ax-space-4);
  padding-bottom: var(--ax-space-3);
  border-bottom: 1px solid var(--ax-border-soft);
}

[data-design="new"] .project-verwaltung-row [data-testid="btn-delete-project"] {
  margin-left: auto;
}

/* Ticket #2163: der Wissensdatenbank-Knopf war nur ein Symbol, der Text
   stand allein im Tooltip -- Anwender fanden die Funktion nicht. Er traegt
   jetzt eine sichtbare Beschriftung (dialogproject.js "showLabel()") und
   hebt sich als umrandeter Knopf ab. Vorbild der Beschriftung:
   ".chatbot-blatt .button-icon-label". */
[data-design="new"] .project-verwaltung-row [data-testid="btn-open-project-kb"] {
  width: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--ax-space-2);
  padding: var(--ax-space-1) var(--ax-space-3);
  border: 1px solid var(--ax-border-soft);
  border-radius: var(--ax-radius-md);
}

[data-design="new"] .project-verwaltung-row [data-testid="btn-open-project-kb"] .button-icon-label {
  color: var(--ax-text-primary);
  font-size: var(--ax-font-size-label-sm);
  white-space: nowrap;
}

/* ===================================================================
   Sichtpruefung 2026-09-23, Befund P2: die Sternbewertung
   (ratingstars.js "OrganismsRatingStars", Element "#rating"/".rating",
   fuenf Kinder mit der Klasse ".star"). Drei Teile:

   1) Optik. Der Bestand faerbt die Sterne ueber
      "--font-color-navigation(-hover)" (webapp.css:5560-5568,
      unantastbar) -- im neuen Design tragen sie stattdessen die
      semantischen Marken: ruhend gedaempft, gewaehlt in der
      Warnmarke ("--ax-status-warning-on-bg", dieselbe, die auch die
      mittlere Souveraenitaetsstufe traegt -- ein Stern ist nun einmal
      golden, und eine zweite Goldmarke waere eine neue
      Uneinheitlichkeit). Spezifitaet (0,3,0) gegen die ungescopten
      Bestandsregeln (0,1,0 bzw. 0,2,0) -- kein "!important" noetig.

   2) Der Ueberfahr-Effekt faerbt den Stern UND alle davor. Der
      Bestand faerbt nur den einen unter dem Zeiger, was beim Waehlen
      von "vier von fuenf" keine Rueckmeldung ueber die Auswahl gibt.
      Geloest ueber ":has()" statt ueber JavaScript: "ratingstars.js"
      ist mit der AI-Service-Bewertung GETEILT und laeuft in beiden
      Designs -- eine Ereignisbehandlung dort haette das alte Design
      veraendert. ":has(> .star:nth-child(N):hover)" trifft immer
      genau eine der fuenf Regeln, "> .star:nth-child(-n+N)" faerbt
      daraufhin die ersten N. Spezifitaet: ":has()" erbt die seines
      spezifischsten Arguments (0,3,0), zusammen (0,7,0) -- schlaegt
      damit auch ".star.active", was beabsichtigt ist: waehrend des
      Ueberfahrens zeigt die Reihe die MOEGLICHE Wahl, nicht die
      getroffene.

   3) Die Bewertung sitzt in der Knopfreihe der Antwort und ist
      entsprechend klein.

      BERICHTIGT (2026-09-23, zweite Sichtpruefung -- Anwender: "die
      Tatsache, dass die Bewertung unter den Modellinformationen
      steht, ist nicht gut geloest. Integriere das doch in die
      Leiste, in der die Exportfunktionen stehen, und mache es
      entsprechend kleiner"): hier standen bis zu diesem Datum zwei
      eigene Regeln, die die Bewertung als letztes Kind von
      ".chat-window" auf "opacity: 0" setzten und sie ueber den
      Nachbar-Selektor ".msg-bot:hover + ..." wieder einblendeten.
      Die Bewertung zieht stattdessen in ".msg-actions" derselben
      Fusszeile um (templatechatwindow.js
      "platziereBewertungImChatfluss()").

      DAS MACHT DAS EINBLENDEN ZU EINER GESCHENKTEN EIGENSCHAFT: die
      Knopfreihe traegt im Bestand ohnehin "opacity: 0" und wird von
      ".msg-bot:hover .msg-actions" sichtbar (webapp.css:2821-2831,
      unantastbar); unterhalb der mobilen Schwelle steht sie
      dauerhaft (webapp.css:8792). Beides gilt fuer die Bewertung
      jetzt mit, ohne eine einzige Regel dafuer. Hier bleibt nur,
      was die Reihe an ihren neuen Nachbarn angleicht: dieselbe
      Hoehe wie die Knoepfe (28px, siehe ".msg-actions
      button.image-small" oben) und kleinere Sterne. "width: auto"
      ist noetig, weil ".rating" im Bestand "width: 100%" traegt
      (webapp.css:6259) und die Reihe sonst die ganze Knopfzeile
      auseinanderzoege. */
[data-design="new"] .rating {
  gap: var(--ax-space-1);
}

[data-design="new"] .rating > .star {
  color: var(--ax-text-muted);
  font-size: 22px;
  line-height: 1;
  transition: color 120ms ease-out, transform 120ms ease-out;
}

[data-design="new"] .rating > .star.active {
  color: var(--ax-status-warning-on-bg);
}

[data-design="new"] .rating:has(> .star:nth-child(1):hover) > .star:nth-child(-n+1),
[data-design="new"] .rating:has(> .star:nth-child(2):hover) > .star:nth-child(-n+2),
[data-design="new"] .rating:has(> .star:nth-child(3):hover) > .star:nth-child(-n+3),
[data-design="new"] .rating:has(> .star:nth-child(4):hover) > .star:nth-child(-n+4),
[data-design="new"] .rating:has(> .star:nth-child(5):hover) > .star:nth-child(-n+5) {
  color: var(--ax-status-warning-on-bg);
}

[data-design="new"] .rating > .star:hover {
  transform: scale(1.15);
}

[data-design="new"] .msg-actions [data-testid="chat-bewertung"] {
  width: auto;
  height: 28px;
  align-items: center;
}

/* #2019: in der Knopfreihe stehen seit dem Umbau keine Sterne mehr, sondern
   Daumen hoch/runter (atombuttondaumen.js, Klassen "image-small
   rating-daumen"). Groesse und Hover-Flaeche kommen von ".msg-actions
   button.image-small" oben. Die Farbe muss hier stehen: die Basisregel
   ":where([data-design=\"new\"]) button" faerbt die Schrift -- und damit
   das Symbol ueber "currentColor" -- in "--ax-action-on-primary", auf
   transparentem Grund waere der Daumen im hellen Theme unsichtbar. Der
   Hover-Sammelregel (nur Hintergrund) steht eine eigene Schriftfarbe
   gegenueber, der gewaehlte Daumen traegt die Aktionsmarke. */
[data-design="new"] button.rating-daumen {
  color: var(--ax-text-muted);
}

[data-design="new"] button.rating-daumen[aria-pressed="false"]:hover:not(:disabled) {
  color: var(--ax-text-primary);
}

[data-design="new"] button.rating-daumen[aria-pressed="true"] {
  color: var(--ax-action-primary);
}

/* Daumen am AI-Service-Ergebnis: in der Knopfreihe neben Download/Teilen/
   Testfall (".button-container", zentriert). ".rating" traegt im Bestand
   "width: 100%" und wuerde die Reihe sprengen; "#rating" (webapp.css) setzt
   "margin-left: 10px" und schlaegt jede reine Klassen-/Attributregel, daher
   hier ebenfalls ueber die Id. */
[data-design="new"] .button-container > #rating[data-testid="aiservice-bewertung"] {
  width: auto;
  margin-left: var(--ax-space-2);
}

@media (prefers-reduced-motion: reduce) {
  [data-design="new"] .rating > .star {
    transition: none;
  }

  [data-design="new"] .rating > .star:hover {
    transform: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   KI-Service-Katalog (Spec 2026-09-23). Vorlage: Figma
   "AuxData.ai — Product / Screens", Seite "DE · KI-Services · Katalog",
   Knoten 264:11484. Gemessene Werte der Vorlage stehen je Regel dabei;
   abgebildet wird auf vorhandene Marken, KEINE neuen Farbwerte. */

/* BEFUND C-2 (Abschlussreview 2026-09-24): der Wirt beider Seiten,
   ".aiservice-container", ist ungescopt "display: flex; flex-direction:
   column; align-items: center" (webapp.css:2475, unantastbar). "align-items:
   center" gibt jedem Kind, das keine eigene Breite setzt, fit-content --
   Katalogleiste und Raster beanspruchten die Seitenbreite damit NIE, und das
   Raster loeste auf EINE Spalte auf statt auf drei. Der Luna-Pfad macht es an
   derselben Stelle explizit richtig (".card-container { width: calc(100% -
   40px) }", webapp.css). Beide neuen Bloecke bekommen deshalb hier ihre
   volle Breite -- der Katalog hat keinen eigenen Innenabstand, "box-sizing"
   ist also nicht beteiligt. */
[data-design="new"] .service-katalog {
  width: 100%;
}

[data-design="new"] .service-katalog-kopf {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--ax-space-4);
  flex-wrap: wrap;
}

[data-design="new"] .service-katalog-titelspalte {
  display: flex;
  flex-direction: column;
  /* Vorlage: 6px. Die naechste Stufe der Skala ist 8px; eine eigene
     Zwischenstufe waere eine neue Marke. */
  gap: var(--ax-space-2);
  min-width: 0;
}

[data-design="new"] .service-katalog-ueberschrift {
  margin: 0;
  font-size: 26px;
  font-weight: 700;
  color: var(--ax-text-primary);
}

[data-design="new"] .service-katalog-bestand {
  margin: 0;
  font-size: 14px;
  color: var(--ax-text-secondary);
}

/* Vorlage: 210x36, Radius 10. Die Breite ist eine Untergrenze, kein
   Festmass -- die Leiste bricht schmal um. */
[data-design="new"] .service-katalog-suche input {
  width: 210px;
  max-width: 100%;
  height: 36px;
  min-height: 0;
  border-radius: var(--ax-radius-md);
  background: var(--ax-bg-input);
  margin-bottom: 0;
}

[data-design="new"] .service-katalog-kategorien {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ax-space-2);
  margin-top: var(--ax-space-5);
}

/* Vorlage: 32px hoch, padding 0 13px, Radius 999, Name 12px/500. */
[data-design="new"] .service-katalog-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 13px;
  border-radius: var(--ax-radius-full);
  border: 1px solid var(--ax-border-default);
  background: var(--ax-bg-surface-1);
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-label-sm);
  font-weight: 500;
  cursor: pointer;
  /* M-1 (Abschlussreview 2026-09-24): die nackte "button"-Regel traegt
     ungescopt "margin-right: 6px" (webapp.css:870, unantastbar). Der Wert
     ADDIERT sich zur "gap" der Reihe -- gemessen 14px statt der
     spezifizierten 8px. Genullt, weil die Reihe ihren Abstand ueber "gap"
     vergibt; der letzte Chip verliert dabei nichts, er hatte rechts nichts
     zu halten. */
  margin-right: 0;
}

/* Der Zaehler ist eine ZAHL, kein uebersetzbarer Text -- erzeugter Inhalt
   ist hier deshalb unbedenklich (dieselbe Technik wie "attr(data-time)"
   im Bestand) und erspart dem Chip ein zweites Kindelement, das ein
   Knopf-Atom ohnehin nicht tragen kann. */
[data-design="new"] .service-katalog-chip::after {
  content: attr(data-anzahl);
  font-size: 11px;
  font-weight: 600;
  color: var(--ax-text-muted);
}

[data-design="new"] .service-katalog-chip:hover {
  background: var(--ax-bg-hover);
}

[data-design="new"] .service-katalog-chip.aktiv {
  background: var(--ax-action-primary);
  border-color: var(--ax-action-primary);
  color: var(--ax-action-on-primary);
}

[data-design="new"] .service-katalog-chip.aktiv::after {
  color: var(--ax-action-on-primary);
}

/* Vorlage: drei Spalten zu 353px, gap 20px auf 1100px Inhaltsbreite. Die
   353 sind das ERGEBNIS dieser Breite, nicht ihre Aussage -- deshalb ein
   atmendes Raster mit derselben Fuge. */
[data-design="new"] .service-katalog-raster {
  display: grid;
  /* SICHTPRUEFUNG MOBIL 2026-09-25: "minmax(300px, 1fr)" unterschreitet
     seine Untergrenze nicht. Gemessen bei 360px Fenster: dem Raster blieben
     296px, die Spur wurde trotzdem 300 -- die Karte lief bis x=364 aus dem
     Bild, und weil der Wirt nicht scrollt, war sie abgeschnitten statt
     erreichbar. "min(300px, 100%)" macht die Untergrenze zur Obergrenze der
     verfuegbaren Breite. */
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: 20px;
  margin-top: var(--ax-space-5);
  /* Befund C-2, zweite Haelfte: ohne diese Zeile bekommt das Raster von
     ".aiservice-container" (align-items: center) fit-content und faellt auf
     eine Spalte. Siehe die Begruendung am Kopf dieses Abschnitts. */
  width: 100%;
}
/* Servicekarte, neues Design (Spec 2026-09-23, Abschnitt 6).
   Gemessen an Figma 264:11538, erste Karte der ersten Rasterzeile. */
[data-design="new"] .service-karte {
  display: flex;
  flex-direction: column;
  padding: 18px 18px 16px 18px;
  border: 1px solid var(--ax-border-soft);
  border-radius: 14px;
  background: var(--ax-bg-surface-1);
  min-width: 0;
}

[data-design="new"] .service-karte-kopf {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--ax-space-2);
  margin-bottom: 13px;
}

[data-design="new"] .service-karte-kachel {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 11px;
  overflow: hidden;
}

/* Kein eigenes Bild: einheitliche Toenung statt einer geratenen
   Kategoriefarbe -- siehe Spec, Abschnitt 6.2.

   BEFUND M-2 (Abschlussreview 2026-09-24): diese Toenung war NIE zu sehen.
   Die Karte haengte auch ohne eigenes Bild ein <img> in die Kachel, und das
   Ersatzbild "./images/aiservice.jpg" ist ein DECKENDES JPEG ueber der
   ganzen Flaeche -- die Regel behauptete eine Farbe, die kein Anwender je
   gesehen hat. Die Karte erzeugt in diesem Fall jetzt gar kein <img> mehr
   (organismsaiservicecard.js "_setupUiNeu()"); das Standardsymbol, das Spec
   Abschnitt 6.2 Regel 2 verlangt, malt die Zeile darunter.

   ALS MASKE, NICHT ALS BILD: "./images/aiservice.svg" traegt eine feste
   Fuellfarbe (#5f6368) und stuende damit im dunklen Theme fast unsichtbar
   auf der violetten Toenung. Die Maske nimmt nur die Form; die Farbe kommt
   aus der Marke, die zur Toenung gehoert. Dasselbe Mittel nutzt der Bestand
   fuer das Sendesymbol des eingebetteten Chats (webapp.css:2332). */
[data-design="new"] .service-karte-kachel.ohne-bild {
  background: var(--ax-accent-ai-bg);
}

[data-design="new"] .service-karte-kachel.ohne-bild::before {
  content: "";
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  background-color: var(--ax-accent-ai-on-bg);
  -webkit-mask: url("../images/aiservice.svg") no-repeat center / 20px 20px;
  mask: url("../images/aiservice.svg") no-repeat center / 20px 20px;
}

[data-design="new"] .service-karte-symbol {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 2026-09-24 (Anwender: "trotzdem sollen alle Karten die gleiche Hoehe
   haben"): der Titel ist auf EINE Zeile gekuerzt. Ohne diese Grenze
   bestimmt der laengste Name die Hoehe seiner Rasterzeile -- ein Raster
   mit einzeiligen und zweizeiligen Titeln steht ungleich. Der volle Name
   steht im Hinweistext der Karte (organismsaiserviceresultcard.js
   "fillData()"). */
[data-design="new"] .service-karte-titel {
  font-size: 15px;
  font-weight: 600;
  line-height: 21px;
  color: var(--ax-text-primary);
  margin-bottom: 5px;
  min-width: 0;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Freitext: zwei Zeilen, dann Ellipse. Ohne diese Grenze bestimmt der
   laengste Text die Hoehe JEDER Zeile des Rasters. */
/* BERICHTIGT 2026-09-24: "line-height" und "min-height" ergaenzt. Die
   Zweizeilen-Grenze allein macht Karten nur nicht HOEHER -- eine Karte mit
   einzeiliger Beschreibung blieb NIEDRIGER, und im Raster standen die
   Trennlinien dadurch auf verschiedenen Hoehen. Der Platz fuer beide
   Zeilen ist jetzt immer reserviert, auch wenn nur eine gefuellt ist.
   21px + 2 x 18px + die Abstaende ergeben fuer jede Karte dieselbe Hoehe. */
[data-design="new"] .service-karte-text {
  font-size: 13px;
  line-height: 18px;
  min-height: 36px;
  color: var(--ax-text-muted);
  margin-bottom: 14px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Die Ergebniskarte schreibt ZWEI Zeilen in EIN Element, getrennt durch
   einen echten Zeilenumbruch im "textContent" -- so bleibt der sichtbare
   Text ueber "textContent" gesetzt und braucht kein "innerHTML" mit einem
   <br>. "pre-line" macht den Umbruch sichtbar und faltet sonstige
   Leerraeume weiterhin zusammen. */
[data-design="new"] .service-karte-text.zweizeilig {
  white-space: pre-line;
}

/* Die Trennlinie der Vorlage ist hier ein Rand, kein eigenes Element --
   ein Rechteck von 1px Hoehe waere ein Knoten ohne Aufgabe. */
[data-design="new"] .service-karte-fuss {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ax-space-3);
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--ax-border-soft);
}

[data-design="new"] .service-karte-kategorie {
  font-size: 11px;
  color: var(--ax-text-muted);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* BEFUND I-2 (Abschlussreview 2026-09-24): "AtomButtonCommand" baut einen
   reinen Symbolknopf -- der Text lebte nur im "title". Spec Abschnitt 6
   verlangt eine Beschriftung (12px/600, ruhend umrissen), die Figma-Fusszeile
   zeigt "[> Ausfuehren]". Die Beschriftung entsteht als <span> ueber
   "textContent" (nicht ueber CSS-"content"); hier steht nur, was die
   Geometrie des Symbolknopfs dafuer aufgeben muss:
   "[data-design="new"] button.button-icon" (0,2,1) setzt eine quadratische
   Flaeche ohne Innenabstand und ohne Rand, diese Regel (0,3,1) schlaegt sie.

   BERICHTIGT 2026-09-24 (Anwender: "Das Icon fuer Ergebnis einsehen ist
   nicht im Button. Der ist weiter rechts."): die vier Regeln dieses Blocks
   hingen an der Testid "aiservice-execute" und galten damit NUR fuer die
   Servicekarte. Der Knopf der Ergebniskarte heisst "results-detail" und
   erbte deshalb weiter die quadratische 36px-Flaeche des Symbolknopfs --
   das Symbol sass darin zentriert, die Beschriftung lief rechts heraus, und
   der alte "::after"-Hinweis aus webapp.css:1440 stand zusaetzlich daneben.
   Der Selektor greift jetzt jeden Aktionsknopf in einer Kartenfusszeile,
   egal welche Testid er traegt; die Fusszeile enthaelt ohnehin genau einen.
   Eine zweite Kopie des Blocks je Testid waere die Art Duplikat, die beim
   naechsten Kartentyp wieder auseinanderlaeuft. */
[data-design="new"] .service-karte-fuss button.button-icon {
  flex: 0 0 auto;
  height: 28px;
  min-height: 0;
  width: auto;
  padding: 0 10px;
  gap: 6px;
  /* M-1, zweite Haelfte: ".button-icon" traegt ungescopt
     "margin-right: 4px" (webapp.css:1414, unantastbar) -- in einer Fusszeile
     mit "justify-content: space-between" ruecken davon 4px vom rechten Rand
     ab. */
  margin-right: 0;
  border: 1px solid var(--ax-border-default);
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ax-text-secondary);
}

/* Das Symbol sitzt jetzt neben Text in einem 28px hohen Knopf; die 20px der
   Symbolknopf-Regel ("--ax-size-icon-md") waeren dort zu gross. */
[data-design="new"] .service-karte-fuss button.button-icon img {
  width: 14px;
  height: 14px;
}

/* Der title-Hinweis von ".button-icon::after" (webapp.css:1440, ungescopt,
   liest "attr(title)") wuerde ueber dem Knopf jetzt genau das wiederholen,
   was daneben schon steht. */
[data-design="new"] .service-karte-fuss button.button-icon::after {
  content: none;
}

/* Die Vorlage zeigt den gefuellten Knopf an der hervorgehobenen Karte --
   uebersetzt in einen Zustand: die Karte unter dem Zeiger. */
[data-design="new"] .service-karte:hover {
  border-color: var(--ax-border-accent);
}

[data-design="new"] .service-karte:hover button.button-icon {
  background: var(--ax-action-primary);
  border-color: var(--ax-action-primary);
  color: var(--ax-action-on-primary);
}

/* BEFUND C-1 / M-3 (Abschlussreview 2026-09-24): der Favoritenstern verliess
   die Karte. ".card-favorite" traegt ungescopt "position: absolute; top:
   10px; left: 10px" (webapp.css:4726, unantastbar). In Luna faengt
   ".card { position: relative }" das ab -- die neue Karte hat kein
   positioniertes Gegenstueck, der Stern haengte sich also an den naechsten
   positionierten Vorfahren und ALLE Sterne stapelten sich ausserhalb ihrer
   Karten. Er kommt hier in den Fluss zurueck, damit der Flex-Kopf ihn rechts
   platziert.

   "position: relative" statt "static", weil der Stern darunter als Maske auf
   einem "::before" entsteht und dafuer einen enthaltenden Block braucht.
   "top"/"left" muessen dabei ausdruecklich auf "auto": relativ positioniert
   wuerden die geerbten 10px sonst als VERSATZ wirken.

   "display: inline-flex" ist nicht nur Layout: unterhalb von 640px blendet
   der Bestand ".card-favorite" ganz aus (webapp.css:10704, "display: none").
   Im Katalog darf das nicht passieren -- dort ist der Stern die einzige
   Stelle, an der ein Favorit gesetzt wird. Spezifitaet (0,3,0) gegen (0,1,0),
   gilt damit auch innerhalb der Medienabfrage. */
[data-design="new"] .service-karte-kopf .card-favorite {
  position: relative;
  top: auto;
  left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  /* Spec Abschnitt 6: Stern 17x17. Geerbt waren 24x24
     (".img-favorite img", webapp.css:4732). */
  width: 17px;
  height: 17px;
  cursor: pointer;
}

/* Das <img> traegt nur noch den ZUSTAND -- sein "src" wechselt in
   "atomcontainerfavorite.js" zwischen favorite_active.svg und
   favorite_inactive.svg, und die Favoritenlogik haengt daran. Es bleibt
   deshalb im Fluss und klickbar ("opacity: 0" statt "display: none"),
   gezeichnet wird der Stern aber vom "::before" darunter. Dasselbe Muster
   wie im eingebetteten Chat-Wirt (webapp.css:2243: <img> aus, Pseudo-Element
   malt die Maske). */
[data-design="new"] .service-karte-kopf .card-favorite img {
  position: relative;
  z-index: 1;
  width: 17px;
  height: 17px;
  opacity: 0;
  /* Geerbt war "filter: brightness(1.7)" (webapp.css:4734) -- eine
     Aufhellung, keine Farbe, und in keinem Theme eine Aussage. */
  filter: none;
}

/* Ruhend: umrissen in der gedaempften Marke. Die Kontur steckt im Pfad des
   SVG selbst (favorite_inactive.svg zeichnet den Ring), die Maske uebernimmt
   sie unveraendert. */
[data-design="new"] .service-karte-kopf .card-favorite::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--ax-text-muted);
  -webkit-mask: url("../images/favorite_inactive.svg") no-repeat center / 17px 17px;
  mask: url("../images/favorite_inactive.svg") no-repeat center / 17px 17px;
}

/* Gesetzt: gefuellt in derselben Warnmarke, die seit der Sichtpruefung vom
   2026-09-23 auch die Bewertungssterne im Chat tragen (Spec, Abschnitt 6).
   Der Zustand wird am "src" des <img> abgelesen -- das ist die einzige
   Stelle, an der ihn der Bestand fuehrt. */
[data-design="new"] .service-karte-kopf .card-favorite:has(img[src$="favorite_active.svg"])::before {
  background-color: var(--ax-status-warning-on-bg);
  -webkit-mask-image: url("../images/favorite_active.svg");
  mask-image: url("../images/favorite_active.svg");
}

/* ═══════════════════════════════════════════════════════════════════
   Ergebnisseite (2026-09-24). Sie nutzt die Katalogleiste und die
   Kartenklassen des KI-Service-Katalogs unveraendert; neu ist nur das,
   was ihre EIGENEN beiden Besonderheiten brauchen.

   1) Der Werkzeugbereich der Kopfzeile traegt jetzt ZWEI Bedienelemente
      (Suchfeld und Tageszahl) statt einem. Solange es eins war, brauchte
      er keine eigene Regel -- ein Block genuegte. Mit zweien muss er
      ordnen. Die Figma-Vorlage setzt dort 10px zwischen die beiden
      Elemente; "--ax-space-3" ist die naechste Stufe der Skala (12px).
   2) Die Tageszahl ist ein SERVER-Parameter (sie laedt neu), kein
      Anzeigefilter -- sie steht deshalb neben dem Suchfeld und nicht in
      der Chipreihe. Ihre Beschriftung darf nicht umbrechen, sonst
      springt die Kopfzeile beim Tippen. */
[data-design="new"] .service-katalog-werkzeuge {
  display: flex;
  align-items: center;
  gap: var(--ax-space-3);
  flex-wrap: wrap;
}

[data-design="new"] .ergebnis-tage {
  display: flex;
  align-items: center;
  gap: var(--ax-space-2);
}

[data-design="new"] .ergebnis-tage label {
  margin: 0;
  white-space: nowrap;
  font-size: var(--ax-font-size-label-sm);
  color: var(--ax-text-secondary);
}

/* Dieselbe Hoehe wie das Suchfeld daneben (siehe
   ".service-katalog-suche input"). "min-height: 0" ist noetig, weil eine
   globale Untergrenze ein kleineres "height" sonst IMMER schlaegt --
   unabhaengig von der Spezifitaet. */
[data-design="new"] .ergebnis-tage input {
  width: 72px;
  height: 36px;
  min-height: 0;
  margin-bottom: 0;
}

/* Das Zustandsabzeichen sitzt dort, wo die Servicekarte ihren Stern
   traegt. Es braucht keine eigene Farbe -- die kommt aus der vorhandenen
   Abzeichen-Familie (".badge-success"/"-danger"/"-warning", oben in
   dieser Datei), die Karte vergibt nur die passende Klasse
   (organismsaiserviceresultcard.js "ergebnisZustand()"). Hier steht
   allein, dass es nicht schrumpfen und nicht umbrechen darf. */
[data-design="new"] .service-karte-kopf > .badge {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Sichtpruefung (2026-09-25, Befund des Auftraggebers): "Der Kontrast des
   Hovers Weniger bzw. Mehr Anzeigen im Cockpit ist nicht gut und der Text
   nicht lesbar."

   AM BROWSER NACHGEMESSEN, nicht aus der CSS abgeschrieben:
       Ruhe   Text rgb(53,50,74) auf rgb(255,255,255)  -> 12,306:1
       Hover  Text rgb(53,50,74) auf rgb(0,81,122)     ->  1,440:1
   WCAG AA verlangt 4,5:1 fuer normalen Text. 1,44 ist praktisch unsichtbar.

   URSACHE -- und sie liegt NICHT bei einer Altlast, sondern im neuen Design
   selbst: ".cockpit-sidebar-more" ist ein nacktes "<button>" und faellt
   damit unter die Sammelregel oben (Zeile 123):
       :where([data-design="new"]) button:hover:not(:disabled)
   ":where()" traegt keine Spezifitaet, die Regel zaehlt also (0,2,1) und
   schlaegt die Grundregel des Knopfes ("[data-design=...] .cockpit-sidebar-more",
   (0,2,0)). Sie setzt NUR den Hintergrund auf die Aktionsfarbe
   (--ax-action-primary-hover = cyan/700) und laesst die Textfarbe stehen --
   der Knopf behaelt "--ax-text-secondary" aus seiner Grundregel. Dunkler
   Text auf dunklem Cyan.

   BEHEBUNG: derselbe Hover wie bei den Geschwistern derselben Leiste
   (".cockpit-sidebar-item:hover", siehe oben) -- die Flaeche tont nur an,
   statt die Aktionsfarbe zu tragen. Der Knopf ist auch keine Aktion in
   diesem Sinn: er klappt ein Fach auf und zu.

   (0,3,0) schlaegt (0,2,1) -- deshalb ohne "!important", das hier ohnehin
   verboten waere. Die Textfarbe bleibt unangetastet: sie war nie das
   Problem, nur ihr Untergrund. */
[data-design="new"] .cockpit-sidebar-more:hover {
  background: var(--ax-bg-hover);
}

/* ═══════════════════════════════════════════════════════════════════════
   SICHTPRUEFUNG 2026-09-25 (Auftraggeber): "Die Suche sieht im
   Ursprungszustand (noch keine Suche erfolgt) sehr zusammengestaucht und
   lieblos aus. Ausserdem kann ich die Suche nur durch den Escape Tastatur
   Button schliessen. Ich moechte einen Schliessen Button im Dialog und eine
   schoenere Darstellung."

   GEMESSEN vor der Aenderung: der Dialog war in diesem Zustand 660x110 --
   60px Kopfzeile, 40px Fusszeile, dazwischen nichts.
   ═══════════════════════════════════════════════════════════════════════ */

/* Der Schliessen-Knopf sitzt in der Ecke, wo ihn jeder sucht; der esc-Chip
   rueckt dafuer nach links (siehe dort).

   DIE :hover-REGEL IST PFLICHT, nicht Zierde: ".cockpit-search-close" ist
   ein nacktes "<button>" und faellt sonst unter die Sammelregel ganz oben
   (":where([data-design=...]) button:hover:not(:disabled)"), die NUR den
   Hintergrund auf die Aktionsfarbe setzt und die Textfarbe stehen laesst.
   Genau daran war am selben Tag schon der Knopf "Mehr/Weniger anzeigen" in
   der Seitenleiste unlesbar geworden (1,44:1 hell, 1,05:1 dunkel). (0,3,0)
   schlaegt (0,2,1), deshalb ohne "!important".

   Die Masse stehen ausdruecklich da, weil die ungescopte Grundregel fuer
   "button" (webapp.css) 24x24 samt Aussenabstaenden vorgibt. */
[data-design="new"] .cockpit-search-close {
  position: absolute;
  top: 16px;
  right: var(--ax-space-4);
  width: 28px;
  height: 28px;
  min-height: 0;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--ax-border-default);
  border-radius: var(--ax-radius-sm);
  background: transparent;
  color: var(--ax-text-secondary);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

[data-design="new"] .cockpit-search-close:hover {
  background: var(--ax-bg-hover);
  color: var(--ax-text-primary);
}

/* Der Ausgangszustand. Die Mindesthoehe haengt am BLOCK, nicht an der
   Trefferliste: so bekommt der leere Dialog seine Flaeche, ohne dass eine
   kurze Trefferliste kuenstlich auseinandergezogen wird. */
[data-design="new"] .cockpit-search-leer {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--ax-space-2);
  min-height: 200px;
  padding: var(--ax-space-6) var(--ax-space-8);
  box-sizing: border-box;
  text-align: center;
}

/* Die Lupe traegt "currentColor" (siehe "_leerzustand()"), erbt also diese
   Farbe -- ein Symbol, zwei Themen, keine zweite Datei. */
[data-design="new"] .cockpit-search-leer > svg {
  width: 40px;
  height: 40px;
  color: var(--ax-text-muted);
  opacity: 0.7;
}

[data-design="new"] .cockpit-search-leer-titel {
  margin: var(--ax-space-2) 0 0 0;
  color: var(--ax-text-primary);
  font-size: var(--ax-font-size-body-md);
  font-weight: 600;
}

[data-design="new"] .cockpit-search-leer-text {
  margin: 0;
  max-width: 44ch;
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-body-sm);
  line-height: 20px;
}

/* #2025: der gemeinsame Leerzustand (moleculeleerzustand.js) -- dieselbe
   Anmutung wie der Ausgangszustand der Kommandopalette direkt darueber,
   nur ohne Mindesthoehe: er steht in Seiten und Listen, nicht in einem
   Dialog, der eine Flaeche braucht. Im Kartenraster ueberspannt er alle
   Spalten. */
[data-design="new"] .leerzustand {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ax-space-2);
  padding: var(--ax-space-6) var(--ax-space-4);
  box-sizing: border-box;
  text-align: center;
}

[data-design="new"] .leerzustand-titel {
  margin: 0;
  color: var(--ax-text-primary);
  font-size: var(--ax-font-size-body-md);
  font-weight: 600;
}

[data-design="new"] .leerzustand-text {
  margin: 0;
  max-width: 44ch;
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-body-sm);
  line-height: 20px;
}

/* ═══════════════════════════════════════════════════════════════════════
   SICHTPRUEFUNG MOBIL 2026-09-25, Befund 1 (Auftraggeber): "dass die
   Agentenauswahl nicht von der Leiste ueberdeckt werden darf".

   GEMESSEN, nicht hergeleitet. Die Huelle ist ein Raster
   ("grid-template-columns: auto 1fr", Spalte 1 die Navigation):

       Fenster 900px -> Spalten "64px 836px", Kopfleiste ab x=64   richtig
       Fenster 390px -> Spalten "0px 390px",  Kopfleiste ab x=0    falsch
       dabei: topbar-agent 12..72 IM Band der 64px breiten Leiste

   URSACHE, und sie ist eine Altlast: "webapp.css:10981" (im Block
   "@media (max-width: 640px)") setzt

       .chatbot-service:not(.panel-collapsed) { position: absolute; ... }

   "position: absolute" nimmt die Navigation aus dem Fluss -- sie traegt
   damit nichts mehr zur "auto"-Spalte bei, und die Spalte faellt auf 0.

   Die Klasse "panel-collapsed" vergibt AUSSCHLIESSLICH das alte Design
   (cockpitnavigation.js:426/430). Im neuen trifft ":not(...)" deshalb
   immer. Die Regel beschreibt das Ausklapp-Overlay der ALTEN Symbolleiste
   und war fuer diese Huelle nie gedacht.

   "webapp.css" ist unantastbar, also steht die Gegenregel hier. Gleiche
   Spezifitaet wie die Altregel ((0,2,0) gegen (0,2,0)) -- es gewinnt die
   spaetere Datei, und "components.css" wird nach "webapp.css" geladen.
   Kein "!important" (in dieser Datei verboten) und keine kuenstlich
   verlaengerte Klassenkette. */
@media (max-width: 640px) {
  [data-design="new"] .chatbot-service {
    position: static;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   SICHTPRUEFUNG MOBIL 2026-09-25, Befund 1, zweiter und schwererer Teil.

   GEMESSEN bei 900px auf der AI-Services-Seite -- der Inhalt lag UNTER der
   Leiste, sichtbar an der angeschnittenen Ueberschrift ("t-agent-rag"
   statt "test-agent-rag"):

       chatbot-service      0..64    col=1  pos=static
       cockpit-topbar      64..900   col=2  pos=static
       aiservice-container 20..880   col=2  pos=ABSOLUTE

   Der Behaelter ist absolut positioniert und ignoriert die Rasterspalte
   deshalb vollstaendig.

   URSACHE: "webapp.css:6655" ("@media screen and (max-width: 1024px)")
   setzt "position: absolute; left: 20px" auf die Inhaltsbehaelter. Der
   640er-Block derselben Datei korrigiert das spaeter auf "left: 60px" --
   ZWISCHEN 641 UND 1024 PIXELN KORRIGIERT ES NIEMAND. Im alten Design gab
   es dort keine Leiste an dieser Stelle; im neuen gibt es sie immer.

   STATT DEN VERSATZ WEITER VON HAND NACHZURECHNEN, kehren die Behaelter in
   den Fluss zurueck: dann setzt das Raster sie selbst in Spalte 2, und
   zwar bei jeder Breite gleich. Das macht auch die frueheren
   Handkompensationen ueberfluessig (siehe die entfernte Stelle oben).

   "width"/"left"/"top" werden mit zurueckgenommen, weil sie an einem
   Element im Fluss entweder wirkungslos (left/top) oder schaedlich waeren
   (die "calc()"-Breiten zoegen den Versatz ein zweites Mal ab).

   NUR FUER DAS NEUE DESIGN. "webapp.css" bleibt unangetastet, das alte
   Design behaelt seine Regeln unveraendert. */
@media (max-width: 1024px) {
  [data-design="new"] .aiservice-container,
  [data-design="new"] .aiservice-execution-container,
  [data-design="new"] .chat-container {
    position: static;
    left: auto;
    top: auto;
    width: auto;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   SICHTPRUEFUNG MOBIL 2026-09-25, Reste aus der Messung nach Befund 1.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 1024px) {
  /* Der Behaelter der AI-Services schrumpfte auf seinen Inhalt, statt die
     Rasterspalte zu fuellen -- gemessen 460px in einer 836px breiten Spalte
     bei 900px Fenster, und 300px bei 360px Fenster. Ursache ist die
     Legacy-Grundregel ".aiservice-container { align-items: center }"
     (webapp.css), die den Behaelter auf fit-content zieht; seine
     Untergrenze war die 300px-Spur des Kartenrasters (siehe dort).
     "width: 100%" macht daraus wieder eine volle Spalte. */
  [data-design="new"] .aiservice-container {
    width: 100%;
    box-sizing: border-box;
  }
}

@media (max-width: 640px) {
  /* Die Kopfleiste konnte nicht unter ihren Inhalt schrumpfen: gemessen
     320px in einer 296px breiten Spalte bei 360px Fenster -- der Avatar
     rechts wurde abgeschnitten. Grund ist "min-width: auto", die
     Vorgabe fuer Flex-Elemente; sie setzt den Inhalt als harte Untergrenze.

     DAS IST EINE FOLGE DER BEHEBUNG OBEN, nicht ein Altbefund: vorher
     spannte die Kopfleiste ueber die volle Fensterbreite (weil die Leiste
     aus dem Fluss fiel) und hatte deshalb Platz genug. Erst in der Spalte
     wird die Enge sichtbar. */
  [data-design="new"] .cockpit-topbar,
  [data-design="new"] .cockpit-topbar-controls,
  [data-design="new"] .cockpit-topbar-agent {
    min-width: 0;
  }
}

@media (max-width: 640px) {
  /* SICHTPRUEFUNG MOBIL 2026-09-25: der Inhalt klebte ohne Abstand an der
     Leiste. Technisch lag er nicht darunter (gemessen: Ueberschrift ab
     x=64, Leiste bis 64) -- gelesen wird es aber wie angeschnitten, und der
     Auftraggeber hat genau das gemeldet.

     Ursache: der 640er-Block von "webapp.css" nimmt dem inneren Behaelter
     seine Raender ("\.aiservice-container .container { margin-left: 0 }"),
     weil die Leiste dort frueher anders lag. Oberhalb 640px ist der Abstand
     vorhanden (bei 900px gemessen).

     Gesetzt wird er am WIRT, nicht am Inhalt: so gilt er fuer jede der elf
     Zielseiten gleich, statt in jeder Vorlage einzeln zu fehlen. */
  [data-design="new"] .aiservice-container,
  [data-design="new"] .chat-container {
    padding-left: var(--ax-space-3);
    padding-right: var(--ax-space-3);
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   MOBIL, SCHRITT 2 / TEIL A (2026-09-26): DIE KOPFLEISTE WIRD EINZEILIG.

   GEMESSEN (Chromium, neues Design, Rolle "user", Fenster 360px,
   Inhaltsspalte 296px) VOR dieser Aenderung:

     cockpit-topbar-agent          76..76    0px   (auf null gedrueckt)
       container-cockpit-agent     76..116  40px   (ragt heraus)
     cockpit-topbar-controls       86..382 296px   (22px UEBER dem Rand)
       cockpit-chat-sichern        86..121  35px
       cockpit-modell             129..253 124px
       cockpit-topbar-timesaving  261..315  54px
       cockpit-avatar             323..382  59px

   Rund 340px Inhalt auf 296px Platz. "cockpit-topbar-controls" traegt
   "flex-shrink: 0" und nimmt deshalb alles; der Agentenwahl bleibt nichts.

   UNTERHALB 640PX BLEIBEN SICHTBAR: die Agentenwahl und der Avatar. Chat
   sichern, Modell-/Routing-Chip und Zeitersparnis ziehen in das
   Avatar-Menue (cockpittopbar.js, "_baueMobilBlock()").

   WARUM IN DAS VORHANDENE MENUE UND NICHT IN EIN NEUES UEBERLAUFMENUE:
   es haengt bereits in der Kopfleiste und wird mit der Huelle abgebaut.
   Ein neues schwebendes Menue waere das siebte Portal an "document.body"
   -- jedes einzelne davon war in den letzten Tagen ein Befund.

   UND DER EIGENTLICHE GRUND: die Angaben zur Datensouveraenitaet stecken
   im "title" des Modell-Chips (cockpittopbar.js "setzeModell()"). AUF
   EINEM TOUCHGERAET GIBT ES KEIN HOVER -- auf dem Telefon sind sie heute
   ueberhaupt nicht abrufbar. Im Menue stehen sie als sichtbarer Text.

   OBERHALB 640PX AENDERT SICH NICHTS: der Block unten ist dort
   "display: none", die drei Kopfleisten-Elemente bleiben unberuehrt.
   ═══════════════════════════════════════════════════════════════════════ */

/* Der mobile Block existiert in JEDER Breite im Baum (ein Aufbauweg, eine
   Textquelle) und ist oberhalb des Haltepunkts verborgen. */
[data-design="new"] .cockpit-avatar-menu-mobil {
  display: none;
}

@media (max-width: 640px) {
  [data-design="new"] .cockpit-avatar-menu-mobil {
    display: block;
  }

  /* Die drei Elemente, die in das Menue gezogen sind, verlassen die Leiste.
     "cockpit-topbar-modell-chip" traegt selbst "display: inline-flex"
     (0,2,0) -- der Kindkombinator mit dem Wirt hebt diese Regel auf (0,3,0)
     und schlaegt sie damit. Die Zeitersparnis steht hier NICHT: ihr Knoten
     haengt unterhalb des Haltepunkts gar nicht mehr in der Leiste, sondern
     im Menue (cockpittopbar.js "_ordneZeitersparnis()").
     ">"-Kombinator, damit das Abbild IM Menue unberuehrt bleibt. */
  [data-design="new"] .cockpit-topbar-controls > .cockpit-chat-sichern,
  [data-design="new"] .cockpit-topbar-controls > .cockpit-topbar-modell-chip {
    display: none;
  }

  /* Ohne die drei bleibt in der rechten Gruppe nur der Avatar (gemessen
     53px) -- die Agentenwahl bekommt den Rest der Spalte zurueck.
     "min-width: 44px" ist die Fingergroesse und die Untergrenze, unter die
     sie auch bei einem sehr langen Agentennamen nicht fallen darf. */
  [data-design="new"] .cockpit-topbar-agent {
    min-width: 44px;
  }

  /* Das Menue haengt mit "right: 0" am Avatar, der ganz rechts steht. Ohne
     Obergrenze schoebe die laengste Zeile ("Datensouveränität des Agenten:
     hoch (durch Anonymisierung)") seine linke Kante ins Negative, also aus
     dem Fenster. "--ax-space-4" ist der Innenabstand der Leiste in diesem
     Band (siehe "[data-design=\"new\"] .cockpit-topbar" im 1024er-Block). */
  [data-design="new"] .cockpit-avatar-menu {
    max-width: calc(100vw - 2 * var(--ax-space-4));
  }

  [data-design="new"] .cockpit-avatar-menu-mobil-info {
    padding: var(--ax-space-2) var(--ax-space-3);
  }

  /* "pre-line": der Routing-Hinweis ist selbst mehrzeilig (er stand bis
     hierher nur im "title", wo der Browser die Umbrueche haelt).
     "overflow-wrap: anywhere" bricht einen ueberlangen Modellnamen, statt
     das Menue breiter werden zu lassen, als die Obergrenze oben erlaubt. */
  [data-design="new"] .cockpit-avatar-menu-mobil-zeile {
    color: var(--ax-text-secondary);
    font-size: var(--ax-font-size-label-sm);
    line-height: 18px;
    white-space: pre-line;
    overflow-wrap: anywhere;
  }

  /* Die erste Zeile ist der Modellname bzw. der Routing-Chiptext -- sie
     traegt, was der Chip in der Leiste trug, und steht deshalb kraeftiger
     als die Angaben darunter. */
  [data-design="new"] .cockpit-avatar-menu-mobil-zeile:first-child {
    color: var(--ax-text-primary);
    font-weight: 600;
  }

  /* Die umgehaengte Zeitersparnis-Zeile sitzt im Menue in derselben Flucht
     wie die Informationszeilen darueber, nicht mehr als Kachel in einer
     72px hohen Leiste. */
  [data-design="new"] .cockpit-avatar-menu-mobil-zeit .cockpit-topbar-timesaving {
    padding: 0 var(--ax-space-3) var(--ax-space-2);
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   MOBIL, SCHRITT 2 / TEIL B (2026-09-26): DAS EINGABE-WIDGET.

   GEMESSEN (Chromium, neues Design, Rolle "user", Fenster 360px) VOR
   dieser Aenderung:

     chatbot-input-container   248x100   (Hoehe inline gepinnt)
       inputrow                218x70
       composer-buttons        218x159   <- DREI Reihen
         Reihe 1               125x36    (Klammer, Optimieren, "⋯")
         Reihe 2               218x109
           chat-regler         176x109   <- drei Chips auf drei Zeilen
           chatbot-submit       36x36    <- unter der Unterkante des Kastens

   Die Knopfzeile war hoeher als der ganze Kasten. Unterhalb 640px bleiben
   deshalb nur noch Bueroklammer, "⋯" und Senden in der Zeile; Regler,
   Prompt optimieren, Dateien entfernen, Memory, Gremium und
   Anonymisierung ziehen in ein Blatt, das ueber dem Widget aufsteigt
   (chatwindowinput.js "_baueBlatt()"/"_ordneKnopfzeile()").

   WARUM EIN BLATT UND KEINE SCROLLENDE SYMBOLZEILE: die Regler sind
   EINSTELLUNGEN, keine Aktionen -- der Auftrag verlangt ausdruecklich
   "aufrufbar UND einstellbar". In einer Symbolzeile ist ein Zustand
   ("Auto", "Ein", "Aus") nicht ablesbar; neben seinem Namen schon.

   DIE REGLER BLEIBEN DIESELBEN BAUTEILE: das Blatt zeigt den GLEICHEN
   Knoten (".chat-regler", chatregler.js), nur anders gelegt -- keine
   zweite Fassung daneben, die auseinanderlaufen koennte.

   VERBORGEN UEBER "[hidden]", NICHT UEBER EINE DESIGN-REGEL: so ist das
   Blatt auch dort unsichtbar, wo keine Regel dieser Datei greift (altes
   Design). Die Regeln unten setzen "display" und muessen "[hidden]"
   deshalb ausdruecklich zurueckerobern -- derselbe Kniff wie bei
   ".cockpit-avatar-menu[hidden]" weiter oben.

   #2021 (2026-09-28, UEBERHOLT "oberhalb 640px aendert sich nichts"):
   Toolsupport, Live-Suche und persoenliche Wissensdatenbank stehen auf
   JEDER Breite nur noch im Blatt ("Weitere Einstellungen"), in der
   Knopfzeile bleibt allein das Antwortverhalten. Die Regeln fuer das Blatt
   selbst und fuer die Regler darin gelten deshalb ohne Haltepunkt; nur der
   Kasten und die Aktionszeilen bleiben im "@media"-Block. Oberhalb 640px
   ist das Blatt schmaler und ohne Griff (Block "#2021" unten).
   ═══════════════════════════════════════════════════════════════════════ */

/* Der Reglername steht NUR im Blatt. In der Knopfzeile bleibt der Chip ein
   Symbol-plus-Kurzwert, wie seit Sichtpruefung/Task 4. */
[data-design="new"] .chat-regler-name {
  display: none;
}

/* #2021: dasselbe fuer die kurze Erklaerung je Regler (chatregler.js). */
[data-design="new"] .chat-regler-erklaerung {
  display: none;
}

/* #2021: der Knopf "Weitere Einstellungen" steht oberhalb 640px nur dort,
   wo das Blatt Regler traegt (Klasse aus chatwindowinput.js
   "_ordneKnopfzeile()"). Die Altregel "webapp.css" blendet ihn dort aus;
   (0,3,0) schlaegt ihre (0,1,0). */
[data-design="new"] .chatbot-hat-weitere .chatbot-more-toggle {
  display: inline-flex;
}

@media (max-width: 640px) {

  /* DER KASTEN HAELT SEINE EIGENE KNOPFZEILE WIEDER, UND DAS IST GEMESSEN.
     "setupAutoResize()" (chatwindowinput.js) pinnt die Hoehe INLINE auf
     100px; unterhalb 640px ist das dank "box-sizing: border-box"
     (webapp.css:10600) die AUSSENhoehe, dem Inhalt bleiben 70px. GEMESSEN
     bei 360px nach dem Umbau oben: Eingabereihe 70 + Fuge 4 + Knopfzeile
     41 = 115px -- die Zeile stand 27px UNTER der Unterkante des Kastens,
     auf dem Seitengrund statt auf seiner Flaeche. Vor dem Umbau waren es
     rund 150px (die Zeile war 159px hoch).

     "min-height" schlaegt ein kleineres "height" IMMER, unabhaengig von
     Spezifitaet und Kaskade -- das ist der einzige Weg, eine INLINE
     gesetzte Hoehe ohne "!important" (in dieser Datei verboten) zu
     korrigieren. "fit-content" statt einer Zahl: der Inhalt ist je Seite
     verschieden (Chat mit Sprachknopf, Projektchat, Galerie-Kachel ohne
     beides), eine feste Zahl waere ueberall sonst falsch.

     DAS UEBERHOLT ZWEI ZUSICHERUNGEN in design-chat-composer.spec.ts
     ("Inhaltshoehe" und "Ueberstand" bei 620/640px, neues Design) -- beide
     dort berichtigt, mit altem Wert, Datum und Grund. */
  [data-design="new"] .chatbot-input {
    min-height: fit-content;
  }
}

  /* ── Das Blatt ────────────────────────────────────────────────────── */
  /* #2021: ab hier bis zu den Aktionen OHNE Haltepunkt (siehe Kopf). */
  /* ES STEIGT UEBER DEM WIDGET AUF, NICHT UEBER DEM FENSTER, und das ist
     gemessen. Ein erster Entwurf haengte es fest am unteren Fensterrand
     ("position: fixed; bottom: 0") mit einem bildschirmfuellenden,
     abgedunkelten Grund. Zwei Befunde dagegen, beide gemessen:

       1. Das Blatt lag UEBER dem "⋯"-Knopf, der es schliessen soll, UND
          ueber dem Sendeknopf -- der eigene Testfall "das Blatt schliesst
          sich ueber den Knopf" fiel mit "chatbot-blatt intercepts pointer
          events". Ein Bottom-Sheet, das seinen eigenen Schalter verdeckt,
          nimmt dem Auftrag ("Senden bleibt sichtbar") die Grundlage.
       2. ".chat-container" traegt "z-index: 5" (webapp.css:2181) und ist
          damit ein eigener Stapelkontext -- kein z-index eines Nachfahren
          kann darin gegen die Leiste gewinnen, die im 640er-Block von
          webapp.css:10985 "z-index: 200" bekommt. Das Blatt lag deshalb
          UNTER der 64px breiten Leiste, "Prompt optimieren" war links
          angeschnitten ("...ompt optimieren").

     BEIDES ENTFAELLT, wenn das Blatt absolut am Eingabe-Widget haengt
     (".chatbot-input" ist seit webapp.css:5681 "position: relative") und
     nach OBEN aufsteigt: es bleibt in der Inhaltsspalte, es verdeckt das
     Widget nicht, und es braucht keinen Sprung aus dem Stapelkontext.

     KEIN ABGEDUNKELTER GRUND: der Auftrag laesst die Wahl ("ueber einen
     Griff/abgedunkelten Grund") und warnt im selben Absatz vor genau der
     Bauform, die eine bildschirmfuellende Sperrschicht ist. Geschlossen
     wird ueber Griff, Knopf, "Escape" und einen Klick daneben
     (chatwindowinput.js "addEvents()").

     "z-index: 41" reicht innerhalb des Containers: es muss ueber den
     Nachrichten liegen, die keinen eigenen z-index tragen. */
  [data-design="new"] .chatbot-blatt {
    position: absolute;
    left: 0;
    right: 0;
    bottom: calc(100% + var(--ax-space-2));
    z-index: 41;
    display: flex;
    flex-direction: column;
    gap: var(--ax-space-1);
    max-height: 60vh;
    overflow-y: auto;
    box-sizing: border-box;
    padding: var(--ax-space-2) var(--ax-space-3) var(--ax-space-3);
    background: var(--ax-bg-elevated);
    border: 1px solid var(--ax-border-default);
    border-radius: var(--ax-radius-lg);
    box-shadow: var(--ax-shadow-card);
  }

  [data-design="new"] .chatbot-blatt[hidden] {
    display: none;
  }

  /* Der Griff: die Leiste, die man auf einem Telefon erwartet, und
     zugleich der Schliessknopf. EIGENE ":hover"-Regel (unten), weil die
     Sammelregel des neuen Designs nur den Hintergrund faerbt -- hier ist
     der Hintergrund die ganze sichtbare Flaeche. */
  [data-design="new"] .chatbot-blatt-griff {
    flex: 0 0 auto;
    align-self: center;
    width: 48px;
    height: 5px;
    min-height: 5px;
    padding: 0;
    margin: var(--ax-space-1) 0 var(--ax-space-2);
    border: 0;
    border-radius: var(--ax-radius-full);
    background: var(--ax-border-default);
    cursor: pointer;
  }

  [data-design="new"] .chatbot-blatt-griff:hover {
    background: var(--ax-text-muted);
  }

  [data-design="new"] .chatbot-blatt-trenner {
    height: 1px;
    margin: var(--ax-space-2) 0;
    border: 0;
    background: var(--ax-border-soft);
    flex-shrink: 0;
  }

  [data-design="new"] .chatbot-blatt-trenner[hidden] {
    display: none;
  }

  /* ── Die Regler im Blatt: Name links, Zustand rechts ──────────────── */
  /* "align-items: stretch" ist die tragende Zeile -- BEFUND B2
     (2026-09-26). ".chat-regler" traegt seit Gestaltung/C
     "align-items: center" (oben in dieser Datei, fuer die WAAGERECHTE
     Chipleiste richtig). In der Spalte hier bedeutet dasselbe Wort etwas
     anderes: jede Zeile schrumpft auf ihren Inhalt und wird mittig
     gesetzt. GEMESSEN, beide Themen, 360px: die drei Zeilen begannen bei
     x=123 / 118 / 108 und endeten bei 295 / 301 / 310 -- alle um x=209
     zentriert, ein ausgefranster Block ueber den linksbuendigen,
     vollbreiten Aktionszeilen. Das "justify-content: space-between" der
     Zeile lief dabei ins Leere, weil es in einer inhaltsbreiten Zeile
     nichts zu verteilen gibt. Mit "stretch" fuellt jede Zeile die Breite
     des Blattes, und erst dann heisst "Name links, Zustand rechts" auch,
     was es sagt. */
  [data-design="new"] .chatbot-blatt .chat-regler {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--ax-space-1);
    width: 100%;
  }

  [data-design="new"] .chatbot-blatt .chat-regler-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ax-space-3);
    flex-wrap: wrap;
    min-height: 44px;
    padding: 0 var(--ax-space-2);
  }

  /* NACHBESSERUNG N2 (2026-09-26): DER NAME GIBT NACH, NICHT DER ZUSTAND.
     GEMESSEN bei 360px, beide Themen: "Persönliche Wissensdatenbank"
     fuellte die Zeile, und der Zustandschip ("📚 Aus") wich in die naechste
     Zeile aus und stand linksbuendig UNTER dem Namen. Ablesbar blieb es --
     die Zusicherung "Name und Zustand" hielt --, nur das Satzbild kippte:
     der Zustand ist die Antwort auf die Frage, die der Name stellt, und
     gehoert in dieselbe Zeile.

     Zwei Zeilen loesen das zusammen: "flex-basis: 0" nimmt dem Namen die
     hypothetische Breite, mit der er den Umbruch ausloeste, und
     "overflow-wrap: anywhere" laesst ihn INNERHALB seines eigenen Kastens
     umbrechen. GEMESSEN danach (beide Themen, 360px): Name 108..235 auf
     zwei Zeilen (40px hoch), Chip 245..310 RECHTS daneben in derselben
     Zeile; die beiden kurzen Namen bleiben einzeilig.

     GEKUERZT WIRD NICHTS: zwei Zeilen Name sind lesbar, ein abgeschnittenes
     "Persönliche Wissensda…" waere es nicht. Die Zeile bleibt dabei bei
     ihren 44px -- der zweizeilige Name misst gemessen 40px und passt in die
     "min-height"; waere er hoeher, duerfte die Zeile mitwachsen. */
  [data-design="new"] .chatbot-blatt .chat-regler-name {
    display: block;
    flex: 1 1 0;
    min-width: 0;
    overflow-wrap: anywhere;
    color: var(--ax-text-primary);
    font-size: var(--ax-font-size-label-sm);
  }

  /* Der Chip behaelt seine Inhaltsbreite -- er darf weder schrumpfen noch
     wachsen, sonst waere der Zustand doch wieder der Nachgebende. */
  [data-design="new"] .chatbot-blatt .chat-regler-chip {
    flex: 0 0 auto;
  }

  /* Das Optionsmenue schwebt im Blatt als Dropdown UEBER dem Text, statt
     ihn im Fluss nach unten zu schieben (2026-10-08, Anwender). "fixed"
     statt "absolute": ein absolut gelegtes Menue haette der scrollende
     Behaelter (".chatbot-blatt", "overflow-y: auto") beschnitten. Die Lage
     (oben/unten, Kante) rechnet chatregler.js "_platziere()" beim Oeffnen
     aus; "top/left" hier sind nur der Ausgangswert vor dem Messen. */
  [data-design="new"] .chatbot-blatt .chat-regler-menu {
    position: fixed;
    top: 0;
    left: 0;
    bottom: auto;
    right: auto;
    z-index: 60;
  }

  /* #2021: die kurze Erklaerung -- eigene Zeile unter Name und Zustand. */
  [data-design="new"] .chatbot-blatt .chat-regler-erklaerung {
    display: block;
    flex: 1 1 100%;
    padding-bottom: var(--ax-space-2);
    color: var(--ax-text-secondary);
    font-size: var(--ax-font-size-label-sm);
    line-height: 1.4;
  }

  /* #2021: oberhalb 640px steigt das Blatt als schmale Karte ueber dem
     linken Rand des Widgets auf -- dort sitzt der Knopf "Weitere
     Einstellungen". Der Griff ist eine Telefon-Geste und entfaellt;
     geschlossen wird ueber den Knopf, "Escape" und einen Klick daneben. */
@media (min-width: 641px) {
  [data-design="new"] .chatbot-blatt {
    right: auto;
    width: min(400px, 100%);
  }

  [data-design="new"] .chatbot-blatt-griff {
    display: none;
  }
}

@media (max-width: 640px) {
  /* ── Die Aktionen im Blatt: ganze Zeilen mit Beschriftung ─────────── */
  [data-design="new"] .chatbot-blatt-aktionen {
    display: flex;
    flex-direction: column;
    gap: var(--ax-space-1);
  }

  /* Dieselbe Spezifitaet (0,3,0) wie
     "[data-design=new] .chatbot-input .chatbot-button" weiter oben, aber
     spaeter in der Datei -- die 36x36 der Knopfzeile gelten hier nicht
     mehr. "44px" ist die Fingergroesse. */
  [data-design="new"] .chatbot-blatt .chatbot-button,
  [data-design="new"] .chatbot-blatt .chatbot-button-deactivated {
    width: 100%;
    height: auto;
    min-height: 44px;
    justify-content: flex-start;
    gap: var(--ax-space-3);
    padding: 0 var(--ax-space-2);
    border-radius: var(--ax-radius-md);
  }

  [data-design="new"] .chatbot-blatt .button-icon-label {
    color: var(--ax-text-primary);
    font-size: var(--ax-font-size-label-sm);
    text-align: left;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   ANHAENGE/S1 (2026-09-26) — DAS AUSSEHEN DER DATEI-ANHAENGE

   Befund des Anwenders: "nun werden alle Dateien angezeigt, aber die
   Darstellung ist nicht gut. Weil das Input Widget in der Groesse
   anwaechst." Ursache: die Chips standen in ".chatbot-buttons", und die
   Knopfzeile traegt "flex-wrap: wrap" (webapp.css:8805) -- jede weitere
   Datei schob eine ganze Knopfreihe nach.

   HIER STEHT NUR DAS AUSSEHEN. Die STRUKTUR (flex, "nowrap",
   "overflow-x: auto", die Ellipse am Namen, die Trefferflaeche des
   Kreuzes) setzt chatwindowinput.js INLINE -- und zwar mit Absicht: diese
   Datei darf ausschliesslich Regeln unter "[data-design=new]" tragen
   (belegt durch tests/unit/components-css.test.js), webapp.css ist
   unantastbar, und das ALTE Design braucht dieselbe Struktur. Es hat kein
   Blatt ("_baueBlatt()": "if (!neuesDesign) return"), dort ist die
   Chip-Zeile der einzige Ort der Anhaenge, auf jeder Breite. Derselbe
   Weg, den "_ordneKnopfzeile()" fuer die Beschriftungen schon geht.

   KEIN NEUER FARBWERT: die Kreuze arbeiten mit "currentColor" und
   "transparent", die Chips erben ".chatbotfile-chip" (webapp.css:2425).
   ═══════════════════════════════════════════════════════════════════════ */

/* DIE SAMMELREGEL DES NEUEN DESIGNS FAERBT NUR DEN HINTERGRUND.
   ":where([data-design=new]) button:hover:not(:disabled)" ist (0,2,1) und
   laesst "color" stehen -- sie hat in dieser Woche zweimal einen Knopf
   unlesbar gemacht (1,44:1 und 1,05:1 gemessen). Diese Regel ist (0,2,1)
   mit dem Design-Vorfahren als echtem Nachfahrenselektor statt ":where()"
   und setzt BEIDE Eigenschaften. */
[data-design="new"] .chatbotfile-chip-entfernen,
[data-design="new"] .chatbot-blatt-anhang-entfernen {
  background: transparent;
  color: currentColor;
}

[data-design="new"] .chatbotfile-chip-entfernen:hover,
[data-design="new"] .chatbot-blatt-anhang-entfernen:hover {
  /* "color-mix" auf "currentColor" statt eines Farbwerts: die Flaeche
     entsteht aus der Farbe, die der Chip ohnehin traegt -- richtig in
     beiden Themen, ohne dass hier eine Farbe entschieden wird. */
  background: color-mix(in srgb, currentColor 20%, transparent);
  color: currentColor;
}

@media (max-width: 640px) {
  /* Der Abschnitt im Blatt. Nur hier, weil es das Blatt nur im neuen
     Design und nur unterhalb des Haltepunkts gibt ("_blattGilt()"). */
  [data-design="new"] .chatbot-blatt-anhaenge {
    display: flex;
    flex-direction: column;
    gap: var(--ax-space-1);
    padding-bottom: var(--ax-space-2);
    margin-bottom: var(--ax-space-2);
    border-bottom: 1px solid var(--ax-border-subtle);
  }

  [data-design="new"] .chatbot-blatt-anhaenge[hidden] {
    display: none;
  }

  [data-design="new"] .chatbot-blatt-anhang {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ax-space-2);
    /* 44px ist die Fingergroesse -- dieselbe Begruendung wie bei den
       Knoepfen des Blattes weiter oben. */
    min-height: 44px;
    padding: 0 var(--ax-space-2);
    border-radius: var(--ax-radius-md);
    color: var(--ax-text-primary);
    font-size: var(--ax-font-size-label-sm);
  }

  [data-design="new"] .chatbot-blatt-anhang-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
  }

  [data-design="new"] .chatbot-blatt-anhang-entfernen {
    width: 32px;
    height: 32px;
    font-size: 18px;
  }
}

/* ANHAENGE/S1 (2026-09-26, Sichtpruefung): DER SAMMELCHIP IST KEIN
   SINNBILD-KNOPF. Er traegt die Klasse ".chatbot-button", und die zwingt
   im Composer auf 36x36 (components.css:11582 oben) -- GEMESSEN am Bild
   bei 360px: ein leeres helles Rechteck zwischen Bueroklammer und "⋮",
   die Beschriftung "3 Dateien" abgeschnitten. Kein Test hatte das
   gemeldet, weil alle den TEXTINHALT prueften und keiner die FLAECHE;
   die Zusicherung ist seither nachgezogen.

   Gleiche Spezifitaet wie die 36x36-Regel (0,3,0), aber spaeter in der
   Datei -- deshalb ohne "!important", das hier ohnehin verboten waere. */
[data-design="new"] .chatbot-input .chatbot-anhaenge-sammel {
  width: auto;
  min-width: 0;
  /* ABSOLUT, NICHT IN PROZENT. Ein Prozentwert bezieht sich auf den
     ENTHALTENDEN BLOCK -- das ist hier ".button-container" (die linke
     Knopfgruppe), und der ist selbst inhaltsbreit ("width: auto",
     components.css:11514). "30%" ergab deshalb GEMESSEN 49px Knopfbreite
     und eine auf 31px beschnittene Beschriftung, nicht die gemeinten 89px
     der Inhaltsspalte.
     96px reichen fuer "12 Dateien" und halten die Zeile bei 360px auf
     EINER Reihe: Bueroklammer 41 + Chip <=96 + "⋮" 36 + Senden 36 plus
     Abstaende bleiben unter den 296px Inhaltsbreite. Mit 133px brach sie
     um und der Sendeknopf rutschte darunter. */
  max-width: 96px;
  padding: 0 var(--ax-space-2);
  gap: var(--ax-space-1);
}

/* DIE SCHRIFTFARBE MUSS HIER STEHEN. Der Sammelchip ist der ERSTE
   ".chatbot-button" im Composer mit sichtbarem Text -- alle anderen tragen
   ein <img>, deshalb ist nie aufgefallen, dass der Knopf "color: #ffffff"
   erbt. GEMESSEN 2026-09-26: labelFarbe "rgb(255, 255, 255)" auf heller
   Flaeche, also unsichtbar. Dieselbe Fehlerfamilie wie die sechs Klassen
   im Kopfkommentar dieser Datei (Zeile 184) und wie das unsichtbare Badge
   aus T5. Kein neuer Farbwert: der Vordergrund-Token des Designs. */
[data-design="new"] .chatbot-input .chatbot-anhaenge-sammel .button-icon-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--ax-font-size-label-sm);
  color: var(--ax-text-primary);
}

/* ═══════════════════════════════════════════════════════════════════════
   #2016 — DATEIANHANG UND ANONYMISIERUNG ZUGAENGLICH

   Die Bueroklammer: das <input type=file> ist nur visuell versteckt und
   per Tab erreichbar; den Fokusring am sichtbaren Label zeichnet die
   Regel in webapp.css (".fileupload-input") fuer beide Designs. Hier
   steht bewusst keine zweite: der Waechter in components-css.test.js
   laesst keine ungescopte ".upload-container ... label"-Regel zu.

   Die Anonymisierung zeigt ihren Zustand als kurzen Text neben dem Symbol
   ("Anonymisiert" / "Nicht anonymisiert", chatwindowinput.js
   "_zeigeAnonymisierung()"). Unter 1024px nur das Symbol, der Name bleibt
   ueber "aria-label" erhalten (Muster #2020 "Exportieren"); unter 640px
   steht der Knopf im Blatt und traegt dort seine Beschriftung ohnehin.
   Die Schriftfarbe steht hier, weil der Knopf sonst "color: #ffffff" erbt
   (siehe Sammelchip direkt darueber) -- auch im Hover, denn die
   Sammelregel des neuen Designs faerbt nur den Hintergrund. */
[data-design="new"] .chatbot-buttons .chatbot-anonymize .button-icon-label,
[data-design="new"] .chatbot-buttons .chatbot-anonymize:hover .button-icon-label {
  white-space: nowrap;
  font-size: var(--ax-font-size-label-sm);
  color: var(--ax-text-primary);
}

/* Erzwungen/automatisch: nicht umschaltbar, aber der Zustand "an" muss
   lesbar bleiben -- die Legacy-Deckkraft 0,45 (".chatbot-button-
   deactivated") gilt deshalb nur noch fuer das Symbol. */
[data-design="new"] .chatbot-input .chatbot-anonymize.chatbot-button-deactivated {
  opacity: 1;
}

@media (min-width: 1025px) {
  [data-design="new"] .chatbot-buttons .chatbot-anonymize {
    width: auto;
    padding: 0 var(--ax-space-2);
    gap: var(--ax-space-1);
  }
}

@media (max-width: 1024px) {
  [data-design="new"] .chatbot-buttons .chatbot-anonymize .button-icon-label {
    display: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   MOBIL/S2 (2026-09-26) — DIE HAMBURGER-SCHUBLADE UNTERHALB 640PX

   Entwurf: docs/superpowers/specs/2026-09-26-mobile-hamburger-schublade-
   design.md. Vorlage: Figma YS6fyZouLfQr3SlGDbAQKY, Rahmen 544:78186
   ("DE · Chat · Menü · Mobile 390") -- dort gibt es auf 390px KEINE linke
   Leiste, sondern ein "☰" in der Kopfleiste und eine Schublade, die die
   VOLLSTAENDIGE Navigation samt Chatverlauf traegt.

   ENTSCHEIDUNG DES ANWENDERS (2026-09-26): "Ja, unter 640 px ersetzen".
   Kein Widerspruch zur frueheren Absage -- die galt einer Schublade auf
   ALLEN Breiten. Oberhalb 640px aendert hier nichts.

   WAS DAS NEBENBEI ERLEDIGT: der Block "@media (max-width: 1024px)" weiter
   oben blendet ".cockpit-sidebar-history" unbedingt aus. Unterhalb 640px
   war der Chatverlauf damit UNERREICHBAR -- der seit Mobil-Schritt 2
   offene Punkt des Anwenders ("Es sollte trotzdem die Möglichkeit geben
   auch mobil die Chathistorie zu öffnen"). Die Schublade zeigt ihn wieder.
   ═══════════════════════════════════════════════════════════════════════ */

/* Der "☰" existiert im Baum bei jeder Breite (cockpittopbar.js), sichtbar
   wird er nur unterhalb des Haltepunkts. */
[data-design="new"] .cockpit-hamburger {
  display: none;
}

/* Wiederholende Services (Liste): die Kopfzeile traegt dort nur den "☰"
   (cockpittopbar.js "nurHamburger") -- oberhalb des Haltepunkts ist sie
   leer und faellt ganz weg, damit die Tabelle den Platz bekommt. */
@media (min-width: 641px) {
  [data-design="new"] .cockpit-topbar.cockpit-topbar--nur-hamburger {
    display: none;
  }
}

/* Der Grund ebenso: er steht immer im Baum (als Geschwister der Leiste in
   der Huelle), ist aber ohne offene Schublade nicht vorhanden. "display:
   none" statt "opacity: 0" -- eine unsichtbare, aber klickbare
   Sperrschicht ueber der ganzen Seite war diese Woche der Suchdialog-
   Befund. */
[data-design="new"] .cockpit-schublade-grund {
  display: none;
}

@media (max-width: 640px) {
  [data-design="new"] .cockpit-hamburger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px ist die Fingergroesse -- dieselbe Begruendung wie bei den
       Knoepfen des Composer-Blattes. */
    width: 44px;
    height: 44px;
    flex: 0 0 auto;
    margin-left: calc(var(--ax-space-2) * -1);
    padding: 0;
    border: 0;
    border-radius: var(--ax-radius-md);
    background: transparent;
    color: var(--ax-text-primary);
    cursor: pointer;
  }

  /* Die Sammelregel ":where([data-design=new]) button:hover:not(:disabled)"
     faerbt NUR den Hintergrund und liesse die Striche stehen, wo sie
     stehen. Sie hat in dieser Woche zweimal einen Knopf unlesbar gemacht
     (1,44:1 und 1,05:1 gemessen); diese Regel setzt BEIDE Eigenschaften. */
  [data-design="new"] .cockpit-hamburger:hover {
    background: var(--ax-bg-hover);
    color: var(--ax-text-primary);
  }

  [data-design="new"] .cockpit-hamburger svg {
    width: 22px;
    height: 22px;
  }

  /* ── DIE SCHUBLADE ───────────────────────────────────────────────────
     AUS DEM FLUSS GENOMMEN. Das ist der Kern: die Huelle ist ein Raster
     mit "grid-template-columns: auto 1fr" (Mobil-Schritt 1), und eine
     "position: fixed" gesetzte Leiste traegt nichts mehr zur ersten
     Spalte bei -- sie faellt auf 0, der Inhalt bekommt die vollen 390px.
     Genau das zeigt die Vorlage.

     DIESE REGELN HEBEN DEN ERZWUNGENEN EINKLAPP-ZUSTAND AUF, den der
     Block "@media (max-width: 1024px)" weiter oben unbedingt setzt
     (Breite 64px, Beschriftungen/"Mehr anzeigen"/Verlauf/Logo verborgen).
     Gleiche Spezifitaet, aber spaeter in der Datei -- deshalb ohne
     "!important", das hier ohnehin verboten waere. */
  [data-design="new"] .cockpit-sidebar {
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    /* Figma: 300 von 390. "85vw" faengt die schmalsten Geraete ab, damit
       vom abgedunkelten Grund immer ein Streifen sichtbar bleibt -- er
       ist der Weg zurueck. */
    width: min(300px, 85vw);
    max-width: none;
    transform: translateX(-100%);
    transition: transform 180ms ease;
    overflow-y: auto;
    overscroll-behavior: contain;
    z-index: 120;
  }

  [data-design="new"] .cockpit-sidebar--schublade-offen {
    transform: translateX(0);
  }

  /* DIE SPALTE MUSS MIT. "position: fixed" nimmt die LEISTE aus dem Fluss
     -- ihren WIRT nicht. ".chatbot-service" ist die erste Spalte des
     Huellenrasters und behielt seine 64px (gesetzt von den Regeln der
     Sichtpruefung weiter oben in dieser Datei, deckungsgleich mit
     ".chatbot-service.panel-collapsed"). GEMESSEN nach dem ersten Entwurf
     bei 390px: ".chat-container" begann weiter bei x=64, daneben stand
     eine 64px breite leere Spalte, und der Composer war so schmal, dass
     sein Platzhalter mitten im Satz abgeschnitten wurde.

     "width: 0" statt "display: none": der Wirt traegt die Schublade UND
     den abgedunkelten Grund. Beide sind fest positioniert und brauchen
     ihn nur als Anker im Baum, nicht als Flaeche.

     WARUM ":has(.cockpit-sidebar)" UND NICHT DIE BLANKE KLASSE: weiter
     oben steht "[data-design=new] .chatbot-service:has(.cockpit-sidebar--
     eingeklappt) { width: 64px; min-width: 64px }". ":has()" traegt die
     Spezifitaet seines staerksten Arguments, die Regel steht also bei
     (0,3,0) -- eine blanke ".chatbot-service"-Regel bei (0,2,0) verliert
     gegen sie, spaeter in der Datei oder nicht. GEMESSEN mit der blanken
     Fassung: Rasterspalten weiterhin "64px 326px". Mit demselben
     Bauprinzip kommt diese Regel ebenfalls auf (0,3,0) und gewinnt ueber
     die Reihenfolge -- ohne "!important", das hier verboten waere.
     Der eingeklappte Zustand ist unterhalb 640px ohnehin bedeutungslos:
     dort ist die Leiste eine Schublade, entweder eingefahren oder offen. */
  [data-design="new"] .chatbot-service:has(.cockpit-sidebar) {
    width: 0;
    min-width: 0;
    padding: 0;
    overflow: visible;
  }

  /* Offen ist sie AUSGEKLAPPT -- Beschriftungen, "Mehr anzeigen", Marke
     und vor allem der VERLAUF. Ohne diese vier Regeln stuende in der
     Schublade dieselbe Symbolspalte wie vorher, nur breiter. */
  [data-design="new"] .cockpit-sidebar--schublade-offen .cockpit-sidebar-item-label,
  [data-design="new"] .cockpit-sidebar--schublade-offen .cockpit-sidebar-more {
    display: block;
  }

  /* "block", NICHT "flex". Der 1024er-Block setzt hier "display: none";
     der Urzustand dieses <div> ist der Vorgabewert "block" -- die Regel
     bei components.css:15473 setzt nur "flex: 1" (die Leiste selbst ist
     die Flex-Spalte), nicht das eigene "display". Mit "flex" wurde die
     Liste darin zum Flex-Element und ihre Zeilen standen GESEHEN mittig
     statt linksbuendig. */
  [data-design="new"] .cockpit-sidebar--schublade-offen .cockpit-sidebar-history {
    display: block;
  }

  /* EINE UNGESCOPTE ALTREGEL TRIFFT DIE SCHUBLADE UNBEDINGT.
     "webapp.css:6661" setzt im Block "@media screen and (max-width:
     1024px)":
         nav li { display: block; background: var(--clr-shell);
                  text-align: center; }
     Die Seitenleiste IST ein <nav> (cockpitsidebar.js "renderUi()"), also
     galt das immer schon -- nur war der Verlauf unterhalb 1024px per
     "display: none" verborgen, sodass es niemand sah. GEMESSEN in der
     offenen Schublade: jede Verlaufszeile mittig ausgerichtet, auf einem
     grauen Kasten (srgb 0.938 0.933 0.955), waehrend dieselbe Liste bei
     1280px linksbuendig und ohne Flaeche steht.

     Dieselbe Fehlerform wie ".chatbot-service:not(.panel-collapsed)" aus
     Mobil-Schritt 1: eine Altregel fuer eine Navigation, die es so nicht
     mehr gibt. webapp.css ist unantastbar, die Gegenregel steht deshalb
     hier -- und nur fuer die Schublade, damit sie sonst nichts beruehrt. */
  [data-design="new"] .cockpit-sidebar--schublade-offen .cockpit-sidebar-history li {
    text-align: left;
    background: transparent;
  }

  /* Der Einklapp-Chevron gehoert nicht in die Schublade: sie ist entweder
     offen oder eingefahren, einen dritten Zustand gibt es hier nicht. Ein
     Knopf, der nichts Sinnvolles tut, kostet mehr Vertrauen als er nuetzt
     (dieselbe Begruendung wie beim "Mehr anzeigen"-Knopf ohne Fach,
     cockpitsidebar.js). */
  [data-design="new"] .cockpit-sidebar--schublade-offen .cockpit-sidebar-toggle {
    display: none;
  }

  [data-design="new"] .cockpit-sidebar--schublade-offen .cockpit-sidebar-logo {
    display: block;
  }

  [data-design="new"] .cockpit-sidebar--schublade-offen .cockpit-sidebar-item {
    justify-content: flex-start;
    padding: 0 var(--ax-space-3);
  }

  [data-design="new"] .cockpit-sidebar--schublade-offen .cockpit-sidebar-brand {
    justify-content: space-between;
  }

  /* Das Fach bleibt zugeklappt, bis jemand "Mehr anzeigen" antippt. Der
     1024er-Block zeigt es unbedingt ("[hidden] { display: flex }"), weil
     es dort ohne "Mehr anzeigen"-Knopf sonst unerreichbar waere -- in der
     Schublade gibt es den Knopf wieder. */
  [data-design="new"] .cockpit-sidebar--schublade-offen .cockpit-sidebar-item--fach[hidden] {
    display: none;
  }

  [data-design="new"] .cockpit-schublade-grund {
    display: block;
    position: fixed;
    inset: 0;
    /* "--ax-bg-overlay" ist der Token, den das Design GENAU DAFUER fuehrt
       (tokens.css:58/:106 -- "--ax-ink-1000" hell, "--ax-ink-600" dunkel).
       Hier stand zuerst "--ax-bg-base": GEMESSEN war der Grund damit im
       hellen Thema praktisch weiss auf weiss und dunkelte gar nichts ab.
       Dieselbe Fehlerfamilie wie das unsichtbare Badge aus T5. */
    background: color-mix(in srgb, var(--ax-bg-overlay) 55%, transparent);
    opacity: 0;
    pointer-events: none;
    transition: opacity 180ms ease;
    z-index: 119;
  }

  /* NUR MIT OFFENER SCHUBLADE FAENGT ER KLICKS. "pointer-events: none"
     oben ist die zweite Sicherung gegen genau den Befund, der diese Woche
     sechsmal auftrat: eine Schicht, die liegen bleibt und die Seite
     unbedienbar macht. */
  [data-design="new"] .cockpit-sidebar--schublade-offen ~ .cockpit-schublade-grund {
    opacity: 1;
    pointer-events: auto;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   COMPOSER/H1 (2026-09-26) — EINE MITTELLINIE FUER DIE GANZE KNOPFZEILE

   Befund des Anwenders: "die Buttons im Chat Input Widget sind nicht auf
   gleicher Höhe. Die müssen alle auf gleicher Höhe sein."

   GEMESSEN (1280px, neues Design, echtes Chromium):

     Gruppe           Hoehe  align-items   Mitte der Kinder
       links            30   flex-start        589,5
       rechts           30   center            586,5

   BEIDE Gruppen sind 30px hoch -- also NIEDRIGER als jedes Bedienelement
   darin (36 bis 41) -- und beginnen bei y=571,5. Die linke HAENGT ihre
   Kinder oben ein, die rechte ZENTRIERT sie. Daher genau 3px Versatz
   zwischen den beiden Haelften der Zeile. Das "center" der rechten Gruppe
   setzt chatwindowinput.js inline ("fillData()"), und zwar nur dort; die
   linke behielt "flex-start".

   BEHOBEN WIRD NICHT DIE AUSRICHTUNG, SONDERN DIE HOEHE: nimmt die Gruppe
   die Hoehe ihres hoechsten Kindes, fallen "flex-start" und "center"
   zusammen, und keine der beiden Zeilen im Code muss angefasst werden
   (Regel unten, samt der Begruendung, warum der Weg ueber den Code falsch
   waere).

   Dazu die zweite Ursache, die Hoehen:
     .chatbot-button            36
     .upload-container          41   <- Huelle der Bueroklammer
     .chat-regler-chip          31
     .chatbot-button-send       38

   Die 41 der Huelle sind das eigentliche Aergernis: ihr LABEL ist bereits
   36x36 (Regel weiter oben, 2026-09-16 "die Klammer nimmt die Geometrie
   ihrer Nachbarn"), die Huelle darum aber nicht. Unterhalb 1024px kippt
   es zusaetzlich in die andere Richtung -- "webapp.css" gibt ihr dort
   "height: 24px" und dem Label "margin-top: 10px", eine auf die ALTE
   40px-Klammer abgestimmte Rechnung (der Block bei components.css:11315
   beschreibt genau diesen 3,5px-Versatz, konnte ihn damals aber nicht
   beheben, weil webapp.css unantastbar ist). Beides wird hier aufgehoben.

   NICHT ANGETASTET: die 31 der Reglerchips und die 38 des Sendeknopfes.
   Beide sind gewollte Groessen der Vorlage (ein Chip ist kein Symbolknopf,
   der Sendeknopf ist der betonte Abschluss) -- sie stehen jetzt auf
   derselben Mittellinie wie alles andere, und darum ging es.

   DAS ALTE DESIGN BLEIBT UNVERAENDERT.
   ═══════════════════════════════════════════════════════════════════════ */

/* DIE GRUPPE NIMMT DIE HOEHE IHRES HOECHSTEN KINDES -- und damit fallen
   "flex-start" und "center" zusammen, ohne dass irgendjemand die
   Ausrichtung anfassen muesste.

   ".button-container" traegt "height: 30px" (webapp.css:1562) und ist
   damit NIEDRIGER als jedes Bedienelement darin (36 bis 41). Die linke
   Gruppe haengt ihre Kinder oben ein, die rechte zentriert sie -- daher
   die zwei Mittellinien. Bei 360px gibt es das Problem NICHT, weil
   webapp.css der Gruppe dort schon "height: auto" gibt (:10998):
   GEMESSEN bei 360px eine einzige Mittellinie (756), bei 1280px zwei
   (755 und 752).

   Diese eine Zeile hebt den 360er-Zustand auf jede Breite. Sie ist der
   Ausrichtung im Code ausdruecklich VORZUZIEHEN: ein inline gesetzter
   Wert wird beim Rendern entschieden und folgt keinem spaeteren
   Designwechsel -- in der Design-Galerie, die genau davon lebt, stuende
   das alte Design danach falsch da. Eine CSS-Regel wechselt mit dem
   Attribut. */
[data-design="new"] .chatbot-buttons > .button-container {
  height: auto;
}

/* ZWEI VERWORFENE ANSAETZE, damit niemand sie wieder versucht:

   1. "align-items: center" HIER als Regel -- wirkungslos.
      chatwindowinput.js "fillData()" setzt den Wert INLINE, und inline
      schlaegt jeden Selektor ohne "!important", das in dieser Datei
      verboten ist. GEMESSEN: die linke Gruppe blieb auf "flex-start".

   2. Den inline gesetzten Wert im CODE designabhaengig machen (wie die
      rechte Gruppe ihn am 2026-09-22 bekam). Das wirkte, war aber falsch:
      ein inline gesetzter Wert wird BEIM RENDERN entschieden und folgt
      keinem spaeteren Designwechsel. GEMESSEN in der Design-Galerie, die
      genau davon lebt: nach dem Umschalten auf "legacy" stand die linke
      Gruppe weiter auf "center", die Fuge fiel von 20 auf 18,5 -- das
      alte Design haette sich also geaendert. Beim ECHTEN Legacy-Aufbau
      (Design VOR dem Laden gesetzt) waren es unveraendert 20/"flex-start",
      der Fehler war also nur dort erreichbar -- aber "dort" ist die
      Seite, auf der man Designs vergleicht.

   Die Hoehenregel darueber braucht beides nicht. */

/* Die Huelle der Bueroklammer nimmt die Geometrie ihres eigenen Labels an.
   "justify-content: center" haelt das Label mittig, falls die Huelle doch
   einmal hoeher gerechnet wird; "margin: 0" nimmt der Legacy-Regel
   "margin-top: 10px" (webapp.css, <=1024px) ihre Wirkung, die auf die alte
   40px-Klammer gerechnet war. */
[data-design="new"] .chatbot-input .upload-container {
  height: 36px;
  min-height: 36px;
  justify-content: center;
}

[data-design="new"] .chatbot-input .upload-container label {
  margin: 0;
  flex: 0 0 auto;
}

/* ═══════════════════════════════════════════════════════════════════════
   CHAT/H2 (2026-09-26) — DER COMPOSER RUTSCHT UNTER DEN FENSTERRAND

   Befund des Anwenders (mit Bild): "wenn ich eine Antwort im Chatfenster
   erhalten habe, wird danach das Chat Input Widget nicht mehr vollständig
   angezeigt." Im Bild steht das Textfeld noch da, die Knopfzeile darunter
   fehlt.

   GEMESSEN (390x800, neues Design, echtes Chromium):

                          leer            nach Antworten
     .chat-container    97 .. 872        97 .. 872
     Composer          561 .. 688  ok   737 .. 864   64px UNTER dem Rand
     Fensterhoehe      800             800

   URSACHE: ".chat-container" (webapp.css:2173, unantastbar) rechnet seine
   Hoehe selbst aus: "height: calc(100vh - 25px)" plus "margin-top: 25px".
   Diese Rechnung stammt aus der Zeit der 50px hohen "navbar2" und setzt
   voraus, dass der Behaelter bei y=0 BEGINNT. Seit dem Huellenumbau (C1)
   steht die Kopfleiste als eigene Rasterreihe DARUEBER: der Behaelter
   beginnt bei y=97 (Kopfleiste 72 + 25 Abstand) und endet deshalb 72px
   unter dem Fensterrand.

   DAS RASTER SELBST IST RICHTIG: gemessen "grid-template-rows: 72px
   728px" bei genau 800px Hoehe. Der Behaelter muss seine Reihe nur
   ausfuellen, statt an ihr vorbeizurechnen.

   WARUM ES ERST NACH EINER ANTWORT AUFFIEL: ".chat-container" traegt
   "justify-content: center". Solange das Gespraech kurz war, stand der
   Composer in der Mitte des zu hohen Behaelters -- also noch im Bild.
   Erst wenn der Inhalt waechst, wandert er an dessen Unterkante und
   verschwindet. Der Fehler war die ganze Zeit da, nur unsichtbar.

   ZWEITE URSACHE: ".chat-window" traegt "flex: 0 1 auto" und
   "min-height: auto". Ein Flex-Kind mit eigenem Bildlauf kann so nicht
   unter seine Inhaltshoehe schrumpfen -- gemessen wuchs es von 270 auf
   622px und schob den Composer vor sich her, statt selbst zu scrollen.
   "min-height: 0" ist die Standardbehebung dafuer.

   NUR IM NEUEN DESIGN: das alte hat diese Kopfleiste nicht und rechnet
   mit "navbar2" weiter richtig.
   ═══════════════════════════════════════════════════════════════════════ */

[data-design="new"] .chat-container {
  /* "auto" statt "calc(100vh - 25px)": als Rasterkind streckt sich der
     Behaelter damit von selbst ueber seine Reihe -- Rand eingerechnet,
     ohne dass hier irgendeine Kopfleistenhoehe hingeschrieben werden
     muss. Ein fester Wert waere beim naechsten Umbau der Kopfleiste
     wieder falsch. */
  height: auto;
  /* Erlaubt dem Behaelter, unter die Hoehe seines Inhalts zu gehen --
     sonst wuechse er ueber die Reihe hinaus, statt innen zu scrollen. */
  min-height: 0;
}

[data-design="new"] .chat-container > .chat-window {
  /* Das Gespraech nimmt den uebrigen Platz UND gibt ihn wieder her.
     "min-height: 0" hebt die Vorgabe "auto" auf, die ein Flex-Kind an
     seiner Inhaltshoehe festhaelt. */
  flex: 1 1 auto;
  min-height: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   #2053 (2026-09-29) — STARTSEITE EINES NEUEN CHATS

   Figma "DE · Chat · New chat" (Knoten 264:9921, Stapel 264:10004):
   Begruessung und Composer stehen mittig im Chatbereich, darunter vier
   Vorschlagskacheln. Der Zustand haengt an ".chat-container--start"
   (templatechatwindow.js "setzeStartzustand()") und endet mit dem ersten
   Absenden oder dem Laden eines bestehenden Chats -- danach gilt wieder
   die Chat/H2-Regel oben (Gespraech fuellt, Composer unten).

   MITTIG: ".chat-container" traegt schon "justify-content: center"
   (webapp.css). Gibt das Gespraech seinen Platz nicht mehr her
   ("flex: 0 1 auto" statt "1 1 auto"), wandert der ganze Stapel in die
   Mitte. "min-height: 0" aus Chat/H2 bleibt stehen: ein sehr langer
   Begruessungstext scrollt weiter in sich selbst.

   BEGRUESSUNG: Figma setzt den Gruss als Ueberschrift (Inter Bold 30/38,
   -0,6 Laufweite, text/primary) und darunter eine Zeile in body-lg
   (17/26, text/secondary), ohne Blase. Unser Gruss ist ein ganzer Satz
   statt drei Woertern -- die Ueberschrift nimmt deshalb h3 statt 30px,
   sonst braeche er auf vier bis sechs Zeilen. Der Avatar waechst auf
   Figmas 56px, wenn der Agent eines hat; ohne Bild bleibt er weg
   (Sichtpruefung A3, kein Platzhalter). Absenderzeile und KI-Kennzeichen
   bleiben stehen (Transparenz), nur mittig.

   VORSCHLAEGE: Kachel nach Figma 264:10035 -- surface-1, Rahmen
   border-soft, Radius 14 (radius-lg), Innenabstand 14/16, Symbolfeld
   34x34 mit Radius 10 (radius-md) und 14 % Akzentflaeche, Titel
   Semi Bold 14/20 text/primary, Unterzeile 12,5/18 text/muted, 2px
   dazwischen, Raster 2x2 mit 12px Fuge.

   #2061 (2026-09-30) BUENDIG MIT DEM COMPOSER: die Leiste ist in Summe
   genau so breit wie das Chat-Eingabefenster. Beide sind Kinder von
   ".chat-container", die Leiste uebernimmt deshalb die Breitenformel
   des Composers statt fester Aussenabstaende (die frueheren 50/48px
   rechts rechneten seinen Innenabstand nicht mit -- 20 bzw. 30px zu
   kurz). Der Composer ist ueber 640px "content-box" mit "width:
   calc(100% - 100px)" (webapp.css ".chatbot-input"), dazu kommen
   Innenabstand 16+12 und Rahmen 2 (oben, "[data-design=new]
   .chatbot-input") -- aussen also "100% - 70px"; links sein
   Aussenabstand 40. Im Band 641-1024px "calc(100% - 112px)" bei 64px
   links (Abschnitt oben, :3014), aussen "100% - 82px". Unter 641px "border-box"
   mit je 8px. Gemessen 1440/1280/900/700/390px, alle Kanten auf 1px.
   Die Spalten brechen auf EINE Kachel je Zeile um, sobald eine Kachel
   in halber Breite unter 260px faellt (ab da bricht die Unterzeile) --
   dann ist jede Kachel exakt so breit wie der Composer. Das ersetzt die
   waagerecht scrollende Reihe unter 641px.
   ═══════════════════════════════════════════════════════════════════════ */

[data-design="new"] .chat-container.chat-container--start > .chat-window {
  flex: 0 1 auto;
}

[data-design="new"] .chat-container--start .msg-greeting {
  flex-direction: column;
  align-items: center;
  gap: 16px;
  width: 100%;
  max-width: 740px;
  margin: 0 auto 8px;
  text-align: center;
}

[data-design="new"] .chat-container--start .msg-greeting-avatar {
  width: 56px;
  min-width: 56px;
  height: 56px;
  margin-top: 0;
}

[data-design="new"] .chat-container--start .msg-greeting-avatar .chatbot-avatar {
  width: 56px;
  height: 56px;
}

[data-design="new"] .chat-container--start .msg-greeting-content {
  flex: 0 0 auto;
  width: 100%;
}

[data-design="new"] .chat-container--start .msg-greeting .msg-sender-row {
  justify-content: center;
}

[data-design="new"] .chat-container--start .msg-bubble-greeting {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 0;
  color: var(--ax-text-secondary);
  font-size: var(--ax-font-size-body-lg);
  line-height: var(--ax-line-height-body-lg);
}

[data-design="new"] .chat-container--start .msg-bubble-greeting > :first-child > p:first-child {
  color: var(--ax-text-primary);
  font-family: var(--ax-font-display);
  font-size: var(--ax-font-size-h3);
  line-height: var(--ax-line-height-h3);
  font-weight: 700;
  letter-spacing: -0.02em;
}

[data-design="new"] .chat-container--start .chat-vorschlaege {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, max(260px, calc(50% - 6px))), 1fr));
  gap: 12px;
  box-sizing: border-box;
  width: calc(100% - 70px);
  margin: 0 0 24px 40px;
}

[data-design="new"] .chat-vorschlag {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  margin: 0;
  padding: 14px 16px;
  background: var(--ax-bg-surface-1);
  border: 1px solid var(--ax-border-soft);
  border-radius: var(--ax-radius-lg);
  color: var(--ax-text-primary);
  font-family: var(--ax-font-sans);
  letter-spacing: normal;
  text-align: left;
  cursor: pointer;
}

/* Eigene Hover-Regel (0,3,0): ohne sie faerbte die Sammelregel
   ":where(...) button:hover" die Kachel in die Primaerfarbe. */
[data-design="new"] .chat-vorschlag:hover:not(:disabled) {
  background: var(--ax-bg-hover);
  border-color: var(--ax-border-default);
  color: var(--ax-text-primary);
}

[data-design="new"] .chat-vorschlag-symbol {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  border-radius: var(--ax-radius-md);
  color: var(--chat-vorschlag-akzent);
  background: color-mix(in srgb, var(--chat-vorschlag-akzent) 14%, transparent);
}

[data-design="new"] .chat-vorschlag--ki { --chat-vorschlag-akzent: var(--ax-accent-ai); }
[data-design="new"] .chat-vorschlag--aktion { --chat-vorschlag-akzent: var(--ax-action-primary); }
[data-design="new"] .chat-vorschlag--erfolg { --chat-vorschlag-akzent: var(--ax-status-success); }
[data-design="new"] .chat-vorschlag--magenta { --chat-vorschlag-akzent: var(--ax-magenta-500); }

[data-design="new"] .chat-vorschlag-texte {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

[data-design="new"] .chat-vorschlag-titel {
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
  color: var(--ax-text-primary);
}

[data-design="new"] .chat-vorschlag-text {
  font-size: 12.5px;
  line-height: 18px;
  font-weight: 400;
  color: var(--ax-text-muted);
}

@media (min-width: 641px) and (max-width: 1024px) {
  [data-design="new"] .chat-container--start .chat-vorschlaege {
    width: calc(100% - 82px);
    margin-left: 64px;
  }
}

/* Mobil: untereinander gestapelt stauchten die vier Kacheln die Startseite
   -- dort entfaellt die Vorschlagsleiste ganz. */
@media (max-width: 640px) {
  [data-design="new"] .chat-container--start .chat-vorschlaege {
    display: none;
  }

  [data-design="new"] .chat-container--start .msg-bubble-greeting {
    font-size: var(--ax-font-size-body-md);
    line-height: var(--ax-line-height-body-md);
  }
}

/* Dialog "In Wissensdatenbank speichern" (dialogsavechatasdocument.js).
   ".dialog .container-tab-widget" (webapp.css) erzwingt "width: 100%" UND
   "padding: 8px 12px" mit !important bei content-box -- jeder der beiden
   verschachtelten Reiter (Assistent + Schritt) wurde damit 24px breiter als
   sein Wirt, Auswahlfelder und Dokumentname liefen ueber den rechten Rand.
   border-box rechnet den Innenabstand in die 100% ein. Die Zeilen fuer
   Ziel-Agent/-Projekt/Container stehen wie "Ziel-Datenbank" und
   "Dokumentname" untereinander statt nebeneinander -- nebeneinander
   quetschte die Flexzeile "Ziel-Agent" auf zwei Zeilen. */
[data-design="new"] .dialog-save-chat .container-tab-widget {
  box-sizing: border-box;
}

[data-design="new"] .dialog-save-chat #step-target > div {
  flex-direction: column;
  align-self: stretch;
}

[data-design="new"] .dialog-save-chat #step-target select,
[data-design="new"] .dialog-save-chat #step-target input[type="text"] {
  width: 100%;
}

/* #2091: Eintrag "Konnektoren" unter "Weitere Einstellungen"
   (chatwindowinput.js "setConnectorsEntry()"). Neues Design: eine ganze
   Zeile im Blatt unter den Reglern, auf jeder Breite. (0,3,0) wie
   "[data-design=new] .chatbot-input .chatbot-button", aber spaeter in der
   Datei -- die 36x36 der Knopfzeile gelten hier nicht. */
[data-design="new"] .chatbot-blatt .chat-connectors-eintrag {
  display: flex;
  flex-direction: column;
}

[data-design="new"] .chatbot-blatt .chatbot-connectors-knopf {
  width: 100%;
  height: auto;
  min-height: 44px;
  justify-content: flex-start;
  gap: var(--ax-space-3);
  padding: 0 var(--ax-space-2);
  border-radius: var(--ax-radius-md);
}

[data-design="new"] .chatbot-blatt .chatbot-connectors-knopf .button-icon-label {
  color: var(--ax-text-primary);
  font-size: var(--ax-font-size-label-sm);
  text-align: left;
}

[data-design="new"] .chatbot-blatt .chat-connectors-eintrag .chat-regler-erklaerung {
  padding-left: var(--ax-space-2);
  padding-right: var(--ax-space-2);
}
