/* ===================== Grundgerüst: Tokens-Aliase, Body, App-Shell (Topbar/Rail), Fokus, Zeilen (.hrow) ===================== */
/* Design-Migration: alte Alias-Namen zeigen jetzt auf die Design-System-Tokens aus 01-tokens.css (per <link>
   vorher geladen) statt auf eigene Hex-Werte — jede der vielen bestehenden var(--schwach)-artigen Stellen in
   dieser Datei zieht dadurch automatisch nach, ohne jede Stelle einzeln anfassen zu müssen. */
:root {
  --fg: var(--text-1);
  --bg: var(--surface-app);
  --karte: var(--surface-panel);
  --rand: var(--border-1);
  --akzent: var(--blue-500);
  --akzent-hell: var(--blue-50);
  --ok: var(--green-500);
  --fehler: var(--red-500);
  --warn: var(--orange-500);
  --schwach: var(--text-3);
  --mono: var(--font-mono);
}
* {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
  height: 100%;
}
/* Design-Migration: body nutzt jetzt den Design-System-Font-Stack (Source Sans 3, selbst gehostet, s.
   Scheibe 1) statt der alten system-ui-Schriftkette — dieselbe Regel überschrieb sonst weiterhin die neuen
   Tokens aus 01-tokens.css (app.css lädt zuletzt, gleiche Selektor-Spezifität). */
body {
  font: 15px / 1.45 var(--font-sans);
  color: var(--fg);
  background: var(--bg);
}
/* height statt min-height (Design-Migration Politur 9): min-height ist nur eine Untergrenze — wenn der
   Inhalt einer Seite höher als der Bildschirm war, wuchs #app einfach mit, und die ganze Seite (inkl.
   Topbar/Rail) scrollte statt nur des jeweiligen Seiteninhalts. Mit `height:100%` bleibt #app exakt
   bildschirmhoch; jede Seite muss ihren eigenen Inhalt selbst scrollen (s. .seite `overflow-y` unten,
   .verlauf/.chats/.db-main/.sk-canvas taten das für ihre Bereiche schon vorher). */
#app {
  display: flex;
  flex-direction: column;
  height: 100%;
  max-width: 68rem;
  margin: 0 auto;
  padding: 0 1rem;
}
/* .rail (03-app-shell.css) setzt kein eigenes overflow — passen alle Einträge (üblicher Fall) nicht anders
   sichtbar, ragt sie sonst aber ohne Klick-Rand einfach unten aus ihrer eigentlich schon bildschirmhohen Box
   heraus und zieht (da nichts das clippt) die ganze Seite in einen Scroll-Zustand, obwohl nur die Leiste zu
   wenig Platz hatte. overflow-y:auto lässt in diesem Fall nur die Leiste selbst scrollen. */
.rail {
  overflow-y: auto;
}
.hinweis {
  color: var(--schwach);
  text-align: center;
  margin-top: 4rem;
}
a {
  color: var(--akzent);
}

header.kopf {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--rand);
}
header.kopf h1 {
  font-size: 1.05rem;
  margin: 0;
  flex: 1;
  font-weight: 600;
}
header.kopf .nutzer {
  color: var(--schwach);
  font-size: 0.9rem;
}
/* Design-Migration Scheibe 8: .mandant-schalter-wrap trägt keine eigene Optik mehr (.tenant/.ax-select
   übernehmen das, s. mandant-schalter.ts) — Klassenname bleibt als Anker erhalten. */
.mandant-schalter-wrap .hinweis.klein {
  color: var(--fehler);
}
button {
  font: inherit;
  border: 1px solid var(--rand);
  background: var(--karte);
  color: var(--fg);
  border-radius: 0.5rem;
  padding: 0.45rem 0.8rem;
  cursor: pointer;
}
button:hover {
  border-color: var(--akzent);
}
/* Design-Migration Scheibe 8 (Barrierefreiheit): sichtbarer Fokusring mit dem Design-System-Token für alle
   noch nicht auf ax-btn umgestellten interaktiven Elemente (ax-btn/ax-input/ax-select bringen ihren eigenen
   :focus-visible schon aus 02-components.css mit, hier nur die Lücke für die übrigen). */
button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
/* .ax-composer__box zeigt den Fokus schon selbst an der äußeren Box (:focus-within, 02-components.css) —
   ohne diese Rücknahme bekäme die Frage-Eingabe zusätzlich noch den obigen Ring direkt aufs <textarea>,
   also außen UND innen blau. */
.ax-composer__box textarea:focus-visible {
  box-shadow: none;
}
button.primaer {
  background: var(--akzent);
  color: #fff;
  border-color: var(--akzent);
}
button:disabled {
  opacity: 0.5;
  cursor: default;
}
button.klein {
  padding: 0.2rem 0.55rem;
  font-size: 0.85rem;
}
button.aktiv {
  background: var(--akzent-hell);
  border-color: var(--akzent);
}
/* .hrow (design-system/03-app-shell.css) ist für ein reines <div onclick> ausgelegt (Mockup) — unsere Zeilen
   sind aus Tastatur-Zugänglichkeit echte <button>-Elemente und bekommen den Rahmen der globalen button{...}-
   Regel oben mit (border setzt .hrow selbst nicht — background bewusst NICHT hier zurückgesetzt: var(--karte)
   entspricht var(--surface-panel), also demselben Ton wie .panel selbst, und .hrow--active braucht seine
   eigene Hintergrundfarbe weiterhin unbeeinflusst — eine Regel hier hätte bei gleicher Selektor-Spezifität
   die von .hrow--active überschrieben, weil app.css nach den design-system-Dateien lädt). Ohne diesen Reset
   sehen Dashboard-/Chat-Verlaufszeilen wie einzelne Kästchen statt einer flachen Liste aus (Nutzer-Meldung
   2026-09-28: „im Mockup ein Eintrag auf voller Breite, bei uns kleine Kacheln"). */
.hrow {
  border: 0;
  width: 100%;
  text-align: left;
}

.anmeldung {
  margin: 6rem auto;
  text-align: center;
  max-width: 28rem;
}
.anmeldung h1 {
  font-size: 1.4rem;
}
.anmeldung p {
  color: var(--schwach);
}

/* Design-Migration Politur 5 (2026-09-26): links/rechts fehlte Innenabstand komplett (padding: 1rem 0 …
   setzt links/rechts explizit auf 0 und überschreibt damit .chat-scrolls eigentliches padding:16px aus
   03-app-shell.css, gleiche Selektor-Spezifität, app.css lädt zuletzt) — seit der #app-Randkorrektur
   (Politur 2) klebte der Inhalt dadurch sichtbar am rechten Rand, vorher kaschierte das noch #apps alter
   16px-Rand. 1rem seitlich entspricht dem Mockup (chat-scroll{padding:16px}, s. 01-chat-verlauf.png). */
.verlauf {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 1rem 1rem 8rem;
}
.verlauf:empty::before {
  content: "Stelle eine Frage zu deinen Kunden, z. B. „Wie viele Neukunden habe ich zum 30.06.2025?“ oder „Kundentypen pro Monat 2025“.";
  color: var(--schwach);
  text-align: center;
  margin-top: 3rem;
  display: block;
}
/* ===================== Chat: Verlauf, Antwortkarte, Tabelle/Diagramm im Ergebnis, Composer, Leiste früherer Unterhaltungen ===================== */
/* Design-Migration Politur 6: Mockup packt Nutzer-/Assistenten-Bubbles flach nebeneinander in .chat-scroll
   (Basis-Abstand 18px über dessen `gap`) und legt vor jeder neuen Nutzereingabe zusätzlich 22px obendrauf
   (`.ax-msg--assistant + .ax-msg--user{margin-top:22px}`, 02-components.css) — bei uns steckt jedes
   Frage/Antwort-Paar zusätzlich in einem eigenen `.verlauf-eintrag`, wodurch Nutzer- und Assistenten-Bubble
   verschiedener Austausche nie direkte Geschwister sind und diese Regel nie greift (Auswahl bezog sich schon
   dort). Gleiche zwei Abstände deshalb hier nachgebaut: 18px innerhalb eines Austauschs (.verlauf-eintrag
   selbst als Flex-Spalte) und die zusätzlichen 22px zwischen zwei Austauschen (jedes .verlauf-eintrag nach
   dem ersten), addiert auf .verlaufs eigenen 18px-Abstand — macht 40px zur nächsten Nutzereingabe, wie im
   Mockup „zusätzlicher Abstand" (nicht anstelle des Basisabstands). */
.verlauf-eintrag {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.verlauf-eintrag + .verlauf-eintrag {
  margin-top: 22px;
}

.karte {
  background: var(--karte);
  border: 1px solid var(--rand);
  border-radius: 0.75rem;
  padding: 1rem 1.1rem;
}
.karte .frage {
  font-weight: 600;
  margin: 0 0 0.6rem;
}
.karte .frage::before {
  content: "Du: ";
  color: var(--schwach);
  font-weight: 400;
}

.schritte {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0 0 0.7rem;
  padding: 0;
  list-style: none;
  font-size: 0.8rem;
}
.schritte li {
  padding: 0.15rem 0.55rem;
  border-radius: 1rem;
  background: var(--bg);
  color: var(--schwach);
  border: 1px solid var(--rand);
}
.schritte li.ok {
  color: var(--ok);
}
.schritte li.fehler {
  color: var(--fehler);
  border-color: var(--fehler);
}
.schritte li.laeuft {
  color: var(--akzent);
  border-color: var(--akzent);
  animation: puls 1.2s infinite;
}
@keyframes puls {
  50% {
    opacity: 0.5;
  }
}

.text {
  white-space: pre-wrap;
  margin: 0.4rem 0 0.6rem;
}
.text.laeuft::after {
  content: "▍";
  color: var(--akzent);
  animation: puls 0.9s infinite;
}
.rueckfrage {
  border-left: 3px solid var(--warn);
  padding-left: 0.7rem;
}
.fehlertext {
  color: var(--fehler);
}

.daten {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
  margin: 0.5rem 0;
}
/* Design-Migration Scheibe 2: .daten (bisher immer einspaltiges Grid) bekommt zusätzlich den Design-System-
   Kartenrahmen .ax-result (Flex-Spalte) — beide zusammen auf einem Element ergeben denselben einspaltigen
   Ablauf wie bisher (.daten allein war schon einspaltig), nur mit weißer Karte/Schatten/Radius. */
.daten.ax-result {
  display: flex;
  flex-direction: column;
}
/* Antwortkarte: Text, darunter Diagramm, darunter Tabelle — untereinander in voller Breite (Nutzer-Wunsch 2026-09-09) */
.karte .daten {
  gap: 1.25rem;
  margin: 0.9rem 0 0.6rem;
}
.karte .diagramm-huelle {
  height: 20rem;
}
@media (min-width: 52rem) {
  .daten.mit-diagramm {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}
/* Design-Migration Politur 5: Rahmen/Rundung waren die alte, vor-Migration-Optik der Tabellen-Box — das
   .ax-table selbst nutzt jetzt design-system/02-components.css (eckige th/td, kein eigener Rahmen), die
   abgerundeten Ecken hier kollidierten sichtbar mit dessen eckigem Kopf. overflow/max-height bleiben: nur
   damit hat der sticky th (.ax-table th{position:sticky}) überhaupt einen Scroll-Rahmen, in dem er kleben kann. */
.tabelle {
  overflow: auto;
  max-height: 24rem;
}
table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.9rem;
}
th,
td {
  text-align: left;
  padding: 0.35rem 0.6rem;
  border-bottom: 1px solid var(--rand);
  white-space: nowrap;
}
th {
  position: sticky;
  top: 0;
  background: var(--bg);
  font-weight: 600;
}
td.zahl,
th.zahl {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.diagramm-huelle {
  position: relative;
  height: 18rem;
  min-width: 0;
}

.meta {
  font-size: 0.8rem;
  color: var(--schwach);
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1rem;
  margin-top: 0.5rem;
  align-items: center;
}
.sql-knopf {
  font-size: inherit;
}
.sql-dialog .sql-dialog__code {
  font: 12px / 1.45 var(--mono);
  background: var(--bg);
  padding: 0.75rem;
  border-radius: 0.5rem;
  overflow: auto;
  max-height: 60vh;
  white-space: pre;
  margin: 0.5rem 0 0;
  user-select: text;
  font-variant-ligatures: none;
}
.sql-dialog .sql-dialog__hinweis {
  margin: 0;
  font-size: 0.85rem;
  color: var(--schwach);
}
.sql-dialog .sql-dialog__status {
  font-size: 0.85rem;
  color: var(--schwach);
}
details.sql summary {
  cursor: pointer;
}
details.sql pre {
  font: 12px / 1.4 var(--mono);
  background: var(--bg);
  padding: 0.6rem;
  border-radius: 0.5rem;
  overflow: auto;
  max-height: 20rem;
}
.fuss {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  margin-top: 0.6rem;
  flex-wrap: wrap;
}
.fuss .danke {
  font-size: 0.85rem;
  color: var(--ok);
}
.feedback-text {
  flex: 1;
  min-width: 12rem;
  font: inherit;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--rand);
  border-radius: 0.5rem;
}

.trace {
  margin-top: 0.6rem;
  border-top: 1px dashed var(--rand);
  padding-top: 0.6rem;
  font-size: 0.85rem;
}
.trace table td:last-child {
  white-space: normal;
}
.trace pre {
  font: 11px / 1.4 var(--mono);
  background: var(--bg);
  padding: 0.4rem;
  border-radius: 0.4rem;
  overflow: auto;
  max-height: 12rem;
  margin: 0.2rem 0;
  white-space: pre-wrap;
}

/* Design-Migration Politur 8: eigener Verlauf-Hintergrund (transparent → --bg) entfernt — .composer-wrap
   (03-app-shell.css) bringt schon eine deckende Fläche (var(--gray-50)) mit, aber `form.eingabe` (Element+
   Klasse, höhere Spezifität, app.css lädt zuletzt) überschrieb sie mit dem Verlauf. Ergebnis: im oberen
   Bereich der Eingabeleiste (wo der Verlauf noch fast durchsichtig war) schimmerte der darunter scrollende
   Chat-Inhalt sichtbar durch. Eigenes Padding ebenfalls entfernt, `.composer-wrap`s eigenes (12px 16px 24px)
   reicht jetzt aus — nur `position:sticky` bleibt hier, das liefert `.composer-wrap` nicht. */
form.eingabe {
  position: sticky;
  bottom: 0;
}
/* Optischer Ausgleich (Politur 8): .ax-composer__box textarea{padding:5px 0} ist rechnerisch symmetrisch
   (Zeilenhöhe passt fast exakt in den Innenraum), Source Sans 3 setzt das Schriftbild darin aber sichtbar
   zu hoch (übliche Font-Metrik-Eigenheit: mehr reservierter Raum über der Grundlinie als darunter). Kleine
   Verschiebung nach unten gleicht das nur für unsere Eingabe aus, ohne die allgemeine Komponentenregel
   anzufassen. */
.ax-composer__box textarea {
  padding: 7px 0 3px;
}
/* Design-Migration Politur 5: eigene .zeile-Box (Rahmen/Hintergrund/Rundung) und eigenes textarea-Padding
   entfernt — beides kollidierte mit .ax-composer__box/dessen textarea-Regel (02-components.css, gleiche
   Selektor-Spezifität, app.css lädt zuletzt und gewann). Zwei sichtbare Folgen: der äußere (Box) UND innere
   (textarea) Fokusring wurden beide blau (s. :focus-visible-Regel unten), und das eigene, seit dem
   Höhen-Redesign der Knöpfe (30px, --control-h-md) veraltete textarea-Padding (.55rem statt der
   Design-System-eigenen 5px) ließ den Senden-Knopf bei `align-items:flex-end` nicht mehr mittig zur
   einzeiligen Eingabe wirken. .ax-composer__box textarea liefert jetzt beides korrekt (padding:5px 0,
   exakt Knopfhöhe). */
form.eingabe .optionen {
  display: flex;
  gap: 0.8rem;
  font-size: 0.8rem;
  color: var(--schwach);
  margin: 0.4rem 0.2rem 0;
  align-items: center;
  flex-wrap: wrap;
}
form.eingabe .optionen input {
  font: inherit;
  border: 1px solid var(--rand);
  border-radius: 0.4rem;
  padding: 0.1rem 0.3rem;
}
/* Design-Migration Politur 3: derselbe Composer (form.eingabe) wird in die „Neue Unterhaltung"-Ansicht
   (.nc) umgehängt (s. zeigeNeu()/zeigeVerlauf() in app.ts) statt ihn zu duplizieren — dort ohne die klebende
   Fußzeilen-Optik und ohne die Mandant/Segment-Chip-Zeile (die nc-scope-Bausteine oben zeigen das schon). */
.nc form.eingabe {
  position: static;
  background: none;
  padding: 0;
}
.nc form.eingabe .optionen {
  display: none;
}

/* Leiste früherer Unterhaltungen */
/* Vollbild (Nutzer-Wunsch 2026-09-09): Chat nutzt die ganze Breite. `padding` gehört hierher statt in die
   Basisregel oben — sonst bleibt links/rechts ein 1rem-Rand um Topbar/Rail/Inhalt, den kein Mockup-Screen
   zeigt (2026-09-26 gefunden: „Mailblock hat links und rechts padding, das soll nicht sein"). */
#app {
  max-width: none;
  padding: 0;
}
/* Design-Migration Politur 5: kein Grid-`gap` mehr zwischen Leiste und Inhalt — im Mockup trennt allein
   .panels eigener `border-right` (s. design-system/03-app-shell.css), das zusätzliche 1.2rem hier ließ den
   Chat-Inhalt viel weiter vom linken Rand abrücken als im Mockup. Spaltenbreite jetzt `--sidebar-w` (244px,
   01-tokens.css) statt eines eigenen 17rem-Werts. */
.rumpf {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  flex: 1;
  min-height: 0;
}
/* Design-Migration Scheibe 2: .chats erzwingt volle Breite (früher gegen align-self:start im alten
   Grid-Kontext, s. Git-Historie) — width:100% bleibt unabhängig vom heutigen Layout die robuste Lösung.
   Seit Politur 5 kein direktes Kind von .panel mehr (liegt in .ax-section > .ax-section__body, s. app.ts),
   Selektor entsprechend als Nachfahre statt Kind. */
.panel .chats {
  width: 100%;
}
/* padding-top entfällt (Politur 5): .ax-section__body polstert jetzt ringsum wie im Mockup (VERLAUF-Kopf +
   Innenabstand), das eigene `panel-list` gibt es an dieser Stelle nicht mehr. */
/* Design-Migration Politur 10: .verlauf-abschnitt (die eine ax-section-Gruppe, die die ganze Leiste
   ausfüllen soll, s. app.ts) reicht `flex:1;min-height:0` bis zu `.chats` durch — sonst behielt `.chats`
   trotz `overflow:auto` seine volle Inhaltshöhe (frühere `max-height:100vh`-Notlösung kannte die tatsächlich
   verfügbare Höhe unterhalb der Topbar nicht und war fast immer größer als die wirklich verfügbare Fläche),
   sprengte dadurch `.ax-section`/`.panel` (beide ohne eigenes min-height:0/overflow) und zog — da nichts
   das clippte — die ganze Seite in einen Scroll-Zustand, obwohl nur die Unterhaltungsliste selbst zu lang
   war. `position:sticky`/`max-height:100vh` dafür nicht mehr nötig: */
.verlauf-abschnitt {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.verlauf-abschnitt .ax-section__body {
  display: flex;
  flex: 1;
  min-height: 0;
}
.chats {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  flex: 1;
  min-height: 0;
  overflow: auto;
}
.chats .neu {
  text-align: left;
  margin-bottom: 0.4rem;
}
.chats .chat {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.45rem 0.6rem;
  border-color: transparent;
  background: transparent;
}
.chats .chat:hover {
  background: var(--karte);
  border-color: var(--rand);
}
.chats .chat.aktiv {
  background: var(--akzent-hell);
  border-color: var(--akzent);
}
.chats .titel {
  font-size: 0.9rem;
  line-height: 1.3;
}
.chats .wann {
  font-size: 0.75rem;
  color: var(--schwach);
}
.chats .hinweis.klein {
  margin: 0.5rem 0;
  font-size: 0.85rem;
  text-align: left;
}
/* min-height:0 (Politur 10): .inhalt ist ein Grid-Element von .rumpf — Grid-Elemente haben genau wie
   Flex-Elemente eine implizite Mindesthöhe „so hoch wie mein Inhalt", solange man sie nicht explizit auf 0
   setzt. Ohne das konnte .verlauf/.nc (beide selbst flex:1;min-height:0) die eigene Zeile trotzdem über die
   verfügbare Höhe hinaus aufblähen, sobald ihr Inhalt (z. B. viele Nachrichten) mehr Platz wollte. */
.inhalt {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}
.nur-schmal {
  display: none;
}
@media (max-width: 52rem) {
  .rumpf {
    grid-template-columns: 1fr;
  }
  .chats {
    display: none;
    position: static;
    max-height: none;
  }
  .chats.offen {
    display: flex;
  }
  .nur-schmal {
    display: inline-block;
  }
}
.chats .alle {
  font-size: 0.8rem;
  color: var(--schwach);
  display: flex;
  gap: 0.4rem;
  align-items: center;
  padding: 0 0.2rem 0.4rem;
}

/* ===================== Arbeitsliste (Vorschläge) ===================== */
/* Arbeitsliste */
/* ax-card selbst setzt kein Padding (nur Rahmen/Schatten) — für die schlichten, nicht in ax-card__head/
   ax-card__body unterteilten Karten dieser Migrationsscheibe (al-eintrag/gl-eintrag/kachel) hier direkt
   nachgezogen, statt jede einzeln in ax-card__body zu verschachteln. */
.al-eintrag.ax-card,
.gl-eintrag.ax-card,
.kachel.ax-card {
  padding: 0.8rem 1rem;
}
.zaehler {
  display: inline-block;
  min-width: 1.4em;
  padding: 0 0.35em;
  border-radius: 1em;
  background: var(--akzent);
  color: #fff;
  font-size: 0.75rem;
  text-align: center;
  margin-left: 0.2em;
}
.arbeitsliste {
  padding: 1rem 1rem 4rem;
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}
.arbeitsliste .al-kopf {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
}
.arbeitsliste h2 {
  font-size: 1.05rem;
  margin: 0;
}
.arbeitsliste .hinweis-inline {
  color: var(--schwach);
  font-size: 0.85rem;
  flex: 1;
}
.arbeitsliste .alle {
  font-size: 0.8rem;
  color: var(--schwach);
  display: flex;
  gap: 0.4rem;
  align-items: center;
}
.al-liste {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
/* Design-Migration Scheibe 6: .al-eintrag trägt keine eigene Optik mehr (ax-card übernimmt das jetzt, s.
   arbeitsliste.ts/merkmale.ts/prompt.ts) — Klassenname bleibt als Anker/Selector-Kompatibilität erhalten. */
.al-zeile {
  display: flex;
  gap: 0.8rem;
  align-items: baseline;
  flex-wrap: wrap;
}
.al-zeile .wann {
  color: var(--schwach);
  font-size: 0.8rem;
  flex: 1;
}
.al-inhalt {
  margin: 0.4rem 0 0.2rem;
  white-space: pre-wrap;
}
.al-grund {
  margin: 0;
  color: var(--schwach);
  font-size: 0.85rem;
}
.status {
  font-size: 0.75rem;
  padding: 0.1rem 0.5rem;
  border-radius: 1rem;
  border: 1px solid var(--rand);
  color: var(--schwach);
}
.status.offen {
  color: var(--warn);
  border-color: var(--warn);
}
.status.angenommen,
.status.geaendert_uebernommen {
  color: var(--ok);
  border-color: var(--ok);
}
.status.abgelehnt {
  color: var(--fehler);
  border-color: var(--fehler);
}

/* ===================== Allgemein: hidden, App-Höhe ===================== */
/* hidden muss auch gegen display:flex/grid gewinnen (Chat-Inhalt, Schrittleiste, Arbeitsliste). */
[hidden] {
  display: none !important;
}
.knopf-link,
.titel-link {
  text-decoration: none;
  color: inherit;
}
/* Design-Migration Politur 9: #app ist jetzt bildschirmhoch gedeckelt (height statt min-height, s. oben) —
   `overflow-y: auto` hier lässt lange Seiteninhalte (Arbeitsliste, Merkmale, Verbrauch, …) innerhalb ihres
   eigenen Bereichs scrollen, statt dass `.seite`/`#app`/die ganze Seite mitwächst und Topbar/Rail mit
   wegscrollen. Für Segmente/Dashboards/Segment-Builder ein No-op — deren Inhalt füllt `.seite` per eigenem
   `flex:1;min-height:0` exakt aus (kein eigener Überlauf), sie scrollen selbst weiter innen
   (.db-main/.sk-canvas/.sg-canvas). */
.seite {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
} /* volle Breite wie der Chat */
.arbeitsliste {
  padding-top: 0.4rem;
}

/* ===================== Chat (Fortsetzung): Rückfrage-Lesarten ===================== */
/* Rückfrage: anklickbare Lesarten */
.lesarten {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  margin: 0.2rem 0 0.6rem;
}
.lesarten-hinweis {
  font-size: 0.85rem;
  color: var(--schwach);
  margin-right: 0.2rem;
}
button.lesart {
  border-color: var(--warn);
  background: #fff7ed;
  text-align: left;
}
button.lesart:hover {
  background: #ffedd5;
}

/* ===================== Verbrauch ===================== */
/* Verbrauchsansicht */
.verbrauch {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 0.4rem 1rem 3rem;
}
.verbrauch h3 {
  font-size: 0.95rem;
  margin: 0.2rem 0 0.5rem;
}
.zeitraum {
  display: flex;
  gap: 0.3rem;
}
.kacheln {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.8rem;
}
/* Design-Migration Scheibe 6: .kachel trägt keine eigene Optik mehr (ax-card + metric-label/val/sub
   übernehmen das, s. verbrauch.ts/daten.ts) — Klassennamen bleiben als Anker erhalten. */
.kachel-hinweis {
  font-size: 0.8rem;
  color: var(--schwach);
}
.limit-balken {
  height: 0.5rem;
  background: var(--rand);
  border-radius: 0.25rem;
  overflow: hidden;
}
.limit-fuellung {
  height: 100%;
  background: var(--ok);
  border-radius: 0.25rem;
  transition: width 0.3s;
}
.limit-fuellung.warnung {
  background: var(--warn);
}
.limit-fuellung.kritisch {
  background: var(--fehler);
}

/* ===================== Chat (Fortsetzung): Leiste — Umbenennen/Ausblenden ===================== */
/* Leiste: Umbenennen / Ausblenden */
.chat-eintrag {
  display: flex;
  align-items: stretch;
  gap: 0.2rem;
  border-radius: 0.5rem;
}
.chat-eintrag .chat {
  flex: 1;
  min-width: 0;
}
.chat-eintrag .titel {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
}
.chat-eintrag.aktiv .chat {
  background: var(--akzent-hell);
  border-color: var(--akzent);
}
.chat-eintrag.ausgeblendet .chat {
  opacity: 0.6;
}
.chat-aktionen {
  display: none;
  flex-direction: column;
  gap: 0.15rem;
  justify-content: center;
}
.chat-eintrag:hover .chat-aktionen,
.chat-eintrag.aktiv .chat-aktionen {
  display: flex;
}
.chat-aktionen .klein {
  padding: 0.05rem 0.35rem;
  font-size: 0.8rem;
  line-height: 1.3;
}
.titel-feld {
  font: inherit;
  font-size: 0.9rem;
  width: 100%;
  border: 1px solid var(--akzent);
  border-radius: 0.3rem;
  padding: 0.1rem 0.3rem;
}

/* ===================== Glossar ===================== */
/* Glossar */
.glossar {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 0.4rem 1rem 3rem;
}
.glossar h3 {
  font-size: 0.95rem;
  margin: 0.6rem 0 0.3rem;
}
.gl-neu {
  background: var(--blue-50);
  border: 1px solid var(--blue-500);
  border-radius: var(--radius-4);
  padding: 0.6rem 1rem 0.8rem;
}
.gl-neu h3 {
  margin-top: 0;
}
.gl-auswahl {
  font: inherit;
  padding: 0.3rem 0.4rem;
  border: 1px solid var(--border-1);
  border-radius: var(--radius-2);
  max-width: 22rem;
}
.gl-gruppe {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
/* Design-Migration Scheibe 6: .gl-eintrag trägt keine eigene Optik mehr (ax-card übernimmt das, s.
   glossar.ts) — Klassenname bleibt als Anker erhalten. */
.gl-feld {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex: 1;
  min-width: 14rem;
  font-size: 0.85rem;
  color: var(--text-3);
}
.gl-feld input {
  flex: 1;
}

/* ===================== Prompt-Abschnitte ===================== */
/* Prompt-Abschnitte */
.prompt {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 0.4rem 1rem 3rem;
}
.prompt-kopf {
  cursor: pointer;
}
.prompt-editor {
  width: 100%;
  font: 12.5px / 1.45 var(--mono);
  border: 1px solid var(--rand);
  border-radius: 0.5rem;
  padding: 0.6rem;
  margin: 0.5rem 0;
  resize: vertical;
}
.prompt-editor[readonly] {
  background: var(--bg);
  color: var(--schwach);
}
.eval-box {
  margin-top: 0.4rem;
}
.eval-ergebnis {
  border-left: 3px solid var(--ok);
  padding: 0.3rem 0.7rem;
  font-size: 0.9rem;
  background: var(--bg);
  border-radius: 0.3rem;
}
.eval-ergebnis.warnung {
  border-left-color: var(--warn);
}

/* ===================== Merkmals-Pflege ===================== */
/* Merkmals-Pflege */
.merkmale {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 0.4rem 1rem 3rem;
}
.merkmale .al-kopf {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
}
.merkmale .hinweis-inline {
  color: var(--schwach);
  font-size: 0.85rem;
  flex: 1;
}
.mk-h3 {
  margin: 0.8rem 0 0.3rem;
  font-size: 1rem;
}
.mk-label {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.85rem;
  color: var(--schwach);
}
.mk-editor .prompt-editor {
  margin: 0.25rem 0;
}
.mk-zeile2 {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.mk-auspraegungen {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0.3rem 0 0.5rem;
}
.mk-auspraegung {
  border: 1px solid var(--rand);
  border-radius: 0.5rem;
  padding: 0.5rem 0.7rem;
  background: var(--bg);
}
.mk-auspraegung-kopf {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}
.mk-prio {
  color: var(--schwach);
  min-width: 1.5rem;
}
.mk-bez {
  flex: 1;
}
.mk-datum {
  flex: none;
  min-width: 0;
}
.mk-stichtag {
  font-size: 0.85rem;
  color: var(--schwach);
  display: inline-flex;
  gap: 0.3rem;
  align-items: center;
}
.mk-regel {
  font: 12px / 1.4 var(--mono);
}
.mk-entfallen td {
  color: var(--schwach);
}
.mk-neu {
  border-color: var(--akzent);
}
.eval-ergebnis.ok {
  border-left-color: var(--ok);
}
.eval-ergebnis .tabelle {
  margin-top: 0.4rem;
  max-height: 18rem;
}

/* ===================== Mandanten-Konfiguration ===================== */
/* Mandanten-Konfiguration */
.konfiguration {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 0.4rem 1rem 3rem;
}
.konfiguration .al-kopf {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
}
.konfiguration .hinweis-inline {
  color: var(--schwach);
  font-size: 0.85rem;
  flex: 1;
}
.konf-karten {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 980px;
}
.konf-raster {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 16px;
}
.konf-feld {
  min-width: 0;
}
.konf-hinweis {
  color: var(--text-2);
  font: var(--type-small);
}
.konf-feld .konf-hinweis {
  display: block;
  margin-top: 4px;
}
.konf-google {
  margin-top: 14px;
}
.konf-google[hidden] {
  display: none;
}
.konf-pruefen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
}
.konf-ergebnis {
  display: inline-flex;
  min-width: 0;
}
.konf-feld[hidden] {
  display: none;
}
.konf-meldung {
  height: auto;
  max-width: 100%;
  white-space: normal;
  padding-block: 2px;
}
.konf-warnung {
  margin: 12px 0 0;
  padding: 8px 10px;
  border-radius: var(--radius-2);
  background: var(--orange-50);
  box-shadow: inset 0 0 0 1px #f2c996;
  font: var(--type-small);
}
.konf-fuss {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
@media (max-width: 720px) {
  .konf-raster {
    grid-template-columns: 1fr;
  }
}

/* ===================== Gemeinsam: Ergebnistabelle (sortieren/suchen) ===================== */
/* Ergebnistabelle: sortieren und suchen */
.datentabelle {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}
.tabelle-werkzeug {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.tabelle-suche {
  font: inherit;
  font-size: 0.85rem;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--rand);
  border-radius: 0.5rem;
  min-width: 10rem;
  max-width: 16rem;
}
.tabelle-zaehler {
  font-size: 0.8rem;
  color: var(--schwach);
}
th.sortierbar {
  cursor: pointer;
  user-select: none;
}
th.sortierbar:hover {
  color: var(--akzent);
}
th.sortierbar.aktiv {
  color: var(--akzent);
}

/* ===================== Analysen: Master-Detail (Mockup Analyseseite.png) ===================== */
.analysen {
  padding: 0;
  height: 100%;
}
.an-master {
  display: grid;
  grid-template-columns: 296px minmax(0, 1fr);
  min-height: 100%;
}
.an-panel {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 0 0;
  border-right: 1px solid var(--border-1);
  background: var(--surface-1, #fff);
}
.an-titel {
  margin: 0 16px;
  font-size: 28px;
  font-weight: 600;
  color: var(--akzent);
}
.an-untertitel {
  margin: 0 16px;
  font: var(--type-small);
  color: var(--text-2);
}
.an-panel .ax-input {
  margin: 0 16px;
  width: auto;
  min-width: 0;
}
.an-liste {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border-1);
}
.an-liste li {
  border-bottom: 1px solid var(--border-1);
}
.an-eintrag {
  display: flex;
  gap: 10px;
  width: 100%;
  padding: 10px 16px;
  border: 0;
  border-radius: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  color: inherit;
  font: inherit;
}
.an-eintrag:hover {
  background: var(--blue-50);
}
.an-eintrag--aktiv,
.an-eintrag--aktiv:hover {
  background: var(--blue-100);
}
.an-kachel {
  display: grid;
  place-items: center;
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 6px;
  background: var(--gray-100);
  color: var(--text-2);
}
.an-eintrag--aktiv .an-kachel {
  background: var(--akzent);
  color: #fff;
}
.an-eintrag__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  align-items: flex-start;
}
.an-eintrag__name {
  font-weight: 600;
  color: var(--text-1);
}
.an-eintrag__kurz {
  font: var(--type-small);
  color: var(--text-2);
}
.an-detail-bereich {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px 16px 24px;
  min-width: 0;
}
.an-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}
.an-kopf .ax-btn--primary {
  margin-left: auto;
}
.an-name {
  margin: 0;
  font-size: 28px;
  font-weight: 600;
  color: var(--akzent);
}
.an-tags {
  display: flex;
  gap: 6px;
}
.an-einfuehrung {
  margin: 0;
  max-width: 70ch;
  color: var(--text-2);
}
.an-karten2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  align-items: start;
}
.an-parameter .ax-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.an-einstellungen {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 12px;
}
.an-einstellungen .ax-field {
  min-width: 0;
}
.an-fragen {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.an-fragen button {
  justify-content: flex-start;
  height: auto;
  background: var(--surface-1, #fff);
  box-shadow: inset 0 0 0 1px var(--border-1);
  color: var(--blue-600);
  text-align: left;
  white-space: normal;
  padding-block: 6px;
}
.an-ergebnis-karte {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 320px;
}
.an-ergebnis-karte .ax-tabs {
  padding: 0 12px;
}
.an-ergebnis-karte .an-ergebnis {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.an-ergebnis > div {
  flex: 1;
}
.an-leer {
  display: grid;
  gap: 4px;
  place-content: center;
  justify-items: center;
  padding: 40px 0;
  text-align: center;
  color: var(--text-2);
}
.an-leer .ico {
  width: 20px;
  height: 20px;
  margin-bottom: 6px;
}
.an-leer p {
  margin: 0;
}
.an-aktionen {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.an-methode {
  margin: 0;
  font: var(--type-small);
  color: var(--text-2);
}
.an-methode dt {
  color: var(--text-1);
  font-weight: 600;
}
.an-methode dd {
  margin: 2px 0 0;
}
.an-ergebnis .diagramm-huelle {
  min-height: 200px;
}
@media (max-width: 900px) {
  .an-master {
    grid-template-columns: minmax(0, 1fr);
  }
  .an-panel {
    border-right: 0;
    border-bottom: 1px solid var(--border-1);
  }
  .an-liste {
    flex-direction: row;
    overflow-x: auto;
  }
  .an-liste li {
    flex: none;
    width: 240px;
  }
  .an-detail-bereich {
    padding: 16px;
  }
  .an-karten2 {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 500px) {
  .an-einstellungen {
    grid-template-columns: 1fr;
  }
}

/* Analysen: Kopf der Chat-Antwort (Name, Einstellungen als Chips), Hinweis nach Neuberechnung, Methode */
.an-tag {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 8px 0 4px;
}
.an-tag__l {
  font: var(--type-label-caps);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-3);
}
.an-tag__l--abstand {
  margin-left: 8px;
}
.an-param {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.an-param select,
.an-param input {
  font: inherit;
  color: inherit;
  background: transparent;
  border: none;
  border-bottom: 1px dashed var(--border-1);
  padding: 0;
  cursor: pointer;
}
.an-param input {
  width: 12ch;
  cursor: text;
}
.an-kopf[aria-busy="true"] {
  opacity: 0.6;
}
.an-hinweis {
  margin: 2px 0 0;
  font: var(--type-small);
  color: var(--text-3);
}
.methode {
  font: var(--type-small);
  color: var(--text-2);
  background: var(--surface-2, var(--gray-50));
  border-radius: var(--radius-2);
  padding: 8px 10px;
  margin-top: 6px;
}

/* ===================== Datenbestand ===================== */
/* Datenbestand */
.datenbestand {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 0.4rem 1rem 3rem;
}
.datenbestand .al-kopf {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
}
.datenbestand .hinweis-inline {
  color: var(--schwach);
  font-size: 0.85rem;
  flex: 1;
}
.datenbestand td.werteliste {
  white-space: normal;
  max-width: 40rem;
}

/* ===================== Segmente: Übersicht, Bearbeiten-Modus, Picker, aktives Segment ===================== */
/* Segmente: Übersichts-Leiste + Segment-Builder-Canvas (Scheibe 5). `flex:1;min-height:0` seit der
   so-*-Übersicht (Politur) unconditional nötig, nicht nur im Bearbeiten-Modus: `.so-body{flex:1;min-height:0}`
   (11-segment-overview.css, unverändert seit Scheibe 1) braucht einen höhenbegrenzten Elternrahmen, damit
   `.so-list{overflow:auto}` tatsächlich intern scrollt, statt dass `.seite` die ganze Seite scrollt und der
   `.so-hd`-Tabellenkopf/das `.so-prev`-Panel mit wegwandern. */
.segmente {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 0.4rem 1rem 3rem;
  flex: 1;
  min-height: 0;
}
/* .al-kopf hier absichtlich NICHT mehr gestylt (anders als bei den anderen Seiten oben/unten) — die
   Übersichts-Kopfzeile nutzt seit der so-*-Politur die unveränderte Design-System-Klasse .so-head
   (11-segment-overview.css); .al-kopf bleibt nur als Test-Selektor-Anker auf demselben Element (s.
   segmente.ts). Eine `.segmente .al-kopf`-Regel hier wäre spezifischer als `.so-head` und würde dessen
   Layout überschreiben. .hinweis-inline entfällt hier ersatzlos (der Untertitel ist jetzt der Design-
   System-eigene `.page-sub`, wie im Mockup) — anders als bei den übrigen Seiten oben/unten, die ihn
   weiterhin brauchen. */
/* Bearbeiten-Modus (Segment-Builder): füllt die volle verfügbare Höhe randlos, statt wie die Übersicht
   oben mit Abstand zu beginnen und unten auszulaufen — s. .seite/.segment-builder-Kommentar unten. */
.segmente.segmente--bauen {
  padding: 0;
  gap: 0;
}
/* .segment-leiste: nur noch vom Dashboard-Bearbeiten-Modus genutzt (dashboard.ts) — der Segment-Builder
   hat seine eigene Werkzeugleiste (sg-toolbar) jetzt selbst gebaut, s. Kommentar bei .segment-builder unten. */
.segment-leiste {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* .segment-liste/.segment-karte/.segment-karte-kopf/.segment-bedingungen/.segment-aktionen entfielen mit
   der so-*-Übersicht (Politur) ersatzlos — die Karten-Liste ist jetzt die Design-System-eigene
   so-list/so-row-Tabelle (11-segment-overview.css, s. segmente.ts). .segment-groessen (Kachel-
   Größenanzeige in dashboard.ts) entfiel ebenso — Politur „Dashboard-Kachel im sg-stat-Styling wie der
   Ergebnis-Inspektor", nutzt jetzt .sg-stats/.sg-stat aus 06-segment-builder.css statt einer eigenen Regel. */

/* Segment-Picker (Chat-Kopf, Scheibe 7) — natives <dialog> wie Katalog/Baustein-Info */
/* Design-Migration Scheibe 5: Rahmen/Kopf kommen jetzt von ax-dialog/ax-dialog__head, die Liste von den
   design-system-eigenen sp-head/sp-row-Regeln (design-system/css/08-segment-picker.css, per <link> geladen)
   — .sp-dialog/.sp-kopf/.sp-zeile/.sp-groesse tragen keine eigene Optik mehr, Klassennamen bleiben nur als
   Test-Selektor-Anker (test-e2e/segmente.spec.ts, dashboards.spec.ts referenzieren .sp-dialog/.sp-zeile). */

/* Aktives Segment als Chat-Datenbasis (Scheibe 7) */
.segment-anzeige {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

/* ===================== Dashboards: Seitenleiste, 2D-Kachel-Grid, Griffe, Ghost, Responsive ===================== */
/* Dashboards (Design-Migration Politur 4): feste Seitenleiste (Mockup db-*) statt Übersicht/Detail-Wechsel —
   .panel/.ax-section/.hrow teilen sich Optik mit Segment-Builder-Leiste bzw. Chat-Verlauf, hier nur das
   eigene Wurzel-Layout. .dash-raster/.dash-kachel/.dash-kachel-werkzeuge tragen keine eigene Optik mehr
   (das übernimmt db-grid/db-w/db-w__tools aus design-system/10-dashboard.css) — Klassennamen bleiben nur
   als Test-Selektor-Anker (test-e2e/dashboards.spec.ts referenziert sie direkt). */
.dashboards {
  display: flex;
  align-items: stretch;
  flex: 1;
  min-height: 0;
}

/* Freies 2D-Kachel-Grid (Politur 2026-09-28, Nutzer-Wunsch: Drag & Resize statt fester Auto-Flow-Reihenfolge
   mit +/−-Breite-Knöpfen, s. dashboard.ts-Kopfkommentar) — eigene Ergänzung, nicht im Mockup vorgesehen (das
   hat nur 1D-Umsortieren per HTML5-Drag&Drop, nie ein freies Grid), deshalb hier statt in der vendorierten
   design-system/10-dashboard.css. Einzige Quelle der Wahrheit für Spaltenzahl/Zeilenhöhe/Gap:
   dashboard-grid-logik.ts — dashboard.ts schreibt sie als --db-cols/--db-row-h/--db-gap auf .dash-raster,
   hier nur var(...) mit denselben Werten als Fallback für den allerersten Sekundenbruchteil vor dem JS. */
.dash-raster.db-grid {
  position: relative;
  grid-template-columns: repeat(var(--db-cols, 12), minmax(0, 1fr));
  grid-auto-rows: var(--db-row-h, 24px);
  gap: var(--db-gap, 12px);
}
/* Bezugspunkt für die absolut positionierten Größe-ändern-Griffe (.db-w__resize): ohne ihn lägen alle Griffe aller Kacheln
   in der unteren rechten Ecke des Rasters — bei mehr als einer Kachel ließ sich keine mehr vergrößern. */
.dash-kachel {
  position: relative;
}
.dash-kachel.is-dragging {
  z-index: 3;
  opacity: 0.85;
  pointer-events: none;
}
/* Ziehgriff im Kopf (Politur 2026-09-28) — Anzeige/Verstecken übernimmt schon die vendorierte Regel
   .db-grid.is-edit .db-w__handle{display:flex} (dieselbe is-edit-Klasse, dasselbe Element), hier nur Größe/
   Fokus-Stil ergänzt. */
.db-w__handle {
  width: 20px;
  height: 20px;
  justify-content: center;
}
.db-w__handle svg {
  width: 14px;
  height: 14px;
}
.db-w__handle:active {
  cursor: grabbing;
}
.db-w__handle:focus-visible,
.db-w__resize:focus-visible {
  outline: 2px solid var(--blue-500);
  outline-offset: 1px;
}
/* Größe-ändern-Griffe: rechter/unterer Rand + Ecke unten rechts, wie im Auftrag verlangt (links/oben/übrige
   Ecken bewusst nicht — MVP-Umfang, Nutzer-Entscheidung). Ausreichend große Trefferfläche (brief: 8–12px
   sichtbar, mehr Trefferfläche) über Padding auf einer größeren unsichtbaren Box statt eines 1px-Randes. */
.db-w__resize {
  display: none;
  position: absolute;
}
.db-grid.is-edit .db-w__resize {
  display: block;
}
.db-w__resize--r {
  top: 8px;
  right: -4px;
  bottom: 24px;
  width: 10px;
  cursor: ew-resize;
}
.db-w__resize--b {
  left: 8px;
  right: 24px;
  bottom: -4px;
  height: 10px;
  cursor: ns-resize;
}
.db-w__resize--br {
  right: -4px;
  bottom: -4px;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
}
.db-w__resize:hover {
  background: var(--blue-100);
}
/* Zellen-Hintergrundraster, die GANZE Bearbeiten-Sitzung sichtbar (nicht nur während einer Geste, Nutzer-
   Wunsch: „der Canvas soll sich in ein Grid umschalten") — Spalten als echte Grid-Zellen (dasselbe Template
   wie .db-grid, damit sie bei fluiden Spalten pixelgenau passen), Zeilenlinien als Hintergrund-Verlauf mit
   fester Periode (die Zeilenhöhe IST fest, ein Verlauf ist hier deshalb genauso pixelgenau wie echte Zellen,
   aber ohne unbekannt viele Zeilen-Elemente im DOM erzeugen zu müssen). */
.db-grid-overlay {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 0;
  grid-template-columns: repeat(var(--db-cols, 12), minmax(0, 1fr));
  gap: var(--db-gap, 12px);
  pointer-events: none;
  background-image: repeating-linear-gradient(
    to bottom,
    var(--blue-200) 0,
    var(--blue-200) 1px,
    transparent 1px,
    transparent calc(var(--db-row-h, 24px) + var(--db-gap, 12px))
  );
}
.db-grid-overlay span {
  background: var(--blue-50);
  border-left: 1px dashed var(--blue-200);
  border-right: 1px dashed var(--blue-200);
}
.dash-raster.is-edit .db-grid-overlay {
  display: grid;
}
.dash-raster.is-edit .dash-kachel {
  z-index: 1;
}
/* Platzhalter (Ghost): zeigt die Zielzelle während Verschieben/Größe-ändern — echtes Grid-Item (nicht
   absolut positioniert), damit grid-column/row exakt dieselbe Zelle trifft wie bei den Kacheln selbst. */
.db-ghost {
  background: var(--blue-100);
  border: 2px dashed var(--blue-500);
  border-radius: var(--radius-2);
  z-index: 2;
  pointer-events: none;
}
/* Kachel-Inhalt während der GANZEN Bearbeiten-Sitzung nicht interaktiv (brief: "damit Drag nicht mit Kachel-
   Interaktionen kollidiert") — Kopf/Werkzeuge/Griffe bleiben klickbar, nur .ax-card__body (Zahlen/Diagramm/
   Tabelle) wird stillgelegt. */
.dash-raster.is-edit .ax-card__body {
  pointer-events: none;
}

@media (max-width: 700px) {
  /* Responsive (Politur 2026-09-28): einspaltig, kein freies Ziehen mehr (auf einem Telefon ist Drag/Resize
     mit dem Finger fummelig) — stattdessen bleiben nur die Hoch-/Runter-Knöpfe aus der Werkzeugzeile übrig
     (einfaches Umsortieren), Zieh-/Resize-Griffe und das Hintergrundraster werden ausgeblendet. */
  .dash-raster.db-grid {
    grid-template-columns: 1fr !important;
  }
  .dash-kachel {
    grid-column: 1 / -1 !important;
  }
  .db-w__handle,
  .db-w__resize,
  .db-grid-overlay {
    display: none !important;
  }
}
@media (min-width: 701px) {
  .dash-kachel-werkzeuge button[title^="Nach oben"],
  .dash-kachel-werkzeuge button[title^="Nach unten"] {
    display: none;
  }
}

/* ===================== Segment-Builder: Bausteine-Leiste, Canvas, Knoten, Kanten, Eigenschaften ===================== */
/* Design-Migration Politur 2 (2026-09-26): Nutzer hat die frühere Zurückstellung der Bausteine-Leiste
   (sg-palette) ausdrücklich aufgehoben — Leinwand jetzt so wie im Mockup: Leiste links zum Ziehen/Klicken,
   volle Höhe statt fester 30rem, Werkzeugleiste/Zoom auf die echten sg-*-Klassen umgestellt (Optik dafür
   bereits vollständig in design-system/06-segment-builder.css, hier nur wenige ergänzende Regeln unten):
   .sk-canvas/.sk-name/.sk-eigenschaften/.sk-status bleiben als Klassennamen erhalten, weil test-e2e-Locators
   sie noch referenzieren, tragen aber keine eigene Optik mehr — das übernehmen sg-canvas/ax-input/
   sg-inspector/sg-toolbar .sum). sk-*-Klassennamen/Struktur der Knoten/Ports/Kanten selbst bleiben
   unverändert (dichter Maus-/SVG-Event-Code, s. segment-canvas.ts) — ein Umbenennen auf sg-node/sg-port
   wäre dort riskanter als der Nutzen. Politur 12 hatte hier nur den Daten-Knoten-Sonderfall (immer 100 %
   des Bestands) gebaut, weil `SegmentAuswertung.jeKnoten` damals nur den Ergebnis-Knoten lieferte — Politur
   13 hat den Compiler erweitert (eine Zeile je Knoten, `SegmentBaustein.knotenIds`), seitdem zeigt JEDER
   Knoten seine Fußzeile, sobald der Graph vollständig kompiliert (ENTSCHEIDUNGEN.md „offener Punkt 1" damit
   erledigt). Echte design-system-Klassen (sg-node__foot/__unit/__bar) direkt verwendet statt sk-*-
   Retokenisierung, weil dieses Fußzeilen-Element neu ist (kein Test-Selektor-Altlast). */
.segment-builder {
  display: flex;
  align-items: stretch;
  flex: 1;
  min-height: 0;
}
.sk-canvas {
  outline: none;
}
.sk-canvas:active {
  cursor: grabbing;
}
.sk-viewport {
  position: absolute;
  inset: 0;
  transform-origin: 0 0;
}
/* pointer-events: none auf der vollflächigen Schicht, damit sie Klicks auf Kanten darunter nicht
   abfängt — nur die einzelnen Knoten-Boxen (unten) sollen wieder klickbar sein. */
.sk-knotenschicht {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.sk-kanten {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.sk-knoten {
  position: absolute;
  pointer-events: auto;
  background: var(--surface-panel);
  border: 1.5px solid var(--border-2);
  border-radius: var(--radius-3);
  box-shadow: var(--elev-2);
  cursor: grab;
  user-select: none;
}
.sk-knoten.sk-ausgewaehlt {
  border-color: var(--blue-500);
  box-shadow:
    0 0 0 2px var(--blue-500),
    var(--elev-2);
}
.sk-knoten-daten {
  border-left: 4px solid var(--gray-800);
}
.sk-knoten-filter {
  border-left: 4px solid var(--blue-500);
}
.sk-knoten-logik {
  border-left: 4px solid var(--violet-500);
}
.sk-knoten-aufbereitung {
  border-left: 4px solid var(--teal-500);
}
.sk-knoten-ergebnis {
  border-left: 4px solid var(--ink);
}
/* Auswertungs-Knoten (kundendatenbank-auswertungsknoten, Slice 3): eigene Randfarbe — pink-500 ist im
   Segment-Builder noch unbelegt (Logik hat schon violet-500), aber Teil derselben --chart-*-Palette wie die
   spätere Diagramm-Darstellung (Slice 4, --chart-2). */
.sk-knoten-analyse {
  border-left: 4px solid var(--pink-500);
}
/* Merkmal-Filter (kundendatenbank-merkmal-filter, Slice 4): eigene Randfarbe, damit ein Merkmal-Baustein
   auf den ersten Blick von einem rohen Filter unterscheidbar bleibt (Gate 1 Mockup) — zwei Klassen sind
   spezifischer als die einzelne .sk-knoten-filter-Regel oben, gewinnt also unabhängig von der Ladereihenfolge. */
.sk-knoten-filter.sk-knoten-merkmalfilter {
  border-left-color: var(--orange-500);
}
/* Merkmal-Bausteine in der Leiste (Politur, auf Nutzer-Wunsch in dieselbe Filter-Liste zusammengeführt statt
   einer eigenen Gruppe): dasselbe Orange wie der Knoten-Rand oben, einzige verbleibende Unterscheidung zu
   einem rohen Feld-Filter (dessen Icon-Kreis .sg-ic--filter blau bleibt, s. 06-segment-builder.css). */
.sg-ic--merkmal {
  background: var(--orange-500);
}
/* Auswertung-Baustein in der Leiste (Slice 3): dasselbe Pink wie der Knoten-Rand oben; .sg-ic--analyse ist
   in 06-segment-builder.css noch nicht definiert (nur data/filter/logic/result/prep). */
.sg-ic--analyse {
  background: var(--pink-500);
}
/* Kaufzeitraum-Filter (kundendatenbank-segmentfelder-erweiterung, Politur 2026-09-28): eigene Randfarbe wie
   Merkmal-Filter oben — gold-500 ist im Segment-Builder noch unbelegt. Kein Segmentfeld, deshalb kein
   Gegenstück in der datengetriebenen Filter-Liste, nur der feste Leisten-Eintrag (segment-canvas.ts). */
.sk-knoten-filter.sk-knoten-zeitraumfilter {
  border-left-color: var(--gold-500);
}
.sg-ic--zeitraum {
  background: var(--gold-500);
}
.sk-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  padding: 0 0.5rem;
  height: 32px;
  font: var(--type-card-title);
  border-bottom: 1px solid var(--border-1);
}
.sk-x {
  border: none;
  background: none;
  padding: 0 0.2rem;
  font-size: 1rem;
  line-height: 1;
  color: var(--gray-700);
}
.sk-x:hover {
  color: var(--red-500);
  border: none;
}
/* .sk-knoten hat eine fest berechnete Höhe (knotenHoehe(), keine natürliche Inhaltsfließhöhe wie im Mockup),
   deshalb muss die Fußzeile hier an den unteren Rand geheftet werden statt im normalen Fluss zu stehen. */
.sk-knoten .sg-node__foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
}
/* Körper (Politur 17/18): design-system .sg-node__body ist bewusst nur min-height (wächst mit dem Text) —
   passt nicht zur fest berechneten Boxhöhe hier. Zweizeilig mit Umbruch statt einzeilig mit Ellipsis (Politur
   18, Nutzer-Wunsch) — bei mehr als zwei Zeilen bricht die dritte per line-clamp mit „…" ab, voller Text
   bleibt als Tooltip erreichbar. */
.sk-knoten .sg-node__body {
  height: 50px;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.sk-port {
  position: absolute;
  width: 12px;
  height: 12px;
  margin-top: -6px;
  border-radius: 50%;
  background: var(--surface-panel);
  border: none;
  box-shadow: inset 0 0 0 2px var(--gray-600);
  cursor: crosshair;
}
.sk-port-ein {
  left: -7px;
}
.sk-port-aus {
  right: -7px;
}
.sk-port:hover {
  box-shadow: inset 0 0 0 2px var(--blue-500);
  background: var(--blue-50);
}

.sk-kante {
  fill: none;
  stroke: var(--gray-600);
  stroke-width: 2px;
  pointer-events: stroke;
  cursor: pointer;
}
.sk-kante:hover {
  stroke: var(--blue-500);
}
.sk-kante.sk-ausgewaehlt {
  stroke: var(--blue-500);
  stroke-width: 2.5px;
}
.sk-kante.sk-gummiband {
  stroke-dasharray: 5 4;
  stroke: var(--blue-400);
  pointer-events: none;
}

.sk-eigenschaften {
  padding: 0.7rem 0.8rem;
  font-size: 0.85rem;
} /* sg-inspector liefert Breite/Rand/Scroll */
.sk-formular {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.4rem;
}
.sk-formular label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.8rem;
  color: var(--text-3);
}
.sk-formular select,
.sk-formular input {
  font: inherit;
  border: 1px solid var(--border-1);
  border-radius: var(--radius-2);
  padding: 0.3rem 0.4rem;
}
.sk-kriterien {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.sk-kriterium {
  display: flex;
  gap: 0.3rem;
  align-items: center;
}
/* Merkmal-Filter-Ausprägungen (Slice 4): Checkbox + Bezeichnung nebeneinander statt der für .sk-formular
   label sonst üblichen gestapelten Spalte (Feld-Name über dem Eingabe-Element). */
.sk-ausp-liste {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  max-height: 10rem;
  overflow: auto;
}
.sk-formular label.sk-ausp-zeile {
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: var(--text-1);
}
.sk-kriterium select {
  flex: 1;
  min-width: 0;
}
/* .sk-status sitzt jetzt als .sum in der sg-toolbar (Optik von dort) — hier nur die ID-Regeln aus dem
   Mockup (dort an #sgSum), auf unsere Klasse übertragen: nimmt den Rest der Zeile ein, kein Umbruch,
   verschwindet auf schmalen Fenstern zugunsten der Knöpfe rechts. */
.sg-toolbar .sk-status {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (max-width: 1640px) {
  .sg-toolbar .sk-status {
    visibility: hidden;
  }
}
.sk-kopf-knoepfe {
  display: flex;
  gap: 0.2rem;
  align-items: center;
}
.sk-i,
.sk-x {
  border: none;
  background: none;
  padding: 0 0.2rem;
  font-size: 1rem;
  line-height: 1;
  color: var(--gray-700);
}
.sk-i:hover {
  color: var(--blue-500);
  border: none;
}
.sk-feld-wahl {
  width: 100%;
  text-align: left;
}

/* ===================== Dialoge: Merkmal-Katalog, Baustein-Info, Auswertungs-Modal ===================== */
/* Merkmal-Katalog- und Baustein-Info-Dialog (Scheibe 6) — natives <dialog>, kein eigener Modal-Unterbau.
   Design-Migration Scheibe 4: Rahmen/Kopf-Chrome kommt jetzt von ax-dialog/ax-dialog--wide/ax-dialog__head
   (s. segment-katalog.ts/segment-info.ts) — hier nur noch das, was ax-dialog nicht abdeckt (sticky Kopf,
   die restliche Listen-/Zeilen-Optik), auf die neuen Tokens umgestellt statt umbenannt: die 3-spaltige
   Kategorien|Liste|Vorschau-Struktur des Mockups (mk-nav/mk-list/mk-prev) wird bewusst nicht nachgebaut
   (gleiche Abwägung wie beim Diagramm-Motor in Scheibe 2 — ersetzt eine funktionierende, einfachere Liste
   durch ein größeres, neues Bauteil ohne neuen Nutzen für diese Migration). */
.mk-kopf,
.bi-kopf {
  position: sticky;
  top: 0;
  background: var(--surface-panel);
}
.mk-suche {
  flex: 1;
  font: inherit;
  font-size: 0.9rem;
  border: 1px solid var(--border-1);
  border-radius: var(--radius-2);
  padding: 0.3rem 0.5rem;
}
.mk-liste {
  padding: 0.5rem 0.8rem 1rem;
  overflow: auto;
  max-height: calc(80vh - 3.2rem);
}
.mk-h4 {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-3);
  margin: 0.8rem 0 0.3rem;
}
.mk-h4:first-child {
  margin-top: 0;
}
.mk-zeile {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.3rem;
  border-radius: var(--radius-2);
  cursor: pointer;
}
.mk-zeile:hover {
  background: var(--surface-hover);
}
.mk-stern {
  border: none;
  background: none;
  padding: 0;
  font-size: 1rem;
  line-height: 1;
  color: var(--orange-500);
}
.mk-label {
  flex: 1;
}
.mk-typ {
  font-size: 0.75rem;
  color: var(--text-3);
}
.mk-verteilung {
  margin: 0 0 0.4rem 1.7rem;
  padding: 0.3rem 0.5rem;
  background: var(--surface-app);
  border-radius: var(--radius-2);
  font-size: 0.8rem;
}
.mk-verteilung-zeile {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.1rem 0;
}

.bi-inhalt {
  padding: 0.8rem 1rem 1.1rem;
}
.bi-inhalt h4 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}
.bi-inhalt dl {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.3rem 0.8rem;
}
.bi-inhalt dt {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-3);
  white-space: nowrap;
}
.bi-inhalt dd {
  margin: 0;
  font-size: 0.9rem;
}

/* ===================== Ladedialog ===================== */
/* Ladedialog (dom.ts mitLadedialog): erscheint nach 200 ms bei längeren Aufrufen */
.ladedialog {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(28, 28, 28, 0.18);
  z-index: 50;
}
.ladedialog-karte {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  background: var(--karte);
  border: 1px solid var(--rand);
  border-radius: 0.75rem;
  padding: 1rem 1.4rem;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
  font-size: 0.95rem;
}
.ladedialog-kreis {
  width: 1.1rem;
  height: 1.1rem;
  border: 2px solid var(--rand);
  border-top-color: var(--akzent);
  border-radius: 50%;
  animation: drehen 0.8s linear infinite;
}
@keyframes drehen {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ladedialog-kreis {
    animation: none;
    border-top-color: var(--akzent);
  }
}
/* Katalog-Kachel im Dashboard: die Kachel füllt ihre Rasterzellen und das Diagramm den Rest unter dem Kopf
   (sonst bestimmt die Zeilenzahl des Diagramms die Höhe und es ragt über die Kachel hinaus). */
.dash-kachel--katalog {
  display: flex;
  align-self: stretch;
}
.dash-kachel--katalog > .ax-card {
  flex: 1;
  min-width: 0;
  min-height: 0;
}
.dash-kachel--katalog .ax-card__body {
  flex: 1;
  min-height: 0;
}
.dash-kachel--katalog .diagramm-huelle {
  flex: 1;
  min-height: 0;
  height: auto;
}
/* Tabelle in der Kachel (Chat-Abfrage ohne Diagramm): füllt den Rest und scrollt in der Kachel, statt sie zu sprengen. */
.dash-kachel--katalog .ax-result__table {
  flex: 1;
  min-height: 0;
  overflow: auto;
}

/* RFM-Raster (shared/analyse-raster.ts): eine Kachel je Segment, höchstens vier Spalten (Mindestbreite 96px, bei
   schmalen Behältern weniger Spalten). Farben nur aus den Chart-Tokens, Reihenfolge = Rangordnung der Segmente. */
.an-raster {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max(96px, calc((100% - 18px) / 4)), 1fr));
  gap: 6px;
  padding: 6px; /* Rand = Abstand zwischen den Kacheln */
}
.an-raster__zelle {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 64px;
  padding: 8px;
  border-radius: var(--radius-2);
  color: var(--text-on-accent);
}
.an-raster__zelle b {
  font: var(--fw-semibold) 18px / 1.1 var(--font-sans);
}
.an-raster__zelle span {
  font: var(--type-small);
}
.an-raster__zelle--s0 {
  background: var(--chart-1);
}
.an-raster__zelle--s1 {
  background: color-mix(in srgb, var(--chart-1) 80%, var(--surface-1, #fff));
}
.an-raster__zelle--s2 {
  background: var(--chart-2);
}
.an-raster__zelle--s3 {
  background: color-mix(in srgb, var(--chart-2) 80%, var(--surface-1, #fff));
}
/* Lesbarkeit: Weiß trägt nur auf den kräftigen Farben (Blau, Pink, abgedunkeltes Türkis); Amber und die blassen
   Segmente (Schlafend, Verloren — bewusst zurückgenommen) bekommen dunkle Schrift. */
.an-raster__zelle--s4 {
  background: color-mix(in srgb, var(--chart-4) 80%, var(--gray-950));
}
.an-raster__zelle--s5 {
  background: var(--chart-3);
  color: var(--gray-950);
}
.an-raster__zelle--s6 {
  background: var(--gray-300);
  color: var(--gray-950);
}
.an-raster__zelle--s7 {
  background: var(--gray-200);
  color: var(--gray-900);
}
/* In der Dashboard-Kachel füllt das Raster die Höhe unter dem Kopf; die Zellen strecken sich mit. */
.dash-kachel--katalog .an-raster {
  flex: 1;
  align-content: stretch;
}

/* Kohorten-Heatmap (shared/analyse-heatmap.ts): Tabelle Kohorte × Monate seit Erstkauf. Die Stufe 1…10 ist der
   Wert relativ zum Maximum der ganzen Matrix (Mischung aus --chart-1 und dem Panel-Hintergrund, keine Inline-Styles);
   leere Zellen (Monat noch nicht abgeschlossen) sind grau und tragen keine Zahl. Schmale Behälter scrollen waagerecht. */
.an-heat-huelle {
  overflow-x: auto;
  padding: 4px 0;
}
.an-heat {
  border-collapse: collapse;
  width: 100%;
  font: var(--type-small);
  font-variant-numeric: tabular-nums;
}
.an-heat th {
  padding: 3px 6px;
  font-weight: 400;
  color: var(--text-3);
  text-align: center;
  white-space: nowrap;
}
.an-heat thead th:first-child,
.an-heat tbody th {
  text-align: left;
}
.an-heat tbody th {
  color: var(--text-2);
}
.an-heat__kunden {
  padding: 3px 8px;
  color: var(--text-2);
  text-align: right;
}
.an-heat__zelle {
  min-width: 44px;
  padding: 6px 4px;
  border: 2px solid var(--surface-panel);
  border-radius: var(--radius-2);
  text-align: center;
  color: var(--text-1);
}
.an-heat__zelle--leer {
  background: var(--gray-100);
}
.an-heat__zelle--s0 {
  background: var(--gray-50);
}
.an-heat__zelle--s1 {
  background: color-mix(in srgb, var(--chart-1) 10%, var(--surface-panel));
}
.an-heat__zelle--s2 {
  background: color-mix(in srgb, var(--chart-1) 20%, var(--surface-panel));
}
.an-heat__zelle--s3 {
  background: color-mix(in srgb, var(--chart-1) 30%, var(--surface-panel));
}
.an-heat__zelle--s4 {
  background: color-mix(in srgb, var(--chart-1) 40%, var(--surface-panel));
}
.an-heat__zelle--s5 {
  background: color-mix(in srgb, var(--chart-1) 50%, var(--surface-panel));
}
.an-heat__zelle--s6 {
  background: color-mix(in srgb, var(--chart-1) 60%, var(--surface-panel));
}
/* Lesbarkeit (Kontrast ≥ 4,5 : 1): dunkle Schrift trägt bis Stufe 8 (80 % Blau, ≈ 5 : 1); zwischen 80 % und reinem
   Blau trägt weder dunkle noch weiße Schrift, deshalb springt Stufe 9 auf das volle Blau mit weißer Schrift
   (≈ 4,7 : 1) und Stufe 10 wird noch dunkler (Blau mit etwas Schwarz) — die Reihe bleibt monoton dunkler. */
.an-heat__zelle--s7 {
  background: color-mix(in srgb, var(--chart-1) 70%, var(--surface-panel));
}
.an-heat__zelle--s8 {
  background: color-mix(in srgb, var(--chart-1) 80%, var(--surface-panel));
}
.an-heat__zelle--s9 {
  background: var(--chart-1);
  color: var(--text-on-accent);
}
.an-heat__zelle--s10 {
  background: color-mix(in srgb, var(--chart-1) 80%, var(--gray-950));
  color: var(--text-on-accent);
}
.an-heat__hinweis {
  margin: 6px 0 0;
  font: var(--type-small);
  color: var(--text-3);
}
/* In der Dashboard-Kachel scrollt die Heatmap in der Kachelhöhe statt sie zu sprengen. */
.dash-kachel--katalog .an-heat-huelle {
  flex: 1;
  min-height: 0;
  overflow: auto;
}

/* Kennzahl (shared/analyse-kennzahl.ts): große Hauptzahl, darunter die übrigen Kennzahlen als kleine Blöcke.
   Die Blöcke brechen je nach Breite um (Mindestbreite 104px); in der Dashboard-Kachel steht alles zentriert in der Kachelhöhe. */
.an-kennzahl {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 4px 0;
}
.an-kennzahl__haupt {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.an-kennzahl__wert {
  font-size: 2.25rem;
  line-height: 1.1;
}
.an-kennzahl__weitere {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
}
.an-kennzahl__block {
  min-width: 0;
}
/* In der Chat-Karte: gleicher Randabstand wie der Kartenkopf (ax-result__head: 12px links). */
.ax-result .an-kennzahl {
  padding: 8px 12px 16px;
}
.dash-kachel--katalog .an-kennzahl {
  flex: 1;
  justify-content: center;
  min-height: 0;
  overflow: auto;
}
/* Kompakt in der Kachel: kleinere Hauptzahl, breitere Blöcke (drei je Zeile, Beschriftung darf umbrechen), damit alle
   sechs Blöcke in die Mindestgröße passen. */
.dash-kachel--katalog .an-kennzahl {
  gap: 8px;
}
.dash-kachel--katalog .an-kennzahl__wert {
  font-size: 1.75rem;
}
.dash-kachel--katalog .an-kennzahl__weitere {
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: 6px;
}
.dash-kachel--katalog .an-kennzahl__block {
  padding: 4px 8px;
}

/* „Als Segment…" aus der Analyse-Karte: Auswahl der Segmente. Der Hinweis steht linksbündig über der Liste
   (.hinweis zentriert sonst mit großem Abstand — gedacht für leere Seiten, nicht für Dialoge). */
.sa-dialog .hinweis {
  text-align: left;
  margin: 0;
}
.sa-liste {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.sa-zeile {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

/* Analysenseite: Datenbasis (Segment oder gesamter Bestand) unter den Einstellungen */
.an-datenbasis {
  margin-top: 12px;
}
.an-datenbasis__wahl {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}

/* Info-Icon (i) an Ergebnisspalten mit Erklärtext (shared/spalten-info.ts): Tabellenkopf, KPI-Karte; Text als Tooltip. */
.spalten-info {
  display: inline-flex;
  align-items: center;
  vertical-align: -2px;
  margin-left: 4px;
  color: var(--gray-600, #738091);
  cursor: help;
  border-radius: 50%;
}
.spalten-info:hover {
  color: var(--blue-600, #2b6cb0);
}
.spalten-info:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring, 0 0 0 2px #2b6cb0);
}
.spalten-info svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Beta-Kennzeichnung in der Kopfzeile (Nutzer-Wunsch 2026-10-06): gut sichtbar, aus den Warnfarben des Design-Systems. */
.beta-badge {
  display: inline-flex;
  align-items: center;
  margin-left: 4px;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background: var(--warning);
  color: #fff;
  font: 700 12px / 1 var(--font-sans);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Eigener Tooltip (shared/tooltip.ts): sofort sichtbar, im Dunkel der App-Beschriftung; Popover = oberste Ebene, auch über modalen Fenstern. */
.kdb-tooltip {
  position: fixed;
  inset: auto;
  margin: 0;
  max-width: 340px;
  padding: 8px 12px;
  border: 0;
  border-radius: var(--radius-4);
  background: var(--ink);
  color: #fff;
  font: var(--fw-regular, 400) var(--fs-12) / 1.45 var(--font-sans);
  white-space: pre-line;
  box-shadow: var(--elev-4);
  pointer-events: none;
  overflow: visible;
}

/* Verwaltung der Benutzer und ihrer Mandanten (pflege/benutzer.ts) — Bausteine aus dem Design-System (ax-card, ax-table, ax-field, ax-tag) */
.benutzer-seite {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 0.4rem 1rem 3rem;
}
.benutzer-seite .al-kopf {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
}
.benutzer-seite .hinweis-inline {
  color: var(--text-2);
  font: var(--type-small);
  flex: 1;
}
.benutzer-karten {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 1100px;
}
.benutzer-scroll {
  overflow-x: auto;
}
.benutzer-leer,
.benutzer-hinweis {
  margin: 0;
  color: var(--text-2);
  font: var(--type-small);
}
.benutzer-leer {
  padding: 16px 12px;
}
.benutzer-tabelle td {
  height: 52px;
}
.benutzer-tabelle th.haken,
.benutzer-tabelle td.haken {
  text-align: center;
  width: 1%;
}
.benutzer-tabelle th.haken .ax-tag {
  margin-left: 6px;
}
.benutzer-tabelle td.haken.inaktiv {
  opacity: 0.5;
}
.benutzer-tabelle td.haken input {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--blue-500);
  cursor: pointer;
  vertical-align: middle;
}
.benutzer-tabelle td.haken input:disabled {
  cursor: not-allowed;
}
.benutzer-tabelle .benutzer-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: var(--fw-semibold);
  color: var(--text-1);
}
.benutzer-tabelle .benutzer-sub {
  font: var(--type-mono);
  color: var(--text-3);
  overflow: hidden;
  text-overflow: ellipsis;
}
.benutzer-tabelle .benutzer-gesehen {
  color: var(--text-2);
}
.benutzer-tabelle .benutzer-aktion {
  text-align: right;
}
.benutzer-status {
  margin-right: 0.5rem;
  color: var(--text-3);
  font: var(--type-small);
}
.benutzer-neu {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.benutzer-neu-zeile {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
}
.benutzer-neu-zeile .ax-field {
  flex: 1 1 220px;
}
.mandant-wahl button {
  display: block;
  margin: 0.5rem 0;
}
