/* ============================================================
   TCHIBO NFSP – Wireframe System
   Intentional lo-fi aesthetic. No colors, no polish.
   Sharpie on warm paper.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&display=swap');

:root {
  --border: #1a1a1a;
  --border-light: #777;
  --bg: #ede8df;
  --bg-white: #faf8f3;
  --bg-stripe: #e4ddd2;
  --text: #111;
  --text-muted: #555;
  --text-placeholder: #888;
  --font: 'Space Mono', 'Courier New', monospace;
  --radius: 2px;
  --gap: 16px;
  /* Bewusste Ausnahmen vom sonst durchgehend monochromen Farbschema – die einzigen Orte, an denen Farbe
     (statt Graustufe) etwas bedeutet: Überplanung in der Heatmap-Zelle (siehe wfHeatmapCellValue/
     renderHeatmap) sowie der Selektions-Rahmen (siehe .wf-heatmap__cell--sel-* unten), der auf allen
     Farbskala-Helligkeiten von hell bis dunkel erkennbar bleiben muss. */
  --wf-overallocated-bg: #f2d9d6;
  --wf-selection-accent: #1abc9c;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font);
  font-size: 15px;
  background: var(--bg);
  color: var(--text);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* ── SIDEBAR ── */
.wf-sidebar {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: 200px;
  background: var(--bg-white);
  border-right: 3px solid var(--border);
  display: flex;
  flex-direction: column;
  z-index: 100;
  transition: width 0.15s ease;
}

.wf-sidebar__logo {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 2px;
  text-transform: uppercase;
  border: 3px solid var(--border);
  padding: 4px 8px;
  display: inline-block;
  margin: 16px;
}

.wf-sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 0;
  flex: 1;
}

.wf-sidebar__item {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 9px 16px;
  border-left: 3px solid transparent;
  display: flex;
  align-items: center;
  gap: 10px;
}

.wf-sidebar__item i {
  font-size: 16px;
  width: 20px;
  flex-shrink: 0;
  text-align: center;
}

.wf-sidebar__item--active {
  color: var(--text);
  font-weight: 700;
  border-left-color: var(--border);
  background: var(--bg);
}

/* Nav-Punkt kommt später, noch nicht erreichbar: <span> statt <a>, zusätzlich gedämpft. */
.wf-sidebar__item--disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.wf-sidebar__section {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-muted);
  padding: 16px 16px 4px;
  opacity: 0.6;
}

/* Collapse-Button: gleiche Position/Rahmen wie vorher der User-Block am Sidebar-Fuß, seit 17.08. im
   selben Stil wie die Nav-Items (.wf-sidebar__item), inkl. Label-Ausblendung im eingeklappten Zustand. */
.wf-sidebar__collapse-btn {
  border: none;
  border-top: 2px solid var(--border);
  background: var(--bg-white);
  cursor: pointer;
  width: 100%;
  font-family: var(--font);
}

.wf-sidebar__collapse-btn:hover { color: var(--text); background: var(--bg); }

/* MVP-Vollversions-Umschalter (wireframe-nav.js, wfToggleMvpFullView) – letzter Eintrag in .wf-sidebar__nav,
   direkt oberhalb der Trennlinie zum Collapse-Button. <button> statt <a> wie die echten Nav-Punkte, daher
   eigener Reset (kein natives Button-Styling). Optisch gedämpfter als echte Nav-Punkte, da kein
   Produkt-Feature, sondern nur Vorschau-Werkzeug für Julian/Leonie. */
.wf-sidebar__item--mvp-toggle {
  border: none;
  background: none;
  width: 100%;
  font-family: var(--font);
  cursor: pointer;
  opacity: 0.5;
  font-size: 11px;
}
.wf-sidebar__item--mvp-toggle:hover { opacity: 1; }
.wf-sidebar__item--mvp-toggle-active { opacity: 0.85; }

/* Icon-Rail (12.08.): Sidebar schrumpft auf reine Icon-Breite, Labels/Section-Titel ausgeblendet, Nav-Item-
   Icons zentriert. Tooltip (title-Attribut) liefert das Label, siehe renderNavItem in wireframe-nav.js. */
.wf-sidebar--collapsed { width: 56px; }
.wf-sidebar--collapsed .wf-sidebar__logo { font-size: 11px; padding: 4px; margin: 16px 8px; text-align: center; }
.wf-sidebar--collapsed .wf-sidebar__logo-suffix { display: none; }
.wf-sidebar--collapsed .wf-sidebar__item-label,
.wf-sidebar--collapsed .wf-sidebar__section { display: none; }
.wf-sidebar--collapsed .wf-sidebar__item { justify-content: center; padding: 9px 0; }

/* ── PAGE LAYOUT ── */
.wf-page {
  margin-left: 200px;
  padding: var(--gap) 32px;
  transition: margin-left 0.15s ease;
}

/* Sidebar-Collapse wirkt auf Topbar/Page-Offset (12.08.): :has() statt Klasse auf body setzen, gleiches
   Muster wie body:has(.wf-selection-bar) .wf-page weiter unten. */
body:has(.wf-sidebar--collapsed) .wf-topbar { left: 56px; }
body:has(.wf-sidebar--collapsed) .wf-page { margin-left: 56px; }

/* ── TOPBAR ── */
.wf-topbar {
  position: fixed;
  top: 0;
  left: 200px;
  right: 0;
  height: 44px;
  background: var(--bg-white);
  border-bottom: 2px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--gap);
  gap: 8px;
  z-index: 90;
  transition: left 0.15s ease;
}

/* Platzhalter (17.08.): Topbar-Inhalt noch nicht entschieden, siehe renderTopbar in wireframe-nav.js. */
.wf-topbar__placeholder {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-placeholder);
}

/* ── PAGE LAYOUT (offset for topbar) ── */
.wf-page {
  padding-top: calc(44px + var(--gap));
}

/* ── PAGE HEADER ── */
.wf-page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: var(--gap);
  padding-bottom: var(--gap);
  border-bottom: 2px solid var(--border);
}

.wf-page-header__title {
  font-size: 22px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
}

.wf-page-header__subtitle {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 4px;
}

/* ── TOOLBAR ── */
.wf-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: var(--gap);
  padding: 10px 12px;
  background: var(--bg-white);
  border: 2px solid var(--border);
}

.wf-toolbar__label {
  font-size: 13px;
  text-transform: uppercase;
  color: var(--text-muted);
  letter-spacing: 0.5px;
  margin-right: 4px;
}

.wf-toolbar__spacer { flex: 1; }

/* ── SELECTION BAR ──
   Sticky am unteren Bildschirmrand (14.07., Julians Änderung) statt über der
   Tabelle – sonst rutscht der komplette Seiteninhalt nach unten, sobald die
   erste Zeile markiert wird. Erscheint, sobald per Checkbox mindestens eine
   Zeile markiert ist. Nur für Multi-Select-Aktionen gedacht, die sich auf
   mehrere Datenprodukte gleichzeitig beziehen (z.B. Szenarien vergleichen) –
   nicht für Aktionen auf einem einzelnen Datenprodukt, die gehören auf die
   Detailseite (SOT-Prinzip, Julian 14.07.). Volle Füllung statt Rahmen, weil
   aktiver Auswahlzustand (gleiche Fülldichte-Logik wie bei Badges/Status).
   Gedacht als wiederverwendbares Pattern für alle Übersichtstabellen mit
   Multi-Select. `.wf-page` reserviert dauerhaft Platz am unteren Rand
   (`padding-bottom`), damit Tabelleninhalt nicht verdeckt wird, wenn die Bar
   erscheint. */
.wf-selection-bar {
  display: none;
  align-items: center;
  gap: 12px;
  position: fixed;
  bottom: 0;
  left: 200px;
  right: 0;
  z-index: 90;
  padding: 14px 32px;
  background: var(--border);
  color: var(--bg-white);
}

.wf-selection-bar__count { font-size: 13px; font-weight: 700; }

.wf-selection-bar__spacer { flex: 1; }

.wf-selection-bar .wf-btn--secondary {
  background: var(--bg-white);
  color: var(--text);
}

.wf-selection-bar__clear {
  font-size: 13px;
  color: var(--bg-white);
  text-decoration: underline;
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font);
}

/* Modifier für Seiten ohne Sidebar (Checkout-Pattern, z.B. scenario-vergleich.html) – Bar spannt
   die komplette Bildschirmbreite statt des 200px-Sidebar-Offsets. */
.wf-selection-bar--full-width { left: 0; }

/* Einfache klickbare Liste (z.B. "+ Add Scenario" in scenario-vergleich.html) – ein Klick auf
   einen Eintrag löst die Aktion direkt aus, kein separater Bestätigungsschritt. Volle Breite,
   linksbündig, dezente Trennlinie zwischen Einträgen. */
.wf-add-scenario-item {
  display: block;
  width: 100%;
  text-align: left;
  font-family: var(--font);
  font-size: 14px;
  background: none;
  border: none;
  border-bottom: 1px solid var(--bg-stripe);
  padding: 8px 4px;
  cursor: pointer;
  color: var(--text);
}

.wf-add-scenario-item:hover { background: var(--bg-stripe); }

.wf-add-scenario-item:last-child { border-bottom: none; }

/* ── PAGE LAYOUT (offset for sticky bottom Selection Bar) ──
   Nur auf Seiten mit `.wf-selection-bar` im Markup (`:has()`, moderner Browser
   vorausgesetzt – für ein Wireframe, das lokal im Browser geöffnet wird,
   akzeptabel). Dauerhaft reserviert, nicht erst wenn die Bar sichtbar ist –
   vermeidet einen Layout-Sprung beim Erscheinen/Verschwinden (JS müsste sonst
   das Padding mitschalten). Betrifft aktuell `scenario-uebersicht.html` und
   `product-groups-uebersicht.html`. */
body:has(.wf-selection-bar) .wf-page {
  padding-bottom: 64px;
}

/* ── FORM CONTROLS ── */
.wf-select,
.wf-input {
  font-family: var(--font);
  font-size: 14px;
  border: 2px solid var(--border);
  background: var(--bg-white);
  padding: 4px 8px;
  border-radius: var(--radius);
  color: var(--text);
}

.wf-select { cursor: pointer; }

.wf-input::placeholder { color: var(--text-placeholder); }

/* Gesperrter Zustand (z.B. Set-Potential-Drawer, solange nicht per "Edit Potential" entsperrt): gedämpfte
   Fülldichte-Stufe (border-light, heller Fond) statt reinem Browser-Default. */
.wf-input:disabled {
  background: var(--bg);
  color: var(--text-muted);
  border-color: var(--border-light);
  cursor: not-allowed;
}

/* ── BUTTONS ── */
.wf-btn {
  font-family: var(--font);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-radius: var(--radius);
  cursor: pointer;
  padding: 5px 14px;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.wf-btn--primary {
  background: var(--border);
  color: var(--bg-white);
  border: 3px solid var(--border);
}

.wf-btn--secondary {
  background: var(--bg-white);
  color: var(--text);
  border: 2px solid var(--border);
}

.wf-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ── BADGE / STATUS ── */
.wf-badge {
  font-family: var(--font);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 3px 10px;
  border-radius: 999px;
  display: inline-block;
}

/* Bündel-Status "New" – frisch angelegt, noch nicht in Bearbeitung. Schwächster Zustand (unterhalb Draft):
   dünner, durchgezogener Rahmen in border-light + text-placeholder (heller als text-muted bei Draft). Folgt
   der Fülldichte-Grammatik: New < Draft (gestrichelt) < Approved (gefüllt). */
.wf-badge--new {
  border: 1px solid var(--border-light);
  color: var(--text-placeholder);
  background: transparent;
}

.wf-badge--draft {
  border: 1px dashed var(--border-light);
  color: var(--text-muted);
  background: transparent;
}

.wf-badge--approved {
  border: 2px solid var(--border);
  color: var(--bg-white);
  background: var(--border);
}

/* Szenario-Status "Review" – dritter, mittlerer Status zwischen Draft (gestrichelt) und Approved (voll gefüllt), sonst nirgends im System benötigt (Bündel/Warengruppen kennen nur 2 Stati). Folgt der Mittel-Stufe der Codierungs-Grammatik: umrandet, nicht gefüllt. */
.wf-badge--review {
  border: 2px solid var(--border);
  color: var(--text);
  background: transparent;
}

/* Kleiner Live-Indikator im "Live"-Badge (Potential-Kopfzahl/Live-Vergleichszeile) – reine Fülldichte
   (currentColor), keine eigene Farbe, konsistent zum Rest der Codierungs-Grammatik. */
.wf-live-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  margin-right: 2px;
  vertical-align: middle;
}

/* Warengruppen-Status "Planning Hypothesis" (Freeze) – eigene Klasse, unabhängig vom Bündel-Status (wf-badge--approved), gleiche gefüllte Optik da beides "verbindlich" bedeutet. */
.wf-badge--freeze {
  border: 2px solid var(--border);
  color: var(--bg-white);
  background: var(--border);
}

/* KI-vorgeschlagenes, noch nicht existierendes Bündel (gepunktet statt gestrichelt/gefüllt, damit es nicht mit den echten Bündel-Stati New/Draft/Approved verwechselt wird). */
.wf-badge--suggested {
  border: 1px dotted var(--border-light);
  color: var(--text-muted);
  background: transparent;
  font-style: italic;
}

/* ── TABLE ── */
.wf-table-wrap {
  background: var(--bg-white);
  border: 2px solid var(--border);
}

.wf-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
}

.wf-table thead {
  border-bottom: 3px solid var(--border);
  background: var(--bg);
}

.wf-table th {
  text-align: left;
  padding: 10px 14px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Sortierbare Spalten-Header (17.08., Wiedereinführung – Sortierpfeile waren seit 10.07. entfernt, weil
   die Unicode-Pfeile mit der Projektschrift nicht sauber rendern; die Icon-Font (28.07.) löst das). */
.wf-table th.wf-sortable { cursor: pointer; }
.wf-table th.wf-sortable:hover { color: var(--text); }
.wf-sort-icon { font-size: 12px; margin-left: 2px; vertical-align: middle; color: var(--text-placeholder); }
.wf-sort-icon--active { color: var(--text); }

/* ── INFO ICON + HOVER OVERLAY (Spalten-Erklärung) ── */
.wf-info-icon-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.wf-info-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  border: 1px solid var(--border-light);
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
  color: var(--text-muted);
  margin-left: 4px;
  cursor: help;
  text-transform: none;
  letter-spacing: 0;
  vertical-align: middle;
}

.wf-info-overlay {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: 240px;
  background: var(--bg-white);
  border: 2px solid var(--border);
  box-shadow: 3px 3px 0 var(--border);
  padding: 12px 14px;
  z-index: 200;
  text-align: left;
  white-space: normal;
  font-size: 12px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text);
  line-height: 1.5;
}

.wf-info-icon-wrap:hover .wf-info-overlay { display: block; }

.wf-info-overlay__title {
  font-weight: 700;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border-light);
}

.wf-info-overlay__states {
  list-style: none;
  margin-top: 8px;
  padding: 0;
}

.wf-info-overlay__states li {
  margin-top: 5px;
}

/* ── TOOLTIP (kurzer Hinweis, z.B. Begründung für einen deaktivierten Button) – statt native title-Attribute,
   damit Text/Position gestaltbar bleiben. Wrapper um das Element legen, das den Hinweis auslösen soll
   (Button bleibt dabei ganz normal fokussierbar/klickbar, sofern nicht separat disabled). Erscheint über
   dem Trigger (Footer-Kontext, dort mehr Platz nach oben als nach unten) – bei Bedarf mit
   .wf-tooltip--below spiegeln. */
.wf-tooltip { position: relative; display: inline-flex; }
.wf-tooltip__bubble {
  display: none;
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 220px;
  background: var(--border);
  color: var(--bg-white);
  padding: 6px 10px;
  font-size: 12px;
  line-height: 1.4;
  box-shadow: 3px 3px 0 rgba(17, 17, 17, 0.3);
  z-index: 300;
  text-align: left;
}
.wf-tooltip--below .wf-tooltip__bubble { bottom: auto; top: calc(100% + 8px); }
.wf-tooltip:hover .wf-tooltip__bubble { display: block; }

.wf-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--bg-stripe);
  vertical-align: middle;
}

.wf-table tbody tr:last-child td { border-bottom: none; }

.wf-table tbody tr:nth-child(even) { background: var(--bg-stripe); }

.wf-table tbody tr:hover { background: #ddd7cc; }

/* Summenzeile z.B. der Potential-Distribution-Tabelle (siehe wfHeatmapPotentialTableHtml) – fett +
   dickere Trennlinie statt der normalen Zebra-Trennlinie, damit sie sich als Summe abhebt. */
.wf-table tbody tr.wf-table__total-row td {
  font-weight: 700;
  border-top: 2px solid var(--border);
  background: transparent;
}

/* Zeile = KI-Vorschlag, kein reales Bündel – überschreibt Zebra-Streifen mit gestricheltem Rahmen oben/unten, damit auf einen Blick klar ist: existiert noch nicht. */
.wf-table tbody tr.wf-table-row--suggested td {
  background: var(--bg-white);
  border-top: 1px dashed var(--border-light);
  border-bottom: 1px dashed var(--border-light);
}

.wf-table tbody tr.wf-table-row--suggested:hover td {
  background: var(--bg-stripe);
}

.wf-table__name {
  font-weight: 700;
  color: inherit;
}

.wf-table__name--suggested {
  font-style: italic;
  font-weight: 400;
}

/* Klickbarer Text innerhalb von Tabellen ist immer unterstrichen (Konvention) */
a.wf-table__name {
  text-decoration: underline;
}

.wf-table__meta {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 3px;
}

.wf-table__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.wf-tag {
  font-size: 13px;
  color: var(--text);
  text-decoration: underline;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  border-radius: 0;
}

.wf-table__actions {
  display: flex;
  gap: 6px;
  white-space: nowrap;
  justify-content: flex-end;
}

.wf-table th:last-child,
.wf-table td:last-child {
  text-align: right;
}

/* Checkbox-Spalte für Multi-Select (erste Spalte): width allein auf dem <th> reicht nicht
   zuverlässig, ohne table-layout:fixed kann die Auto-Layout-Berechnung die Spalte trotzdem
   aufblasen – deshalb Breite explizit auf jeder Zelle (th UND td) derselben Spalte. */
.wf-table th.wf-select-col,
.wf-table td.wf-select-col {
  width: 36px;
  min-width: 36px;
  max-width: 36px;
  text-align: center;
  padding-left: 12px;
  padding-right: 0;
}

/* ── PORTFOLIO-DOT (MVKP006: Ausbau/Stabilisierung/Reduktion) ── */
.wf-portfolio-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
}

.wf-portfolio-dot--ausbau {
  background: var(--border);
  border: 2px solid var(--border);
}

.wf-portfolio-dot--stabilisierung {
  background: var(--bg);
  border: 2px solid var(--border);
}

.wf-portfolio-dot--reduktion {
  background: transparent;
  border: 1px dashed var(--border-light);
}

/* ── ANOMALIE-ICON (MVKP007c: Alerting bei Anomalien) ── */
.wf-anomaly-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border: 1.5px solid var(--border);
  border-radius: 50%;
  background: var(--border);
  color: var(--bg-white);
  font-size: 10px;
  font-weight: 700;
  margin-left: 6px;
  vertical-align: middle;
  cursor: help;
}

/* ── AI-HINWEIS-ICON (KI-Empfehlung je Bündel-Zeile, z.B. "Potenzial verringern") ── */
/* Bewusst eckig + gestrichelt statt rund + gefüllt wie .wf-anomaly-icon: Anomalie = Daten-Alarm (hart), AI-Hinweis = Handlungsempfehlung (weich/vorläufig). */
.wf-ai-hint-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border: 1.5px dashed var(--border);
  color: var(--text);
  font-size: 10px;
  font-weight: 700;
  margin-left: 6px;
  vertical-align: middle;
  cursor: help;
}

/* ── AI STATEMENT (28.07., mit Julian: 1 Satz Gesamteinschätzung je Bündel-Karte, Bundle Checkout) ──
   Gestrichelter Rahmen wie .wf-ai-hint-icon (weich/vorläufig statt hart wie Anomalie), aber als volle
   Textzeile statt reinem Icon – sitzt direkt unter dem Karten-Header, an der Stelle des früher entfernten
   separaten Reason-Texts. */
.wf-ai-statement {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  border: 1.5px dashed var(--border);
  padding: 8px 10px;
  margin: 8px 0;
  font-size: 13px;
  color: var(--text);
}

.wf-ai-statement__icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border: 1.5px dashed var(--border);
  border-radius: 50%;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--text);
}

/* ── TREND-INDIKATOR (Potenzial-Entwicklung je Tertial) ── */
.wf-trend {
  font-size: 12px;
  font-weight: 700;
  margin-left: 6px;
  white-space: nowrap;
  cursor: help;
}

/* ── KPI CELL ── */
.wf-kpi {
  font-weight: 700;
}
.wf-kpi__sub {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 2px;
}
.wf-kpi__of {
  font-weight: 400;
  color: var(--text-muted);
}

/* ── PAGINATION ── */
.wf-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  border-top: 2px solid var(--border);
  font-size: 13px;
  color: var(--text-muted);
}

.wf-pagination__pages {
  display: flex;
  gap: 4px;
}

.wf-page-btn {
  font-family: var(--font);
  font-size: 13px;
  border: 2px solid var(--border-light);
  background: var(--bg-white);
  padding: 2px 8px;
  cursor: pointer;
}

.wf-page-btn--active {
  background: var(--border);
  color: var(--bg-white);
  border-color: var(--border);
}

/* ── STAT CARDS ── */
.wf-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: var(--gap);
}

.wf-stat {
  background: var(--bg-white);
  border: 2px solid var(--border);
  padding: 12px 14px;
}

.wf-stat__label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}

.wf-stat__value {
  font-size: 26px;
  font-weight: 700;
  margin-top: 4px;
}

.wf-stat__sub {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 3px;
}

/* ── SECTION ── */
.wf-section {
  margin-bottom: calc(var(--gap) * 1.5);
}

.wf-section__title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-muted);
  margin-bottom: 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border-light);
}

/* ── CARD ── */
.wf-card {
  background: var(--bg-white);
  border: 2px solid var(--border);
  padding: 16px;
}

/* ── COLUMNS ── */
.wf-cols {
  display: grid;
  gap: var(--gap);
}

.wf-cols--2 { grid-template-columns: 1fr 1fr; }
.wf-cols--3 { grid-template-columns: 1fr 1fr 1fr; }

/* ── CHART PLACEHOLDER ── */
.wf-chart {
  background: var(--bg-white);
  border: 2px solid var(--border);
  padding: 16px;
  position: relative;
}

.wf-chart__area {
  margin: 8px 0;
  position: relative;
  display: flex;
  gap: 6px;
}

/* Eine Spalte je Woche – bündelt Balken + Wochenlabel im selben Flex-Item, damit beide immer exakt gleich breit sind (zwei getrennte Flex-Reihen liefen bei 52 Spalten leicht auseinander). */
.wf-chart__col {
  flex: 1;
  min-width: 2px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  position: relative;
}

.wf-chart__bar-slot {
  height: 220px;
  display: flex;
  align-items: flex-end;
}

/* Ein Balken je Woche – durchgezogen = historisch/belegt, gestrichelter Rahmen (hohl) = Prognose/unsicher. Gleiche Konvention wie sonst im Design-System (solide→gestrichelt am Umbruchpunkt), nur als Fülldichte statt Linie. */
.wf-chart__bar {
  width: 100%;
  background: var(--border);
}

.wf-chart__bar--prognose {
  background: transparent;
  border: 2px dashed var(--border);
}

/* Y-Achse – Skala für die Balkenhöhe in €, nicht in % (relative Skalen ohne klaren Bezugspunkt sind bei mehreren Warengruppen/aggregierten Charts mehrdeutig; € ist die überall sonst im Produkt verwendete Einheit) */
.wf-chart__y-axis {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-end;
  height: 220px;
  margin: 8px 0;
  padding-right: 6px;
  font-size: 10px;
  color: var(--text-muted);
  width: 56px;
  flex-shrink: 0;
}

.wf-chart__x-label {
  font-size: 8px;
  color: var(--text-muted);
  text-align: center;
  margin-top: 4px;
}

.wf-chart__x-label--today {
  font-weight: 700;
  color: var(--text);
}

/* "Lines"-Darstellung (24.07., siehe renderLineChart in wireframe-stackchart.js). flex:1 (11.08.,
   Bugfix) – .wf-chart__lines-outer ist direktes Kind von #wf-chart-area (display:flex), ohne flex:1
   schrumpfte es auf seinen Inhalt statt die volle Breite auszufüllen (Stacked hat dasselbe Problem nicht,
   da dort .wf-chart__col direkt im Flex-Container liegt und schon flex:1 hat). min-width:0 verhindert,
   dass der Flex-Item trotzdem an seinem Inhalt (52 Spalten) aufbricht statt zu schrumpfen.
   KEINE feste Höhe mehr auf .wf-chart__lines-outer (11.08., 2. Bugfix, ersetzt den vorherigen
   18px-Puffer-Versuch): wächst jetzt wie im Stacked-Modus automatisch mit seinem Inhalt (Zeilen +
   Wochen-Label darunter), exakt analog zu #wf-chart-expanded dort – kein geschätzter Pixelwert mehr, der
   je nach Zeilenumbruch/Schriftrendering leicht daneben liegen kann. Stattdessen trägt der neue innere
   .wf-chart__lines-plot (siehe renderLineChart) exakt dieselbe Höhe wie .wf-chart__lines-wrap – Seiten mit
   eigenem Höhen-Override setzen daher .wf-chart__lines-wrap UND .wf-chart__lines-plot auf denselben Wert,
   .wf-chart__lines-outer bekommt gar keinen Override mehr. */
.wf-chart__lines-outer { position: relative; flex: 1; min-width: 0; }
.wf-chart__lines-wrap, .wf-chart__lines-plot { position: relative; height: 220px; }
.wf-chart__lines-plot { position: absolute; top: 0; left: 0; width: 100%; }

/* Potential Score (24.07., product-groups-uebersicht.html; 2. Anpassung nach Julians Feedback: unten
   im dunklen Balkensegment war die Zahl kaum lesbar). Jetzt normales Flex-Kind statt position:absolute
   – da .wf-chart__bar-slot column-reverse ist, landet ein später im Markup stehendes Kind automatisch
   ÜBER den Balken, direkt über der tatsächlichen (variablen) Balkenhöhe der jeweiligen Woche, statt an
   einer festen Pixel-Position im Container. Opt-in über opts.scoreByWeek in renderStackChart. */
.wf-chart__score {
  display: block;
  width: 100%;
  text-align: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 4px;
}

/* Feiertags-Marker (24.07., TODO-Wireframes.md Prio-2; 27.07. mit Julian: Emojis statt ★, größer,
   direkt über den Balken als Flex-Kind im Bar-Slot). */
.wf-chart__holiday {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 24px;
  font-size: 20px;
  color: var(--text);
  line-height: 1;
  flex-shrink: 0;
}

/* Hover-Popover-Platzhalter am Potenzial-Chart (24.07.): noch ohne echten Inhalt, nur die Hover-Mechanik.
   Zwei Varianten (--expanded/--collapsed), da Inhalt/Kontext später unterschiedlich sein wird. */
.wf-chart-popover {
  display: none;
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-white);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 10px;
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  z-index: 5;
}

/* Hover jetzt je Teilbalken statt je Spalte (24.07., Bugfix): jedes Segment triggert nur sein eigenes
   Popover, das direkt über diesem Segment erscheint statt immer über der Gesamt-Balkenhöhe. */
.wf-chart__seg:hover .wf-chart-popover--expanded { display: block; }
.wf-chart-collapsed__cell:hover .wf-chart-popover--collapsed { display: block; }

/* Tertiale-Hintergrund (27.07., mit Julian): subtile Streifen hinter den Balken/Linien zur optischen
   Tertial-Markierung (KW 1–17 / 18–34 / 35–52). Absolute Positionierung hinter dem Chart-Content. */
.wf-chart {
  position: relative;
}

.wf-chart__area {
  position: relative;
  z-index: 1;
}

.wf-chart__tertial-bg {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 0;
  opacity: 0.5;
}

.wf-chart__tertial-bg--t1 {
  left: 0;
  width: 32.7%;
  background: #ddd7cc;
}

.wf-chart__tertial-bg--t2 {
  left: 32.7%;
  width: 32.7%;
  background: #c9c2b7;
}

.wf-chart__tertial-bg--t3 {
  left: 65.4%;
  width: 34.6%;
  background: #ddd7cc;
}

/* ── MULTI-SERIES FÜLLMUSTER (gestapelte Charts mit >3 Kategorien, z.B. Warengruppen-/UWG-Aufschlüsselung) ──
   Erweitert die 3-stufige Fülldichte-Grammatik (voll/umrandet/gestrichelt) um weitere unterscheidbare,
   farblose Muster. Bei mehr Kategorien als Muster: zyklisch wiederverwenden (wf-fill-0..5, dann von
   vorn) – exakte Zuordnung liefert die Legende (Reihenfolge = Stapel-Reihenfolge) + Hover-Tooltip je
   Segment, nicht das Muster allein. Siehe wireframe-stackchart.js. */
/* Graustufen statt Füllmuster (24.07., mit Julian abgestimmt) – weiterhin farblos, aber pro Serie
   ein eigener Grauton statt Strichmuster; dünne helle Trennlinie (border-top) zwischen den Segmenten
   eines Stapels, damit auch benachbarte, ähnliche Grautöne im Stack erkennbar bleiben. */
.wf-fill-0 { background: #1a1a1a; border-top: 2px solid var(--bg-white); }
.wf-fill-1 { background: #3d3d3d; border-top: 2px solid var(--bg-white); }
.wf-fill-2 { background: #606060; border-top: 2px solid var(--bg-white); }
.wf-fill-3 { background: #858585; border-top: 2px solid var(--bg-white); }
.wf-fill-4 { background: #aaaaaa; border-top: 2px solid var(--bg-white); }
.wf-fill-5 { background: #cfcfcf; border-top: 2px solid var(--bg-white); }

.wf-stack-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-bottom: 10px;
  font-size: 12px;
  color: var(--text-muted);
}
.wf-stack-legend__item { display: flex; align-items: center; gap: 6px; }
.wf-stack-legend__swatch { display: inline-block; width: 14px; height: 14px; flex-shrink: 0; }
/* Tabellen-Checkbox-Auswahl im Chart sichtbar machen (11.08., product-groups-uebersicht.html): nicht
   ausgewählte Warengruppen-Cluster werden gedimmt statt entfernt, damit der Kontext erhalten bleibt. */
.wf-stack-legend__item--dimmed { opacity: 0.45; }
.wf-chart__seg--dimmed { opacity: 0.35; }

/* Obertes Segment (visuell, wegen column-reverse) sollte keinen border-top haben. */
.wf-chart__bar-slot > .wf-chart__seg:nth-last-child(2) { border-top: none !important; }

/* Ganze Wochen-Spalte optisch zurückgenommen für Vergangenheits-Wochen (27.07., mit Julian: zukünftige
   Wochen sollen in voller Transparenz sein, weil das die wichtigen Planungs-Wochen sind). Gleiche Logik wie
   .wf-chart__bar--prognose, nur auf Spaltenebene und invertiert. */
.wf-chart__col:not(.wf-chart__col--prognose) .wf-chart__bar-slot { opacity: 0.55; }

/* ── BÜNDEL-GANTT (unter dem Potenzialverlauf: welche Bündel laufen in welcher KW, mehrzeilig bei Überschneidung) ── */
.wf-gantt {
  position: relative;
  padding-top: 2px;
}

.wf-gantt__lane {
  position: relative;
  height: 20px;
  margin-bottom: 4px;
}

.wf-gantt__lane:last-child {
  margin-bottom: 0;
}

.wf-gantt__bar {
  position: absolute;
  top: 0;
  height: 100%;
  box-sizing: border-box;
  font-size: 10px;
  line-height: 18px;
  padding: 0 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: help;
}

/* Gleiche Fülldichte-Konvention wie Status-Badges: New=dünner Rahmen, Draft=gestrichelt, Approved=gefüllt, AI Suggestion=gepunktet. */
.wf-gantt__bar--new {
  border: 1px solid var(--border-light);
  color: var(--text-placeholder);
  background: var(--bg-white);
}

.wf-gantt__bar--approved {
  background: var(--border);
  color: var(--bg-white);
  font-weight: 700;
}

.wf-gantt__bar--draft {
  border: 1px dashed var(--border-light);
  color: var(--text-muted);
  background: var(--bg-white);
}

.wf-gantt__bar--suggested {
  border: 1px dotted var(--border-light);
  color: var(--text-muted);
  font-style: italic;
  background: var(--bg-white);
}

.wf-gantt__today {
  position: absolute;
  top: 0;
  bottom: 0;
  border-left: 1px dashed var(--border-light);
}

/* ── DETAIL LAYOUT (Spaltenzahl je Seite per Inline-Style überschrieben) ── */
.wf-detail-layout {
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: var(--gap);
  align-items: start;
}

/* ── HANDLUNGSFENSTER (Dringlichkeits-Indikator, monochrom über Füllung statt Farbe) ── */
.wf-urgency-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
}

.wf-urgency-dot--ok {
  background: transparent;
  border: 1px dashed var(--border-light);
}

.wf-urgency-dot--soon {
  background: var(--bg);
  border: 2px solid var(--border);
}

.wf-urgency-dot--urgent {
  background: var(--border);
  border: 2px solid var(--border);
}

/* ── DATA ROW ── */
.wf-data-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px solid var(--bg-stripe);
  font-size: 14px;
}

.wf-data-row:last-child { border-bottom: none; }

.wf-data-row__label { color: var(--text-muted); font-size: 13px; }
.wf-data-row__value { font-weight: 700; }

/* ── VIEW TOGGLE ──
   Umgebaut (14.07.): sah vorher wie eine normale Button-Gruppe aus (aktives Segment =
   identische Optik zu .wf-btn--primary, volle dunkle Füllung) – zu leicht mit echten
   Aktions-Buttons verwechselbar, wenn beide im selben Header nebeneinander stehen
   (siehe scenario-detail.html/bundle-detail.html). Jetzt als "Track mit erhöhtem
   aktivem Segment" – nur bestehende Tokens (bg-stripe als Track, bg-white + Rahmen
   als aktives Segment), keine neue Farbe. */
.wf-view-toggle {
  display: flex;
  gap: 2px;
  margin-bottom: var(--gap);
  background: var(--bg-stripe);
  border: 2px solid var(--border-light);
  border-radius: var(--radius);
  padding: 2px;
  width: fit-content;
}

.wf-view-btn {
  font-family: var(--font);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 5px 14px;
  border: 2px solid transparent;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: 1px;
}

.wf-view-btn--active {
  background: var(--bg-white);
  color: var(--text);
  border: 2px solid var(--border);
}

/* ── CONFIDENCE BAR ── */
/* ── SOQ – SHARE OF QUOTA (Potenzial vs. verplant) ── */
.wf-progress {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 700;
}

.wf-progress__bar {
  width: 56px;
  height: 6px;
  border: 1px solid var(--border-light);
  background: var(--bg);
  position: relative;
  flex-shrink: 0;
}

.wf-progress__fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  background: var(--border);
}

/* ── CHIP (Referenz-/ID-Pill, z.B. CR-IDs in Regeln & Ausnahmen) ── */
.wf-chip {
  display: inline-block;
  font-size: 12px;
  border: 1px solid var(--border-light);
  background: var(--bg);
  padding: 2px 8px;
  border-radius: 999px;
  margin: 2px 4px 2px 0;
}

/* ── BÜNDELVORSCHLAG CARD ── */
.wf-suggestion-card {
  background: var(--bg-white);
  border: 2px solid var(--border);
  padding: 14px 16px;
  margin-bottom: 10px;
}

.wf-suggestion-card__header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 8px;
}

.wf-suggestion-card__title {
  font-weight: 700;
  font-size: 15px;
}

.wf-suggestion-card__reason {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--bg-stripe);
}

/* ── MODAL (Testhilfe, z.B. Gremiums-Freigabe-Bestätigung) ── */
.wf-modal-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(17, 17, 17, 0.4);
  align-items: center;
  justify-content: center;
  z-index: 500;
}

.wf-modal {
  background: var(--bg-white);
  border: 3px solid var(--border);
  box-shadow: 4px 4px 0 var(--border);
  padding: 24px;
  width: 360px;
}

/* Breitere Variante für Modals mit mehr Feldern (z.B. Bündel bearbeiten/erstellen im Checkout). */
.wf-modal--wide {
  width: 640px;
  max-height: 84vh;
  overflow-y: auto;
}

/* Noch breitere Variante für den Create-Bundle-Dialog MIT Warengruppen-Cards (mehrere Wochen-Cards je
   Warengruppe, s. wf-nbd-wg-card) – nur per JS zugeschaltet, wenn tatsächlich Zeilen-Daten vorhanden sind
   (siehe wfOpenNewBundleDialog in wireframe-bundle-dialog.js). */
/* Titel und Actions bleiben fix (sticky), nur .wf-modal__body scrollt intern – bei vielen Warengruppen-
   Cards im Create-Bundle-Dialog sonst Titel/Buttons mit aus dem sichtbaren Bereich raus. */
.wf-modal--xwide {
  width: 1040px;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}
.wf-modal--xwide .wf-modal__title,
.wf-modal--xwide .wf-modal__actions {
  flex: 0 0 auto;
}
.wf-modal--xwide .wf-modal__body {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}

/* ── BÜNDEL-CHECKOUT: reduzierte Kopfzeile (Ecom-Pattern – keine Sidebar/Topbar, Fokus aufs Abschließen) ── */
.wf-checkout-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  border-bottom: 3px solid var(--border);
  background: var(--bg-white);
}

.wf-checkout-header__brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.wf-checkout-header__logo {
  font-weight: 700;
  letter-spacing: 1px;
}

.wf-checkout-header__title {
  font-size: 15px;
  color: var(--text-muted);
}

/* ── VERTEILUNGSLEISTE (sticky, volle Breite: wie verteilt sich das Potenzial über die ausgewählten Bündel) ── */
.wf-distribution-bar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg-white);
  border-bottom: 2px solid var(--border);
  padding: 10px 24px 14px;
}

.wf-distribution-bar__label {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  margin-bottom: 6px;
}

.wf-distribution-bar__track {
  display: flex;
  height: 22px;
  border: 1px solid var(--border);
}

.wf-distribution-bar__segment {
  height: 100%;
  border-right: 1px solid var(--bg-white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: var(--bg-white);
  background: var(--border);
  overflow: hidden;
  white-space: nowrap;
  cursor: help;
}

.wf-distribution-bar__segment:last-child { border-right: none; }

/* Card ist gerade abgewählt – Segment zählt nicht mit, bleibt aber als Kontext sichtbar (schwach statt kräftig). */
.wf-distribution-bar__segment--excluded {
  background: var(--bg-stripe);
  color: var(--text-muted);
}

/* ── CHECKOUT-LAYOUT: Card-Liste (volle Breite) + rechte sticky Summary-Box ── */
.wf-checkout-layout {
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: var(--gap);
  align-items: start;
  padding: var(--gap) 24px;
}

.wf-checkout-summary {
  position: sticky;
  top: 96px;
  background: var(--bg-white);
  border: 2px solid var(--border);
  padding: 16px;
}

.wf-checkout-summary__title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-muted);
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border-light);
}

.wf-checkout-summary__row {
  display: flex;
  justify-content: space-between;
  padding: 6px 0;
  font-size: 14px;
}

.wf-checkout-summary__total {
  display: flex;
  justify-content: space-between;
  font-weight: 700;
  font-size: 18px;
  margin: 10px 0;
  padding-top: 10px;
  border-top: 2px solid var(--border);
}

/* ── POTENZIAL-SLIDER (auf der Bündel-Card selbst – Einzelpotenzial editierbar ohne die Card zu öffnen) ── */
.wf-potential-slider {
  margin-top: 10px;
}

.wf-potential-slider__labels {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 4px;
}

.wf-potential-slider__value {
  font-weight: 700;
  font-size: 14px;
}

.wf-potential-slider__total {
  font-size: 12px;
  color: var(--text-muted);
}

.wf-potential-slider__track {
  position: relative;
  height: 6px;
  background: var(--bg);
  border: 1px solid var(--border-light);
  margin-top: 8px;
}

.wf-potential-slider__fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  background: var(--border);
}

.wf-potential-slider__handle {
  position: absolute;
  top: 50%;
  width: 13px;
  height: 13px;
  background: var(--bg-white);
  border: 2px solid var(--border);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  cursor: ew-resize;
}

/* Sweet-Spot-Markierung (28.07., mit Julian – 2. Anlauf: erster Versuch mit dünnem Balken über dem
   Track verschmolz optisch mit Fill/Rahmen zu einer durchgehenden Linie, kaum als Zone lesbar. Neue
   Version nach Julians Vorlage: Zielspanne (baseline ± Schwelle) als eigenes Segment DIREKT auf dem
   Track, mittelgrau abgesetzt von Fill (fast schwarz) und leerem Track (hell) – monochrom statt Farbe
   wie im Beispiel, um konsistent zur restlichen Fülldichte-Sprache des Design-Systems zu bleiben. Liegt
   im DOM vor dem Fill, wird also vom Fill überdeckt, sobald der Handle die Zone erreicht/durchläuft –
   genau wie im Beispielbild. Handle wird zusätzlich voll ausgefüllt (statt weiß mit Rahmen), sobald der
   Wert außerhalb der Zielspanne liegt. */
.wf-potential-slider__sweetspot {
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--border-light);
}

.wf-potential-slider__handle--outside {
  background: var(--border);
}

/* Card gerade abgewählt (Checkbox aus) – bleibt sichtbar, damit KI-Vorschläge nicht verloren gehen, aber deutlich zurückgenommen. Opacity gezielt nur auf Inhalt (Titel, Meta, Begründung, Slider), NICHT auf Checkbox/Edit/Remove – die Card bleibt bedienbar statt "disabled" zu wirken. */
.wf-suggestion-card--excluded .wf-suggestion-card__title {
  opacity: 0.45;
}
.wf-suggestion-card--excluded > div:not(.wf-suggestion-card__header) {
  opacity: 0.45;
}

/* Manuell erstelltes Bündel (nicht KI-generiert), in der Gruppe "New Bundles" mitgekennzeichnet. */
.wf-chip--custom {
  font-style: italic;
}

/* ── TOAST (Bestätigung nach Bündel-Checkout) ── */
.wf-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--border);
  color: var(--bg-white);
  padding: 12px 20px;
  border: 2px solid var(--border);
  box-shadow: 4px 4px 0 rgba(17, 17, 17, 0.3);
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 14px;
  z-index: 600;
}

.wf-toast__close {
  background: none;
  border: none;
  color: var(--bg-white);
  font-size: 16px;
  cursor: pointer;
  line-height: 1;
}

/* ── SNACKBAR (Bestätigung, z.B. nach Bündel-Checkout) – siehe wireframe-snackbar.js ── */
.wf-snackbar-stack {
  position: fixed;
  top: 24px;
  right: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  z-index: 600;
}

.wf-snackbar {
  width: 400px;
  background: var(--border);
  color: var(--bg-white);
  padding: 12px 16px;
  border: 2px solid var(--border);
  box-shadow: 4px 4px 0 rgba(17, 17, 17, 0.3);
  font-size: 14px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.wf-snackbar__icon {
  flex-shrink: 0;
  font-size: 18px;
  line-height: 1.4;
}

.wf-snackbar__body {
  flex: 1;
}

.wf-snackbar__title {
  font-weight: 700;
}

.wf-snackbar__content {
  margin-top: 2px;
  opacity: 0.85;
}

.wf-snackbar__close {
  background: none;
  border: none;
  color: var(--bg-white);
  font-size: 16px;
  cursor: pointer;
  line-height: 1;
  flex-shrink: 0;
}

.wf-modal__title {
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--border);
}

.wf-modal__body {
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 20px;
}

.wf-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.wf-drawer__group-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-muted);
  margin: 20px 0 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border-light);
}

.wf-drawer__group-title:first-of-type {
  margin-top: 0;
}

/* ── HEATMAP-DRAWER-HEADER (Titel "Selection" + Chips für Anzahl/Zeitraum) – eigene, schmalere Variante
   statt .wf-drawer__title (dort uppercase/letter-spacing für andere Drawer wie KI-Konfidenz), da hier
   Title-Case und größere Schrift gewünscht sind. Nur im Heatmap-Detail-Panel verwendet. */
.wf-heatmap-drawer__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 24px 24px 16px;
  flex-shrink: 0;
}

.wf-heatmap-drawer__header-title {
  font-size: 20px;
  font-weight: 700;
}

/* Zeigt nur, was aktuell selektiert ist (Anzahl Product Groups, Zeitraum) – reiner Text statt Chip/Pill,
   keine Statusaussage (die volle Fülldichte ist Status-Badges wie .wf-badge--approved vorbehalten, siehe
   Codierungs-Grammatik in DESIGN-SYSTEM.md). */
.wf-heatmap-drawer__header-subtitle {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 4px;
}

/* ── DRAWER TABS (z.B. Heatmap-Detail-Drawer: Potentials/Bundles) ── */
/* Volle Trennlinie am Container + eigene Unterstreichung des aktiven Tabs, die lückenlos direkt daran
   anliegt. Kein negativer Margin-Trick mehr (reagierte auf Button-Default-Stile/Line-Height je Browser
   unterschiedlich und ließ eine kleine Lücke). Stattdessen liegt der komplette Abstand unter dem Tab-Text
   in der Tab-eigenen Padding (kein zusätzliches Padding mehr am Container) – so grenzt die Tab-Border
   (transparent/aktiv) direkt an die Container-Border, beide auf derselben Höhe.*/
.wf-drawer__tabs {
  display: flex;
  gap: 20px;
  padding: 0 24px 0;
  border-bottom: 2px solid var(--border-light);
}

.wf-drawer__tab {
  background: none;
  border: none;
  padding: 0 0 10px;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
}

.wf-drawer__tab--active {
  color: var(--text);
  font-weight: 700;
  border-bottom-color: var(--border);
}

/* ── POTENTIAL (Current Potential / je Planable Potential im Heatmap-Detail-Drawer) ── */
/* Kein Card-Rahmen mehr – Distribution/Reason/Bound/Alerts sind eigene Sections statt eines umrandeten
   Blocks, die Potentials-Tab-Fläche selbst ist die Abgrenzung (siehe .wf-drawer__scroll). */
.wf-potential-title {
  font-weight: 700;
  font-size: 14px;
}

.wf-potential-kpi-row,
.wf-potential-live-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
/* Statt Umbruch: Badge-Labels fallen weg (nur Icon+Zahl bleibt), sobald Zahl+Badges nicht mehr auf eine
   Zeile passen (siehe wfCollapseBadgeRowsIfNeeded) – Icon-Grammatik bleibt dadurch weiterhin eindeutig. */
.wf-badge-row--compact .wf-badge__label { display: none; }

.wf-potential-live-row {
  margin-bottom: 16px;
}

.wf-potential-kpi-row .wf-potential-card__timestamp,
.wf-potential-live-row .wf-potential-card__timestamp,
.wf-potential-box-head .wf-potential-card__timestamp {
  margin-left: auto;
}

.wf-potential-card__timestamp {
  font-weight: 400;
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}

.wf-potential-kpi {
  font-size: 26px;
  font-weight: 700;
  white-space: nowrap;
}

.wf-potential-live-value {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-muted);
  white-space: nowrap;
}

.wf-potential-kpi-row .wf-badge,
.wf-potential-live-row .wf-badge {
  font-size: 11px;
  padding: 2px 8px;
  /* Kein internes Umbrechen (z.B. zwischen Zahl und Label) – sonst "passt" die Zeile technisch immer und
     wfCollapseBadgeRowsIfNeeded erkennt den Platzmangel nie. flex-shrink:0, da sonst der Flex-Algorithmus
     versucht, das Badge trotz nowrap-Inhalt zu stauchen. */
  white-space: nowrap;
  flex-shrink: 0;
}

/* Reason/Bound/Distribution/Alerts – einheitliche Section-Labels, bewusst ohne Trennlinie (reiner
   Abstand reicht zur Gliederung). */
.wf-potential-section-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  margin: 24px 0 10px;
}

/* Ersetzt die frühere Distribution-Tabelle (Umsatz/Volume/VC × Online/Stores/Depot) im Heatmap-Detail-
   Drawer: nur noch Umsatz (führende Kennzahl), dafür Vertriebe direkt sichtbar statt hinter einem
   Tabellen-Klapp-Pfeil versteckt – Volume/VC bleiben auf der Warengruppen-Detailseite. Card-Rahmen wie bei
   .wf-bundle-card/.wf-potential-reason-box, damit die Section sich vom Rest des Drawers abhebt. */
.wf-potential-channels {
  margin-top: 4px;
  border: 1px solid var(--border-light);
  padding: 12px 14px;
}
/* Kopfzeile der Card: Section-Label + Toggle-Link nebeneinander statt Toggle unterhalb der Werte. */
.wf-potential-channels__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.wf-potential-channels__row { display: flex; gap: 16px; }
.wf-potential-channels__col { display: flex; gap: 6px; flex: 1; min-width: 0; }
/* Ausgeblendeter Vertrieb (Control Bar "Channels", siehe wfHeatmapChannelsCardHtml im Script) wird
   komplett zurückgenommen – Bar, Label und Zahl gemeinsam, gleiche Opacity-Stufe wie sonst im
   Design-System für deaktivierte Elemente (.wf-btn:disabled, .wf-menu__item--disabled). */
.wf-potential-channels__col--muted { opacity: 0.4; }
/* Tick über die volle Spaltenhöhe (Label+Zahl) – echter Balken relativ zu den anderen beiden Kanälen
   dieser Karte (siehe valueRow im Script), bottom-anchored über column-reverse. */
.wf-potential-channels__tick { width: 4px; display: flex; flex-direction: column-reverse; flex-shrink: 0; background: var(--bg-stripe); }
.wf-potential-channels__tick-fill { width: 100%; background: var(--border); }
.wf-potential-channels__col-text { display: flex; flex-direction: column; min-width: 0; }
.wf-potential-channels__label {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  margin-bottom: 2px;
}
.wf-potential-channels__value { font-size: 14px; font-weight: 700; }
.wf-potential-channels__toggle {
  display: inline-block;
  font-size: 12px;
  text-decoration: underline;
  cursor: pointer;
}
.wf-potential-channels__clusters { display: flex; gap: 16px; margin-top: 6px; }
.wf-potential-channels__cluster-col { flex: 1; min-width: 0; }
.wf-potential-channels__cluster-row {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  padding: 2px 0;
}
.wf-potential-channels__cluster-code { color: var(--text-muted); }

/* Editierbare Entsprechungen der Distribution-Card-Werte (Set/Edit-Potential-Dialog, Karten-Modus,
   wireframe-potential-edit.js) – gleiche Typografie wie die Read-only-Spans (.wf-potential-channels__value/
   .wf-potential-channels__cluster-code+Zahl), nur als Input statt Text. */
.wf-potential-channels__value-input { font-size: 14px; font-weight: 700; width: 100%; box-sizing: border-box; padding: 2px 4px; }
.wf-potential-channels__cluster-input { width: 76px; font-size: 12px; text-align: right; padding: 1px 4px; }

.wf-pe-total-row { margin-bottom: 14px; }
.wf-pe-total-input { font-size: 26px; font-weight: 700; width: 100%; box-sizing: border-box; margin-top: 4px; }

.wf-potential-bound-bar {
  margin-bottom: 16px;
}

.wf-potential-bound-bar__label {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-muted);
  margin-bottom: 4px;
}

.wf-potential-bound-bar__track {
  width: 100%;
  height: 10px;
  border: 1px solid var(--border-light);
  background: var(--bg);
}

.wf-potential-bound-bar__fill {
  height: 100%;
  background: var(--border);
}

.wf-potential-reason-box {
  font-size: 14px;
  border: 1px solid var(--border-light);
  padding: 8px;
  line-height: 1.4;
}

.wf-potential-reason-box p {
  margin: 0;
  white-space: pre-wrap;
}

/* Gemeinsame Icon+Titel-Kopfzeile, genutzt von der Reason-Box (Icon+Autor) UND den Alert-Cards
   (Icon+Titel) – dasselbe visuelle Muster für "wer/was steht dahinter". */
.wf-potential-box-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  margin-bottom: 4px;
}

/* Overallocation/Volatility = harter Daten-Alarm (solid), Potential Deviation = weicherer Hinweis
   (dashed) – gleiche Zwei-Stufen-Logik wie .wf-anomaly-icon vs. .wf-ai-hint-icon. */
.wf-potential-alert {
  border: 1px solid var(--border-light);
  padding: 10px 12px;
  font-size: 12px;
  line-height: 1.4;
  margin-bottom: 10px;
}

.wf-potential-alert--anomaly { border-style: solid; }
.wf-potential-alert--hint { border-style: dashed; }

.wf-potential-alert p {
  margin: 0;
  color: var(--text-muted);
}

/* Bundle Cards im (read-only) Bundles-Tab des Selektions-Drawers – mehr Kontext je Bündel als die frühere
   schlichte Zeile (Name + Status), siehe wfHeatmapDrawerBundlesTabHtml. */
.wf-bundle-card {
  border: 1px solid var(--border-light);
  padding: 12px 14px;
  margin-bottom: 10px;
  cursor: pointer;
}
.wf-bundle-card:hover {
  border-color: var(--border);
}
.wf-bundle-card__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}
.wf-bundle-card__name {
  font-weight: 700;
}
.wf-bundle-card__row {
  display: flex;
  justify-content: space-between;
  padding: 2px 0;
  font-size: 12px;
  color: var(--text-muted);
}
.wf-bundle-card__row span:last-child {
  color: var(--text);
  font-weight: 600;
}

/* ── CREATE-BUNDLE-DIALOG: Live-Banner + Parts-Multiselect (Potentials-Modus, s. wireframe-bundle-dialog.js) ── */
.wf-nbd-live-banner {
  border: 1px solid var(--border-light);
  padding: 10px 12px;
  margin-bottom: 14px;
  font-size: 13px;
}
#wf-nbd-live-banner-list {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 4px;
}

.wf-nbd-parts-block__header {
  margin-bottom: 10px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-light);
}
.wf-nbd-parts-block__title {
  display: block;
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 10px;
}
.wf-nbd-parts-block__subrow {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 16px;
}
.wf-nbd-parts-block__sum-label {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 2px;
}
.wf-nbd-parts-block__sum-value {
  font-weight: 700;
  font-size: 15px;
}
/* "Available potential"-Control: Label + Slide-Toggle mit beidseitiger Zustands-Beschriftung
   (Total/Unbundled) statt eines einzelnen Buttons – Begriff "Unbundled" bleibt unverändert, da an
   anderer Stelle (Zeilen-Label, Wochen-Tooltip, Heatmap-Filter) bereits etabliert. */
.wf-nbd-avail-control {
  text-align: right;
}
.wf-nbd-avail-control__label {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.wf-toggle2 {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
}
.wf-toggle2__state {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-placeholder);
  transition: color 0.15s ease;
}
.wf-toggle2__state--active {
  color: var(--text);
}
.wf-toggle2__track {
  position: relative;
  width: 36px;
  height: 18px;
  border: 2px solid var(--border);
  background: var(--bg-white);
  border-radius: var(--radius);
  flex-shrink: 0;
  transition: background 0.15s ease;
}
.wf-toggle2__knob {
  position: absolute;
  top: 1px;
  left: 1px;
  width: 12px;
  height: 12px;
  background: var(--border);
  transition: transform 0.15s ease;
}
.wf-toggle2--on .wf-toggle2__track {
  background: var(--border);
}
.wf-toggle2--on .wf-toggle2__knob {
  background: var(--bg-white);
  transform: translateX(18px);
}

/* Eine Card je Warengruppe (s. renderNewBundleWgCard in wireframe-bundle-dialog.js) statt einer
   gemeinsamen Matrix-Tabelle für alle Warengruppen – Name + Gesamt-KPI + Distribute-Control im Kopf,
   darunter die kompakte Wochen-Tabelle nur für diese eine Warengruppe. Gruppierung entsteht wie in der
   Bundle-Übersichtstabelle über alternierenden Hintergrund statt über einen eigenen Rahmen je Card. */
.wf-nbd-wg-card {
  padding: 14px 16px;
  margin-bottom: 0;
  border-bottom: 1px solid var(--border-light);
}
.wf-nbd-wg-card:last-child { border-bottom: none; }
.wf-nbd-wg-card:nth-child(even) { background: var(--bg-stripe); }
/* WG-Name links, Total-Feld + Distribute-Link rechts in einer Kopfzeile. */
.wf-nbd-wg-card__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.wf-nbd-wg-card__name {
  font-size: 15px;
  font-weight: 700;
}
/* Total-Feld (wfNbdRowTotalHtml) – gleiches "Input / Referenz"-Prinzip wie eine Wochen-Card, nur mit
   dynamischem Label statt KW-Nummer und eingebettetem Distribute-Icon-Button statt separatem Button. */
.wf-nbd-row-total {
  display: flex;
  align-items: center;
  gap: 8px;
}
.wf-nbd-row-total__label {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}
.wf-nbd-row-total__field {
  display: flex;
  align-items: stretch;
  border: 2px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.wf-nbd-row-total__field:focus-within { border-color: var(--border); }
.wf-nbd-row-total__input {
  border: none;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 700;
  padding: 4px 8px;
  width: 90px;
  text-align: right;
}
.wf-nbd-row-total__input:focus { outline: none; }
.wf-nbd-row-total__of {
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
}
/* Inline-Textlink statt Icon-Button (analog .wf-potential-channels__toggle) – "Distribute" war als reines
   Icon nicht verständlich; die ausführliche Erklärung steckt jetzt im title-Attribut statt in einem
   eigenen Tooltip. */
.wf-nbd-row-total__distribute-link {
  border: none;
  background: none;
  padding: 0;
  font-family: var(--font);
  font-size: 12px;
  text-decoration: underline;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.wf-nbd-row-distribute__hint {
  margin-bottom: 10px;
  font-size: 11px;
  font-weight: 400;
  color: var(--text-muted);
}

/* Wochen als einzelne Cards statt Tabellenzeile (Figma-Vorlage, 22.08.): Label, Eingabefeld, Gesamt-Bezug
   gestapelt je Woche, nebeneinander in einer Reihe. Umbricht bei vielen Wochen statt horizontal zu
   scrollen (anders als die vorherige Tabellen-Variante), da einzelne Cards das ohnehin vertragen. */
.wf-nbd-week-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border-light);
}
.wf-nbd-week-card {
  padding: 10px 12px;
  text-align: center;
  flex: 1 1 100px;
  min-width: 100px;
  border-left: 1px solid var(--border-light);
}
.wf-nbd-week-card:first-child { border-left: none; }
.wf-nbd-week-card--empty { color: var(--text-placeholder); }
.wf-nbd-week-card__label {
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 8px;
}
/* Input + "/ €X"-Referenz nebeneinander statt gestapelt – Input dadurch schmaler, da er sich die Zeile mit
   der Referenz teilt. */
.wf-nbd-week-card__row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.wf-nbd-week-card__input {
  width: 56px;
  flex: 0 0 auto;
  box-sizing: border-box;
  text-align: center;
  font-size: 13px;
  font-weight: 400;
  font-family: var(--font);
  padding: 6px 4px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius);
}
.wf-nbd-week-card__input:focus { border-color: var(--border); outline: none; }
.wf-nbd-week-card__of {
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Zahlen-Spinner (Auf/Ab-Pfeile) bei allen €-Eingabefeldern dieses Dialogs ausblenden – sonst Chrome/
   Safari-Pfeile mitten in der schmalen Card/Zelle. */
.wf-nbd-wg-card input[type="number"]::-webkit-outer-spin-button,
.wf-nbd-wg-card input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.wf-nbd-wg-card input[type="number"] {
  -moz-appearance: textfield;
}

/* ── DRAWER (Testhilfe, z.B. KI-Konfidenz-Zusammensetzung) ── */
.wf-drawer-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(17, 17, 17, 0.4);
  z-index: 500;
}

.wf-drawer {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: 340px;
  background: var(--bg-white);
  border-left: 3px solid var(--border);
  box-shadow: -4px 0 0 var(--border);
  padding: 24px;
  overflow-y: auto;
}

/* Breitere Variante für Drawer mit mehr Inhalt je Zeile (z.B. Bündelvorschläge) – Standard-Drawer (z.B. KI-Konfidenz) bleiben schmal. */
.wf-drawer--wide {
  width: 580px;
}

.wf-drawer__title {
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 16px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.wf-drawer__close {
  cursor: pointer;
  font-size: 18px;
  font-weight: 700;
  border: none;
  background: none;
  color: var(--text);
}

/* Modifier: Drawer mit fixiertem Header/Footer, nur der mittlere Bereich scrollt (z.B. Bündelvorschläge-Drawer). Andere Drawer (z.B. KI-Konfidenz) bleiben unverändert – einfaches Padding, ganzer Drawer scrollt. */
.wf-drawer--sticky {
  display: flex;
  flex-direction: column;
  padding: 0;
}

.wf-drawer--sticky .wf-drawer__title {
  flex-shrink: 0;
  padding: 24px 24px 10px;
  margin-bottom: 0;
}

.wf-drawer__scroll {
  flex: 1;
  overflow-y: auto;
  padding: 16px 24px;
}

.wf-drawer__footer {
  flex-shrink: 0;
  padding: 16px 24px 24px;
  border-top: 2px solid var(--border);
}

/* ── DROPDOWN MENU (z.B. "+ New Bundle ▾", Snapshot-Zeilen-Aktionen) ──
   Trigger + Menü im Markup mit position:relative umschließen (inline style am Aufrufort,
   kein eigenes Wrapper-Pattern). Zentralisiert 20.07. (vorher lokal in bundle-uebersicht.html). */
.wf-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 260px;
  background: var(--bg-white);
  border: 2px solid var(--border);
  box-shadow: 3px 3px 0 var(--border);
  z-index: 200;
}

/* Modifier für Trigger am unteren Viewport-Rand (z.B. Bundles-Popover in der Heatmap-Control-Bar) – öffnet
   nach oben statt nach unten, damit das Menü nicht über den Rand hinausragt. */
.wf-menu--up {
  top: auto;
  bottom: calc(100% + 4px);
}

/* Modifier für Trigger am linken Viewport-Rand (z.B. Sortier-Menü in der Heatmap-Corner-Zelle, ganz links
   neben der Sidebar) – öffnet linksbündig statt rechtsbündig, damit das (breitere) Menü nicht über die
   schmale Corner-Zelle hinaus nach links über den Bildschirmrand hinausragt. */
.wf-menu--left {
  right: auto;
  left: 0;
}

.wf-menu__item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-bottom: 1px solid var(--bg-stripe);
  padding: 10px 14px;
  font-family: var(--font);
  cursor: pointer;
}

.wf-menu__item:last-child { border-bottom: none; }
.wf-menu__item:hover { background: var(--bg-stripe); }
.wf-menu__item-title { font-size: 14px; font-weight: 700; color: var(--text); }
.wf-menu__item-sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* Product Group deaktiviert, wenn eine Category-Auswahl aktiv ist und diese Option nicht dazu passt
   (18.08., siehe wireframe-filterbar.js wfIsOptionDisabled). */
.wf-menu__item--disabled { opacity: 0.4; cursor: not-allowed; }

/* ── FILTER-DROPDOWN (Category/Product Group) ──
   320px, linksbündig statt des .wf-menu-Standards (right:0, passend für rechtsseitige Trigger wie
   "+ New Bundle") – Category/Product Group sitzen links, das Menü soll dort vom Trigger nach rechts
   aufklappen. Category kommt ohne Scroll aus (kurze, feste Liste). Product Group nutzt den
   .wf-filter-menu--scroll-Modifier (mehrere hundert Einträge möglich, siehe .wf-filter-menu__list). */
.wf-filter-menu {
  width: 320px;
  left: 0;
  right: auto;
}

/* 640px ≈ Höhe der ungescrollten Category-Liste (15 Einträge) – Product-Group-Dropdown soll optisch
   genauso hoch wirken wie Category, nicht kürzer abgeschnitten. */
.wf-filter-menu--scroll .wf-filter-menu__list {
  max-height: 640px;
  overflow-y: auto;
}

/* Suchfeld oben im Product-Group-Menü (search-as-you-type, siehe wireframe-filterbar.js
   wfGroupsSearchInputHtml). */
.wf-filter-menu__search-row {
  padding: 8px 14px;
  border-bottom: 1px solid var(--bg-stripe);
}
.wf-filter-menu__search-row input {
  width: 100%;
  font-family: var(--font);
  font-size: 13px;
  padding: 6px 8px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius);
  background: var(--bg-white);
  color: var(--text);
}
.wf-filter-menu__search-row input:focus { outline: none; border-color: var(--border); }

/* Hinweis-Zeile oben im Product-Group-Menü, nur sichtbar solange mind. 1 Category gewählt ist (siehe
   wfFilterMenuHintHtml) – macht transparent, dass die Liste auf die gewählte(n) Category(ien) eingeschränkt
   ist, statt Optionen kommentarlos verschwinden zu lassen. */
.wf-filter-menu__hint {
  font-size: 12px;
  color: var(--text-muted);
  padding: 8px 14px;
  border-bottom: 1px solid var(--bg-stripe);
}

/* Auswahl-Zähler + Select all/Clear all im Product-Group-Menü (siehe wfGroupsMetaRowHtml) – Zähler bleibt
   sichtbar, auch wenn die Auswahl gerade durch einen Suchtext aus der sichtbaren Liste gefiltert ist. */
.wf-filter-menu__bulk-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 14px;
  font-size: 12px;
  color: var(--text-muted);
  border-bottom: 1px solid var(--bg-stripe);
}
.wf-filter-menu__bulk-actions a { color: var(--text); text-decoration: underline; }

.wf-filter-menu__empty {
  padding: 14px;
  font-size: 13px;
  color: var(--text-muted);
}

/* ── WOCHEN-PICKER (18.08., ersetzt die KW-Von/Bis-Dropdowns) ──
   Popover wie .wf-menu (Rahmen/Schatten/Position), eigene Breite + Innenabstand für Grid + Navigation.
   Immer 2 volle Jahres-Grids nebeneinander (Airbnb-Vorbild, Julian: "so darstellen wie die Tage in einem
   normalen Datepicker") statt eines mit Jahres-Wechsel – deckt jahresübergreifende Ranges zwischen
   benachbarten Jahren direkt ab, ohne zu blättern. 2. Anlauf (18.08.): insgesamt größer, Tertiale als
   eigene Blöcke im Grid statt separater Schnellfilter-Reihe, Jahr/Tertial-Beschriftung selbst klickbar. */
.wf-week-picker {
  width: 920px;
  padding: 18px;
}

.wf-week-picker__nav {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}

/* Pfeile + beide Jahres-Überschriften in einer Zeile, gleiche Höhe (Julian: "Pfeile und Jahre auf die
   gleiche Höhe setzen") – die Jahres-Buttons teilen sich den Platz analog zu den Panes darunter. */
.wf-week-picker__nav-years {
  display: flex;
  flex: 1;
  justify-content: space-around;
}

.wf-week-picker__year-label {
  font-family: var(--font);
  font-weight: 700;
  font-size: 16px;
  background: none;
  border: 2px solid transparent;
  cursor: pointer;
  color: var(--text);
  padding: 3px 12px;
  border-radius: var(--radius);
}

.wf-week-picker__year-label:hover { border-color: var(--border-light); }

/* Ganzes Jahr aktuell exakt ausgewählt: volle Füllung (Codierungs-Grammatik "aktiv"). */
.wf-week-picker__year-label--active {
  background: var(--border);
  color: var(--bg-white);
  border-color: var(--border);
}

.wf-week-picker__panes {
  display: flex;
  gap: 24px;
}

.wf-week-picker__pane { flex: 1; min-width: 0; }

.wf-week-picker__tertial-block { margin-bottom: 10px; }
.wf-week-picker__tertial-block:last-child { margin-bottom: 0; }

.wf-week-picker__tertial-label {
  display: block;
  font-family: var(--font);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  background: none;
  border: 1px solid var(--border-light);
  cursor: pointer;
  color: var(--text-muted);
  padding: 3px 8px;
  margin-bottom: 4px;
}

.wf-week-picker__tertial-label:hover { color: var(--text); border-color: var(--border); }

/* Tertial exakt ausgewählt: volle Füllung, wie beim Jahr-Label. */
.wf-week-picker__tertial-label--active {
  background: var(--border);
  color: var(--bg-white);
  border-color: var(--border);
}

/* Je Tertial eine eigene Zeile (17/18/17 Spalten) statt eines durchgehenden 13x4-Rasters – zeigt die
   Tertial-Gliederung direkt im Grid (Julian: "Tertiale im Grid darstellen"). */
.wf-week-picker__grid {
  display: grid;
  gap: 4px;
}

.wf-week-picker__cell {
  font-family: var(--font);
  font-size: 11px;
  border: 1px solid var(--border-light);
  background: var(--bg-white);
  cursor: pointer;
  color: var(--text);
  /* Fast quadratisch (Julian) + min-width:0 (Bugfix, 18.08.): ohne min-width:0 respektiert eine 1fr-
     Grid-Spalte die Mindestbreite ihres Inhalts und schrumpft nicht mit – bei der 18-Spalten-Zeile (T2)
     lief das Grid dadurch über den Pane-Rand hinaus (sichtbarer "Überlapp" zum Nachbar-Jahr). */
  min-width: 0;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.wf-week-picker__cell:hover { background: var(--bg-stripe); }

.wf-week-picker__cell--preview { background: var(--bg-stripe); }

/* Ausgewählte KW: volle Füllung (Codierungs-Grammatik "aktiv"), Julian: "aktive KWs schwarz markieren". */
.wf-week-picker__cell--selected {
  background: var(--border);
  color: var(--bg-white);
  border-color: var(--border);
  font-weight: 700;
}

/* "Heutige" KW (18.08., 3. Anlauf – Punkt und ein nur leicht verstärkter Rahmen waren im dichten Grid
   beide kaum erkennbar; Farbe bewusst nicht eingesetzt, um die "keine Farben"-Regel des Design-Systems
   nicht zu brechen). Deutlich dickerer, durchgezogener schwarzer statt hellgrauer Rahmen + fett gesetzte
   Zahl. Rahmenfarbe wechselt auf weiß, wenn die Zelle zusätzlich ausgewählt ist (sonst unsichtbar:
   schwarzer Rahmen auf schwarzer Füllung). */
.wf-week-picker__cell--today {
  border-width: 3px;
  border-color: var(--border);
  font-weight: 700;
}
.wf-week-picker__cell--today.wf-week-picker__cell--selected {
  border-color: var(--bg-white);
}

/* ── LIST ITEM (z.B. Snapshot-History-Drawer, Confluence-Versionshistorie-artig) ── */
.wf-list-item {
  padding: 10px 0;
  border-bottom: 1px solid var(--bg-stripe);
  cursor: pointer;
}
.wf-list-item:last-child { border-bottom: none; }
.wf-list-item:hover { background: var(--bg-stripe); }
.wf-list-item__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.wf-list-item__row + .wf-list-item__row { margin-top: 6px; }

/* ── FULL-BLEED FILTER BAR (z.B. Planning Year + Zeitraum, immer als erstes Element auf der Seite) ──
   Hebt nur das horizontale .wf-page-Padding lokal auf (negative Margins), damit die Leiste randlos bis zu
   Sidebar/Viewport-Rand wirkt, ohne die globale .wf-page-Regel anzufassen. Vertikal bleibt die normale
   Position (direkt unter der Topbar, wie jedes andere erste Element auf der Seite). Sticky (20.07.) hält
   sie beim Scrollen direkt unter der Topbar sichtbar – z-index unter Topbar (100)/Sidebar, über normalem
   Seiteninhalt. */
.wf-filterbar {
  margin: calc(-1 * var(--gap)) -32px var(--gap) -32px;
  padding: 10px 32px;
  background: var(--bg-white);
  border-bottom: 2px solid var(--border);
  position: sticky;
  top: 44px;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

/* Zwei Zonen innerhalb der Filterbar (22.07., UX-Umbau): Zeit-Kontext (links) vs. echte Filter
   (rechts) – vorher optisch nicht unterschieden, obwohl Planning Year kein Filter im engeren Sinn
   ist, sondern globaler Zeit-Kontext. */
.wf-filterbar__group {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* ── EMPTY STATE ── */
.wf-empty {
  text-align: center;
  padding: 48px;
  color: var(--text-muted);
  font-size: 12px;
  border: 2px dashed var(--border-light);
  background: var(--bg-white);
}

.wf-empty__text { text-transform: uppercase; letter-spacing: 0.5px; }

/* ── HEATMAP VIEW ──
   Randlos wie .wf-filterbar (negative Margins heben das .wf-page-Padding lokal auf), aber ohne deren
   oberen negativen Anteil UND zusätzlich mit negativem top-Margin in Höhe von --gap, um den
   margin-bottom der Filterbar selbst zu kompensieren (die Filterbar reserviert sich sonst immer einen
   Abstand zum nächsten Element, den wir hier bewusst nicht wollen – Heatmap soll direkt anschließen). */
/* Zweite, feste Grid-Spalte für den Detail-Drawer (siehe weiter unten, DETAIL-DRAWER) – dauerhaft
   sichtbar, kein Toggle/Animation mehr nötig (Drawer zeigt immer eine Selektion, siehe renderHeatmap
   Default-Selektion). Der Heatmap-Bereich selbst (erste Spalte, 1fr) bleibt in der Breite unangetastet. */
.wf-heatmap-outer {
  margin: calc(-1 * var(--gap)) -32px 0 -32px;
  display: grid;
  /* Detail-Drawer skaliert mit der tatsächlichen Breite dieses Grids statt fest 600px zu bleiben (auf
     schmaleren Laptop-Breiten sonst ein unverhältnismäßig großer Anteil) – Boden/Deckel halten ihn
     trotzdem immer lesbar bzw. nicht unnötig breit auf großen Monitoren. Bewusst % statt vw: die Sidebar
     (200px, eingeklappt 56px, siehe .wf-page margin-left) nimmt links bereits Platz weg, vw würde das
     ignorieren und dadurch rechts über den tatsächlichen Rand hinausrechnen. */
  grid-template-columns: 1fr clamp(320px, 28%, 480px);
  /* Ohne grid-template-rows würde die (einzige, implizite) Zeile nach ihrem höchsten Inhalt sizen statt
     die volle, per JS gesetzte Höhe (wfHeatmapFitHeight) zu übernehmen – bei viel Drawer-Inhalt wächst
     dann die ganze Zeile mit und die Seite scrollt statt nur der Drawer intern (siehe height/overflow
     unten, analog zur bereits gefixten Prozent-Höhen-Kette von .wf-heatmap-wrap/#wf-heatmap-body). */
  grid-template-rows: 1fr;
  align-items: stretch;
  height: calc(100vh - 96px);
  overflow: hidden;
}

.wf-heatmap-wrap {
  overflow: auto;
  /* Höhe wird per JS exakt auf den verbleibenden Viewport gesetzt (wfHeatmapFitHeight) – vermeidet
     doppelte Scrollbereiche (Seite + Heatmap-interner Scroll), CSS-Wert ist nur der Startwert vor dem
     ersten Render. */
  height: calc(100vh - 96px);
  background: var(--bg-white);
  /* Scrollbalken ausgeblendet, Scroll/Pan (Space+Drag, siehe JS) bleibt funktional – Navigation läuft
     über Ziehen der Zellen bzw. Space+Drag, sichtbare Balken sind dafür nicht nötig. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.wf-heatmap-wrap::-webkit-scrollbar { display: none; }

/* Ohne definierte Höhe hier würde min-height:100% auf .wf-heatmap (weiter unten) ins Leere laufen –
   Prozent-Höhen brauchen eine Elternkette mit echter (nicht auto-)Höhe bis zu .wf-heatmap-wrap. */
#wf-heatmap-body {
  height: 100%;
}

.wf-heatmap {
  display: flex;
  flex-direction: column;
  width: max-content;
  min-width: 100%;
  /* Analog zur Breite: Zeilen sollen sich bei wenigen sichtbaren Produktgruppen vertikal auf die volle
     Höhe von .wf-heatmap-wrap strecken statt Leerraum unter der letzten Zeile zu lassen. */
  min-height: 100%;
  /* Zoomstufe steuert die Spaltenbreite zentral über diese Custom Property (siehe wfHeatmapFitHeight/
     renderHeatmap im Script) statt jede Zelle einzeln inline zu stylen. */
  --wf-heatmap-cell-w: 64px;
}

.wf-heatmap__headrow,
.wf-heatmap__row {
  display: flex;
}

.wf-heatmap__headrow {
  position: sticky;
  top: 0;
  z-index: 4;
  background: var(--bg-white);
  border-bottom: 2px solid var(--border);
}

.wf-heatmap__namecell,
.wf-heatmap__corner {
  position: sticky;
  left: 0;
  z-index: 3;
  width: 240px;
  flex: 0 0 240px;
  background: var(--bg-white);
  border-right: 2px solid var(--border);
}

.wf-heatmap__corner {
  padding: 6px 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Sortier-Controls in der Corner-Zelle (Trichter-Icon öffnet Kriterien-Menü, Pfeil-Icon togglet auf-/
   absteigend) – siehe wfHeatmapApplySort im Script. .wf-heatmap__corner ist bereits position:sticky, dient
   damit auch als Anker für das absolut positionierte .wf-menu. */
.wf-heatmap__sort-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.wf-heatmap__sort-controls { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.wf-heatmap__sort-icon { font-size: 14px; color: var(--text-muted); cursor: pointer; }
.wf-heatmap__sort-icon:hover { color: var(--text); }

/* Zweispaltig: links reine Grip-Spalte (vollflächig ziehbar), rechts Content (Name/Zahl/Balken, komplett
   klickbar zum Selektieren) – siehe renderHeatmap im Script. Jede Zeile dieselbe Hintergrundfarbe (kein
   Zebra-Streifen mehr, bewusster Wunsch, damit die Karten optisch gleichwertig wirken). */
.wf-heatmap__namecell {
  display: flex;
  align-items: stretch;
}

.wf-heatmap__row { border-bottom: 1px solid var(--bg-stripe); min-height: 90px; flex: 1 1 auto; }

/* Detailed (Zoom 3, siehe renderHeatmap in marketing-calendar.html – product-groups-uebersicht.html nutzt
   diese Zoom-Stufe nicht mehr, siehe .wf-heatmap--show-channel-bars unten): Zelle doppelt so groß wie
   Default – Platz für die Vertriebs-Aufschlüsselung je Zelle (Mini-Bar-Chart, siehe
   .wf-heatmap__cell-channels unten), nicht nur eine optische Vergrößerung ohne Grund. Breite: die
   Basis-Regel min-width:90px auf .wf-heatmap__cell/.wf-heatmap__weekhead-cell (siehe unten) gewinnt sonst
   gegen den höheren --wf-heatmap-cell-w-Wert im flex-basis (Flex-Shrink zieht die Zelle zurück auf die
   Mindestbreite) – min-width muss hier genauso explizit angehoben werden wie sie bei .wf-heatmap--compact
   abgesenkt wird. */
.wf-heatmap--detailed .wf-heatmap__cell,
.wf-heatmap--detailed .wf-heatmap__weekhead-cell {
  min-width: 176px;
}
.wf-heatmap--detailed .wf-heatmap__row,
.wf-heatmap--detailed .wf-heatmap__cell {
  min-height: 180px;
}

/* Default-Zoom in product-groups-uebersicht.html (Zoom 2, siehe renderHeatmap) – Zellgröße hängt
   ausschließlich an der Zoom-Stufe, nicht am Channel-Bars-Toggle (wfFilterbar.heatmapShowChannelBars):
   die Zelle ist immer groß genug für die Vertriebs-Aufschlüsselung (Mini-Bar-Chart, siehe
   .wf-heatmap__cell-channels unten), ob der Toggle an oder aus ist ändert nur, ob die Balken selbst
   gerendert werden, nicht die Zellgröße (sonst würde sich beim Umschalten das ganze Grid-Layout
   verschieben). min-width explizit auf den Default-Wert (120px, siehe WF_HEATMAP_ZOOM_CELL_WIDTH)
   angehoben, sonst gewinnt bei vielen Spalten die Basis-Regel min-width:90px auf
   .wf-heatmap__cell/.wf-heatmap__weekhead-cell (Flex-Shrink zieht die Zelle darunter zurück). */
.wf-heatmap--default-lg .wf-heatmap__cell,
.wf-heatmap--default-lg .wf-heatmap__weekhead-cell {
  min-width: 120px;
}
.wf-heatmap--default-lg .wf-heatmap__row,
.wf-heatmap--default-lg .wf-heatmap__cell {
  min-height: 140px;
}

.wf-heatmap__namecell__category {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}

.wf-heatmap__namecell__grip-col {
  flex: 0 0 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid var(--bg-stripe);
  cursor: grab;
  color: var(--text-placeholder);
  font-size: 20px;
}

.wf-heatmap__namecell__grip-col:active { cursor: grabbing; }

.wf-heatmap__namecell__content-col {
  flex: 1 1 auto;
  min-width: 0;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
}

.wf-heatmap__namecell__total {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
}

.wf-heatmap__namecell__bar {
  height: 8px;
  border-radius: 4px;
  background: var(--bg-stripe);
  overflow: hidden;
}

.wf-heatmap__namecell__bar-fill {
  height: 100%;
  background: var(--text-muted);
}

/* flex:1 statt 0 0 <fix> – Spalten strecken sich auf die volle Breite, wenn wenige Wochen sichtbar sind
   (z.B. ein Tertial), min-width verhindert das Schrumpfen unter eine noch lesbare/quadratische Größe bei
   vielen sichtbaren Wochen (dann greift stattdessen das horizontale Scrollen von .wf-heatmap-wrap). 90px
   = dieselbe Mindestgröße wie .wf-heatmap__row (min-height), macht Zellen im Minimum quadratisch.
   Zweizeilig (KW-Label + Summe je Woche über alle sichtbaren/gefilterten Warengruppen) statt einer
   separaten Summenzeile darunter – analog zu Name+Total in der Warengruppen-Namenszelle, siehe
   renderHeatmap im Script. */
.wf-heatmap__weekhead-cell {
  flex: 1 1 var(--wf-heatmap-cell-w);
  min-width: 90px;
  text-align: center;
  padding: 6px 2px;
  border-left: 1px solid var(--bg-stripe);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.wf-heatmap__weekhead-cell__label {
  font-size: 11px;
  color: var(--text-muted);
}

.wf-heatmap__weekhead-cell__total {
  font-size: 12px;
  font-weight: 700;
}

/* Compact (nur Farbe, siehe renderHeatmap): Summe passt nicht in die schmalen Spalten, gleiche Logik wie
   bei den Zellen selbst (dort auch kein Text in Compact). */
.wf-heatmap--compact .wf-heatmap__weekhead-cell__total { display: none; }

/* Aktuelle KW hervorgehoben: dickerer Rahmen statt Farbe (Design-System-Regel "keine Farben"), gleiche
   Konvention wie .wf-week-picker__cell--today. box-shadow statt border: border würde mit dem "border"
   von .wf-heatmap__cell--selected kollidieren (dieselbe Eigenschaft, eine überschreibt die andere je nach
   Regel-Reihenfolge) und zusätzlich die Zellenbreite/den Inhalt verschieben (border-box zählt den Rahmen
   zur Boxgröße) – box-shadow ist rein dekorativ, ändert die Boxgröße nicht und kann neben dem Selektions-
   Rahmen unabhängig bestehen. */
.wf-heatmap__weekhead-cell--current,
.wf-heatmap__cell--current {
  box-shadow: inset 2px 0 0 0 var(--border), inset -2px 0 0 0 var(--border);
}

.wf-heatmap__weeks {
  position: relative;
  display: flex;
  flex: 1 1 auto;
}

/* Compact (Zoom 1, siehe renderHeatmap): .wf-heatmap wird hart auf die Größe von .wf-heatmap-wrap gekappt
   (width/height statt nur min-width/min-height wie bei Default) – zusammen mit den abgesenkten
   Mindestgrößen unten verteilen die schon vorhandenen flex-shrink-Regeln auf Zellen/Zeilen die
   tatsächlich verfügbare Breite/Höhe immer auf so viele Spalten/Zeilen wie sichtbar sind, unabhängig vom
   Filter – kein Scroll wie bei Default, dafür auch kein Text mehr in den Zellen (nur Farbe). Compound-
   Selektor (.wf-heatmap.wf-heatmap--compact) statt nur .wf-heatmap--compact, damit die höhere Spezifität
   unabhängig von der Regel-Reihenfolge zuverlässig über .wf-heatmap greift. */
.wf-heatmap.wf-heatmap--compact {
  width: 100%;
  min-width: 0;
  height: 100%;
  min-height: 0;
}

.wf-heatmap--compact .wf-heatmap__cell,
.wf-heatmap--compact .wf-heatmap__weekhead-cell {
  min-width: 4px;
}

.wf-heatmap--compact .wf-heatmap__cell,
.wf-heatmap--compact .wf-heatmap__row {
  min-height: 4px;
}

/* Immer einzeilig mit Ellipsis (nicht mehr nur Compact) – Umbruch bei langen Warengruppen-Namen war der
   Grund für unterschiedlich hohe Zeilen in Default, macht jetzt alle Zeilen gleich hoch (min-height auf
   .wf-heatmap__row ist nur ein Minimum, die Zeile wächst mit, wenn der Name auf mehrere Zeilen umbricht).
   Die Namenszelle selbst bleibt fix 240px breit (.wf-heatmap__namecell), lange Namen brechen um statt die
   Spalte zu verbreitern oder gekürzt zu werden. */
.wf-heatmap__namecell__name-text {
  flex: 1 1 auto;
  min-width: 0;
  white-space: normal;
  font-size: 16px;
  font-weight: 700;
}

.wf-heatmap--compact .wf-heatmap__row {
  /* flex-basis 0 statt auto (Default) – alle Zeilen bekommen exakt gleich viel Höhe statt anteilig nach
     ihrem (durch die Ellipsis oben ohnehin gleich hohen) Inhalt. */
  flex: 1 1 0%;
}

/* Floating Control Bar (Metric/Channels/Zoom/Available Only/Bundles, siehe wfHeatmapControlBarHtml) –
   eigenes Element außerhalb von .wf-heatmap (siehe HTML-Kommentar bei #wf-heatmap-controlbar),
   position:fixed statt sticky: sticky würde innerhalb der horizontal scrollenden Heatmap an deren u.U.
   sehr breiter Content-Box zentrieren statt am sichtbaren Ausschnitt von .wf-heatmap-wrap. left wird per
   JS gegen .wf-heatmap-wrap berechnet (wfHeatmapControlBarFitPosition), 50%/translateX nur als Startwert
   vor der ersten Messung. z-index unter Modal/Drawer-Overlay (500), über der Heatmap selbst. */
.wf-heatmap-controlbar {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 5px;
  background: var(--bg-white);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 5px 8px;
  box-shadow: 3px 3px 0 var(--border);
}

.wf-heatmap-controlbar:empty { display: none; }

.wf-heatmap-controlbar .wf-view-toggle,
.wf-heatmap-controlbar .wf-view-btn,
.wf-heatmap-controlbar > .wf-btn {
  white-space: nowrap;
  flex-shrink: 0;
}

/* Alle Controls exakt gleich hoch (32px, box-sizing:border-box greift global über *): ohne feste Höhe
   ergeben sich kleine Unterschiede aus unterschiedlichen Border-Breiten (.wf-btn--primary 3px vs.
   --secondary 2px – ein Button ändert sonst sogar beim Umschalten aktiv/inaktiv seine eigene Höhe) und
   unterschiedlichen Font-Sizes (Icon-Buttons 13px vs. Text-Buttons 11px). Höhe sitzt nur am äußersten
   Element jeder Control-Art – beim Toggle also am .wf-view-toggle-Wrapper, nicht zusätzlich an den
   einzelnen .wf-view-btn darin, die stattdessen per align-items:stretch (Flex-Default des Wrappers) auf
   dessen Innenhöhe gestreckt werden. display:inline-flex + align-items:center zentriert den Inhalt
   unabhängig von Padding/Border/Line-Height. */
.wf-heatmap-controlbar .wf-view-toggle,
.wf-heatmap-controlbar .wf-btn {
  height: 32px;
}

.wf-heatmap-controlbar .wf-view-btn,
.wf-heatmap-controlbar .wf-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.wf-heatmap-controlbar .wf-btn--primary,
.wf-heatmap-controlbar .wf-btn--secondary {
  border-width: 2px;
}

.wf-heatmap-controlbar .wf-view-toggle { margin-bottom: 0; padding: 1px; }

/* Kompakter als die sonst genutzten Standardgrößen von .wf-view-btn/.wf-btn – die Bar sitzt dauerhaft
   schwebend über der Heatmap und soll möglichst wenig Platz/Aufmerksamkeit einnehmen. Nachfahren-Selektor
   (nicht nur direkte Kinder), da der Bundles-Button in einem position:relative-Wrapper steckt (siehe
   wfHeatmapControlBarHtml) – sonst bleibt er bei der alten, größeren .wf-btn-Standardgröße. */
.wf-heatmap-controlbar .wf-view-btn,
.wf-heatmap-controlbar .wf-btn {
  font-size: 11px;
  padding: 0 9px;
}

/* Icon-only-Variante (z.B. Zoom-Stufen in der Control Bar) statt Text – noch kompakter als die generische
   Control-Bar-Verkleinerung oben, damit die Buttons annähernd quadratisch statt textbreit wirken. */
.wf-view-btn--icon {
  padding-left: 7px;
  padding-right: 7px;
  font-size: 13px;
  line-height: 1;
}

.wf-heatmap-controlbar__divider {
  width: 1px;
  align-self: stretch;
  background: var(--bg-stripe);
}

.wf-heatmap-legend {
  position: fixed;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-white);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 6px 10px;
  box-shadow: 3px 3px 0 var(--border);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  pointer-events: none;
}

.wf-heatmap-legend__bar {
  width: 90px;
  height: 8px;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: linear-gradient(to right, var(--bg-white), var(--border));
}

.wf-heatmap__cell {
  position: relative;
  flex: 1 1 var(--wf-heatmap-cell-w);
  min-width: 90px;
  min-height: 44px;
  border-left: 1px solid var(--bg-stripe);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  /* "cell" statt "pointer" – die ganze Zelle startet jetzt Klick-oder-Zieh (vorher nur ein schmaler
     Randstreifen, siehe wfHeatmapCellMouseDown im Script), "cell" ist der CSS-Standardcursor für
     "Zelle(n) werden ausgewählt" wie in Tabellenkalkulationen (Google Sheets/Excel). */
  cursor: cell;
  user-select: none;
}

/* Zoomstufe 1 ("Compact"): keine Zahl, nur Farbe. */
.wf-heatmap__cell--blank { font-size: 0; }

/* Planable-Status an der Zellecke statt im Zelltext: Lock-Icon immer, zusätzliches Warn-Icon nur bei
   signifikanter Abweichung zwischen eingefrorenem und aktuellem Potenzial (siehe
   wfHeatmapHasSignificantDeviation im Script). Farbe inline gesetzt, wechselt wie der Zelltext selbst
   zwischen hell/dunkel je nach Zellfarbe (wfColorScaleTextColor). pointer-events:none, damit die Icons
   das Zell-Drag (wfHeatmapCellMouseDown) nicht blockieren. */
.wf-heatmap__cell-icons {
  position: absolute;
  right: 4px;
  bottom: 2px;
  display: flex;
  gap: 3px;
  font-size: 13px;
  line-height: 1;
  pointer-events: none;
}

/* Überplanungs-Warnung hebt sich vom Rest der (zellabhängigen) Icon-Farbe ab, damit sie unabhängig von
   Farbmodus/Zellhelligkeit ins Auge fällt – Fett statt einer im Design System nicht vorhandenen Warnfarbe. */
/* Vertriebs-Mini-Bar-Chart – in product-groups-uebersicht.html an den Channel-Bars-Toggle gebunden (siehe
   .wf-heatmap--show-channel-bars oben), in marketing-calendar.html weiterhin an Zoom 3/Detailed (siehe
   .wf-heatmap--detailed oben). 3 Balken
   (Online/Filiale/Depot), Höhe relativ zueinander statt absolut zur €-Skala (siehe renderHeatmap im
   Script). Unten links in der Zelle, unabhängig vom zentrierten €-Wert (.wf-heatmap__cell ist
   display:flex/center) und ohne Überlappung mit den Status-Icons unten rechts. Immer weiß mit dünnem Rahmen
   statt zellabhängiger Textfarbe, damit die Balken auf jeder Zellhelligkeit gleich aussehen und lesbar
   bleiben. Ein über die Control Bar ausgeblendeter Vertrieb wird zurückgenommen (Opacity), nicht entfernt – gleiche
   Konvention wie .wf-chart__col:not(.wf-chart__col--prognose), damit das Verhältnis zum Ganzen ablesbar
   bleibt statt beim Ausblenden verloren zu gehen. */
.wf-heatmap__cell-channels {
  position: absolute;
  left: 8px;
  bottom: 8px;
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 48px;
  pointer-events: none;
}

/* Immer weiß statt currentColor (unabhängig von Zellhelligkeit) – plus dünner Rahmen in --border, sonst auf
   hellen Zellen (niedriger Ratio, Hintergrund nahe --bg-white) unsichtbar. */
.wf-heatmap__cell-channel-bar {
  width: 12px;
  background: var(--bg-white);
  border: 1px solid var(--border);
  border-radius: 1px 1px 0 0;
}

.wf-heatmap__cell-channel-bar--muted {
  opacity: 0.3;
}

.wf-heatmap__cell-icon--warn {
  font-weight: 700;
  -webkit-text-stroke: 0.4px currentColor;
}

/* Zellgrenze als eigener Grab-Bereich für die Rechteck-Selektion – schmaler Streifen am linken Rand jeder
   Zelle, damit ein Drag dort startet statt eine 1x1-Selektion auszulösen, und Bündel-Cards (die innerhalb
   der Zellfläche liegen) nie im Weg sind. */
.wf-heatmap__bundles {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  pointer-events: none;
}

/* overflow bewusst NICHT hidden auf der Card selbst (sonst würde die Hover-Aktion, die oberhalb der Card
   mit negativem top rendert, abgeschnitten) – Textkürzung übernimmt stattdessen .wf-heatmap-bundle__label
   als eigenes Element. */
.wf-heatmap-bundle {
  position: absolute;
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 6px;
  font-size: 11px;
  white-space: nowrap;
  cursor: pointer;
  border-radius: var(--radius);
}

.wf-heatmap-bundle__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Hover-Aktion "Group rows" – nur bei Cross-Warengruppen-Bündeln gerendert (siehe
   renderHeatmapBundleLanes), sortiert alle betroffenen Zeilen direkt übereinander. */
.wf-heatmap-bundle__group-action {
  display: none;
  position: absolute;
  top: -22px;
  left: 0;
  background: var(--border);
  color: var(--bg-white);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 3px 8px;
  border-radius: var(--radius);
  white-space: nowrap;
  z-index: 10;
}

.wf-heatmap-bundle:hover .wf-heatmap-bundle__group-action { display: block; }
.wf-heatmap-bundle__group-action:hover { background: var(--text); }

/* Farbe/Hintergrund NICHT mehr hier fest, sondern inline per Zeile gesetzt (siehe renderHeatmapBundleLanes
   im Script) – sonst auf dunklen (hochpotenzialigen) Zellen praktisch unsichtbar, da beide Stati feste
   dunkle Rahmen-/Textfarben hatten. Border-Stil bleibt die stabile, farbunabhängige Unterscheidung
   zwischen den Stati (Design-System-Konvention: Muster statt Farbe). */
.wf-heatmap-bundle--approved { border-width: 2px; border-style: solid; }
.wf-heatmap-bundle--draft { border-width: 2px; border-style: dashed; }

.wf-heatmap-bundle--highlight { box-shadow: 3px 3px 0 var(--border); z-index: 5; }

/* Selektions-Marker (Klick auf die Bündel-Bar, siehe openHeatmapBundlePreview) – derselbe Akzent wie die
   Zellen-Selektion (--wf-selection-accent, siehe .wf-heatmap__cell--sel-.../-corner oben), damit beide
   Selektionsarten optisch als "dasselbe Konzept" erkennbar sind. Färbt die gesamte Bar in der Akzentfarbe
   ein (statt nur einen Rahmen zu ziehen), damit die Selektion auch auf dunklen (hochpotenzialigen) Zellen
   klar erkennbar ist. background/border-color/color mit !important, da renderHeatmapBundleLanes je Status
   inline eigene background/border-color/color setzt (siehe Kommentar oben bei --approved/--draft) – Inline-
   Styles hätten sonst Vorrang und der Akzent würde nicht durchschlagen. Icon/Label bekommen ihre schwarze
   Schrift über eigene Kind-Selektoren, da sie selbst keine Inline-Farbe tragen und sonst weiter die (nun
   überschriebene, aber potenziell helle/dunkle) geerbte Farbe der Bar anzeigen würden. Exklusiv zur
   normalen Zellen-Selektion (siehe wfHeatmapUpdateDragSelection/wfHeatmapSelectRow). */
.wf-heatmap-bundle--selected {
  /* Fester Hex-Wert statt var(--wf-selection-accent): !important auf einer CSS-Variable schlägt inline
     background/border-color (siehe renderHeatmapBundleLanes) in mehreren Browsern nicht zuverlässig durch,
     ein literaler Farbwert dagegen schon (siehe color-Deklaration unten, die als var-freier Wert bereits
     zuverlässig funktioniert hat). Wert muss synchron zu --wf-selection-accent (#1abc9c) gehalten werden. */
  background: #1abc9c !important;
  border-color: #1abc9c !important;
  color: #000 !important;
  z-index: 4;
}
.wf-heatmap-bundle--selected .wf-heatmap-bundle__type-icon,
.wf-heatmap-bundle--selected .wf-heatmap-bundle__label {
  color: #000;
}

.wf-heatmap-bundle__type-icon { font-size: 11px; flex-shrink: 0; }

/* Selektions-Zustand: reine Marker-Klasse ohne eigene Optik (kein Rahmen mehr auf jeder Zelle einzeln) –
   der sichtbare Rahmen kommt ausschließlich über die sel-top/bottom/left/right-Klassen unten, die nur auf
   den Zellen am jeweiligen Rand der GESAMTselektion sitzen (siehe wfHeatmapSelectionBounds im Script).
   Innere Grenzen zwischen zwei selektierten Zellen bleiben dadurch linienfrei statt doppelt umrandet. */
.wf-heatmap__cell--sel-top { border-top: 2px dashed var(--wf-selection-accent); }
.wf-heatmap__cell--sel-bottom { border-bottom: 2px dashed var(--wf-selection-accent); }
.wf-heatmap__cell--sel-left { border-left: 2px dashed var(--wf-selection-accent); }
.wf-heatmap__cell--sel-right { border-right: 2px dashed var(--wf-selection-accent); }

/* 4 echte, unabhängige Spans statt ::before/::after (siehe cellsHtml im Script, immer im Markup, hier per
   Default versteckt) – bei einer nur 1 Woche oder nur 1 Zeile breiten Selektion braucht eine einzelne
   Zelle bis zu 4 Ecken gleichzeitig (z.B. bei 1x1 alle 4), das reicht mit nur einem Pseudo-Element pro
   Zelle nicht aus und führt zu Positions-Konflikten (top/left "gewinnt" immer gegen bottom/right, siehe
   frühere Version). Jede Ecke ist ein eigenes Element mit eigener, nicht kombinierter Positionierung. */
.wf-heatmap__cell-corner {
  display: none;
  position: absolute;
  width: 10px;
  height: 10px;
  pointer-events: none;
}
.wf-heatmap__cell-corner--tl { top: -2px; left: -2px; border-top: 3px solid var(--wf-selection-accent); border-left: 3px solid var(--wf-selection-accent); }
.wf-heatmap__cell-corner--tr { top: -2px; right: -2px; border-top: 3px solid var(--wf-selection-accent); border-right: 3px solid var(--wf-selection-accent); }
.wf-heatmap__cell-corner--bl { bottom: -2px; left: -2px; border-bottom: 3px solid var(--wf-selection-accent); border-left: 3px solid var(--wf-selection-accent); }
.wf-heatmap__cell-corner--br { bottom: -2px; right: -2px; border-bottom: 3px solid var(--wf-selection-accent); border-right: 3px solid var(--wf-selection-accent); }

.wf-heatmap__cell--sel-top.wf-heatmap__cell--sel-left > .wf-heatmap__cell-corner--tl,
.wf-heatmap__cell--sel-top.wf-heatmap__cell--sel-right > .wf-heatmap__cell-corner--tr,
.wf-heatmap__cell--sel-bottom.wf-heatmap__cell--sel-left > .wf-heatmap__cell-corner--bl,
.wf-heatmap__cell--sel-bottom.wf-heatmap__cell--sel-right > .wf-heatmap__cell-corner--br {
  display: block;
}

/* Space+Drag Viewport-Pan (siehe wfHeatmapKeyDown/wfHeatmapPanStart im Script) – Cursor nur bei
   gehaltener Leertaste UND tatsächlichem Hover über der Heatmap, nicht permanent. Zusätzlich explizit auf
   Zelle/Name/Bündel-Card, weil die selbst einen eigenen Cursor setzen (cell/pointer) – ohne diese
   gezielten Overrides (höhere Spezifität durch den zweiten Klassen-Teil) würde deren Cursor beim Hover
   weiterhin gewinnen statt der Hand. */
.wf-heatmap-wrap--pannable:hover { cursor: grab; }
.wf-heatmap-wrap--panning,
.wf-heatmap-wrap--panning:hover { cursor: grabbing; }

.wf-heatmap-wrap--pannable .wf-heatmap__cell,
.wf-heatmap-wrap--pannable .wf-heatmap__namecell__content-col,
.wf-heatmap-wrap--pannable .wf-heatmap-bundle {
  cursor: grab;
}
.wf-heatmap-wrap--panning .wf-heatmap__cell,
.wf-heatmap-wrap--panning .wf-heatmap__namecell__content-col,
.wf-heatmap-wrap--panning .wf-heatmap-bundle {
  cursor: grabbing;
}

/* ── HEATMAP-EINSTELLUNGEN-PANEL (Filterbar, nur in Heatmap View) ── */
.wf-heatmap-settings-pop { width: 260px; padding: 4px 0; }
.wf-heatmap-settings-pop__group { padding: 10px 14px; border-bottom: 1px solid var(--bg-stripe); }
.wf-heatmap-settings-pop__group:last-child { border-bottom: none; }
.wf-heatmap-settings-pop__label { font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); margin-bottom: 6px; }
.wf-heatmap-settings-pop__option { display: flex; align-items: center; gap: 8px; padding: 4px 0; cursor: pointer; }

/* .wf-page reserviert per body:has(.wf-selection-bar) dauerhaft 64px Bottom-Padding (das Element existiert
   im DOM, auch wenn die Table View gerade ausgeblendet ist) – für die Heatmap View brauchen wir das nicht,
   sie endet bündig am Viewport-Rand (siehe wfHeatmapFitHeight im Script). Gleiche Selektor-Form wie die
   :has()-Regel, damit die Spezifität sicher gewinnt statt sich auf !important zu verlassen. */
body:has(.wf-selection-bar) .wf-page.wf-heatmap-active,
.wf-page.wf-heatmap-active {
  padding-bottom: 0;
}

/* ── DETAIL-DRAWER (zweite, feste Grid-Spalte von .wf-heatmap-outer) ──
   Titel/Footer bleiben fix, nur der mittlere Bereich scrollt (.wf-drawer--sticky/.wf-drawer__scroll,
   wireframe.css oben). */
.wf-heatmap-panel {
  height: 100%;
  overflow: hidden;
}

.wf-heatmap-panel__inner {
  /* Füllt die Grid-Spalte (siehe clamp() bei .wf-heatmap-outer) statt einer eigenen festen Breite –
     sonst bricht dieser fixe Wert die dortige Anpassung wieder. */
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  background: var(--bg-white);
  border-left: 2px solid var(--border);
}

/* ── BÜNDEL-PREVIEW (zentriertes Overlay, wie "Preview" im Themenkalender – bewusst kein positioniertes
   Popover) ── */
.wf-heatmap-preview-overlay {
  position: fixed;
  inset: 0;
  background: rgba(17, 17, 17, 0.4);
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
}

.wf-heatmap-preview {
  width: 420px;
  max-width: 90vw;
  background: var(--bg-white);
  border: 2px solid var(--border);
  box-shadow: 4px 4px 0 var(--border);
  padding: 24px;
}
