:root {
  /* Optimizely Axiom Design System, Tokens ueber den MCP-Server
     @optiaxiom/mcp 3.0.8 abgerufen (20.08.2026). Der vollstaendige Satz liegt
     in docs/axiom-tokens.json -- die Namen unten sind die dortigen Token-Namen,
     damit nachvollziehbar bleibt, woher jeder Wert stammt.

     Die Akzentfarbe ist ein kraeftiges Limettengruen und traegt IMMER dunklen
     Text (fg.default darauf: 12,9:1). Weisser Text auf dieser Flaeche waere
     unlesbar -- das ist der Grund, warum unten ueberall --text als Schriftfarbe
     auf --accent-bg steht.

     Alle Paarungen sind nachgerechnet und erreichen mindestens 4,5:1; einzige
     Ausnahme ist fg.disabled, was bei deaktivierten Elementen so gewollt und
     von WCAG ausgenommen ist. */

  --bg: #F9FCF8;              /* bg.page */
  --panel: #FFFFFF;           /* bg.default */
  --panel-2: #EFF5EB;         /* bg.secondary */
  --line: #D8E4CB;            /* border.default */
  --line-soft: #E4F0DA;       /* border.secondary */

  --text: #202320;            /* fg.default */
  --muted: #484E46;           /* fg.secondary */
  --muted-2: #616755;         /* fg.tertiary */
  --disabled: #A1AC8D;        /* fg.disabled */

  --accent: #226B1E;          /* fg.link.default -- Akzent als SCHRIFT */
  --accent-bg: #ABFF44;       /* bg.accent -- Akzent als FLAECHE, dunkler Text */
  /* Die Schrift AUF der Akzentflaeche. In Axiom ist das --text, weil das
     Limettengruen hell ist. Als eigenes Token, damit White Labeling es
     umstellen kann: eine dunkle Markenfarbe -- Magenta, Marineblau -- braucht
     helle Schrift, und ohne diese Trennung waere jeder Knopf unlesbar.
     Der Standardwert aendert an Axiom nichts. */
  --accent-fg: var(--text);
  --accent-bg-hover: #99F141; /* bg.accent.hovered */
  --accent-subtle: #EEFFD9;   /* bg.accent.subtle */
  --pill: #D8E4CB;            /* bg.pill.default */

  --success-text: #226B1E;    /* fg.success.strong */
  /* Badge-Intents nach Axiom: subtile Flaeche plus passender Rand. */
  --bg-success-subtle: #EEFFD9;   /* bg.success.subtle */
  --border-success: #5F9B85;      /* border.success */
  --bg-warning-subtle: #FEF1C6;   /* bg.warning.subtle */
  --border-warning: #F79008;      /* border.warning */
  --bg-error-subtle: #FFDFE8;     /* bg.error.subtle */
  --bg-neutral: #F5F6F7;          /* bg.message.neutral */
  --warn-text: #B54707;       /* fg.warning.strong */
  --danger: #8F4764;          /* fg.error */
  --danger-border: #A95A77;   /* border.error */
  --info: #036988;            /* fg.information.strong */
  --focus: #197A94;           /* border.focus */

  /* maxSize. Die Breite, die ein einzelnes Eingabefeld hoechstens haben
     soll. Sie fehlten hier bisher, und deshalb lief ein Feld fuer einen
     Mandantennamen ueber 826 px -- eine Zeile, die niemand liest, weil das
     Auge den Anfang verliert. */
  --max-xs: 320px;
  --max-sm: 384px;
  --max-md: 448px;
  --max-lg: 512px;

  /* size. Die Hoehe der Bedienelemente. */
  --hoehe-md: 32px;
  --hoehe-lg: 40px;

  /* borderRadius */
  --radius-sm: 6px;
  --radius: 8px;              /* md */
  --radius-lg: 12px;
  --radius-full: 9999px;

  /* boxShadow */
  --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);

  /* zIndex. Nur der Wert, der gebraucht wird: die Toast-Schicht. Die uebrigen
     Ebenen dieser Anwendung (Topbar 10, Seitenspalte 20, Klappmenue 30) sind
     lokal und liegen weit darunter; der Dialog braucht keinen, weil
     `<dialog>.showModal()` den Top-Layer des Browsers nutzt. */
  --z-toast: 3010;            /* zIndex.toast */

  /* fontFamily. Die Grotesk B und Roboto Variable sind lizenzpflichtig und
     werden hier nicht nachgeladen -- die CSP verbietet externe Quellen. Der
     Stack steht trotzdem vollstaendig da: auf Rechnern, wo die Schriften
     installiert sind, greifen sie; sonst faellt es sauber auf system-ui. */
  --font-sans: "Die Grotesk B", "DI Grotesk B", "Roboto Variable", system-ui, sans-serif;
  --font-mono: "Roboto Mono Variable", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;

  font-synthesis: none;
}

* { box-sizing: border-box; }

/* [hidden] setzt nur display:none aus dem Browser-Stylesheet -- jede eigene
   display-Regel ueberstimmt das. .layout ist ein Grid, der Editor blieb
   dadurch beim Ansichtswechsel sichtbar. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--font-sans);
  background: var(--bg);
  font-size: 14px;
  line-height: 20px;
  color: var(--text);
  min-height: 100vh;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 22px;
  border-bottom: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.85);
  position: sticky;
  top: 0;
  z-index: 10;
  backdrop-filter: blur(8px);
}
.brand { display: flex; align-items: center; gap: 12px; }
.logo {
  background: var(--accent-bg);
  color: var(--accent-fg);
  font-weight: 800;
  padding: 8px 10px;
  border-radius: var(--radius);
  letter-spacing: 1px;
}
/* Traegt die Marke ein Bild statt des Kurzzeichens, ist das Kaestchen nur
   noch Rahmen: keine Flaeche, kein Innenabstand -- ein Logo bringt seinen
   eigenen mit. */
.logo-mit-bild { background: none; padding: 0; }
.logo-bild { display: block; max-height: 32px; max-width: 120px; object-fit: contain; }
.topbar h1 { font-size: 17px; margin: 0; }
.sub { margin: 0; font-size: 12px; color: var(--muted); }
.send-status { font-size: 12px; color: var(--muted); }
.send-status.on { color: var(--success-text); }
.send-status.off { color: var(--muted); }
.send-status.warn { color: var(--warn-text); }
.send-status.expired { color: var(--danger); }

/* --- Grundgeruest: Seitenleiste links, Inhalt rechts ---------------------
   Aufbau nach dem Axiom-Sidebar-Muster (NavHeader / NavBody / NavFooter).
   Das Benutzerkonto sitzt unten, wie es NavAccountItem dort vorsieht. */

.app-shell { display: flex; min-height: 100vh; }

.sidebar {
  width: 232px;
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-right: 1px solid var(--line);
  position: sticky;
  top: 0;
  height: 100vh;
  transition: width .14s ease;
}
.sidebar.collapsed { width: 64px; }
/* Nichts darf seitlich herausragen: der Umschaltknopf lag eingeklappt
   ausserhalb der Leiste, unter der Topbar-Ueberschrift -- einklappen ging,
   aufklappen nicht mehr. */
.sidebar { overflow: hidden; }
.sidebar.collapsed .nav-header {
  flex-direction: column;
  gap: 8px;
  padding: 12px 8px;
}
.sidebar.collapsed .sidebar-toggle { margin-left: 0; }
.sidebar.collapsed .nav-label,
.sidebar.collapsed .nav-header-text,
.sidebar.collapsed .nav-group-trigger,
.sidebar.collapsed .konto-text { display: none; }
.sidebar.collapsed .nav-item { justify-content: center; }

.nav-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 12px;
  border-bottom: 1px solid var(--line);
}
.nav-header-text { display: flex; flex-direction: column; min-width: 0; }
.nav-header-text strong { font-size: 14px; }
.nav-header-text small { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-toggle {
  margin-left: auto;
  width: 22px; height: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  cursor: pointer;
  position: relative;
  flex: none;
}
.sidebar-toggle::before {
  content: "";
  position: absolute; inset: 4px auto 4px 6px;
  width: 2px;
  background: var(--muted);
}

.nav-body { flex: 1; overflow-y: auto; padding: 10px 8px; }
.nav-group-trigger {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: var(--muted);
  padding: 8px 10px 4px;
}
.nav-list, .nav-group-content { display: flex; flex-direction: column; gap: 2px; }
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.nav-item:hover { background: var(--panel-2); }
.nav-item.active { background: var(--accent-subtle); font-weight: 600; }
/* Icon links; es traegt die Markierung mit, damit der aktive Eintrag auch bei
   eingeklappter Leiste erkennbar bleibt. */
.nav-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px; height: 18px;
  flex: none;
  color: var(--muted);
}
.nav-item.active .nav-icon { color: var(--accent); }
.nav-item:hover .nav-icon { color: var(--text); }
.nav-separator { border: none; border-top: 1px solid var(--line); margin: 10px 4px; }

.nav-footer { border-top: 1px solid var(--line); padding: 8px; position: relative; }
.nav-account-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px;
  border: none;
  border-radius: var(--radius);
  background: transparent;
  cursor: pointer;
  font: inherit;
  text-align: left;
}
.nav-account-item:hover { background: var(--panel-2); }
.konto-text { display: flex; flex-direction: column; min-width: 0; }
.konto-text strong { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.konto-text small { font-size: 11px; color: var(--muted); }
.avatar {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--accent-bg);
  color: var(--accent-fg);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
  flex: none;
}
.avatar.klein { width: 26px; height: 26px; font-size: 11px; }
.konto-menu {
  position: absolute;
  bottom: 100%; left: 8px; right: 8px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 4px;
  z-index: 20;
}
.konto-menu-item {
  display: block; width: 100%;
  padding: 8px 10px;
  border: none; border-radius: var(--radius-sm);
  background: transparent; color: var(--text);
  font: inherit; font-size: 13px; text-align: left; cursor: pointer;
}
.konto-menu-item:hover { background: var(--panel-2); }

.app-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.views { padding: 18px 22px 60px; }

.topbar-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }

@media (max-width: 760px) { .sidebar { width: 64px; } .sidebar .nav-label, .sidebar .nav-header-text, .sidebar .nav-group-trigger, .sidebar .konto-text { display: none; } }


/* Inhalt der Ansichten */
.layout {
  display: grid;
  grid-template-columns: minmax(360px, 1fr) minmax(300px, 380px);
  gap: 18px;
  padding: 18px 22px 60px;
  align-items: start;
  max-width: 1200px;
}
/* Ausgabe und Eingang stehen ganz unten ueber die volle Breite, nicht
   als dritte Spalte -- der Editor selbst bekommt dadurch mehr Platz. */
.output-col { grid-column: 1 / -1; }
@media (max-width: 1000px) { .layout { grid-template-columns: 1fr; } }

/* Verwaltungsseiten stehen einspaltig -- drei Spalten braucht dort niemand. */
/* --- Die Ansichten ---------------------------------------------------------
   `.views` traegt den Innenabstand, `.view` die Anordnung. **Ohne
   Breitenbegrenzung lief ein einspaltiges Formular auf 1130 px** -- ein
   Eingabefeld, das breiter ist als eine Bildschirmhaelfte, liest sich nicht
   mehr. Die Referenz loest das mit einer Klasse je Ansichtsart
   (`.verwaltung` 860 px, `.dashboard` 1200 px); hier heissen sie `schmal` und
   `breit`, weil sie nichts ueber den Inhalt behaupten, sondern ueber die
   Form.

   Der Abstand zwischen Karten steht hier, nicht an `.card`: eine Karte weiss
   nicht, ob eine zweite folgt. */
.view { display: flex; flex-direction: column; gap: 16px; }
.view > .card { margin-bottom: 0; }

/* Einspaltige Formulare und Listen. 860 px ist die Breite der Referenz. */
.view.schmal { max-width: 860px; }
/* Kacheln, Karten und Tabellen. */
.view.breit { max-width: 1240px; }

.topbar h1 { font-size: 17px; margin: 0; }
.topbar-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }

/* --- Verwaltungslisten --- */
.admin-liste { display: flex; flex-direction: column; gap: 8px; }
.admin-zeile {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 10px;
  padding: 10px 12px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.admin-zeile.inaktiv { opacity: .55; }
.admin-kopf { display: flex; align-items: center; gap: 10px; min-width: 0; }
.admin-text { display: flex; flex-direction: column; min-width: 0; }
.admin-text strong { font-size: 13px; }
.admin-text small { font-size: 11px; color: var(--muted); overflow-wrap: anywhere; }
.admin-aktionen { display: flex; flex-wrap: wrap; gap: 6px; }
.admin-aktionen .btn-ghost.danger { color: var(--danger); border-color: var(--danger-border); }
.admin-form {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 12px;
}
.admin-form h3 { margin: 0 0 12px; font-size: 13px; }

/* --- Anmeldeseite --- */
.auth-body { display: flex; align-items: center; justify-content: center; padding: 24px; }
.auth-karte {
  width: 100%; max-width: 380px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 24px;
}
.auth-marke { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.auth-marke h1 { font-size: 18px; margin: 0; }
.auth-knopf { width: 100%; margin-top: 6px; }
.auth-fehler { color: var(--danger); font-size: 13px; min-height: 18px; display: none; margin-bottom: 4px; }

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 16px;
  margin-bottom: 16px;
  box-shadow: var(--shadow-sm);
}
.card h2 { font-size: 14px; margin: 0 0 12px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); }
.card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }

/* --- Ein- und ausklappbare Kacheln --- */
.klapp-kopf {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 0;
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-align: left;
}
.klapp-kopf h2 { flex: 1; }
.klapp-kopf:hover h2 { color: var(--text); }
.klapp-pfeil {
  display: flex;
  color: var(--muted);
  transition: transform .14s ease;
  flex: none;
}
/* Zugeklappt zeigt der Pfeil nach rechts. */
.card.zu .klapp-pfeil { transform: rotate(-90deg); }
.card.zu .card-body { display: none; }
.card.zu { margin-bottom: 10px; }
.klapp-zaehler {
  background: var(--pill);
  color: var(--text);
  border-radius: var(--radius-full);
  padding: 1px 8px;
  font-size: 10px;
  font-weight: 600;
  flex: none;
}
/* Ohne Ereignisse bliebe sonst eine leere Pille stehen. */
.klapp-zaehler:empty { display: none; }
/* Der Zaehler sagt, was im zugeklappten Block steckt. Offen sieht man es
   ohnehin -- dann waere er nur Doppelung. */
.card:not(.zu) .klapp-zaehler { display: none; }
.card-head-zweit { display: flex; justify-content: flex-end; margin-bottom: 6px; }
.card-head h2 { margin: 0; }
.hint { font-size: 12px; color: var(--muted); margin: 4px 0 12px; }

label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--muted); margin-bottom: 12px; }
/* **Ein einzeiliges Feld ist nicht so breit wie die Seite.** maxSize.md aus
   den Axiom-Token (448px). Textbereiche sind ausgenommen: dort ist die Breite
   Teil der Lesbarkeit. Wer ein Feld in einem Raster oder einer Zeile setzt,
   bekommt die Spaltenbreite -- deshalb die Ausnahmen unten. */
label > input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
label > select,
label > .pw-huelle { max-width: var(--max-md); }
.grid2 label > input, .grid2 label > select,
.werte-zeile input, .golden-zeile input,
.vorschau-tabelle input { max-width: none; }

/* Der Hinweis steht IM Label, unter der Eingabe. Seine eigenen Aussenabstaende
   kaemen zum `gap` des Labels hinzu -- der Abstand waere doppelt so gross wie
   ueberall sonst. */
label > .hint { margin: 0; }
/* In einem Raster bestimmt der Rasterabstand, nicht das Label. Sonst steht
   unter der linken Spalte mehr Luft als unter der rechten. */
.grid2 > label, .golden-eingaben > label, .golden-erwartung > label { margin-bottom: 0; }
/* Eine Knopfreihe am Ende eines Formulars. */
.ax-actions { gap: 10px; }
.admin-form .ax-actions { justify-content: flex-start; margin-top: 4px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 520px) { .grid2 { grid-template-columns: 1fr; } }

/* Eingabefelder nach Axiom `InputRoot`: die Flaeche ist bg.default, NICHT
   bg.secondary. Bis zum 04.09.2026 stand hier --panel-2; das war ein
   gueltiges Token an der falschen Stelle -- im kompilierten InputRoot.css von
   @optiaxiom/react steht `background-color: var(--ax-colors-bg-default)`.
   Nachgezogen, damit rcs und lesedauer gleich UND richtig sind. */
input, textarea, select {
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: var(--radius);
  padding: 9px 11px;
  font-size: 14px;
  font-family: inherit;
  width: 100%;
  /* size.lg = 2.5rem. 35px entsprach keinem Axiom-Token. */
  min-height: 40px;
}
/* Fokusring in border.focus -- deutlich sichtbar gegen Limette und Weiss. */
input:focus, textarea:focus, select:focus { outline: 2px solid var(--focus); outline-offset: 1px; border-color: transparent; }
textarea { resize: vertical; min-height: 76px; }
.counter { font-size: 11px; color: var(--muted); text-align: right; }
.counter.over { color: var(--danger); }

.tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.tab {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--muted);
  padding: 7px 12px;
  border-radius: 999px;
  cursor: pointer;
  font-size: 13px;
}
.tab.active { background: var(--accent-bg); color: var(--accent-fg); border-color: var(--accent-bg); font-weight: 600; }

.btn, .btn-ghost, .btn-primary, .otab {
  cursor: pointer;
  font-family: inherit;
  border-radius: var(--radius);
  /* fontSize.md wie im Nachbarprojekt. Axiom schreibt am ButtonRoot keine
     Schriftgroesse fest -- das hier ist Angleichung, kein Regelverstoss. */
  font-size: 14px;
}
.btn { background: var(--panel-2); border: 1px solid var(--line); color: var(--text); padding: 9px 14px; min-height: var(--hoehe-lg); }
.btn:hover { border-color: var(--accent); color: var(--accent); }
/* bg.accent traegt dunklen Text -- weiss waere darauf unlesbar (1,2:1). */
.btn-primary { background: var(--accent-bg); border: 1px solid var(--accent-bg); color: var(--accent-fg); padding: 9px 16px; min-height: var(--hoehe-lg); }
.btn-primary:hover:not(:disabled) { background: var(--accent-bg-hover); border-color: var(--accent-bg-hover); }
.btn-primary:disabled { opacity: .5; cursor: not-allowed; }
/* Die dritte Stufe: additive und abbrechende Aktionen („+ Wert", „Abbrechen").
   Der gestrichelte Rand kommt aus der Referenz und liest sich als „hier kommt
   etwas hinzu". **Nie zusammen mit `.btn`** -- das ist die zweite Stufe, und
   beide zusammen ergaben einen gestrichelten Rand auf 40 px Hoehe. */
.btn-ghost { background: transparent; border: 1px dashed var(--line); color: var(--muted); padding: 6px 10px; min-height: var(--hoehe-md); }
.btn-ghost:hover { color: var(--accent); border-color: var(--accent); }

.suggestions-list { display: flex; flex-direction: column; gap: 10px; }
.suggestion {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px;
}
.suggestion .row { display: grid; grid-template-columns: 150px 1fr auto; gap: 8px; align-items: center; }
.suggestion .extra { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.suggestion .extra label { margin: 0; }
/* Suggestion-Typ, der die Carousel-Regel bricht: an der Zeile selbst markieren. */
.suggestion.mismatch { border-color: var(--danger-border); }
.suggestion .row-warn {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  font-size: 12px;
  color: var(--danger);
}
/* **`.del` ist der Glyph-Knopf, nicht eine Schaltflaeche mit Text.** In der
   Referenz traegt er ausschliesslich ein „×". Hier stand er eine Zeit lang an
   Knoepfen mit der Aufschrift „Entfernen" und „Loeschen" -- `border: none` und
   `font-size: 18px` ueberschrieben dort die Schaltflaeche, und heraus kam
   grosser roter Text ohne Rahmen. Wer eine zerstoerende Aktion mit Text
   braucht, nimmt `.btn-ghost.danger`. */
.del { background: transparent; border: none; color: var(--danger); cursor: pointer; font-size: 18px; line-height: 1; }

/* Zerstoerende Aktion mit Beschriftung. Aus der Referenz uebernommen; die
   Farbe ist `fg.error`, der Rand `border.error`. */
.btn-ghost.danger { color: var(--danger); border-color: var(--danger-border); }
.btn-ghost.danger:hover { color: var(--danger); border-color: var(--danger); background: var(--bg-error-subtle); }

/* Kompakte Schaltflaeche fuer Tabellenzeilen und Verwaltungslisten.
   size.md = 32px aus den Axiom-Token; die 40px von size.lg lassen eine
   Tabellenzeile auseinanderfallen. */
.btn.klein, .btn-ghost.klein { min-height: var(--hoehe-md); padding: 5px 10px; font-size: 13px; }
/* In einer Verwaltungszeile stehen Felder und Knoepfe nebeneinander -- dann
   auf derselben Hoehe. Ein 40px-Feld neben einem 32px-Knopf laesst die Zeile
   auseinanderfallen. */
.admin-aktionen input, .admin-aktionen select {
  min-height: var(--hoehe-md);
  padding: 4px 8px;
  font-size: 13px;
  max-width: var(--max-xs);
}

.cards-editor { display: flex; flex-direction: column; gap: 14px; }
.card-block { border: 1px solid var(--line); border-radius: 10px; padding: 12px; background: var(--panel-2); }
.card-block h3 { font-size: 12px; margin: 0 0 10px; color: var(--muted); display: flex; justify-content: space-between; }

.validation { font-size: 13px; }
.validation .ok { color: var(--success-text); }



/* --- Vorlagen ------------------------------------------------------------
   Uebersicht als Raster nach dem Axiom-Muster: Grid mit gleich breiten
   Spalten, darin Karten mit Preview, Kopf und Fuss. */

.uebersicht-kopf {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.uebersicht-titel { margin: 0 0 2px; font-size: 18px; }
.uebersicht-kopf .hint { margin: 0; }

.tpl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
}

/* --- Karte nach der Axiom-Anatomie ---------------------------------------
   Card > CardPreview (mit Addon-Ecken) > CardHeader (Titel als CardLink,
   Aktionen als addonAfter) > CardFooter (Nebeninformation).
   Der Footer traegt bewusst KEINE Aktionen -- die stehen im Header. */
.ax-card {
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: box-shadow .14s ease, border-color .14s ease;
}
.ax-card:hover { box-shadow: var(--shadow-md); border-color: var(--accent); }
.ax-card:focus-within { border-color: var(--focus); }

/* Das Beschneiden sitzt hier, nicht an der Karte: mit `overflow: hidden` auf
   der Karte wuerde das Aktionsmenue im Header abgeschnitten. */
.ax-card-preview {
  position: relative;
  /* 132px reichten fuer zwei Plakettenreihen ohne Ueberschrift. Mit ihr fiel
     als Erstes das „+N weitere" heraus -- ausgerechnet die Angabe, die sagt,
     dass es mehr gibt. */
  height: 146px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.ax-card-image { width: 100%; height: 100%; object-fit: cover; display: block; }
.ax-card-auszug {
  margin: 0;
  padding: 12px 14px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ax-card-auszug.leer { font-style: italic; opacity: .7; }

/* addonTopLeft und Geschwister aus der Anatomie. */
.ax-card-addon {
  position: absolute;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-full);
  padding: 2px 9px;
  font-size: 10px;
  font-weight: 600;
  color: var(--text);
}
.ax-card-addon.oben-links { top: 8px; left: 8px; }
/* Die Art des Agenten. **Bewusst keine Plakette:** sie stand als graues Pill
   neben dem Status, sah genauso aus wie er, und die Frage „darf der laufen?"
   verschwand neben der Beschriftung „Auswahl aus Werteliste". */
.ax-card-typ {
  position: absolute;
  top: 10px;
  left: 12px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.ax-card-addon.oben-rechts { top: 8px; right: 8px; }

.ax-card-header {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 12px 12px 8px;
  flex: 1;
}
.ax-card-header-text { min-width: 0; flex: 1; }
.ax-card-header h3 { margin: 0; font-size: 14px; font-weight: 600; }
/* CardLink: der Titel macht die Karte anklickbar. */
.ax-card-link {
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  overflow-wrap: anywhere;
}
.ax-card-link:hover { color: var(--accent); text-decoration: underline; }
.ax-card-desc {
  margin: 3px 0 0;
  font-size: 11px;
  color: var(--muted);
  /* Drei Zeilen. Im Raster bestimmt sonst die laengste Beschreibung die Hoehe
     jeder Karte ihrer Zeile -- und eine Karte, die zu vier Fuenfteln aus
     Fliesstext besteht, ist keine Uebersicht mehr. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Eine fehlende Beschreibung ist kein Inhalt. */
.ax-card-desc.leer { font-style: italic; color: var(--disabled); }

/* **Warum der Agent nicht laufen darf.** In derselben Schrift und Farbe wie
   die Beschreibung las sich „Der Agent ist gesperrt" wie deren letzter Satz.
   Es ist aber die Antwort auf die Frage, mit der man auf diese Uebersicht
   sieht. */
.ax-card-hinweis {
  margin: 7px 0 0;
  padding: 5px 7px;
  border-left: 2px solid var(--border-warning);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--bg-warning-subtle);
  font-size: 11px;
  line-height: 1.35;
  color: var(--warn-text);
}
.ax-card-hinweis.danger {
  border-left-color: var(--danger-border);
  background: var(--bg-error-subtle);
  color: var(--danger);
}

.ax-card-footer {
  padding: 8px 12px 10px;
  border-top: 1px solid var(--line);
  border-radius: 0 0 calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px);
  font-size: 11px;
  color: var(--muted);
  display: flex;
  /* **Umbrechen zwischen den Angaben, nie innerhalb.** Ohne das brach „Sonnet
     5" nach „Sonnet" und „Täglich 03:00" nach „Täglich" -- vier Angaben
     wurden zu acht halben Zeilen. */
  flex-wrap: wrap;
  column-gap: 10px;
  row-gap: 3px;
}
.ax-card-footer span { white-space: nowrap; }
/* Das Einzige im Fuss, das von selbst geschieht. */
.ax-card-footer .plan { color: var(--accent); font-weight: 600; }

/* --- Aktionsmenü (addonAfter) --- */
.ax-menue { position: relative; flex: none; }
.ax-menue-knopf {
  border: 1px solid transparent;
  background: none;
  color: var(--muted);
  border-radius: var(--radius-sm);
  padding: 0 7px;
  font-size: 16px;
  line-height: 22px;
  cursor: pointer;
}
.ax-menue-knopf:hover { border-color: var(--line); background: var(--panel-2); color: var(--text); }
.ax-menue-liste {
  position: absolute;
  right: 0;
  top: 26px;
  z-index: 30;
  min-width: 160px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 4px;
  display: flex;
  flex-direction: column;
}
.ax-menue-liste[hidden] { display: none; }
.ax-menue-eintrag {
  border: none;
  background: none;
  text-align: left;
  font: inherit;
  font-size: 13px;
  padding: 6px 9px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text);
}
.ax-menue-eintrag:hover { background: var(--accent-subtle); }
.ax-menue-eintrag.danger { color: var(--danger); }

/* --- DataTable -----------------------------------------------------------
   Anatomie: DataTable > DataTableBody (Zeilen, Zellen, DataTableAction) >
   DataTableFooter. Kopfzeile klebt, Zeilen gleich hoch, Aktionen erscheinen
   beim Ueberfahren. */
.ax-table {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}
/* Nicht die Tabelle beschneiden -- sonst faellt das Aktionsmenue der letzten
   Zeile heraus. Die Rundung tragen Kopf und letzte Zeile selbst. */
.ax-table-head { border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0; }
.ax-tr:last-child { border-radius: 0 0 calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px); }
.ax-table-head,
.ax-tr {
  display: grid;
  align-items: center;
  gap: 12px;
  padding: 0 14px;
}
.ax-table-head {
  /* **Klebt nicht mehr am oberen Rand der Seite.** `.ax-table` ist seit der
     waagerechten Scrollbarkeit ein eigener Scroll-Bereich; `sticky` bezieht
     sich damit auf diesen statt auf die Seite, und die Kopfzeile steht
     schlicht dort, wo sie ohnehin steht. Die Angabe bleibt, weil sie wieder
     greift, sobald die Tabelle eine Hoehenbegrenzung bekommt -- schaedlich
     ist sie nicht. Waagerecht scrollen zu koennen war hier wichtiger: die
     Tabellen haben bis zu neun Spalten. */
  position: sticky;
  top: 0;
  z-index: 2;
  min-height: 38px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
}
.ax-th {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--muted);
}
.ax-tr {
  min-height: 46px;
  border-bottom: 1px solid var(--line);
}
.ax-tr:last-child { border-bottom: none; }
.ax-tr:hover { background: var(--panel-2); }
.ax-tr.gedimmt { opacity: .55; }
.ax-td { font-size: 13px; min-width: 0; overflow-wrap: anywhere; }
.ax-td-stark { font-weight: 600; }
/* Axiom schreibt `end`, nicht `right` -- und laesst im DataTable-Beispiel
   selbst die Betragsspalte am Anfang stehen. `end` geht ausserdem mit der
   Schreibrichtung mit. Nachgezogen am 04.09.2026, wie Feld und Knopf. */
.ax-th.rechts, .ax-td.rechts { text-align: end; }

/* DataTableAction: in jeder Zeile ein Menue, immer sichtbar. Es war frueher
   bis zum Ueberfahren unsichtbar -- bei einer Knopfreihe eine gute Idee, bei
   einem einzelnen Punkte-Knopf aber nur eine versteckte Funktion. Ruhig
   bleibt die Tabelle jetzt durch die gedaempfte Farbe. */
.ax-actions {
  display: flex;
  /* Axioms Props kennen start | end | center | stretch -- kein flex-end. */
  justify-content: end;
}
.ax-actions .ax-menue-knopf { color: var(--muted); }
.ax-tr:hover .ax-actions .ax-menue-knopf,
.ax-actions .ax-menue-knopf:hover,
.ax-actions .ax-menue-knopf[aria-expanded="true"] { color: var(--text); }

.ax-table-leer { padding: 20px 14px; font-size: 13px; color: var(--muted); text-align: center; }
.ax-table-foot {
  padding: 8px 14px;
  border-top: 1px solid var(--line);
  background: var(--panel-2);
  font-size: 11px;
  color: var(--muted);
}

/* Badge nach Axiom: Variante `subtle`, Intents neutral/information/
   success/warning/danger. Ohne Intent ist es neutral. */
.ax-marke {
  display: inline-block;
  border: 1px solid var(--line);
  border-radius: var(--radius-full);
  padding: 1px 9px;
  font-size: 11px;
  background: var(--bg-neutral);
  color: var(--text);
}
.ax-marke.success { background: var(--bg-success-subtle); border-color: var(--border-success); color: var(--success-text); }
.ax-marke.warning { background: var(--bg-warning-subtle); border-color: var(--border-warning); color: var(--warn-text); }
.ax-marke.danger  { background: var(--bg-error-subtle); border-color: var(--danger-border); color: var(--danger); }
.ax-marke.information { background: #E2F5F5; border-color: var(--info); color: var(--info); }

/* **Immer waagerecht scrollbar, nicht erst auf schmalen Schirmen.**
   Die Medienabfrage fragt die Breite des FENSTERS, die Tabelle steht aber im
   Inhaltsbereich neben der Seitenleiste -- der ist deutlich schmaler. Bei
   einem Fenster von 800 px lief die Tabelle deshalb rechts aus dem Bereich
   heraus, ohne dass man scrollen konnte. Die Tabellen hier haben bis zu
   neun Spalten; sie brauchen das unabhaengig vom Fenster.

   `min-width: max-content` zwingt die Zeilen auf ihre Spaltenbreiten, statt
   sie zu zerquetschen -- ohne das faengt das Grid an, Spalten zu stauchen,
   und der Scrollbalken erscheint nie. */
.ax-table { overflow-x: auto; }
.ax-table-head, .ax-tr { min-width: max-content; }

/* **Die Tabelle, die in die Ansicht passt** -- fuer Ergebnisse, in denen
   Freitext steht (Begruendungen, Eingaben, Gruende). Mit `max-content` wurde
   „Zur Pruefung" ueber 4 000 px breit: eine Begruendung von drei Saetzen war
   eine einzige Zeile, und ein redigierter Name hatte ein Sternchen je
   Zeichen.
   Hier bekommt jede Spalte ihren Anteil (`minmax(0, …fr)` im Raster), und was
   nicht passt, kuerzt `.kurz` mit „…". Unter 680 px wird nicht weiter
   gequetscht, sondern gescrollt -- sonst blieben je Spalte drei Buchstaben. */
.ax-table.passt .ax-table-head,
.ax-table.passt .ax-tr { min-width: 680px; }
.ax-table.passt .ax-tr { align-items: start; padding-top: 10px; padding-bottom: 10px; min-height: 0; }
.ax-table.passt .ax-td { overflow-wrap: normal; }

.kurz {
  display: block;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.kurz-2, .kurz-3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  white-space: normal;
  line-height: 1.4;
}
.kurz-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.kurz-3 { -webkit-line-clamp: 3; line-clamp: 3; }
/* Gekuerzt heisst: da ist mehr. Der Zeiger sagt es, bevor der Tooltip kommt. */
.kurz[title], .eingabe-liste[title] { cursor: help; }

.eingabe-liste { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* **Gekuerzt wird der Feldname, nicht der Wert.** „unternehmen: M… (70)"
   verlor in einer schmalen Spalte zuerst die Laenge -- die einzige Angabe,
   die am redigierten Wert etwas sagt. Der Feldname steht ohnehin im Tooltip. */
.eingabe-zeile {
  display: flex;
  align-items: baseline;
  gap: 4px;
  min-width: 0;
  font-size: 12px;
  white-space: nowrap;
}
.eingabe-feld {
  flex: 0 1 auto;
  min-width: 2ch;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--muted);
  font-size: 11px;
}
.eingabe-feld::after { content: ':'; }
.eingabe-wert { flex: none; }
.kennung { font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 12px; color: var(--muted); }

@media (max-width: 720px) {
  /* Auf dem Telefon sind die Aktionen dauerhaft sichtbar -- es gibt dort kein
     Ueberfahren mit dem Zeiger. */
  .ax-actions { opacity: 1; }
}

.tpl-leer {
  grid-column: 1 / -1;
  padding: 40px 20px;
  text-align: center;
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}
.tpl-leer p { margin: 0 0 6px; font-size: 14px; }
.tpl-leer .hint { margin: 0; }

/* Hinweis neben dem Speichern-Knopf: welche Vorlage gerade offen ist. */
.vorlage-hinweis {
  font-size: 11px;
  color: var(--muted);
  overflow-wrap: anywhere;
}
.vorlage-hinweis.aktiv { color: var(--text); font-weight: 600; }
.actions .btn:disabled { opacity: .5; cursor: not-allowed; }
/* --- Toasts ---------------------------------------------------------------
   Die Schicht liegt fest am unteren Rand, mittig: dort verdeckt sie keine
   Tabelle und keinen Knopf, und sie ist von jedem Punkt der Seite gleich weit
   entfernt -- anders als die Statuszeile, die oben rechts stand, waehrend der
   ausloesende Knopf unten in Schritt 6 lag.

   `pointer-events: none` auf der Schicht, `auto` auf dem Toast: die Spalte ist
   420 px breit und 100 vh hoch, und ohne das fingen ihre leeren Bereiche jeden
   Klick auf die Seite darunter ab. */
.toast-schicht {
  position: fixed;
  z-index: var(--z-toast);
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: min(var(--max-md), calc(100vw - 32px));
  pointer-events: none;
}

.toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 10px 12px 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--shadow-lg);
  font-size: 13px;
  line-height: 1.45;
  color: var(--text);
}
.toast-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.toast-bild { flex: none; margin-top: 1px; }

/* Die Intents. Die Farbe traegt das Symbol und die Kante -- der Text bleibt
   --text, damit er auf jeder Meldung gleich gut lesbar ist. */
.toast-ok      { border-left-color: var(--border-success); }
.toast-ok      .toast-bild { color: var(--success-text); }
.toast-info    { border-left-color: var(--info); }
.toast-info    .toast-bild { color: var(--info); }
.toast-warnung { border-left-color: var(--border-warning); }
.toast-warnung .toast-bild { color: var(--warn-text); }
.toast-err     { border-left-color: var(--danger-border); }
.toast-err     .toast-bild { color: var(--danger); }
.toast-laeuft  { border-left-color: var(--line); }
.toast-laeuft  .toast-bild { color: var(--muted-2); animation: toast-dreht 1.1s linear infinite; }

.toast-zu {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.toast-zu:hover { background: var(--panel-2); color: var(--text); }
.toast-zu:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* Ein Toast kommt von unten herein und geht nach unten hinaus. */
@keyframes toast-auf {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@keyframes toast-dreht { to { transform: rotate(360deg); } }
.toast { animation: toast-auf .16s ease-out; }
.toast-weg { opacity: 0; transform: translateY(8px); transition: opacity .16s, transform .16s; }

@media (prefers-reduced-motion: reduce) {
  .toast, .toast-laeuft .toast-bild { animation: none; }
  .toast-weg { transition: none; }
}


/* --- Topbar: Vorlagenkontext und Speichern --- */
.topbar-editor { display: flex; align-items: center; gap: 10px; }

/* --- Dialog --- */
.modal {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: var(--text);
  padding: 0;
  width: min(420px, calc(100vw - 32px));
  box-shadow: var(--shadow-lg);
}
.modal::backdrop { background: rgba(15, 23, 42, .38); }
.modal-inhalt { padding: 20px; }
.modal-inhalt h2 { margin: 0 0 4px; font-size: 15px; }
.modal-inhalt .hint { margin-top: 0; }
.modal-aktionen { display: flex; justify-content: flex-end; gap: 10px; margin-top: 14px; }

/* --- Hinweise direkt am Feld --- */
.feld-hinweis {
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 1.35;
  color: var(--danger);
  font-weight: 500;
}
/* Im Label sitzt der Hinweis unter der Eingabe und darf deren Breite haben. */
label > .feld-hinweis { width: 100%; }
.rest-hinweis { font-size: 12px; color: var(--danger); }

/* Zugeklappter Block mit Hinweisen darin: ein Punkt am Kopf, sonst waere der
   Fehler unsichtbar, seit es keine Sammelliste mehr gibt. */
.card.klappbar.hat-hinweis.zu .klapp-kopf h2::after {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-left: 8px;
  border-radius: 50%;
  background: var(--danger);
  vertical-align: middle;
}


/* --- Anmeldeseite: Erfolgsmeldung und Nebenwege --- */
.auth-erfolg {
  display: none;
  margin: 8px 0 0;
  padding: 10px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--accent);
  background: var(--accent-subtle);
  color: var(--text);
  font-size: 13px;
  line-height: 1.4;
}
.auth-fuss { display: flex; justify-content: space-between; gap: 12px; margin-top: 14px; }
.auth-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 12px;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
}
.auth-link:hover { color: var(--text); }

.hint.warnung { color: var(--warn-text); }


/* --- Dashboard ----------------------------------------------------------- */


/* Betriebsbereitschaft ganz oben: was den Versand verhindert, sieht man zuerst. */
.dash-betrieb { display: flex; flex-direction: column; gap: 8px; }
.dash-ok {
  padding: 10px 14px;
  border: 1px solid var(--border-success);
  background: var(--bg-success-subtle);
  color: var(--success-text);
  border-radius: var(--radius);
  font-size: 13px;
}
.dash-warnung {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-radius: var(--radius);
  font-size: 13px;
  border: 1px solid var(--line);
  background: var(--bg-neutral);
}
.dash-warnung.fehler { border-color: var(--danger-border); background: var(--bg-error-subtle); color: var(--danger); }
.dash-warnung.warnung { border-color: var(--border-warning); background: var(--bg-warning-subtle); color: var(--warn-text); }
.dash-warnung .btn-ghost { flex: none; }

/* --- KPI-Kacheln --- */
.dash-kpi { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; }
.dash-kachel {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.dash-kachel-titel { font-size: 11px; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
.dash-kachel-wert { font-size: 26px; line-height: 1.15; font-weight: 700; }
.dash-kachel-unten { font-size: 11px; color: var(--muted); }
.dash-trend { font-size: 11px; font-weight: 600; }
.dash-trend.hoch { color: var(--success-text); }
.dash-trend.runter { color: var(--warn-text); }

/* --- Verlauf und neueste Konversationen --- */
.dash-unten { display: grid; grid-template-columns: minmax(320px, 1.6fr) minmax(260px, 1fr); gap: 16px; align-items: start; }
@media (max-width: 900px) { .dash-unten { grid-template-columns: 1fr; } }

.dash-verlauf { display: flex; align-items: flex-end; gap: 4px; height: 120px; }
.dash-tag { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 4px; height: 100%; }
.dash-saeulen { flex: 1; width: 100%; display: flex; align-items: flex-end; justify-content: center; gap: 2px; }
/* Eine Säule mit dem Wert 0 bleibt als Strich sichtbar -- sonst sähe ein
   stiller Tag wie fehlende Daten aus. */
.dash-saeule { width: 7px; min-height: 2px; border-radius: 2px 2px 0 0; }
.dash-saeule.gesendet { background: var(--accent-bg); }
.dash-saeule.empfangen { background: var(--info); }
.dash-tag-label { font-size: 9px; color: var(--muted); }

.dash-neueste { display: flex; flex-direction: column; gap: 2px; }
.dash-konv {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  font: inherit;
  padding: 7px 8px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.dash-konv:hover { background: var(--panel-2); }
.dash-konv-nr { font-size: 12px; font-weight: 600; flex: none; }
.dash-konv-txt { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }

/* --- Bestand --- */
.dash-bestand { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.dash-bestand-kachel {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  cursor: pointer;
  font: inherit;
  text-align: left;
}
.dash-bestand-kachel:hover { border-color: var(--accent); background: var(--accent-subtle); }
.dash-bestand-kachel strong { font-size: 20px; }
.dash-bestand-kachel span { font-size: 11px; color: var(--muted); }
.dash-trend.gleich { color: var(--muted); }
.dash-bestand-block { display: flex; flex-direction: column; gap: 4px; }
.dash-bestand-block h2 { margin: 0; }
.dash-bestand-block .hint { margin: 0 0 6px; }
.dash-legende { display: flex; gap: 14px; margin-bottom: 10px; font-size: 11px; color: var(--muted); }
.dash-legende span { display: inline-flex; align-items: center; gap: 5px; }
.dash-punkt { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.dash-punkt.gesendet { background: var(--accent-bg); }
.dash-punkt.empfangen { background: var(--info); }


/* --- Passwort kurz einblenden -------------------------------------------- */

/* Der Knopf liegt IM Feld, nicht daneben: daneben rutscht er im schmalen
   Fenster in die naechste Zeile und steht dann unter etwas, zu dem er nicht
   mehr sichtbar gehoert. */
.pw-huelle { position: relative; display: block; width: 100%; }
/* Der Platz rechts muss den Knopf ganz aufnehmen. Hier standen 40px -- das
   war die Breite eines Icons, und das Wort „anzeigen" ist breiter: es stand
   auf dem Feldrand und getippter Text lief darunter. */
.pw-huelle input { width: 100%; padding-right: 84px; }
.pw-auge {
  position: absolute;
  top: 50%;
  right: 5px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  /* **Feste Mindestbreite, obwohl der Text sich aendert.** „anzeigen" und
     „verbergen" sind verschieden breit; ohne sie springt der Knopf bei jedem
     Klick um ein paar Pixel, und das Feld sieht aus, als wackle es. */
  min-width: 72px;
  height: 26px;
  padding: 0 8px;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  /* Die Akzentfarbe als SCHRIFT -- dieselbe wie bei „Passwort vergessen?".
     In --muted sah der Knopf aus wie eine Beschriftung, nicht wie etwas,
     das man anklicken kann. */
  color: var(--accent);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
}
.pw-auge:hover { background: var(--panel-2); text-decoration: underline; }
.pw-auge:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
/* Im Formular sitzt das Feld unter seiner Beschriftung -- die Huelle darf den
   Abstand darunter nicht schlucken. */
label > .pw-huelle { margin: 0; }

/* --- Mandantenwechsel ---------------------------------------------------- */

/* Ein Band ueber allem: wer in einem fremden Mandanten arbeitet, soll es
   nicht erst merken, wenn er dort etwas geaendert hat. */
.wechsel-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 8px 18px;
  background: var(--bg-warning-subtle);
  border-bottom: 1px solid var(--border-warning);
  color: var(--warn-text);
  font-size: 13px;
}
.wechsel-band .btn-ghost { flex: none; padding: 4px 12px; font-size: 12px; }
/* Der Filter steht unter der Sender-ID-Auswahl, in derselben schmalen Spalte. */
/* Der Timeout-Ausgang ist keine Eingabezeile -- er zeigt nur, dass es ihn
   gibt und woran er haengt. */
/* „Keine Antwort" am Knoten: gestrichelt statt gefuellt -- er wird nie
   verschickt, sondern greift, wenn nichts kommt. */


/* --- KI-Kosten ------------------------------------------------------------
   Nutzt die Dashboard-Bausteine (.dash-kpi, .card, .dash-verlauf); eigen ist
   nur die Zeile aus Name, Anteil und Betrag. */
.kk-zeitraum { max-width: 160px; }
.kk-liste { display: flex; flex-direction: column; gap: 2px; }
.kk-zeile {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 4px 10px;
  padding: 8px 4px;
  border-bottom: 1px solid var(--line);
}
.kk-zeile:last-child { border-bottom: none; }
.kk-name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.kk-betrag { font-variant-numeric: tabular-nums; font-weight: 600; }
.kk-detail { grid-column: 1 / -1; font-size: 11px; color: var(--muted); }
/* Der Balken zeigt den Anteil am Gesamtbetrag -- eine Zahlenspalte allein
   laesst nicht erkennen, wo das Geld wirklich haengt. */
.kk-balken { grid-column: 1 / -1; height: 3px; border-radius: 2px; background: var(--accent-bg); }
.kk-leer { padding: 10px 4px; color: var(--muted); }
.dash-saeule.kosten { background: var(--accent-bg); }

/* Ein Hinweiskasten in einer Verwaltungsansicht.
   **Die Klasse wurde benutzt, bevor es sie gab** -- die Telegram-Ansicht
   traegt sie an drei Stellen, ohne dass je eine Regel dazu geschrieben
   worden waere; die Kaesten liefen deshalb als Fliesstext mit. Aufgefallen
   ist es erst, als die WeChat-Einrichtung ihre Anleitung in so einen Kasten
   stellte und niemand sie als Kasten erkannte. */
.hinweis-kasten {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent-bg, var(--line));
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-bottom: 12px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}
.hinweis-kasten strong { color: var(--text); }
.hinweis-kasten code {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 4px;
}

/* ==========================================================================
   Ab hier: was nur diese Anwendung braucht.
   Alles darueber stammt aus messenger.studio und ist dort wie hier aus den
   Axiom-Tokens in docs/axiom-tokens.json aufgebaut -- Seitenleiste, Karten,
   Tabelle, Dialog, Kennzahlen-Kacheln und Anmeldeseite sind in beiden
   Anwendungen dieselben Bausteine. Was unten steht, hat dort keinen
   Gegenpart: Feldauswahl, Werteliste, Konfidenzanzeige, Laufergebnisse.
   ========================================================================== */

/* Zaehler in der Navigation -- hier: Ergebnisse, die auf einen Menschen
   warten (Konfidenz unter der Schwelle). */
.nav-badge {
  margin-left: auto;
  background: var(--accent-bg);
  color: var(--accent-fg);
  border-radius: var(--radius-full);
  padding: 0 6px;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
}
.sidebar.collapsed .nav-badge { display: none; }

/* --- Feldauswahl ----------------------------------------------------------
   Die Attributnamen einer Liste als anklickbare Marken. Eine Mehrfachauswahl
   mit <select multiple> waere die naheliegende Loesung und die schlechtere:
   bei 80 Attributen sieht man nicht, was gewaehlt ist, ohne zu scrollen. */
.feld-wahl {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel-2);
  max-height: 180px;
  overflow-y: auto;
}
.feld-chip {
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-full);
  padding: 3px 10px;
  color: var(--text);
}
.feld-chip:hover { border-color: var(--accent); }
.feld-chip[aria-pressed="true"] {
  background: var(--accent-bg);
  border-color: var(--accent-bg);
  color: var(--accent-fg);
  font-weight: 600;
}
/* Das Zielfeld ist als Eingabefeld gesperrt -- ein Agent, der sein eigenes
   Ergebnis liest, bestaetigt sich selbst (siehe public/agent-schema.js). */
.feld-chip:disabled { opacity: .4; cursor: not-allowed; }
.feld-chip.ist-ziel {
  background: var(--bg-warning-subtle);
  border-color: var(--border-warning);
  color: var(--warn-text);
}
/* Ein Ankreuzfeld steht NEBEN seiner Beschriftung, nicht darueber.
   `label` weiter oben setzt `flex-direction: column` -- richtig fuer ein
   Textfeld mit Beschriftung darueber, falsch fuer ein Ankreuzfeld. Ohne das
   `row` hier stand jede Checkbox der Anwendung ueber ihrem Text, mittig
   zentriert, und sah aus wie ein Versehen. `align-items: center` und der
   6px-Abstand standen immer schon da und meinten genau diese Zeile. */
.feld-pflicht {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--muted);
}

/* **Ankreuz- und Auswahlfelder sind keine Textfelder.** Die Regel weiter oben
   (`input, textarea, select`) stammt von Axioms `InputRoot` und setzt Breite,
   Hoehe und Innenabstand -- auf ein Ankreuzfeld angewandt ergibt das einen
   handtellergrossen Kasten neben einer umgebrochenen Beschriftung. Genau so
   sah der Schalter im Bestaetigungsdialog aus. */
input[type="checkbox"],
input[type="radio"] {
  width: auto;
  height: auto;
  min-height: 0;
  padding: 0;
  margin: 0;
  flex: none;
  accent-color: var(--accent);
}

/* Im Dialog ist eine Beschriftung keine Nebensache -- dort wird entschieden. */
.modal-inhalt .feld-pflicht { font-size: 14px; color: var(--text); align-items: flex-start; }
.modal-inhalt .feld-pflicht input { margin-top: 3px; }
.modal-inhalt .hint { font-size: 12px; }

/* --- Werteliste eines Auswahl-Agenten ----------------------------------- */
.werte-liste { display: grid; gap: 6px; }
.werte-zeile {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) minmax(160px, 2fr) auto;
  gap: 6px;
  align-items: center;
}
.werte-zeile input { margin: 0; }
/* **In einer Formularzeile haben Feld und Aktion dieselbe Hoehe.** Sonst
   liest sich die Zeile als zwei Dinge nebeneinander statt als eines: die
   Eingaben sind size.lg (40px), ein Knopf auf size.md (32px) sitzt darin
   verloren. Gleiches gilt fuer die Golden-Zeilen. */
.werte-zeile .btn-ghost,
.golden-erwartung .btn-ghost { min-height: var(--hoehe-lg); padding: 9px 14px; }
.werte-leer {
  padding: 12px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  font-size: 12px;
  color: var(--muted);
  background: var(--panel-2);
}

/* --- Konfidenz -----------------------------------------------------------
   Zahl UND Balken. Die Zahl allein liest niemand in einer Tabelle mit 500
   Zeilen; der Balken allein laesst nicht erkennen, wie weit es bis zur
   Schwelle war. Die Schwelle steht als Strich darin. */
.konf { display: flex; align-items: center; gap: 6px; min-width: 90px; }
.konf-zahl { font-variant-numeric: tabular-nums; font-size: 12px; min-width: 30px; }
.konf-balken {
  position: relative;
  flex: 1;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--pill);
  overflow: hidden;
}
.konf-fuellung { height: 100%; background: var(--accent-bg); }
.konf-fuellung.unter { background: var(--border-warning); }
.konf-schwelle {
  position: absolute;
  top: -2px;
  width: 2px;
  height: 10px;
  background: var(--text);
  opacity: .5;
}

/* --- Der Schieber fuer die Schwelle ------------------------------------- */
.schwelle-zeile { display: flex; align-items: center; gap: 10px; }
.schwelle-zeile input[type="range"] { flex: 1; accent-color: var(--accent); }
.schwelle-wert {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  min-width: 36px;
  text-align: right;
}

/* --- Zahlen eines Laufs ------------------------------------------------- */
.lauf-zahlen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 8px;
}
.lauf-zahl {
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
}
.lauf-zahl-wert { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.lauf-zahl-titel { font-size: 11px; color: var(--muted); }
.lauf-zahl.gut .lauf-zahl-wert { color: var(--success-text); }
.lauf-zahl.pruefen .lauf-zahl-wert { color: var(--warn-text); }
.lauf-zahl.schlecht .lauf-zahl-wert { color: var(--danger); }

/* Woran es gescheitert ist, nach Grund gruppiert. Konzept 10 nennt den
   Anstieg der Eskalationsquote als Fruehindikator -- sichtbar wird er nur,
   wenn die Gruende einzeln dastehen. */
.gruende { display: grid; gap: 4px; }
.grund-zeile {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  font-size: 12px;
  padding: 4px 0;
  border-bottom: 1px solid var(--line-soft);
}
.grund-zeile:last-child { border-bottom: 0; }
.grund-zahl { font-variant-numeric: tabular-nums; font-weight: 600; }

/* --- Golden-Set --------------------------------------------------------- */
.golden-zeile {
  display: grid;
  gap: 6px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
}
.golden-zeile + .golden-zeile { margin-top: 6px; }
.golden-eingaben {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 6px;
}
.golden-erwartung { display: flex; flex-wrap: wrap; gap: 8px; align-items: end; }
.golden-erwartung label { flex: 1 1 140px; margin: 0; }
.golden-freigabe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--border-warning);
  background: var(--bg-warning-subtle);
  font-size: 13px;
}
.golden-freigabe.ist-frei {
  border-color: var(--border-success);
  background: var(--bg-success-subtle);
}

/* --- Vorschau echter Empfaengerdaten im Konfigurator --------------------
   Damit sichtbar ist, was in den gewaehlten Feldern ueberhaupt steht, bevor
   ein Lauf Geld kostet. */
.vorschau-tabelle { width: 100%; border-collapse: collapse; font-size: 12px; }
.vorschau-tabelle th,
.vorschau-tabelle td {
  text-align: left;
  padding: 5px 8px;
  border-bottom: 1px solid var(--line-soft);
  overflow-wrap: anywhere;
}
.vorschau-tabelle th { color: var(--muted); font-weight: 600; }
.vorschau-tabelle td:empty::after { content: '—'; color: var(--disabled); }

/* --- Hinweis, dass etwas fehlt ------------------------------------------ */
.fehlt {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--border-warning);
  background: var(--bg-warning-subtle);
  font-size: 13px;
}
.fehlt.ernst { border-color: var(--danger-border); background: var(--bg-error-subtle); }
.fehlt p { margin: 0 0 4px; }
.fehlt p:last-child { margin: 0; }

/* Eine Liste von Pruefmeldungen am Formular. */
.fehlerliste { margin: 0; padding-left: 18px; font-size: 13px; color: var(--danger); }
.fehlerliste:empty { display: none; }

/* --- Audit-Log ----------------------------------------------------------- */
.audit-zeile {
  display: grid;
  grid-template-columns: 150px 150px 1fr;
  gap: 10px;
  padding: 5px 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: 12px;
}
.audit-zeit { color: var(--muted); font-variant-numeric: tabular-nums; }
.audit-detail { overflow-wrap: anywhere; color: var(--muted); }
@media (max-width: 720px) {
  .audit-zeile { grid-template-columns: 1fr; gap: 2px; }
}

/* Der genaue Grund unter der Marke in der Ergebnistabelle. Die Marke sagt die
   Art, dieser Satz den Grund -- „Der Aufruf ist fehlgeschlagen" allein half
   niemandem weiter. */
.grund-detail {
  display: block;
  margin-top: 3px;
  font-size: 11px;
  line-height: 1.35;
  color: var(--muted);
  overflow-wrap: anywhere;
}

/* --- Voransicht auf der Agentenkarte ---------------------------------------
   Die Preview-Flaeche der Axiom-Karte zeigt sonst ein Bild. Ein Agent hat
   keines -- was ihn ausmacht, ist die Umformung: welche Felder hinein, welcher
   Wert heraus, und welche Werte ueberhaupt herauskommen koennen. Genau das
   steht hier, statt der Beschreibung. Die gehoert unter den Titel; sie sagt,
   wofuer der Agent da ist, nicht was er tut.
   ------------------------------------------------------------------------- */
.agent-vorschau {
  display: flex;
  flex-direction: column;
  gap: 9px;
  /* Oben Platz fuer die Eck-Marken: die sitzen absolut bei `top: 8px` und sind
     rund 18px hoch. Mit gleichem Abstand ringsum lief der Text dahinter. */
  padding: 32px 14px 12px;
  width: 100%;
  align-self: stretch;
  /* **Nicht zentrieren.** Ist der Inhalt hoeher als die Flaeche, tritt er bei
     `center` an BEIDEN Enden aus -- oben also hinter die Eck-Marken. Von oben
     nach unten gefuellt wird notfalls unten beschnitten, und dort steht das
     Unwichtigere. */
  justify-content: flex-start;
  min-width: 0;
}

/* Eingabefelder → Zielfeld. */
.agent-fluss {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px;
  font-size: 11px;
}
.agent-feld {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 2px 7px;
  color: var(--muted);
  overflow-wrap: anywhere;
}
/* Das Zielfeld traegt die Akzentfarbe als SCHRIFT, nicht als Flaeche -- eine
   zweite gruene Flaeche neben der Statusmarke waere Laerm. */
.agent-ziel {
  background: var(--accent-subtle);
  border: 1px solid var(--accent-bg);
  border-radius: var(--radius-sm);
  padding: 2px 7px;
  color: var(--accent);
  font-weight: 600;
  overflow-wrap: anywhere;
}
.agent-pfeil { color: var(--disabled); flex: none; }

/* Die moeglichen Ergebnisse. Bei einem Auswahl-Agenten sind das die erlaubten
   Werte -- das Wesentliche: mehr kann nicht herauskommen. */
/* Die Ueberschrift ueber der Ergebniszeile. Die Zeile darueber -- Felder,
   Pfeil, Zielfeld -- braucht keine: der Pfeil sagt, was sie meint. */
.agent-kopf {
  margin: 0 0 4px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.agent-block { min-width: 0; }
.agent-werte { display: flex; flex-wrap: wrap; gap: 4px; overflow: hidden; max-height: 44px; }
.agent-wert {
  background: var(--pill);
  border-radius: var(--radius-full);
  padding: 1px 8px;
  font-size: 11px;
  color: var(--text);
  white-space: nowrap;
}
.agent-wert.mehr { background: none; color: var(--muted); padding-left: 2px; }
/* Auch die Grenzen eines Textagenten sind Plaketten -- so ist die untere
   Zeile jeder Karte gleich gebaut, unabhaengig von der Art des Agenten. */
.agent-form { display: flex; flex-wrap: wrap; gap: 4px; }
.agent-unfertig { font-size: 11px; color: var(--warn-text); font-style: italic; }

/* --- Workflow-Zeichenfläche ----------------------------------------------
   Übernommen aus rcs.messenger.studio (`public/styles.css`, Abschnitt
   "Workflow Designer"). Die Regeln stehen dort schon auf denselben
   Axiom-Tokens, die diese Anwendung nutzt -- umzurechnen war nichts.
   Weggelassen: alles, was nur zu einem Gespräch gehört (Chips für
   Antwortoptionen, der Timeout-Ausgang, die Kanal- und Absenderwahl, der
   Simulator). Was hier steht, hat ein Ziel in public/workflow-editor.js.
   -------------------------------------------------------------------- */

/* Bühne: Elementbar links, Fläche rechts */
.flow-buehne {
  display: grid;
  grid-template-columns: 232px 1fr;
  /* **Die Hoehe kommt vom Fenster, nicht vom Inhalt** -- die Flaeche scrollt
     in sich, sonst wuechse die Seite mit jedem Knoten weiter nach unten.
     In rcs steht hier `flex: 1`; das setzt voraus, dass jeder Vorfahr bis
     zum Body eine gebundene Hoehe hat. Hier sind es vier, und einer davon
     ist die gemeinsame `.view`-Regel -- ein `calc` ist an dieser Stelle das
     kleinere Uebel als vier Regeln, die nur wegen dieser einen Ansicht
     dastehen. */
  height: calc(100vh - 210px);
  min-height: 420px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--panel);
}

/* Die Editoransicht nutzt die volle Breite -- ein Canvas in 1240px waere
   die Haelfte des Schirms. */
.view.voll { max-width: none; }

.flow-palette {
  overflow-y: auto;
  padding: 12px;
  border-right: 1px solid var(--line);
  background: var(--panel);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.flow-palette-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  cursor: grab;
}

.flow-palette-item:hover { border-color: var(--accent); background: var(--accent-subtle); }

.flow-palette-item:active { cursor: grabbing; }

.flow-palette-name { font-size: 12.5px; font-weight: 600; }

.flow-palette-desc { font-size: 11px; color: var(--muted); line-height: 1.45; }

/* Die farbige Kachel trägt das Icon -- Farbe und Vordergrund kommen je
   Elementtyp aus dem JS. */
.flow-kachel {
  width: 30px; height: 30px;
  flex: none;
  border-radius: var(--radius-sm);
  background: var(--kachel);
  color: var(--kachel-fg);
  display: grid;
  place-items: center;
}

.flow-wrap {
  position: relative;
  overflow: auto;
  /* Ohne das dehnt die 3200 px breite Zeichenflaeche die Rasterspalte auf
     und damit die ganze Seite -- `1fr` allein begrenzt nicht, solange
     min-width auf `auto` steht. */
  min-width: 0;
  min-height: 0;
  background:
    radial-gradient(circle at 1px 1px, var(--line) 1.4px, transparent 0) 0 0/26px 26px,
    var(--bg);
}

.flow-canvas { position: relative; width: 3200px; height: 2000px; }

.flow-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

.flow-leer {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  pointer-events: none;
}

/* Knoten */
.flow-node {
  position: absolute;
  min-width: 210px;
  max-width: 264px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.flow-node.gewaehlt { box-shadow: 0 0 0 2px var(--accent), var(--shadow-sm); }

.flow-node.unfertig { border-color: var(--danger-border); }

.flow-node-kopf {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px;
  cursor: move;
  border-bottom: 1px solid var(--line-soft);
}

.flow-node-titel { font-weight: 600; font-size: 13px; flex: 1; min-width: 0; word-break: break-word; }

.flow-warn {
  flex: none;
  width: 20px; height: 20px;
  border-radius: var(--radius-full);
  background: var(--danger);
  color: #fff;
  display: grid;
  place-items: center;
  cursor: help;
}

/* Ändern und Löschen stehen dauerhaft da -- nur beim Überfahren kräftiger.
   Erst auf Hover zu erscheinen hiess: wer nicht zufällig darüberfährt,
   findet sie nicht. */
.flow-node-aktionen { display: flex; gap: 1px; flex: none; opacity: .55; transition: opacity .12s; }

.flow-node:hover .flow-node-aktionen,
.flow-node-aktionen:focus-within { opacity: 1; }

.flow-act {
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 4px;
  border-radius: var(--radius-full);
  color: var(--muted);
  display: grid;
  place-items: center;
}

.flow-act:hover { background: var(--panel-2); color: var(--text); }

.flow-act.loeschen:hover { background: var(--bg-error-subtle); color: var(--danger); }

.flow-act:disabled { opacity: .35; cursor: default; }

.flow-act:disabled:hover { background: transparent; color: var(--muted); }

.flow-typ {
  font-family: var(--font-mono);
  font-size: 9.5px;
  color: var(--muted);
  padding: 8px 12px 2px;
  text-transform: uppercase;
  letter-spacing: .09em;
}

.flow-blase {
  margin: 3px 12px 9px;
  padding: 8px 10px;
  background: var(--panel-2);
  border-radius: var(--radius-sm);
  font-size: 11.5px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

.flow-blase-marke {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--kachel-fg);
  background: var(--kachel);
  border-radius: var(--radius-full);
  padding: 2px 8px;
  margin-bottom: 6px;
}

.flow-notiz { font-size: 11px; color: var(--muted); padding: 0 12px 9px; line-height: 1.5; word-break: break-word; }

/* Ports und Ausgänge */
.flow-port {
  position: absolute;
  width: 14px; height: 14px;
  border-radius: var(--radius-full);
  background: var(--panel);
  border: 2px solid var(--muted-2);
  cursor: crosshair;
  z-index: 2;
}

.flow-port:hover { border-color: var(--accent); background: var(--accent-bg); }

/* Die Grifflaeche ist groesser als der Punkt -- 14 px trifft man mit der
   Maus nur mit Muehe, und ein danebengegangener Zug wirkt wie ein Fehler. */
.flow-port::before { content: ''; position: absolute; inset: -7px; border-radius: var(--radius-full); }

.flow-port.ein { left: -8px; top: 16px; }

.flow-port.aus { right: -8px; top: 7px; }

.flow-out {
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 6px;
  padding: 6px 12px;
  position: relative;
  min-height: 26px;
  border-top: 1px solid var(--line-soft);
}

.flow-out-text { text-align: right; flex: 1; min-width: 0; }

.flow-out-name { font-size: 11.5px; font-weight: 500; word-break: break-word; }

.flow-out-cond { font-size: 10px; color: var(--muted); font-family: var(--font-mono); margin-top: 2px; word-break: break-word; }

/* Kanten */
.flow-kante { fill: none; stroke: var(--muted-2); stroke-opacity: .5; stroke-width: 2; pointer-events: none; }

.flow-kante.vorschau { stroke: var(--accent); stroke-opacity: 1; stroke-dasharray: 5 4; }

.flow-kante-treffer { stroke: transparent; stroke-width: 16; fill: none; pointer-events: stroke; cursor: pointer; }

.flow-kante-g:hover .flow-kante { stroke: var(--accent); stroke-opacity: 1; }

.flow-pfeil { fill: var(--muted-2); fill-opacity: .5; }

.flow-kante-label { fill: var(--muted); font-family: var(--font-mono); font-size: 10.5px; }

.flow-kante-label-bg { fill: var(--panel); stroke: var(--line); }

.flow-kante-weg { cursor: pointer; opacity: 0; pointer-events: auto; }

.flow-kante-g:hover .flow-kante-weg { opacity: 1; }

.flow-kante-weg circle { fill: var(--panel); stroke: var(--line); }

.flow-kante-weg text { fill: var(--text); font-size: 12px; font-weight: 700; }

.flow-kante-weg:hover circle { fill: var(--danger); stroke: var(--danger); }

.flow-kante-weg:hover text { fill: #fff; }

/* Prüfleiste unter der Fläche */
/* Offene Punkte: ein Knopf oben rechts in der Flaeche, das Popup darunter.
   Frueher stand hier eine Leiste unter der Buehne -- die nahm der Zeichnung
   dauerhaft Hoehe weg, obwohl man sie nur beim Aufraeumen liest. */
.flow-pruef-ecke {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 6;                 /* ueber den Karten, wie die Zoomleiste */
}

.flow-fehler-knopf {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--line);
  border-radius: var(--radius-full);
  background: var(--panel);
  color: var(--text);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}

.flow-fehler-knopf:hover { background: var(--panel-2); }

.flow-fehler-knopf:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

.flow-fehler-zeichen {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-full);
  font-size: 12px;
  font-weight: 700;
  background: var(--bg-neutral);
  color: var(--muted);
}

.flow-fehler-knopf.hat-fehler {
  border-color: var(--danger-border);
  background: var(--bg-error-subtle);
  color: var(--danger);
}

.flow-fehler-knopf.hat-fehler .flow-fehler-zeichen { background: var(--danger); color: var(--panel); }

.flow-fehler-knopf.hat-warnung {
  border-color: var(--border-warning);
  background: var(--bg-warning-subtle);
  color: var(--warn-text);
}

.flow-fehler-knopf.hat-warnung .flow-fehler-zeichen { background: var(--warn-text); color: var(--panel); }

.flow-fehler-knopf.ist-ok { color: var(--success-text); border-color: var(--border-success); }

.flow-fehler-knopf.ist-ok .flow-fehler-zeichen { background: var(--bg-success-subtle); color: var(--success-text); }

.flow-pruefung {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 340px;
  max-width: min(340px, 60vw);
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--shadow-md);
  max-height: 260px;
  overflow-y: auto;
}

.flow-pruefung[hidden] { display: none; }

.flow-pruef-liste {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 12px 0 4px;
  max-height: 320px;
  overflow-y: auto;
}
/* Bühne und Maßstab, Zoomleiste, Prüf-Ecke — die Ergänzungen zu dem, was
   direkt aus rcs kam. */
.flow-buehne-flaeche { position: relative; }

.flow-zoom {
  position: absolute;
  right: 14px;
  bottom: 14px;
  display: flex;
  align-items: stretch;
  gap: 1px;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: var(--radius-full);
  background: var(--panel);
  box-shadow: var(--shadow-sm);
  /* Über den Karten, aber nicht im Weg beim Ziehen. */
  z-index: 5;
}
.flow-zoom-knopf, .flow-zoom-stufe {
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--text);
  font: inherit;
  border-radius: var(--radius-full);
  padding: 4px 10px;
  line-height: 1.2;
}
.flow-zoom-knopf { font-size: 16px; width: 32px; }
.flow-zoom-stufe { font-size: 12px; font-weight: 600; min-width: 62px; font-variant-numeric: tabular-nums; }
.flow-zoom-knopf:hover, .flow-zoom-stufe:hover { background: var(--panel-2); }
.flow-zoom-knopf:disabled { color: var(--disabled); cursor: default; background: transparent; }

.flow-pruef-titel {
  margin: 10px 0 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.flow-pruef-titel:first-child { margin-top: 0; }
.flow-pruef-zeile {
  margin: 0 0 5px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--text);
  overflow-wrap: anywhere;
}
.flow-pruef-zeile.hinweis { color: var(--muted); }

/* Ein Hinweis, der auf etwas Fehlendes zeigt — nicht dieselbe Farbe wie eine
   gewöhnliche Erläuterung. */
.hint.warnend { color: var(--warn-text); }

/* Der Kopf der Editoransicht. */
.flow-kopf {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.flow-name {
  flex: 1;
  min-width: 200px;
  max-width: var(--max-md);
  font-size: 15px;
  font-weight: 600;
}
.flow-kopf-aktionen { display: flex; align-items: center; gap: 8px; margin-left: auto; }

/* --- Durchspielen ---------------------------------------------------------
   Ein Streifen rechts neben der Fläche. Die Fläche wird schmaler statt
   überdeckt: wer durchspielt, will den Weg auf der Zeichnung sehen, und ein
   Panel darüber verdeckte genau das. */
.flow-buehne.mit-sim { grid-template-columns: 232px 1fr 320px; }
.flow-sim {
  overflow-y: auto;
  padding: 12px 14px 20px;
  border-left: 1px solid var(--line);
  background: var(--panel);
}
.flow-sim-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.sim-regler { display: flex; align-items: center; gap: 10px; }
.sim-regler input[type="range"] { flex: 1; min-width: 0; padding: 0; }
.sim-wert {
  min-width: 46px;
  text-align: end;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.sim-ergebnis { margin-top: 16px; }
.sim-schritte { display: flex; flex-direction: column; gap: 6px; }
.sim-schritt {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel-2);
}
.sim-nr {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-full);
  background: var(--pill);
  font-size: 11px;
  font-weight: 600;
}
.sim-titel { font-size: 12.5px; font-weight: 600; overflow-wrap: anywhere; }
.sim-notiz { font-size: 11px; color: var(--muted); }
.sim-menge { font-size: 11px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.sim-abschluss { margin: 0; font-size: 13px; font-weight: 600; }

/* Der zurückgelegte Weg auf der Fläche. Der Akzent als Rahmen, nicht als
   Fläche: eine eingefärbte Karte wäre nicht mehr zu lesen. */
.flow-node.besucht { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-subtle), var(--shadow-sm); }
.flow-kante-g.besucht .flow-kante { stroke: var(--accent); stroke-opacity: 1; stroke-width: 2.5; }
.flow-kante-g.besucht .flow-pfeil { fill: var(--accent); fill-opacity: 1; }

/* --- Der Konfigurator: Reiter und Seitenspalte ----------------------------
   Sechs Karten untereinander waren eine Seite, die man von oben nach unten
   abarbeitet — und bei jeder Änderung an Schritt 4 nach unten scrollen musste,
   um zu sehen, was sie kostet. Die Schätzung steht jetzt daneben und bleibt
   stehen. */
.tabs {
  display: flex;
  gap: 2px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
}
.tab {
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  padding: 9px 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  /* Der Rand liegt AUF der Trennlinie der Leiste, nicht darunter -- sonst
     entstünde beim Wechsel ein Sprung von zwei Pixeln. */
  margin-bottom: -1px;
  border-radius: var(--radius) var(--radius) 0 0;
}
.tab:hover { color: var(--text); background: var(--panel-2); }
.tab.aktiv { color: var(--accent); border-bottom-color: var(--accent-bg); font-weight: 600; }
.tab:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }

.editor-raster {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 16px;
}
/* Der Inhalt ist so hoch wie er ist; die Seitenspalte nimmt die volle Höhe
   der Zeile. */
.editor-inhalt { align-self: start; min-width: 0; }
.editor-seite { min-width: 0; }

/* **Kleben kann nur, was Platz zum Wandern hat.** `position: sticky` bewegt
   ein Element innerhalb SEINER Zelle -- ist die Zelle so hoch wie das Element
   selbst, bleibt kein Weg, und es scrollt einfach mit. Deshalb zwei Ebenen:
   die Spalte nimmt die Höhe der Zeile, der Kasten darin klebt.
   (Genau das war der Fehler: mit `align-items: start` am Raster war die Zelle
   inhaltshoch, und `sticky` tat nichts -- sichtbar erst beim Scrollen.) */
.editor-klebt {
  position: sticky;
  top: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.editor-klebt .hinweis-kasten { margin: 0; }
/* **Die Abfrage misst das FENSTER, der Konfigurator steht aber neben der
   Seitenleiste** — von der Fensterbreite gehen 232 px Navigation und 44 px
   Innenabstand ab. Damit die Inhaltsspalte nicht unter 560 px fällt, braucht
   die zweispaltige Form ein Fenster von rund 1150 px; 1200 ist der bequeme
   Rand. Dieselbe Falle steht weiter oben schon bei den Tabellen. */
@media (max-width: 1200px) {
  .editor-raster { grid-template-columns: 1fr; }
  .editor-klebt { position: static; }
}

/* Offene Punkte in der Seitenspalte — sie gehören dorthin, weil sie auf jedem
   Reiter gelten: was auf Schritt 3 fehlt, sieht man sonst nicht, solange man
   auf Schritt 4 steht. */
.offene-punkte {
  padding: 12px 14px;
  border: 1px solid var(--border-warning);
  border-radius: var(--radius);
  background: var(--bg-warning-subtle);
  font-size: 12px;
}
.offene-punkte.fertig { border-color: var(--border-success); background: var(--bg-success-subtle); }
.offene-punkte p { margin: 0 0 6px; font-weight: 600; color: var(--text); }
.offene-punkte .fehlerliste { font-size: 12px; }
.editor-seite .offene-punkte { margin: 0; }

/* --- Vorlagen-Galerie ---------------------------------------------------- */
.vorlagen-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}
.vorlagen-kopf p { margin: 0 0 4px; }
.vorlagen-kopf .btn { flex: none; white-space: nowrap; }
.vorlagen-gruppe { margin-bottom: 26px; }
.vorlagen-titel {
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--muted);
}
.vorlage-karte .ax-card-footer { flex-wrap: wrap; align-items: center; }
.vorlage-karte .ax-card-footer .btn { margin-left: auto; }
