/* ==========================================================================
   vFlow theme overrides on top of UI5 sap_horizon.
   Tokens are the source of truth (./tokens.css) - only selector-level
   mapping onto UI5-rendered DOM classes happens here. See CLAUDE.md
   (project root) for the full design-system guide this implements.
   ========================================================================== */

html,
body.sapUiBody {
  font-family: var(--vf-font-sans);
  background: var(--vf-bg);
  color: var(--vf-text);
}

/* ---- Horizon theme parameters: brand color throughout the app ----------
   Per CLAUDE.md: map tokens onto Horizon CSS custom properties rather than
   fighting individual control CSS classes (some, e.g. Button's "Inverted"
   fill, live in the UI5 CDN stylesheet and aren't overridable by class
   alone since the color itself is read from these variables). !important
   is needed here: UI5's own theme :root rule is injected at runtime after
   this stylesheet, so equal-specificity source order would otherwise win. */
:root {
  --sapBrandColor: var(--vf-primary) !important;
  --sapHighlightColor: var(--vf-primary-hover) !important;
  --sapSelectedColor: var(--vf-primary-hover) !important;
  --sapActiveColor: var(--vf-brand-100) !important;
  --sapLinkColor: var(--vf-link) !important;
  --sapContent_FocusColor: var(--vf-primary) !important;
  --sapButton_Emphasized_Background: var(--vf-primary) !important;
  --sapButton_Emphasized_BorderColor: var(--vf-primary) !important;
  --sapButton_Emphasized_TextColor: var(--vf-neutral-0) !important;
  --sapButton_Emphasized_Hover_Background: var(--vf-primary-hover) !important;
  --sapButton_Emphasized_Hover_BorderColor: var(--vf-primary-hover) !important;
  --sapButton_Emphasized_Active_Background: var(--vf-primary-active) !important;
  --sapButton_Emphasized_Active_BorderColor: var(--vf-primary-active) !important;
}

/* ---- Typography baseline ------------------------------------------------ */
.sapMText,
.sapMLabel,
.sapMTitle,
.sapMInputBaseInner,
.sapMBtnContent {
  font-family: var(--vf-font-sans);
}

/* Technical values (flow keys, correlation IDs, timestamps) - applied via
   class="vfMono" on the relevant sap.m.Text controls. */
.vfMono {
  font-family: var(--vf-font-mono) !important;
  font-size: var(--vf-fs-sm);
  color: var(--vf-text-secondary);
}

/* Editable technical fields (CSV column lists, element names) - mono font but
   normal input color/size, unlike the read-only .vfMono above. Applied via
   class="vfMonoField" on sap.m.Input / sap.m.TextArea (targets the inner
   editable element). */
.vfMonoField .sapMInputBaseInner,
.vfMonoField textarea {
  font-family: var(--vf-font-mono) !important;
}

/* ---- Page header / top bar --------------------------------------------- */
.sapMPageHeader {
  background: var(--vf-surface);
  border-bottom: 1px solid var(--vf-border);
  box-shadow: none;
}

.sapMPageHeader .sapMTitle {
  font-weight: var(--vf-fw-semibold);
  color: var(--vf-text);
}

/* ---- Buttons ------------------------------------------------------------ */
/* Emphasized (primary) button color comes from the --sapButton_Emphasized_*
   theme parameters above, not from a class override - Horizon renders the
   Button's colored fill on the outer element via those variables. */
.sapMBtn {
  border-radius: var(--vf-radius-sm);
}

/* ---- Inputs -------------------------------------------------------------- */
.sapMInputBase {
  border-radius: var(--vf-radius-sm);
}

.sapMInputBaseContentWrapper {
  border-color: var(--vf-border-strong);
}

.sapMInputBase.sapMInputBaseIconContainer:focus-within,
.sapMInputBase:focus-within {
  box-shadow: var(--vf-shadow-focus);
}

/* ---- IconTabBar: active brand color instead of stock Fiori blue --------- */
.sapMITBFilter .sapMITBText {
  color: var(--vf-text-secondary);
}

.sapMITBFilter.sapMITBSelected .sapMITBText {
  color: var(--vf-primary);
}

.sapMITBFilter .sapMITBFilterIcon {
  background: transparent;
  border-color: var(--vf-border-strong);
  color: var(--vf-text-secondary);
}

.sapMITBFilter.sapMITBSelected .sapMITBFilterIcon {
  background: var(--vf-primary);
  border-color: var(--vf-primary);
  color: var(--vf-neutral-0);
}

.sapMITBFilter.sapMITBSelected .sapMITBContentArrow {
  border-top-color: var(--vf-primary);
}

/* Selection underline bar is a ::after pseudo-element, not a real child. */
.sapMITBFilter.sapMITBSelected::after {
  border-bottom-color: var(--vf-primary) !important;
}

/* ---- Tables: dense rows, zebra, sticky header, right-aligned numerics --- */
.sapMTableTHead {
  background: var(--vf-surface-sunk);
  border-bottom: 1px solid var(--vf-border);
}

.sapMListTblHeaderCell {
  font-weight: var(--vf-fw-medium);
  color: var(--vf-text-secondary);
  font-size: var(--vf-fs-sm);
}

.sapMListTbl .sapMLIB:nth-child(even) {
  background: var(--vf-surface-sunk);
}

.sapMListTbl .sapMLIB:hover {
  background: var(--vf-brand-50);
}

/* ---- Status badges: pill with leading dot instead of plain colored text - */
.sapMObjStatus {
  display: inline-flex;
  align-items: center;
  gap: var(--vf-space-2);
  padding: 1px var(--vf-space-4) 1px var(--vf-space-3);
  border-radius: var(--vf-radius-pill);
  font-size: var(--vf-fs-caption);
  font-weight: var(--vf-fw-medium);
  border: 1px solid transparent;
}

.sapMObjStatus::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: none;
}

.sapMObjStatusSuccess {
  background: var(--vf-success-bg);
  border-color: var(--vf-success-border);
  color: var(--vf-success);
}
.sapMObjStatusSuccess::before {
  background: var(--vf-success);
}

.sapMObjStatusWarning {
  background: var(--vf-warning-bg);
  border-color: var(--vf-warning-border);
  color: var(--vf-warning);
}
.sapMObjStatusWarning::before {
  background: var(--vf-warning);
}

.sapMObjStatusError {
  background: var(--vf-error-bg);
  border-color: var(--vf-error-border);
  color: var(--vf-error);
}
.sapMObjStatusError::before {
  background: var(--vf-error);
}

.sapMObjStatusNone {
  background: var(--vf-surface-sunk);
  border-color: var(--vf-border);
  color: var(--vf-text-secondary);
}
.sapMObjStatusNone::before {
  background: var(--vf-text-muted);
}

/* ---- Dialogs / popovers: vFlow radii + shadows -------------------------- */
.sapMDialog {
  border-radius: var(--vf-radius-lg);
  box-shadow: var(--vf-shadow-lg);
}

.sapMDialogTitleGroup {
  font-weight: var(--vf-fw-semibold);
}

.sapMPopover {
  border-radius: var(--vf-radius-md);
  box-shadow: var(--vf-shadow-md);
}

/* ---- Dashboard stat tiles (Cards, CLAUDE.md Abschnitt 6) ----------------- */
.vfStatTile {
  background: var(--vf-surface);
  border: 1px solid var(--vf-border);
  border-radius: var(--vf-radius-md);
  box-shadow: var(--vf-shadow-sm);
  padding: var(--vf-space-6);
  gap: var(--vf-space-2);
}

.vfStatTileLabel {
  color: var(--vf-text-secondary);
  font-size: var(--vf-fs-sm);
}

/* Klickbare Kacheln (Stefan-Wunsch 2026-07-20: "37 Failed" -> direkt zur
   gefilterten Liste springen). VBox hat kein eigenes press-Event, siehe
   Dashboard.controller.js#onAfterRendering - hier nur die visuelle/
   Tastatur-Fokus-Seite davon. */
.vfStatTileClickable {
  cursor: pointer;
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.vfStatTileClickable:hover {
  box-shadow: var(--vf-shadow-md);
  border-color: var(--vf-border-strong);
}
.vfStatTileClickable:focus-visible {
  outline: none;
  box-shadow: var(--vf-shadow-focus);
}

.vfStatTileValue {
  font-size: var(--vf-fs-display);
  font-weight: var(--vf-fw-semibold);
  color: var(--vf-text);
}

.vfStatTileError {
  /* !important: UI5's own text-color rule for .sapMText is injected at
     runtime after this stylesheet, so equal specificity would win by
     source order otherwise - same trap as the Button color override. */
  color: var(--vf-error) !important;
}

.vfStatTileSuccess {
  color: var(--vf-success) !important;
}

.vfStatTileWarn {
  color: var(--vf-warning) !important;
}

/* Icon-Badge oben in jeder Stat-Kachel (Stefan, 2026-07-17: "Kacheln ein
   wenig aufwerten") - gleiches Rounded-Square-Rezept wie .vfCardIconBadge,
   nur etwas größer und mit Tint-Varianten je Kachel-Semantik statt fix
   violett. */
.vfStatTileIcon {
  box-sizing: border-box;
  width: 28px !important;
  height: 28px !important;
  line-height: 28px !important;
  margin: 0 !important;
  border-radius: var(--vf-radius-sm);
  font-size: 15px !important;
  text-align: center;
}
.vfStatTileIconNeutral {
  background: var(--vf-surface-sunk);
  color: var(--vf-text-secondary) !important;
}
.vfStatTileIconPrimary {
  background: var(--vf-primary-subtle);
  color: var(--vf-primary) !important;
}
.vfStatTileIconError {
  background: var(--vf-error-bg);
  color: var(--vf-error) !important;
}
.vfStatTileIconSuccess {
  background: var(--vf-success-bg);
  color: var(--vf-success) !important;
}

/* ---- Dashboard welcome header + Fuchs-Maskottchen (Valcoba-Branding,
   Stefan-Wunsch 2026-07-17) - bewusst nur hier, kein Wiederholungsmotiv:
   vFlows eigener Indigo-Akzent bleibt der einzige Funktionsfarbton (CLAUDE.md
   §2), der Fuchs ist reine Markenpflege im Willkommens-Header, keine
   UI-Farbänderung. ---------------------------------------------------------- */
.vfWelcomeHeader {
  background: var(--vf-surface);
  border: 1px solid var(--vf-border);
  border-radius: var(--vf-radius-md);
  box-shadow: var(--vf-shadow-sm);
  padding: var(--vf-space-6) var(--vf-space-7);
  overflow: hidden;
}

.vfWelcomeFox {
  height: 96px;
  width: auto;
  flex: none;
  /* Leichter Versatz nach unten/rechts raus - der Fuchs "sitzt" am
     Kartenrand statt mittig zu schweben. */
  margin: 0 calc(var(--vf-space-7) * -1) calc(var(--vf-space-4) * -1) 0;
}

/* Handy-Ansicht Dashboard/Alerts (Stefan, 2026-08-06: "kurz auf dem Handy
   nach dem Rechten schauen") - bewusst nur diese beiden Screens, alles
   andere (Monitoring-Tabellen, FlowEditor) bleibt Desktop-fokussiert.
   599px = UI5s eigene Phone-Grenze (sap.ui.Device.media, dieselbe Schwelle,
   die minScreenWidth="Tablet" in den *.view.xml-Popin-Spalten meint). Der
   Fuchs ist reines Branding (siehe oben) - auf dem schmalen Screen frisst er
   nur Platz, den die Begrüßung sonst hätte. */
@media (max-width: 599px) {
  .vfWelcomeFox {
    display: none;
  }
}

/* Valcoba-Logo auf der About-Seite (Kontakt-Kachel, Stefan-Wunsch
   2026-08-05) - bewusst nur dort, nicht im Shell-Header: die Topbar ist
   vFlows eigene, prominenteste Markenfläche (CLAUDE.md §2, "own accent
   color"), Orange neben dem Indigo-Primary würde dort wie eine zweite,
   konkurrierende Marke wirken. Im Kontaktblock ist es reine Firmen-Info,
   unproblematisch wie beim Fuchs oben. */
.vfValcobaLogo {
  height: 40px;
  width: auto;
}

/* ---- Dashboard-Widgets (Braucht Aufmerksamkeit / Letzte Aktivität / Offene
   Alerts) - je eine .vfCard mit Titel+Untertitel-Kopf und einer dichten
   Tabelle (CLAUDE.md §6: Tables sind der Workhorse von Dashboard &
   Monitoring). ---------------------------------------------------------- */
.vfDashboardWidgetHead {
  gap: var(--vf-space-1);
}

.vfDashboardCount {
  font-family: var(--vf-font-mono) !important;
  font-weight: var(--vf-fw-semibold);
}

/* ---- Flow-Editor Pipeline (Sender-Adapter-Routing-Mapping-Adapter-Receiver)
   Feste Breite (statt min-width) auf Boxen/Pfeilen/Labels, damit die
   Kopfzeile mit den Spaltenbeschriftungen exakt über den Box-Reihen der
   einzelnen Zweige fluchtet. */
.vfPipelineBox {
  width: 140px;
  flex: none;
}

.vfPipelineBox .sapMBtnInner {
  border-radius: var(--vf-radius-md) !important;
  border: 1px solid var(--vf-border-strong) !important;
  background: var(--vf-surface) !important;
  color: var(--vf-text) !important;
  height: 48px !important;
  white-space: normal !important;
}

/* Waagerechter Verbinder zwischen zwei Pipeline-Karten: echte Linie von
   Kante zu Kante (Schaft + Pfeilspitze) statt eines freistehenden Glyphs. Die
   Karten liegen ohne Gap direkt neben dem 32px-Element, daher berührt die
   Linie beide Kartenränder. Der →-Glyph wird über font-size:0 ausgeblendet. */
.vfPipelineArrow {
  width: var(--vf-pipeline-gap);
  flex: none;
  /* Der Verbinder ist genau so hoch wie eine Karte und traegt seine Linie auf
     halber Hoehe (top:50% unten) - damit trifft er die Kartenmitte, ganz egal
     wie die umgebende HBox ausgerichtet ist. Vorher war er 12px hoch und mit
     align-self:center zentriert; das ging aus zwei Gruenden schief (Stefan,
     2026-08-08: "Wieso ist der Pfeil bei den ersten zwei Boxen oben und dann
     wechselt es in die Mitte"):
       1. align-self wirkte gar nicht. UI5 haengt jedes FlexBox-Kind in einen
          eigenen <div class="sapMFlexItem"> - ausgerichtet wird dieser, nicht
          das Control darin. In der oberen Kette steht alignItems="Start"
          (FlowEditor.view.xml), die 29px hohe Huelle klebte also oben in der
          96px hohen Reihe: Pfeil 25px zu hoch.
       2. Auch in den zentrierten Zweig-Reihen sass er 8px zu tief, weil
          .sapMText das Control auf inline-block zwingt - als Inline-Box steht
          es auf der Textgrundlinie, und die Huelle wird um die Unterlaenge
          hoeher als der Pfeil selbst.
     align-self:flex-start ist wichtig fuer den Bridge-Modus: dort ist die
     Sender-Spalte hoeher als eine Karte (Antwort-Box darunter), zentriert
     wuerde der Verbinder auf die Mitte dieses Stapels rutschen statt auf die
     Kartenreihe. */
  align-self: flex-start;
  /* !important: UI5 laedt .sapMText NACH dem App-CSS bei gleicher
     Spezifitaet - ohne !important bliebe es bei inline-block (Grund 2 oben)
     und der ausgeblendete →-Glyph sichtbar (font-size). */
  display: block !important;
  position: relative;
  height: var(--vf-pipeline-card-h);
  font-size: 0 !important;
  color: transparent;
}
.vfPipelineArrow::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 5px;
  height: 2px;
  margin-top: -1px;
  background: var(--vf-border-strong);
}
.vfPipelineArrow::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  margin-top: -5px;
  width: 0;
  height: 0;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 7px solid var(--vf-border-strong);
}

.vfPipelineArrowSpacer {
  width: var(--vf-pipeline-gap);
  flex: none;
}

/* Async-Sync Bridge (adapter-plugin.md Abschnitt 7): Rückspur unter der
   Hinspur. Der Response-Adapter stand früher als eigene Spalte unter dem
   SENDER, mit einem senkrechten Pfeil dazwischen - das legte nahe, die
   Antwort ginge an den Sender zurück. Sie geht aber an ein frei gewähltes,
   unabhängiges Ziel (§7: "kein Bezug zum Sender- oder Receiver-Adaptertyp";
   Stefans Testflow hat einen REST-Sender und schreibt die Antwort in eine
   Datei). Deshalb jetzt eine eigene Reihe, gelesen von rechts nach links:
   Receiver -> Response-Mapping -> Response-Adapter -> hinaus. Die Verbinder
   dieser Reihe zeichnet _drawBranchConnectors als SVG, weil sie über die
   Grenze zwischen linker Kette und Zweig-Stapel hinweglaufen. */
.vfResponseRow {
  margin-top: var(--vf-space-7);
}
/* Hält den Response-Adapter unter dem Inbound-Adapter (Breite von Sender-
   Karte + Verbinder), statt ihn an den linken Rand zu setzen. */
.vfResponseRowSpacer {
  width: calc(var(--vf-pipeline-card-w) + var(--vf-pipeline-gap));
  flex: none;
}

.vfPipelineLabel {
  width: 140px;
  flex: none;
  text-align: center;
  color: var(--vf-text-secondary);
  font-size: var(--vf-fs-sm);
  font-weight: var(--vf-fw-medium);
}

/* Senkrechter Verbinder Routing -> Zweige, unter der Routing-Box zentriert
   (flow-editor.md Layout-Korrektur, ASCII-Diagramm Abschnitt 4). */
/* Fan-out-Canvas: geteilte Kette links, Zweig-Stapel rechts. Die
   Fan-out-Verbinder zeichnet _drawBranchConnectors als absolutes SVG-Overlay
   ueber diese (relativ positionierte) Stage. */
.vfFlowStage {
  position: relative;
}
.vfSharedChain {
  flex: none;
}
.vfBranchStack {
  flex: none;
  /* Luecke fuer die Fan-out-Verbinder zwischen Routing und Mapping. */
  margin-left: 64px;
}
.vfBranchItem {
  margin-bottom: 16px;
}
/* SVG-Overlay: unter den Karten, faengt keine Klicks ab; currentColor traegt
   die Verbinderfarbe an stroke/fill weiter. */
.vfFanoutSvg {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  color: var(--vf-border-strong);
}

.vfBranchesSection {
  gap: var(--vf-space-2);
}

/* Zweig-Liste: eigene Boxen tragen bereits Rahmen/Schatten - die Listenzeile
   selbst soll unsichtbar bleiben, kein doppelter Rahmen/Zebra-Hintergrund. */
.vfBranchesList .sapMLIB {
  background: transparent;
  border: none;
  padding: 0;
}

.vfBranchesList .sapMLIB:hover {
  background: transparent;
}

/* Kleingedrucktes unter einem Adapter-Config-Feld (adapter-config-schema.ts
   auf dem Backend, field.helpText) - z. B. "Default 30 Sekunden". */
.vfFieldHelp {
  display: block;
  /* !important: UI5s .sapMText wird erst zur Laufzeit nach dem App-CSS geladen
     und gewinnt sonst bei gleicher Spezifität (14px/Default-Farbe) - dadurch
     wirkten Untertexte/Hinweise faelschlich so gross wie normaler Text. */
  color: var(--vf-text-muted) !important;
  font-size: var(--vf-fs-caption) !important;
}

/* Beschreibungstext in einer dichten Tabellenzeile auf zwei Zeilen kappen.
   Gebraucht seit dem Messages-Standard-Katalog (docs/architecture/
   message-catalog.md): Katalog-Beschreibungen sind ganze Saetze und trieben
   die Zeilenhoehe von den im Design-System vorgesehenen 36-40px auf ueber
   120px. Der volle Text bleibt ueber das Title-Attribut/den Dialog
   erreichbar. */
.vfClamp2 {
  display: -webkit-box !important;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Zweispaltiges Formular im Property-Panel des Flow Editors (SAP-Integration-
   Suite-Optik): Label links (fett, rechtsbündig), Eingabefeld rechts.
   Aufgebaut in FlowEditor.controller.js#_addFormRow als HBox[Label | VBox]. */
.vfFormRow {
  align-items: flex-start;
  gap: var(--vf-space-4);
  padding: var(--vf-space-2) 0;
}
.vfFormRow > .vfFormLabel {
  flex: 0 0 27%;
  max-width: 27%;
  min-width: 120px;
  /* linksbündig (Stefan-Review 2026-07-10: die frühere rechtsbündige SAP-Optik
     drückte die Labels an die Feldspalte; linksbündig + schmalere Spalte liest
     sich ruhiger). !important, da UI5s .sapMLabel eine eigene text-align-Regel
     mitbringt, die sonst bei gleicher Spezifität nach dem App-CSS gewinnt. */
  text-align: left !important;
  /* auf die Textzeile des 32px hohen Eingabefelds ausrichten */
  padding-top: 7px;
  /* !important: UI5s .sapMLabel-Farbe wird erst zur Laufzeit nach dem App-CSS
     geladen und gewinnt sonst bei gleicher Spezifität (gedämpftes Grau) -
     Stefan möchte kräftigere Labels (siehe CLAUDE.md §4). */
  color: var(--vf-text) !important;
}
/* UI5 rendert das Label als inline-flex (.sapMLabelInner) und packt den
   Textteil per justify-content ans Ende - text-align auf dem Label greift bei
   Flex-Kindern nicht. Für echte Linksbündigkeit hier den inneren Flex umstellen. */
.vfFormRow > .vfFormLabel .sapMLabelInner {
  justify-content: flex-start !important;
}
.vfFormRow > .vfFormField {
  flex: 1 1 auto;
  /* min-width:0, damit lange Werte/Inputs in der Flex-Spalte schrumpfen dürfen
     statt die Zeile zu sprengen. */
  min-width: 0;
  gap: var(--vf-space-1);
}

/* Kicker-Überschrift einer Feld-Untergruppe (adapter-config-schema.ts
   field.section), analog SAP CONNECTION/ADVANCED SETTING. */
.vfFormSection {
  display: block;
  margin: var(--vf-space-5) 0 var(--vf-space-2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  /* !important: gleiche .sapMText-Übersteuerung wie bei .vfFieldHelp. */
  font-size: var(--vf-fs-caption) !important;
  font-weight: 600 !important;
  color: var(--vf-text-secondary) !important;
}
.vfFormSection:first-child {
  margin-top: 0;
}

/* Mapping Studio (mapping-studio.md): Kicker neben dem Typ-Select ohne
   Block-Abstand, und etwas Luft zwischen den Sample-Steuerelementen. */
.vfStudioKicker {
  margin: 0 var(--vf-space-3) 0 0 !important;
}
.vfStudioSampleBar {
  gap: var(--vf-space-2);
  align-items: center;
}

/* Pfadleiste im Server-Verzeichnis-Browser (Value-Help der Verzeichnis-Felder). */
.vfDirBrowseBar {
  gap: var(--vf-space-2);
  padding: var(--vf-space-3);
  border-bottom: 1px solid var(--vf-border);
}
/* Breadcrumb (Stefan, 2026-07-13): jedes Segment ein Link außer dem
   letzten (aktuelles Verzeichnis, reiner Text) - nur die Text-Kinder
   (Trenner "/" + letztes Segment) bekommen die gedämpfte Farbe, Links
   behalten ihre normale Link-Farbe. */
.vfDirBrowsePath {
  flex-wrap: wrap;
}
.vfDirBrowsePath > .sapMText {
  color: var(--vf-text-secondary);
}

/* ---- Rechts-Drawer (model/drawer.js) ------------------------------------ */
.vfDrawerScrim {
  position: fixed;
  inset: 0;
  background: rgba(23, 26, 34, 0.32);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
  /* z-index bewusst NIEDRIG (unter UI5s Popup-Bereich, der bei ~10 startet):
     so erscheinen Select-Dropdowns/DatePicker/MessageBox IM bzw. ÜBER dem
     Drawer statt dahinter. Über dem App-Inhalt (z-index auto) liegt der Drawer
     trotzdem. Nebeneffekt: eine modale MessageBox blockt den Drawer jetzt
     korrekt (ihr Blocklayer liegt darüber). */
  z-index: 8;
}
#vfDrawerHost.vfDrawerOpen .vfDrawerScrim {
  opacity: 1;
  pointer-events: auto;
}
.vfDrawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: 440px;
  max-width: 92vw;
  box-sizing: border-box;
  padding: var(--vf-space-7);
  overflow-y: auto;
  /* !important: .sapMFlexBoxBGTransparent-Falle (VBox ohne backgroundDesign). */
  background: var(--vf-surface) !important;
  box-shadow: var(--vf-shadow-lg);
  transform: translateX(100%);
  transition: transform 0.25s ease;
  z-index: 9;
}
#vfDrawerHost.vfDrawerOpen .vfDrawer {
  transform: translateX(0);
}
.vfDrawerHeader {
  margin-bottom: var(--vf-space-6);
  /* Platz für den absolut positionierten Close-Button (unten) reservieren,
     sonst läuft ein langer Titel/Untertitel unter ihm durch. */
  padding-right: var(--vf-space-10);
  /* UI5 setzt auf jede sap.m.HBox/VBox generell position:relative (eigene
     interne Zwecke) - das würde den Close-Button (s.u.) relativ zu DIESER
     Zeile statt zum ganzen Drawer positionieren. !important nötig, s. dort. */
  position: static !important;
}
/* UI5 wrappt außerdem jedes Flexbox-Kind einzeln in einen eigenen
   position:relative-Div (.sapMFlexItemAlignAuto) - der direkte Wrapper um
   den Close-Button muss ebenso neutralisiert werden, sonst positioniert sich
   der Button relativ zu diesem winzigen Wrapper statt zum Drawer. Scoped auf
   .vfDrawerHeader, um keine anderen Flexbox-Wrapper in der App zu treffen. */
.vfDrawerHeader > div:has(> .vfDrawerClose) {
  position: static !important;
}
.vfDrawerClose {
  /* Oben rechts bündig zur Drawer-Ecke statt in der Header-Zeile zentriert
     (Stefan, 2026-07-27) - .vfDrawer ist position:fixed und damit (nach den
     beiden Overrides oben) der nächste Containing Block. !important nötig:
     UI5s .sapMBtnBase setzt selbst position:relative, gleiche Spezifität,
     aber später im Quellcode injiziert (project_vflow_ui5_theming_quirks). */
  position: absolute !important;
  top: var(--vf-space-3) !important;
  right: var(--vf-space-3) !important;
  margin: 0 !important;
}
.vfDrawerFooter {
  gap: var(--vf-space-2);
  margin-top: var(--vf-space-7);
}

/* Rollen-Auswahl (Users New/Edit): Zeilen als abgesetzte Cards mit etwas
   Abstand statt aneinanderklebender Listenzeilen. */
.vfRoleList .sapMLIB {
  margin-bottom: var(--vf-space-2);
  border-radius: var(--vf-radius-sm);
}
.vfRoleList .sapMLIB:last-child {
  margin-bottom: 0;
}

/* Flow-Freigabe (Technical Users): bei vielen Flows die Checkbox-Liste in einen
   eigenen, scrollbaren Bereich fassen, damit Credentials/Settings darunter
   erreichbar bleiben statt endlos nach unten geschoben zu werden. */
.vfFlowAccessList {
  max-height: 15rem;
  overflow-y: auto;
}

/* Inbound-Zugangsdaten (Systems > Zugriff): einmalig sichtbares Secret + Liste. */
.vfSecretBox {
  gap: var(--vf-space-2);
  padding: var(--vf-space-4);
  border: 1px solid var(--vf-brand-200);
  border-radius: var(--vf-radius-md);
  /* !important: .sapMFlexBoxBGTransparent-Falle. */
  background: var(--vf-brand-50) !important;
  margin-bottom: var(--vf-space-4);
}
.vfSecretTitle {
  font-weight: var(--vf-fw-semibold);
}
.vfSecretValue {
  word-break: break-all;
  font-size: var(--vf-fs-sm) !important;
  color: var(--vf-text) !important;
}
.vfCredRow {
  padding: var(--vf-space-2) 0;
}
.vfCredTitle {
  font-weight: var(--vf-fw-medium);
}
/* Gefahr-Aktion (z. B. Technical User löschen) - roter Transparent-Button. */
.vfDeleteButton .sapMBtnContent,
.vfDeleteButton .sapUiIcon {
  color: var(--vf-error) !important;
}

/* Kalter Start (App.controller.js#_showColdStartCover): blendet die
   ToolPage-Shell (Sidebar mit allen Menüpunkten) beim allerersten,
   noch nie erfolgreich eingeloggten Aufruf aus - sonst wirkt die
   Login-Karte, als läge schon eine aktive Session dahinter. z-index
   niedrig genug, um unter UI5s Popup-Bereich (~10, siehe .vfDrawer) zu
   bleiben, aber über dem normalen Seiteninhalt (z-index auto). */
.vfColdStartCover {
  position: fixed;
  inset: 0;
  background: var(--vf-bg);
  z-index: 2;
}

/* Testlizenz abgelaufen (App.controller.js#_showLicenseExpiredCover,
   docs/architecture/licensing.md Abschnitt 3): gleiche Technik/z-index wie
   .vfColdStartCover, ersetzt aber die normale Navigation nach dem Login
   durch einen erklärenden Hinweis statt sie nur zu verstecken. */
.vfLicenseExpiredCover {
  position: fixed;
  inset: 0;
  background: var(--vf-bg);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
}
.vfLicenseExpiredCard {
  max-width: 420px;
  padding: var(--vf-space-8);
  background: var(--vf-surface);
  border: 1px solid var(--vf-border);
  border-radius: var(--vf-radius-md);
  box-shadow: var(--vf-shadow-md);
  text-align: center;
}
.vfLicenseExpiredIcon {
  width: 48px;
  height: 48px;
  margin: 0 auto 16px;
  border-radius: 50%;
  background: var(--vf-warning-bg);
}
.vfLicenseExpiredIcon::before {
  content: "!";
  display: block;
  line-height: 48px;
  font-family: var(--vf-font-sans);
  font-weight: var(--vf-fw-semibold);
  font-size: 22px;
  color: var(--vf-warning);
}
.vfLicenseExpiredCard h1 {
  margin: 0 0 8px;
  font-family: var(--vf-font-sans);
  font-size: 18px;
  font-weight: var(--vf-fw-semibold);
  color: var(--vf-text);
}
.vfLicenseExpiredCard p {
  margin: 0 0 20px;
  font-family: var(--vf-font-sans);
  font-size: 14px;
  color: var(--vf-text-secondary);
}
.vfLicenseExpiredLogout {
  font-family: var(--vf-font-sans);
  font-size: 14px;
  font-weight: var(--vf-fw-medium);
  padding: 8px 20px;
  border-radius: var(--vf-radius-sm);
  border: 1px solid var(--vf-border-strong);
  background: var(--vf-surface);
  color: var(--vf-text);
  cursor: pointer;
}
.vfLicenseExpiredLogout:hover {
  background: var(--vf-bg);
}

/* Karenzzeit-Sperre bei nie lizenzierter Instanz (App.controller.js#
   _showLicenseLockedCover, Stefan 2026-08-04, licensing.md Abschnitt 3
   Nachtrag) - gleiche Karte wie .vfLicenseExpiredCard, zusätzlich ein
   Eingabefeld + Aktivieren-Button, da dieser Fall (anders als eine
   abgelaufene Testlizenz) per Selbstbedienung behebbar ist. */
.vfLicenseLockedForm {
  display: flex;
  flex-direction: column;
  gap: var(--vf-space-2);
  margin-bottom: var(--vf-space-4);
}
.vfLicenseLockedInput {
  font-family: var(--vf-font-mono);
  font-size: 13px;
  width: 100%;
  min-height: 72px;
  padding: 8px 10px;
  border-radius: var(--vf-radius-sm);
  border: 1px solid var(--vf-border-strong);
  background: var(--vf-bg);
  color: var(--vf-text);
  resize: vertical;
  box-sizing: border-box;
}
.vfLicenseLockedInput:focus {
  outline: none;
  border-color: var(--vf-primary);
  box-shadow: var(--vf-shadow-focus);
}
.vfLicenseLockedError {
  font-family: var(--vf-font-sans);
  font-size: 13px;
  color: var(--vf-error);
  text-align: left;
  min-height: 18px;
}
.vfLicenseLockedActivate {
  font-family: var(--vf-font-sans);
  font-size: 14px;
  font-weight: var(--vf-fw-medium);
  padding: 8px 20px;
  border-radius: var(--vf-radius-sm);
  border: none;
  background: var(--vf-primary);
  color: #fff;
  cursor: pointer;
}
.vfLicenseLockedActivate:hover {
  opacity: 0.92;
}
.vfLicenseLockedActions {
  display: flex;
  gap: var(--vf-space-2);
  justify-content: center;
}

/* ---- Login-Karte (App.controller.js#_showLogin) ------------------------- */
.vfLoginDialog .sapMDialogScrollCont,
.vfLoginDialog .sapMDialogScroll,
.vfLoginDialog .sapMDialogSection {
  padding: 0 !important;
}
.vfLoginCard {
  box-sizing: border-box;
  width: 100%;
  padding: var(--vf-space-8) var(--vf-space-7) var(--vf-space-6);
  gap: var(--vf-space-5);
}
.vfLoginBrand {
  align-items: center;
  gap: var(--vf-space-1);
  margin-bottom: var(--vf-space-2);
}
.vfLoginLogo {
  width: 56px;
  height: 56px;
  align-items: center;
  justify-content: center;
  border-radius: var(--vf-radius-lg);
  /* !important: sap.m.VBox bekommt sonst UI5s .sapMFlexBoxBGTransparent
     (background:transparent), nach dem App-CSS injiziert - das Marken-Quadrat
     bliebe unsichtbar (dokumentierte Falle in project-vflow-ui5-theming-quirks). */
  background: var(--vf-primary) !important;
  margin-bottom: var(--vf-space-3);
}
.vfLoginLogoIcon {
  color: #fff !important;
  font-size: 26px !important;
}
.vfLoginWordmark {
  text-align: center;
  font-size: var(--vf-fs-h1) !important;
  font-weight: var(--vf-fw-semibold) !important;
  letter-spacing: 0.02em;
  color: var(--vf-text) !important;
}
.vfLoginSubtitle {
  text-align: center;
  color: var(--vf-text-secondary) !important;
}
.vfLoginFields {
  gap: var(--vf-space-2);
}
.vfLoginFieldLabel {
  margin-top: var(--vf-space-4);
  font-weight: var(--vf-fw-semibold);
}
.vfLoginFields > .vfLoginFieldLabel:first-child {
  margin-top: 0;
}
.vfLoginTagline {
  margin-top: var(--vf-space-2);
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  /* !important: gleiche .sapMText-Laufzeit-Übersteuerung wie an anderen Stellen. */
  font-size: var(--vf-fs-caption) !important;
  font-weight: var(--vf-fw-semibold) !important;
  color: var(--vf-primary) !important;
}

/* Breadcrumb-Trenner im Flow-Editor-Kopf ("Flows / {Flow-Name}"). */
.vfBreadcrumbSeparator {
  color: var(--vf-text-muted);
  padding: 0 var(--vf-space-2);
}

/* Kopfbereich des Flow Editors: Innenabstand statt Außenabstand auf der
   Seite selbst, damit der Splitter darunter randlos bis zur Sidebar-
   Trennlinie geht (kein Bruch im Trennbalken). */
.vfEditorHeader {
  padding: var(--vf-space-6) var(--vf-space-6) var(--vf-space-5);
  /* !important: UI5 setzt auf jede VBox ohne explizites "background"-Design
     die eigene Klasse .sapMFlexBoxBGTransparent (background-color:
     transparent), geladen nach vflow.css - gleiche Falle wie bei den
     Emphasized-Button-Farben, siehe project_vflow_ui5_theming_quirks. */
  background: var(--vf-surface) !important;
  border-bottom: 1px solid var(--vf-border);
  /* Frozen header (Stefan-Review 2026-07-15): bleibt beim Scrollen der
     sap.m.Page sichtbar, damit "Speichern" ohne Hochscrollen erreichbar
     bleibt. Greift nur, wenn der Kopfbereich selbst so hoch wird, dass die
     Page überhaupt scrollt - der Splitter darunter scrollt ohnehin intern.
     !important: UI5s Basis-CSS setzt auf .sapMFlexBox "position: relative"
     und lädt nach vflow.css - gleiche Falle wie beim Hintergrund oben. */
  position: sticky !important;
  top: 0 !important;
  z-index: 2;
}

/* Trennlinie zwischen dem Kopf (Breadcrumb/Titel/Version/Verarbeitung) und
   der Bearbeitungssperre/dem Canvas im Flow-Editor. */
.vfHeaderDivider {
  height: 1px;
  /* !important: UI5 setzt auf jede VBox ohne explizites "background"-Design
     die eigene Klasse .sapMFlexBoxBGTransparent (background-color:
     transparent), geladen nach vflow.css - gleiche Falle wie bei
     .vfEditorHeader oben, siehe project_vflow_ui5_theming_quirks. */
  background: var(--vf-border) !important;
  margin: var(--vf-space-4) 0;
}

/* ---- Flow-Editor: Canvas + Bottom Property Panel per ziehbarem Trennbalken
   (sap.ui.layout.Splitter, orientation="Vertical") statt rechtem Drawer -
   wie in SAP Cloud Integration ("man kann es hoch und runter ziehen").
   flow-editor.md Abschnitt 5. Randlos (kein Border/Radius) - der
   Trennbalken soll ohne Unterbruch bis zur Sidebar durchgehen. ---- */
.vfEditorSplitter {
  border-top: 1px solid var(--vf-border);
  overflow: hidden;
}

.vfBottomPanel {
  background: var(--vf-surface);
  height: 100%;
  overflow-y: auto;
}

.vfBottomPanel .sapMITB {
  background: transparent;
}

.vfBottomPanelPlaceholder {
  width: 100%;
  height: 100%;
  padding: var(--vf-space-7) var(--vf-space-5) var(--vf-space-5) var(--vf-space-7);
  align-items: flex-start;
  color: var(--vf-text-muted);
  font-size: var(--vf-fs-sm);
}

.vfBottomPanelPlaceholderIcon {
  font-size: 1.1rem;
  color: var(--vf-text-muted);
  margin-right: var(--vf-space-3);
}

/* Der Splitter-Trennbalken soll wie ein echter Drag-Handle aussehen, nicht
   wie eine zufällige graue Linie. */
.vfEditorSplitter > .sapUiLoSplitterBar {
  background: var(--vf-surface-sunk);
  border-top: 1px solid var(--vf-border);
  border-bottom: 1px solid var(--vf-border);
}

/* ==========================================================================
   Design-Refresh (Packages/PackageDetail/FlowEditor), angelehnt an ein von
   Stefan geteiltes Mockup - kein 1:1-Clone (UI5 begrenzt das), aber gleiche
   Richtung: Icon-Avatare, Metadata-Sidecards, Tabellen-Toolbars mit Counts,
   Pipeline-Karten mit Kicker-Label. Nur Elemente mit echten Daten dahinter -
   rein dekorative Mockup-Elemente ohne Backend-Gegenstück (Env-Badge,
   "Runtime healthy", User-Avatar) sind bewusst nicht übernommen.
   ========================================================================== */

/* ---- Entity-Icon-Avatar (Package-/Flow-Header) --------------------------- */
.vfEntityAvatar {
  width: 40px;
  height: 40px;
  border-radius: var(--vf-radius-md);
  /* !important: jede HBox ohne explizites backgroundDesign bekommt UI5s
     eigene .sapMFlexBoxBGTransparent-Klasse (background-color: transparent),
     nach vflow.css injiziert - gleiche Falle wie bei .vfEditorHeader, siehe
     project_vflow_ui5_theming_quirks. */
  background: var(--vf-primary) !important;
  color: var(--vf-neutral-0);
  align-items: center;
  justify-content: center;
  flex: none;
}

.vfEntityAvatar .sapUiIcon {
  color: var(--vf-neutral-0) !important;
}

/* ---- User-Avatar (Initialen statt Icon, z. B. Users-Tabelle) ------------- */
.vfUserAvatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--vf-primary) !important;
  color: var(--vf-neutral-0);
  align-items: center;
  justify-content: center;
  flex: none;
}

.vfUserAvatar .sapMText {
  color: var(--vf-neutral-0) !important;
  font-weight: var(--vf-fw-medium);
  font-size: var(--vf-fs-caption);
}

.vfUserAvatar .sapUiIcon {
  color: var(--vf-neutral-0) !important;
}

/* ---- Role-/Tag-Pill (Rolle, Credential-Typ etc., Users-/Credentials-Tabelle)
   Bewusst KEIN sap.m.ObjectStatus-Zustand (Success/Error/...) - diese sind
   laut Design-System nur für echten funktionalen Zustand reserviert (Monitoring
   etc.), eine Rolle/ein Credential-Typ ist kein Zustand. Eigenständige,
   neutral-brand-getönte Pille statt Zweckentfremdung der Status-Farben - gleiche
   ::before-Dot-Technik wie .sapMObjStatus oben, auf einem einzelnen Text-Control
   statt einer HBox+Kind-Element-Konstruktion (vermeidet die Flex-Item-Kollaps-
   Fallen, die bei mehrknotigen absolut positionierten Overlays aufgetreten sind,
   siehe project_vflow_ui5_theming_quirks). Name ist historisch (zuerst für Users
   gebaut), wird aber bewusst für jede nicht-funktionale Kategorisierungs-Pille
   wiederverwendet statt eine zweite, identische Klasse anzulegen. */
.vfRolePill {
  display: inline-flex;
  align-items: center;
  gap: var(--vf-space-2);
  background: var(--vf-primary-subtle);
  color: var(--vf-primary);
  border-radius: var(--vf-radius-pill);
  padding: 1px var(--vf-space-4) 1px var(--vf-space-3);
  font-size: var(--vf-fs-caption);
  font-weight: var(--vf-fw-medium);
}

.vfRolePill::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--vf-primary);
  flex: none;
}

/* ---- Key-/ID-Badge (statt reinem mono-Text) ------------------------------ */
.vfKeyPill {
  font-family: var(--vf-font-mono) !important;
  font-size: var(--vf-fs-caption);
  color: var(--vf-text-secondary);
  background: var(--vf-surface-sunk);
  border: 1px solid var(--vf-border);
  border-radius: var(--vf-radius-xs);
  padding: 1px var(--vf-space-3);
}

/* ---- Generische Card (Details-Card + Metadata-Sidecard teilen sich das) -- */
.vfCard {
  /* !important: UI5 setzt auf jede VBox/HBox eine eigene
     .sapMFlexBoxBGTransparent-Klasse (background-color: transparent), die
     nach vflow.css injiziert wird und sonst gewinnt - gleiche Falle wie bei
     .vfEditorHeader/.vfEntityAvatar. */
  background: var(--vf-surface) !important;
  border: 1px solid var(--vf-border);
  border-radius: var(--vf-radius-md);
  box-shadow: var(--vf-shadow-sm);
  padding: var(--vf-space-5);
  gap: var(--vf-space-3);
}

/* ---- Metadata-Sidecard (Package-Detail Overview, rechte Spalte) ---------- */
.vfMetadataCard {
  width: 280px;
  flex: none;
}

.vfMetadataCardTitle {
  font-size: var(--vf-fs-caption);
  font-weight: var(--vf-fw-medium);
  color: var(--vf-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: var(--vf-space-2);
}

.vfMetadataRow {
  width: 100%;
  /* !important: UI5 setzt auf jede HBox eine eigene .sapMFlexBoxJustify*-/
     .sapMFlexBoxAlignItems*-Klasse (hier "Start"/"Stretch", je nach
     Default), die nach vflow.css injiziert wird und sonst gewinnt - gleiche
     Falle wie bei .vfEntityAvatar/.vfEditorHeader oben. */
  justify-content: space-between !important;
  align-items: center !important;
  padding: var(--vf-space-1) 0;
}

.vfMetadataRowLabel {
  color: var(--vf-text-secondary);
  font-size: var(--vf-fs-sm);
  /* Abstand zum Wert, falls dieser (langer mono-Pfad im Runtime-Drawer) dicht
     heranrückt. Das "auf einer Zeile halten" macht das Label-Control selbst via
     wrapping:false (Operation._metaRow) - CSS white-space würde von UI5s
     eigener .sapMText-Regel überschrieben (gleicher !important-Footgun). */
  margin-right: var(--vf-space-4);
}

.vfMetadataRowValue {
  font-family: var(--vf-font-mono) !important;
  font-size: var(--vf-fs-sm);
  color: var(--vf-text);
}

/* ---- Runtime-Cockpit Detail-Drawer: Metadaten-Gruppen als abgesetzte Boxen
   (IDENTITY/ADDRESS/ACCESS/LIFECYCLE) - Rahmen statt Schatten (CLAUDE.md §5),
   Gruppentitel mit Hairline darunter. ------------------------------------- */
.vfDrawerSection {
  border: 1px solid var(--vf-border);
  border-radius: var(--vf-radius-md);
  padding: var(--vf-space-3) var(--vf-space-4) var(--vf-space-2);
  margin-bottom: var(--vf-space-3);
  background: var(--vf-surface);
}

.vfDrawerSectionTitle {
  /* Volle Boxbreite (Titel ohne wrapping:false, s. Operation._section), damit
     die Trennlinie durchläuft statt auf Wortbreite zu enden. */
  display: block !important;
  font-size: var(--vf-fs-caption);
  font-weight: var(--vf-fw-semibold) !important;
  color: var(--vf-text-muted) !important;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding-bottom: var(--vf-space-2);
  margin-bottom: var(--vf-space-1);
  border-bottom: 1px solid var(--vf-border);
}

/* ---- Runtime-Cockpit Detail-Drawer: Aktionsleiste am Ende des Inhalts
   (Pause/Resume, Undeploy, Im Editor ansehen) - abgesetzt durch eine dünne
   Trennlinie über den Buttons. --------------------------------------------- */
.vfDrawerActions {
  gap: var(--vf-space-2);
  margin-top: var(--vf-space-4);
  padding-top: var(--vf-space-4);
  border-top: 1px solid var(--vf-border);
}

/* ---- Tip-Callout (dezenter Hinweis, kein Fehler/Warnung - eigene, ruhige
   Farbe statt Status-Semantik, da CLAUDE.md Status-Farben nur für echten
   Laufzeit-/Lifecycle-Zustand reserviert). --------------------------------- */
.vfTipCallout {
  background: var(--vf-brand-50);
  border: 1px solid var(--vf-brand-200);
  border-radius: var(--vf-radius-md);
  padding: var(--vf-space-4) var(--vf-space-5);
  gap: var(--vf-space-1);
}

.vfTipCalloutTitle {
  font-weight: var(--vf-fw-medium);
  color: var(--vf-primary-active);
  font-size: var(--vf-fs-sm);
}

.vfTipCalloutText {
  color: var(--vf-text-secondary);
  font-size: var(--vf-fs-sm);
}

/* ---- Tabellen-Toolbar-Header ("Flows 6 total" + Filter + Aktion) --------- */
.vfTableToolbarTitle {
  font-weight: var(--vf-fw-semibold);
  font-size: var(--vf-fs-h3);
  color: var(--vf-text);
}

.vfTableToolbarCount {
  color: var(--vf-text-muted);
  font-size: var(--vf-fs-sm);
  font-weight: var(--vf-fw-regular);
  margin-left: var(--vf-space-2);
}

/* ---- Versions-Overflow-Badge ("v3 +2") ----------------------------------- */
.vfOverflowBadge {
  color: var(--vf-text-muted);
  font-size: var(--vf-fs-caption);
  margin-left: var(--vf-space-2);
}

/* ---- Flow-Editor Pipeline-Karten (Kicker-Label + zweizeiliger Button) ----
   Die ganze Karte soll klickbar sein und überall einen Pointer zeigen
   (Stefan: "auf der ganzen Box"), nicht nur der Button-Teil unterhalb des
   Kicker-Labels. Der Button trägt weiterhin den eigentlichen Klick-Handler
   (kein neues Control nötig) - er wird per position:absolute auf die volle
   Kartenfläche gelegt, das Kicker-Label liegt als rein dekorative,
   klick-durchlässige (pointer-events:none) Ebene darüber. Feste Kartenhöhe
   (statt auto), damit ein absolut positionierter Button eine wohldefinierte
   100%-Bezugsgröße hat. */
/* Flow-Kachel im SAP-Integration-Suite-Stil: Icon-Badge + Kicker oben, fetter
   Titel + gedämpfter Mono-Untertitel unten. Die Karte (sap.m.VBox) rendert mit
   renderType="Bare" (XML), sodass Kicker/Titel/Untertitel direkte Flex-Kinder
   sind - dadurch entfallen die früheren .sapMFlexItem-/absolute-Hacks: die
   Inhalte liegen im normalen Fluss, nur der Klick-Button ist ein transparentes
   Overlay über der ganzen Karte. */
.vfPipelineCard {
  position: relative;
  display: flex;
  flex-direction: column;
  width: var(--vf-pipeline-card-w);
  /* fixe Höhe für gleich hohe Kacheln in der Reihe; Titel/Untertitel werden
     per margin-top:auto an den unteren Rand geschoben, sodass sie bündig
     stehen, egal ob das Kicker-Label ein- oder zweizeilig umbricht.
     Als Token, weil .vfPipelineArrow dieselbe Höhe braucht, um die Linie auf
     Kartenmitte zu legen - die beiden dürfen nicht auseinanderlaufen. */
  height: var(--vf-pipeline-card-h);
  box-sizing: border-box;
  flex: none;
  padding: var(--vf-space-3);
  border: 1px solid var(--vf-border-strong);
  border-radius: var(--vf-radius-lg);
  background: var(--vf-surface);
}

.vfPipelineCardKicker {
  align-items: center;
  gap: var(--vf-space-2);
}

/* Icon im soften, violett getönten Rounded-Square (wie in der Vorlage). */
.vfCardIconBadge {
  box-sizing: border-box;
  width: 24px !important;
  height: 24px !important;
  line-height: 24px !important;
  margin: 0 !important;
  border-radius: var(--vf-radius-sm);
  background: var(--vf-brand-100);
  color: var(--vf-primary) !important;
  font-size: 13px !important;
  text-align: center;
  flex: none;
}

.vfPipelineCardKickerText {
  font-size: 10px;
  font-weight: var(--vf-fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--vf-text-muted) !important;
  line-height: 1.2;
}

/* Titel: fett, an den unteren Kartenrand geschoben (margin-top:auto), eine
   Zeile mit Ellipsis. */
.vfPipelineCardTitle {
  margin-top: auto;
  padding-top: var(--vf-space-2);
  display: block;
  max-width: 100%;
  /* Direktes Flex-Kind von .vfPipelineCard (renderType="Bare") - ohne
     min-width:0 bleibt Flexbox' Default min-width:auto aktiv, das die
     Ellipsis-Regeln unten wirkungslos macht (der Text bleibt auf seiner
     vollen intrinsischen Breite und läuft über die Karte hinaus, statt zu
     kürzen - Stefan-Review 2026-07-27, lange File-Pfade liefen über die
     Karte). */
  min-width: 0;
  font-size: var(--vf-fs-body) !important;
  font-weight: var(--vf-fw-semibold) !important;
  color: var(--vf-text) !important;
  /* !important: UI5s .sapMText setzt selbst white-space:pre-line (spätere
     Quellreihenfolge, gleiche Spezifität - dieselbe Falle wie an anderer
     Stelle in project_vflow_ui5_theming_quirks dokumentiert), das die
     Ein-Zeile-Ellipsis sonst wirkungslos macht (Text umbricht/wächst über
     die Karte, statt zu kürzen). */
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}

.vfPipelineCardSubtitle {
  display: block;
  max-width: 100%;
  /* Gleicher Flex-Item-min-width-Trap wie .vfPipelineCardTitle oben. */
  min-width: 0;
  font-size: var(--vf-fs-caption) !important;
  color: var(--vf-text-muted) !important;
  /* !important nötig, s. Kommentar bei .vfPipelineCardTitle oben. */
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}

/* Transparentes Klick-Overlay über der ganzen Karte (trägt den Press-Handler).
   !important auf Größe/Position: UI5s .sapMBtn bringt eigene feste Maße mit. */
.vfPipelineCard .vfPipelineCardButton {
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 100% !important;
  min-width: 0 !important;
}
.vfPipelineCard .vfPipelineCardButton .sapMBtnInner {
  border: none !important;
  background: transparent !important;
  box-shadow: none !important;
  width: 100% !important;
  height: 100% !important;
  cursor: pointer;
}

/* Das Klick-Overlay zeichnet KEINEN eigenen Fokusrahmen - sonst lag der
   Button-Fokusring (leicht eingerückt) über dem Kartenrahmen und es sah aus
   wie zwei überlappende Rahmen. Die Auswahl zeigt stattdessen die Karte selbst
   (:focus-within unten) als einen sauberen Rahmen. UI5 zeichnet den Fokusring
   als ::before UND ::after am .sapMBtnInner (je nach Build/Zustand) - beide
   unterdrücken, sonst bleibt bei :focus-visible ein zweiter 2px-Rahmen sichtbar
   (Stefan-Review 2026-07-10: nach Hard-Reload war ::before noch aktiv). */
.vfPipelineCard .vfPipelineCardButton,
.vfPipelineCard .vfPipelineCardButton:focus,
.vfPipelineCard .vfPipelineCardButton:focus-visible {
  outline: none !important;
}
.vfPipelineCard .vfPipelineCardButton .sapMBtnInner::before,
.vfPipelineCard .vfPipelineCardButton .sapMBtnInner::after {
  content: none !important;
  display: none !important;
  border: none !important;
}

/* Hover und Auswahl: EIN violetter Rahmen. Bei Auswahl zusätzlich ein weicher,
   heller Halo + zarte Flächentönung - der frühere harte 3px-Fokusring
   (--vf-shadow-focus, 30% Deckkraft direkt am Rahmen) las sich durch die
   Rundung wie ein zweiter Rahmen (Stefan-Review 2026-07-10). Jetzt ein
   verwaschener Glow (mit Blur, kein harter Rand). */
.vfPipelineCard:hover,
.vfPipelineCard:focus-within {
  border-color: var(--vf-primary);
  cursor: pointer;
}
.vfPipelineCard:focus-within {
  background: var(--vf-brand-50);
  box-shadow: 0 2px 10px rgba(91, 69, 224, 0.18);
}

/* ---- Legende oben rechts im Canvas ("● message flow · 2 Zweige") -------- */
.vfPipelineLegend {
  color: var(--vf-text-muted);
  font-size: var(--vf-fs-caption);
  gap: var(--vf-space-2);
  align-items: center;
}

.vfPipelineLegendDot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--vf-primary);
  flex: none;
}

/* ---- Bedingungs-Pill pro Zweig (ersetzt die eigene Condition-Box in der
   Zweig-Reihe - "Zweig 1 · Bedingung (Standard)"). Wie bei .vfPipelineBox
   oben: der Button rendert seinen eigentlichen Rahmen/Hintergrund auf einem
   inneren .sapMBtnInner-Element, nicht auf der Klasse selbst. ------------- */
.vfBranchConditionPill .sapMBtnInner {
  background: var(--vf-brand-50) !important;
  color: var(--vf-primary-active) !important;
  border: 1px solid var(--vf-brand-200) !important;
  border-radius: var(--vf-radius-pill) !important;
  padding: 1px var(--vf-space-4) !important;
  font-size: var(--vf-fs-caption);
  font-weight: var(--vf-fw-medium);
  height: auto !important;
}

.vfBranchConditionPill:hover .sapMBtnInner {
  border-color: var(--vf-primary) !important;
}

/* Drop-Zone im "New Document"-Modal: gestrichelte Fläche zum Ziehen/Auswählen
   einer Datei. .vfDropZoneActive hebt beim Drüberziehen hervor. */
.vfDropZone {
  border: 2px dashed var(--vf-border-strong);
  border-radius: var(--vf-radius-md);
  padding: var(--vf-space-6, 24px) var(--vf-space-4, 16px);
  background: var(--vf-bg);
}
.vfDropZoneActive {
  border-color: var(--vf-primary);
  background: var(--vf-primary-subtle);
}
.vfDropZone .vfDropZoneIcon {
  color: var(--vf-text-muted);
}

/* ---- Benutzer-Footer unten in der Side-Navigation (Name + Rolle + Abmelden).
   Body-level position:fixed, links an die Sidenav-Spalte ausgerichtet - stört
   so das UI5-Flex-Layout der Aside nicht. z-index unter den UI5-Popups (~10),
   aber über dem Inhalt. Breite fest verdrahtet (256px, sap.tnt.ToolPage-
   Standardbreite in dieser Density/Theme) statt live an der Sidenav gemessen
   (Stefan-Review 2026-07-15, onToggleSideNav) - eine Live-Messung direkt nach
   dem Klick lag noch mitten in der Breiten-Animation der Sidenav und blieb
   bei schnellen Klicks manchmal auf der alten Breite hängen. transition
   animiert stattdessen selbst mit, synchron zur Klasse .vfUserFooterCollapsed
   (App.controller.js#_alignUserFooter, reines Klassen-Toggle, kein Messen). */
.vfUserFooter {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 256px;
  transition: width 0.2s ease;
  z-index: 5;
  box-sizing: border-box;
  padding: var(--vf-space-3) var(--vf-space-4);
  border-top: 1px solid var(--vf-border);
  /* !important: .sapMFlexBoxBGTransparent-Falle auf HBox. */
  background: var(--vf-surface) !important;
}
.vfUserFooterId {
  gap: var(--vf-space-3);
  cursor: pointer;
  min-width: 0;
  /* Stefan-Review 2026-07-17: vorher nur Avatar+Text klickbar, der Rest der
     Zeile bis zum Abmelden-Icon war tote Fläche (justify-content:SpaceBetween
     am Elternelement lässt sonst eine Lücke, die zu keinem der beiden Items
     gehört). flex:1 zieht die klickbare Fläche bis direkt vor das Icon. */
  flex: 1 1 auto;
  border-radius: var(--vf-radius-sm);
  padding: var(--vf-space-1) var(--vf-space-2);
  margin: calc(var(--vf-space-1) * -1) calc(var(--vf-space-2) * -1);
  transition: background 0.1s ease;
}
.vfUserFooterId:hover {
  background: var(--vf-brand-50);
}
.vfUserFooterMeta {
  min-width: 0;
}
.vfUserFooterAvatar {
  display: inline-block;
  flex: none;
  width: 32px;
  height: 32px;
  line-height: 32px;
  text-align: center;
  border-radius: var(--vf-radius-sm);
  background: var(--vf-primary) !important;
  color: #fff !important;
  font-weight: var(--vf-fw-semibold) !important;
}
.vfUserFooterName {
  font-weight: var(--vf-fw-semibold) !important;
  color: var(--vf-text) !important;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vfUserFooterRole {
  font-size: var(--vf-fs-caption) !important;
  color: var(--vf-text-muted) !important;
}

/* Eingeklappte Sidebar (onToggleSideNav, Stefan-Wunsch 2026-07-15): bei
   ~65px Breite ist kein Platz für Name/Rolle nebeneinander mit Avatar +
   Abmelden-Icon - Name/Rolle ausblenden, Avatar + Abmelden übereinander
   stapeln statt nebeneinander. !important: die HBox-Properties
   (justifyContent/alignItems) rendern als sapMFlexJustify…-/-Align…-Klassen,
   die UI5-Bibliotheks-CSS lädt nach vflow.css (gleiche Falle wie an anderen
   Stellen, siehe project_vflow_ui5_theming_quirks). */
.vfUserFooter.vfUserFooterCollapsed {
  width: 65px;
  flex-direction: column !important;
  justify-content: center !important;
  align-items: center !important;
  gap: var(--vf-space-2);
  padding: var(--vf-space-3) var(--vf-space-2);
}
.vfUserFooter.vfUserFooterCollapsed .vfUserFooterMeta {
  display: none;
}
.vfUserFooter.vfUserFooterCollapsed .vfUserFooterId {
  justify-content: center !important;
  /* Collapsed ist eine Spalte (Avatar über Logout-Icon, Meta ausgeblendet) -
     hier gibt es keine tote Fläche zu füllen; flex:1 aus dem expanded State
     würde stattdessen die Zeile über die volle Höhe strecken. */
  flex: none;
}

/* Profil-Seite: großer Marken-Avatar mit Initiale. */
.vfProfileAvatar {
  display: inline-block;
  width: 48px;
  height: 48px;
  line-height: 48px;
  text-align: center;
  border-radius: var(--vf-radius-md);
  background: var(--vf-primary) !important;
  color: #fff !important;
  font-size: 18px !important;
  font-weight: var(--vf-fw-semibold) !important;
}

/* ---- Test-Send: zweispaltiges Layout (Request links / Ergebnis rechts),
   je eine .vfCard - gleiche Karten-Bausteine wie Package-Detail/Runtime-
   Drawer (CLAUDE.md §8: bestehende Muster wiederverwenden). ---------------- */
.vfTestSendLayout {
  gap: var(--vf-space-5);
  /* !important: UI5 setzt auf jede HBox eine eigene
     .sapMFlexBoxAlignItemsStretch-Klasse, die nach vflow.css injiziert wird
     und sonst gewinnt - gleiche Falle wie bei .vfMetadataRow/.vfCard oben. */
  align-items: flex-start !important;
}
.vfTestSendRequestCard {
  width: 55%;
}
.vfTestSendResultCard {
  width: 45%;
}

/* Ergebnis-Karte im Leerzustand: zentriertes Icon + Hinweistext, bis die
   erste Testnachricht gesendet wurde. */
.vfTestSendResultIdle {
  align-items: center;
  text-align: center;
  gap: var(--vf-space-2);
  padding: var(--vf-space-6) var(--vf-space-4);
}
.vfTestSendResultIdleIcon {
  font-size: 32px !important;
  color: var(--vf-text-muted) !important;
}
.vfTestSendResultIdleTitle {
  font-weight: var(--vf-fw-medium);
  color: var(--vf-text-secondary);
}
.vfTestSendResultIdleHint {
  font-size: var(--vf-fs-sm);
  color: var(--vf-text-muted);
}

/* sap.m.Dialog-Content-Innenabstand (Stefan-Review 2026-07-27, Baum-Editor):
   UI5s eigene "sapUiContentPadding"-Klasse existiert in diesem Theme-Build
   nicht (computed padding 0px trotz Klasse) - eigene Klasse statt dessen,
   gleicher Wert wie .vfDrawer. */
.vfDialogContentPadding {
  padding: var(--vf-space-7);
}

/* ---- Help-Seite: sap.ui.core.HTML mit vorgefertigtem DE/EN-Content
   (Help.controller.js läadt help/content-<lang>.html per fetch) - eigenes
   Layout statt UI5-Controls, weil der Inhalt (TOC + lange Screenshot-
   Sektionen) als reines HTML deutlich wartbarer ist. Zwei-Spalten-Layout
   wie das Design-System-Dokument (docs/design/vFlow-Design-System.dc.html):
   sticky TOC links, scrollender Inhalt rechts. */
.vfHelpCard {
  max-width: var(--vf-content-max);
  margin: 0 auto;
}
.vfHelpLayout {
  display: flex;
  align-items: flex-start;
  gap: var(--vf-space-8);
}
.vfHelpToc {
  position: sticky;
  top: var(--vf-space-3);
  flex: 0 0 200px;
  width: 200px;
  display: flex;
  flex-direction: column;
  gap: var(--vf-space-1);
  border-right: 1px solid var(--vf-border);
  padding-right: var(--vf-space-5);
  align-self: flex-start;
}
.vfHelpTocGroup {
  font-size: var(--vf-fs-caption);
  font-weight: var(--vf-fw-medium);
  color: var(--vf-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: var(--vf-space-5);
}
.vfHelpTocGroup:first-child {
  margin-top: 0;
}
.vfHelpToc a {
  color: var(--vf-text-secondary);
  text-decoration: none;
  font-size: var(--vf-fs-sm);
  padding: var(--vf-space-1) 0;
}
.vfHelpToc a:hover {
  color: var(--vf-primary);
}
.vfHelpBody {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--vf-space-9);
}
.vfHelpBody h1 {
  font-size: var(--vf-fs-display);
  line-height: var(--vf-lh-display);
  font-weight: var(--vf-fw-semibold);
  margin: 0 0 var(--vf-space-2);
}
.vfHelpBody h2 {
  font-size: var(--vf-fs-h2);
  line-height: var(--vf-lh-h2);
  font-weight: var(--vf-fw-semibold);
  margin: 0 0 var(--vf-space-3);
  scroll-margin-top: var(--vf-space-5);
  padding-top: var(--vf-space-2);
  border-top: 1px solid var(--vf-border);
}
.vfHelpSection:first-of-type h2 {
  border-top: none;
  padding-top: 0;
}
.vfHelpBody h3 {
  font-size: var(--vf-fs-h3);
  line-height: var(--vf-lh-h3);
  font-weight: var(--vf-fw-semibold);
  margin: var(--vf-space-6) 0 var(--vf-space-2);
}
.vfHelpBody p {
  margin: 0 0 var(--vf-space-3);
  color: var(--vf-text);
  line-height: var(--vf-lh-body);
}
.vfHelpBody ul,
.vfHelpBody ol {
  margin: 0 0 var(--vf-space-3);
  padding-left: var(--vf-space-6);
  color: var(--vf-text);
  line-height: var(--vf-lh-body);
}
.vfHelpBody li {
  margin-bottom: var(--vf-space-2);
}
.vfHelpBody code {
  font-family: var(--vf-font-mono);
  font-size: var(--vf-fs-code);
  background: var(--vf-surface-sunk);
  border: 1px solid var(--vf-border);
  border-radius: var(--vf-radius-xs);
  padding: 1px var(--vf-space-2);
}
.vfHelpLead {
  font-size: var(--vf-fs-h3);
  line-height: var(--vf-lh-h3);
  color: var(--vf-text-secondary);
}
.vfHelpShot {
  display: block;
  max-width: 100%;
  height: auto;
  margin: var(--vf-space-4) 0;
  border: 1px solid var(--vf-border);
  border-radius: var(--vf-radius-md);
  box-shadow: var(--vf-shadow-sm);
}
.vfHelpCaption {
  display: block;
  margin: calc(var(--vf-space-4) * -1) 0 var(--vf-space-4);
  font-size: var(--vf-fs-caption);
  color: var(--vf-text-muted);
}
.vfHelpTable {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 var(--vf-space-5);
  font-size: var(--vf-fs-sm);
}
.vfHelpTable th,
.vfHelpTable td {
  text-align: left;
  padding: var(--vf-space-3) var(--vf-space-4);
  border-bottom: 1px solid var(--vf-border);
  vertical-align: top;
}
.vfHelpTable th {
  color: var(--vf-text-muted);
  font-weight: var(--vf-fw-medium);
  text-transform: uppercase;
  font-size: var(--vf-fs-caption);
  letter-spacing: 0.04em;
}
.vfHelpTable td code {
  font-family: var(--vf-font-mono);
  font-size: var(--vf-fs-code);
}
.vfHelpNote {
  background: var(--vf-info-bg);
  border: 1px solid var(--vf-info-border);
  border-radius: var(--vf-radius-md);
  padding: var(--vf-space-4) var(--vf-space-5);
  font-size: var(--vf-fs-sm);
  color: var(--vf-text);
}
.vfHelpNote strong {
  color: var(--vf-info);
}
.vfHelpTutorial {
  border-top: 3px solid var(--vf-primary);
  padding-top: var(--vf-space-5);
}
.vfHelpStep {
  margin-bottom: var(--vf-space-7);
}

/* Hinweisseite "nur am Desktop" (mobile-scope.md Abschnitt 3). Bewusst ein
   grosses, ruhiges Symbol in Neutralfarbe und NICHT in einer Statusfarbe:
   hier ist nichts fehlgeschlagen, die Seite ist nur woanders zu Hause
   (CLAUDE.md §2 - Statusfarben bleiben echtem Zustand vorbehalten). */
.vfDesktopOnlyIcon {
  font-size: 3rem;
  color: var(--vf-text-muted);
  margin-top: var(--vf-space-6);
}

/* Hilfe auf dem Telefon (mobile-scope.md Abschnitt 5). Die Hilfe ist eine
   eigenständige Seite mit eigenem Viewport-Meta und war damit die halbe
   Miete - was sie auf 390 px trotzdem unbrauchbar machte, ist das
   Zwei-Spalten-Layout: ein Inhaltsverzeichnis mit FESTEN 200 px neben dem
   Text lässt davon keine 150 px übrig.

   Deshalb hier gestapelt statt nebeneinander, und das Verzeichnis verliert
   sein position:sticky - ein klebender Block, der die halbe Höhe eines
   Telefondisplays einnimmt, wäre schlimmer als gar keiner. Es steht dann
   einmal oben, wie ein Inhaltsverzeichnis in einem Buch. */
@media (max-width: 599px) {
  .vfHelpLayout {
    flex-direction: column;
    gap: var(--vf-space-5);
  }
  .vfHelpToc {
    position: static;
    flex: none;
    width: auto;
    border-right: none;
    border-bottom: 1px solid var(--vf-border);
    padding-right: 0;
    padding-bottom: var(--vf-space-4);
  }
  .vfHelpBody {
    gap: var(--vf-space-7);
  }
  /* Die Tabellen sind zwei- und dreispaltig und laufen bei voller Polsterung
     aus dem Rand. Enger setzen statt waagerecht scrollen zu lassen: es sind
     durchweg Begriff/Bedeutung-Paare, die umbrechen dürfen. */
  .vfHelpTable th,
  .vfHelpTable td {
    padding: var(--vf-space-2);
  }
  /* Ein einzelnes langes <code> (das längste ist 45 Zeichen, z. B.
     "<Methode> /inbound/rest/<Adresse>") würde die Tabelle sonst aufspreizen
     und die ganze Seite waagerecht scrollbar machen. */
  .vfHelpTable code {
    overflow-wrap: anywhere;
  }
}

/* Gestufte Verbindungsdiagnose (Stefan, 2026-08-07, connection-test.ts):
   je Zeile eine Stufe - Name aufgeloest / Port erreichbar / Anmeldung /
   Verzeichnis. Ersetzt nicht die MessageStrip darueber, sondern beantwortet
   die Anschlussfrage beim Scheitern: woran genau lag es? */
.vfConnTestSteps {
  margin-top: var(--vf-space-2);
  padding: var(--vf-space-2) var(--vf-space-3);
  background: var(--vf-bg);
  border: 1px solid var(--vf-border);
  border-radius: var(--vf-radius-md);
}
.vfConnTestRow {
  padding: 2px 0;
  gap: var(--vf-space-2);
}
.vfConnTestIcon {
  font-size: 14px;
  width: 1rem;
}
.vfConnTestOk    { color: var(--vf-success) !important; }
.vfConnTestFailed { color: var(--vf-error) !important; }
.vfConnTestSkipped { color: var(--vf-text-muted) !important; }
/* Feste Breite, damit die Detailspalte in allen Zeilen an derselben Kante
   beginnt - sonst franst die Liste je nach Bezeichnungslaenge aus. */
.vfConnTestLabel {
  min-width: 11rem;
  font-size: var(--vf-fs-caption) !important;
}
/* Technische Werte (Adressen, Ports, Pfade, Serverfehler) in Mono - dieselbe
   Trennung wie ueberall sonst im Produkt. */
.vfConnTestDetail {
  font-family: var(--vf-font-mono);
  font-size: var(--vf-fs-caption) !important;
  color: var(--vf-text-muted) !important;
}

/* Kacheln der Ueber-vFlow-Seite (About.view.xml).

   Die Karte muss ihre Gitterzelle ausfuellen, sonst steht sie oben in einer
   Zelle, die durch gridAutoRows="1fr" hoeher ist als ihr Inhalt - und man
   saehe wieder ungleich hohe Kaesten, nur diesmal mit Luft darunter statt
   daneben. box-sizing, damit das Innenmass von .vfCard die 100 % nicht
   sprengt. */
.vfAboutCard {
  height: 100%;
  box-sizing: border-box;
}

/* Kacheln der Engine-Seite (Engine.view.xml).

   Wie .vfAboutCard: die Kachel muss ihre Gitterzelle ausfuellen, sonst steht
   sie oben in einer Zelle, die durch gridAutoRows="1fr" hoeher ist als ihr
   Inhalt - und man saehe wieder ungleich hohe Kaesten, nur mit Luft darunter
   statt daneben.

   Die Statuszeile am unteren Rand auszurichten waere schoener, braucht aber
   einen Selektor auf UI5s Innen-DOM - dafuer wird die Seite erst einmal
   angesehen. */
.vfEngineTile {
  height: 100%;
  box-sizing: border-box;
}

/* Kachelgitter der Ueber-vFlow-Seite (About.view.xml).

   Zwei Spalten, fest - nicht auto-fit. Mit auto-fit passten auf einem breiten
   Bildschirm vier Kacheln nebeneinander, und aus dem gewuenschten 2x2 wurde
   ein 4x1 mit viel zu schmalen Spalten (Stefan, 2026-08-12).

   !important, weil sap.ui.layout.cssgrid.CSSGrid seine Angaben als Inline-Stil
   setzt und ein Klassen-Selektor sonst verliert - dieselbe UI5-Eigenheit wie
   bei den Emphasized-Buttons.

   Unter 48rem eine Spalte: zwei Karten nebeneinander sind auf einem schmalen
   Fenster unlesbar. */
.vfAboutGrid {
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}

@media (max-width: 48rem) {
  .vfAboutGrid {
    grid-template-columns: 1fr !important;
  }
}
