/* ============================================================================
   ui.css · Root Index · Oberflaechenregeln AUSSERHALB von app.js
   ----------------------------------------------------------------------------
   ZWECK
   Groessen, Abstaende, Rahmen und Schriftgrade der Admin-Oberflaeche stehen
   HIER — nicht als style="..." in einem JavaScript-Textbaustein.
   Eine Optik-Aenderung ist damit EINE Zeile in dieser Datei: kein node --check,
   kein Tiefenvergleich, kein ID-Zaehlen, kein Zeichen JavaScript angefasst.

   WARUM
   Am 07.08.2026 gemessen: 3.854 HTML-Tags stehen in app.js (in JS-Strings),
   nur 456 in admin.html. Dazu 3.696 Inline-Stile und 987 zur Laufzeit gesetzte
   Groessen. Ein Inline-Stil schlaegt jede Stylesheet-Regel — deshalb wirkten
   saubere CSS-Aenderungen oft nicht, und es wurde nachkorrigiert.
   Diese Datei dreht das um, Bereich fuer Bereich.

   GELADEN VON admin.html UND index.html.
   app.js ist gemeinsam (CLAUDE.md §10.1), der Produkteditor kann von beiden
   Seiten gerendert werden. Eine reine admin.css wuerde die Consumer-Seite
   ungestylt lassen.

   HAUSREGEL FUER DIESE DATEI (CLAUDE.md §4.2 "eine Regel, ein Ort")
   Was hier steht, steht NICHT zusaetzlich inline am Element.
   Wer eine Regel hierher holt, entfernt den Inline-Stil im selben Durchgang —
   sonst gewinnt weiterhin der Inline-Stil und die Datei luegt.

   Angelegt 07.08.2026 · Build 2026-08-07-0645 · Probe-Durchgang "Kopfbereich".
   Zuletzt erweitert Build 2026-08-07-0851 · Durchgaenge 2a + 2b "Reiter 2" und Aufraeumen feEditorResponsive · Build 2026-08-07-1014 Durchgang 3a "Fussleiste" · Build 2026-08-07-1027 Durchgang 3b "Knopfleiste" · Build 2026-08-07-1049 Durchgang 4 "Reiter 1 Rest" · Build 2026-08-07-1143 Durchgang 5 "Reiter 3" · Build 2026-08-07-1242 Durchgang 3c "Freigabe-Check" · Build 2026-08-07-1251 Durchgang 3d Teil 1 "Ampel" · Build 2026-08-07-1311 Kopfbereich zweispaltig · Build 2026-08-07-1708 Mikro-Karte volle Breite.
   ============================================================================ */


/* ============================================================================
   ADMIN-SEITE · LUFT ZWISCHEN OBERKANTE UND INHALT  (--admin-oben)
   ----------------------------------------------------------------------------
   #adminNav ist position:fixed; top:0 (admin.html Z. 1503). Damit der Inhalt
   nicht darunter liegt, traegt .container oben ein Polster in dieser Hoehe.

   Bis 07.08.2026 waren das 112px — ein Rest aus der Zeit mit ZWEI gestapelten
   Leisten. Die obere Kopfzeile ist seit 28o entfernt, das Polster blieb stehen.

   #adminNav allein misst rechnerisch rund 56px:
       12px Polster oben + ~35px Knopfhoehe + 8px Polster unten + 1px Rahmen.
   Darum jetzt 64px = Leiste plus etwas Luft.

   ⚠ GESCHAETZT, nicht am Bildschirm gemessen. Wenn der Inhalt die Leiste
   beruehrt: Zahl erhoehen. Wenn zu viel Luft bleibt: verkleinern.

   ⚠ Diese Zahl gilt fuer JEDE Admin-Seite — Dashboard, Listen, Erfassung.
   Beim Scrollen faehrt #adminNav weg und admin.html Z. 1509 setzt das Polster
   ohnehin auf 14px; diese Zahl hier betrifft nur den ungescrollten Zustand.
   ============================================================================ */
body{ --admin-oben:64px }


/* ============================================================================
   PRODUKTEDITOR · KOPFLEISTE  (#feNavLeiste)
   ----------------------------------------------------------------------------
   Die schwebende Leiste mit Posteingang / Blaettern / Status / Freigeben /
   markiert / Build. Sie klebt beim Scrollen oben.

   WO SCHRAUBEN?
   · Abstand zur Oberkante beim Kleben .... --nav-oben
   · Hochzug gegen das Polster darueber ... --nav-hochzug   (negativ = weiter hoch)
   · Hoehe der Leiste .................... padding

   ⚠ ZUM VERSTAENDNIS, warum oben Luft sein KANN:
   In admin.html konkurrieren zwei Leisten um die Oberkante.
   1. #adminNav ist position:fixed; top:0 - die Admin-Navigation. Damit der
      Inhalt nicht darunter verschwindet, traegt .container ein Polster von
      padding-top:112px !important (admin.html, Z. 1548).
   2. Beim Scrollen bekommt der body die Klasse .navHidden: #adminNav faehrt
      hoch und das Polster schrumpft auf 14px (admin.html, Z. 1509).
   Diese Leiste hier klebt mit --nav-oben und weiss von #adminNav nichts.
   Wer sie hoeher haben will, stellt --nav-oben und --nav-hochzug nach; wer das
   Polster selbst meint, aendert die 112px in admin.html - das betrifft dann
   ABER JEDE Admin-Seite, nicht nur den Editor.
   ============================================================================ */
/* ----------------------------------------------------------------------------
   KNOEPFE DER KOPFLEISTE  (.feNavBtn)   —   24.08.2026, Ralph
   Ralph: "buttons sind alle irgendwie verschoben."
   Gemessen im Browser an P73650, in EINER sichtbaren Zeile:
     Hoehen  24 · 27 · 28 · 29 px      Schriftgroessen  10 · 11.5 · 12 · 13 px
   Jeder Knopf brachte seinen eigenen Inline-Stil mit. Inline schlaegt jede
   Stylesheet-Regel — das liess sich nicht ueberschreiben, es musste an der
   Quelle weg. Die Inline-Stile stehen deshalb nicht mehr in produkteditor.js.

   🔴 WICHTIG FUER DEN NAECHSTEN, DER HIER SUCHT: dieselben Knoepfe stehen je
   nach Modus an ZWEI Orten. feRailNav() VERSCHIEBT sie im Fokusmodus aus
   #feNavLeiste nach #feRailNav und blendet die alte Leiste aus. Es sind
   dieselben Elemente, nicht zwei Kopien — deshalb wirkt eine Klasse an beiden
   Stellen. Wer stattdessen #feNavLeiste stylt, stylt im Fokusmodus nichts:
   die Leiste ist dort display:none (Zeile weiter unten).

   --nav-btn-h ist die gemeinsame Hoehe von Knoepfen UND Chips (.feSegBtn).
   Wer die Leiste hoeher oder flacher will, aendert genau diese eine Zahl.
   ---------------------------------------------------------------------------- */
:root{ --nav-btn-h:26px }

.feNavBtn{
  display:inline-flex; align-items:center; justify-content:center;
  height:var(--nav-btn-h); box-sizing:border-box;
  padding:0 11px;
  border:1px solid var(--line); border-radius:8px;
  background:var(--card); color:var(--ink);
  font-size:12px; font-weight:600; line-height:1;
  white-space:nowrap; cursor:pointer; flex:0 0 auto;
}
.feNavBtn:hover{ border-color:var(--k-2f6fd6,#2f6fd6) }
/* Ausgegraut heisst: es gibt kein voriges/naechstes Produkt. Der Knopf bleibt
   stehen, damit die Zeile nicht springt, sobald man am Rand der Liste ist. */
.feNavBtn.aus, .feNavBtn:disabled{
  background:var(--bg); color:var(--muted); cursor:default; border-color:var(--line);
}
/* Ralph: "vorherig und naechster wuerde ein kleiner pfeil reichen."
   Quadratisch, damit die beiden als Paar zu lesen sind. */
.feNavBtn.pfeil{ width:var(--nav-btn-h); padding:0; font-size:15px }

/* Chips derselben Zeile auf dieselbe Hoehe. Padding und Schrift bleiben, wie sie
   waren — nur die Hoehe wird gemeinsam, sonst stehen 24 gegen 26 px. */
.feSegBtn{ height:var(--nav-btn-h); box-sizing:border-box;
  display:inline-flex; align-items:center; justify-content:center }

#feNavLeiste{
  --nav-oben:0px;
  --nav-hochzug:-8px;
  position:sticky;
  top:var(--nav-oben);
  z-index:25;
  display:flex;
  align-items:center;
  gap:8px;
  flex-wrap:wrap;
  background:var(--bg);
  border-bottom:1px solid var(--line);
  padding:8px 2px;
  margin:var(--nav-hochzug) 0 12px;
}

/* ============================================================================
   PRODUKTEDITOR · KOPFBAND  (#feKopfband)   —   Work #133 E3, 20.08.2026
   ----------------------------------------------------------------------------
   Ralph zum alten Kopf: "produktwert klebt an der seite. also schoen und
   funktional ist anders." Vorlage ist seine DBKR-Vorgangsmaske:
   bereiche/mockup-erfassung-dbkr.html

   Marke und Kategorie klein darueber, der Produktname gross, das Statuswort als
   Pille, die P-Nummer rechts. Dieselben Elemente wie vorher (feDubChip,
   fePNrInfo) - nur nicht mehr als 12px-Grauzeile am rechten Rand.

   WO SCHRAUBEN?
   · Farbe des Bandes ......... --fkb-bg          — genau EINMAL
   · Schriftgroesse des Namens  .fkbName font-size — ZWEIMAL, und das mit Absicht:
     20px normal, 17px unter 720px Breite. Das sind zwei verschiedene Werte fuer
     zwei verschiedene Faelle, keine Kopie derselben Zahl. Wer den Unterschied
     einebnet, macht den Namen auf dem Handy wieder zum Zeilenbrecher.
   ============================================================================ */
#feKopfband{
  --fkb-bg:#134a63;
  --fkb-hell:#a8cfe0;
  display:flex;
  align-items:center;
  gap:16px;
  flex-wrap:wrap;
  background:var(--fkb-bg);
  color:#fff;
  border-radius:10px 10px 0 0;
  padding:12px 18px;
  margin:0 0 10px;
}
#feKopfband .fkbLinks{ flex:1 1 auto; min-width:0; }
#feKopfband .fkbMarke{
  font-size:12px;
  color:var(--fkb-hell);
  letter-spacing:.3px;
  min-height:1em;          /* haelt die Zeile, auch wenn Marke und Kategorie fehlen */
}
#feKopfband .fkbName{
  font-size:20px;
  font-weight:600;
  line-height:1.25;
  overflow-wrap:anywhere;  /* lange Produktnamen brechen um, statt das Band zu sprengen */
}
#feKopfband .fkbStatus{
  flex:0 0 auto;
  font-size:12.5px;
  font-weight:600;
  letter-spacing:1.1px;
  text-transform:uppercase;
  padding:5px 15px;
  border:1px solid #4d8ba8;
  border-radius:5px;
  background:#0e3a4e;
}
#feKopfband .fkbId{
  flex:0 0 auto;
  font-size:12.5px;
  color:var(--fkb-hell);
  font-variant-numeric:tabular-nums;
}
/* Der Dublettenchip sitzt IM Namen und braucht Kontrast zum dunklen Band. */
#feKopfband #feDubChip{ margin-left:9px; vertical-align:middle; }

/* Schmaler Schirm: das Statuswort und die P-Nummer wandern unter den Namen,
   statt ihn auf zwei Zeichen zu quetschen. */
@media (max-width:720px){
  #feKopfband{ gap:8px; padding:10px 13px; }
  #feKopfband .fkbLinks{ flex:1 1 100%; }
  #feKopfband .fkbName{ font-size:17px; }
}


/* ============================================================================
   FREIGABEGRUENDE AN IHRER STATION  — Work #133 E8, 20.08.2026
   ----------------------------------------------------------------------------
   Ralph, 16.08.: die Gruende sollen "als Chips in der linken Rail UNTER DEM
   ZUSTAENDIGEN SCHRITT" stehen - dort, wo die Handlung ist, die sie schliesst.

   Sie sitzen im Schrittknopf, unter dem Statuswort. Klein und rot umrandet, aber
   ohne Fuellung: ein Grund ist ein Hinweis auf Arbeit, kein Alarm. Der volle
   Satz steht als Mausanzeige - die Rail ist 180px schmal, ein ganzer Satz waere
   dort ein Absatz.

   WO SCHRAUBEN?
   · Farbe .... --fgr-farbe   (einmal, gilt fuer Rand und Schrift)
   ============================================================================ */
.feFokusGruende{
  --fgr-farbe:var(--k-b91c1c,#b91c1c);
  display:flex; flex-wrap:wrap; gap:3px; margin-top:4px;
}
.feFokusGrund{
  font-size:9.5px; line-height:1.35;
  padding:1px 5px; border-radius:var(--fk-r-klein);
  border:1px solid var(--fgr-farbe);
  color:var(--fgr-farbe);
  background:transparent;
  overflow-wrap:anywhere;
}
/* Im aktiven Schritt etwas kraeftiger - dort wird gerade gearbeitet. */
.feFokusSt.akt .feFokusGrund{ background:var(--k-fdecea,#fdecea) }


/* ============================================================================
   RIKI ANGEDOCKT IM EDITOR  (.rikiAngedockt)  — Work #133 E5a, 20.08.2026
   ----------------------------------------------------------------------------
   Ralphs DBKR-Vorlage hat die Benutzerfuehrung als Spalte am rechten Rand mit
   senkrechter Lasche. Vorlage: bereiche/mockup-erfassung-dbkr.html

   ES IST DASSELBE PANEL wie in der Benutzersicht, nur anders gesetzt. Der Inhalt
   wird in app.js EINMAL gebaut; hier steht ausschliesslich, wo er sitzt.

   Der Editor wird schmaler, statt ueberdeckt zu werden: body.rikiAngedocktOffen
   gibt rechts Platz frei. Ein Hilfefenster, das die Maske verdeckt, an der man
   gerade arbeitet, hilft beim Arbeiten nicht.

   WO SCHRAUBEN?
   · Breite der Spalte .... --riki-dock-w   (der Platzhalter zieht automatisch nach)
   · Breite der Lasche .... --riki-lasche-w
   ============================================================================ */
:root{ --riki-dock-w:340px; --riki-lasche-w:26px }

#rikiPanel.rikiAngedockt{
  position:fixed; top:0; right:0; bottom:0;
  width:min(var(--riki-dock-w), 92vw);
  z-index:9991;
  display:flex; flex-direction:column;
  padding:14px 16px 16px calc(var(--riki-lasche-w) + 14px);
  overflow:auto;
  background:var(--tb-card,var(--card,#fff));
  border:0; border-left:1px solid var(--line);
  border-radius:0;
  box-shadow:-8px 0 24px rgba(20,40,70,.14);
  /* Einschieben von rechts statt Aufklappen aus einer Ecke - die Ecke, an der
     der schwebende Knopf sitzt, gibt es hier nicht. */
  animation:rikiEin .2s cubic-bezier(.2,.8,.3,1) both;
  transform-origin:100% 50%;
}
@keyframes rikiEin{ from{ transform:translateX(100%) } to{ transform:none } }
/* 🔴 OHNE ID, und das ist kein Versehen: rikiPanelSchliessen() setzt p.id=""
   (damit ein zweiter Klick nicht dieselbe Karte trifft), BEVOR es .rikiSchliesst
   setzt. Ein Selektor mit #rikiPanel wuerde hier nie greifen.
   Die Oeffnungsregeln oben tragen die ID mit Absicht - sie muessen gegen
   #rikiPanel{animation:rikiAuf} gewinnen, und eine Klasse allein verliert gegen
   eine ID. Beim Schliessen gibt es diesen Gegner nicht mehr. */
.rikiAngedockt.rikiSchliesst{ animation:rikiAus .16s ease-in both }
@keyframes rikiAus{ from{ transform:none } to{ transform:translateX(100%) } }

/* Die senkrechte Lasche. Sie klebt am linken Rand des Panels und traegt dieselbe
   Beschriftung wie im DBKR-Vorbild. */
.rikiAngedockt .rikiLasche{
  position:absolute; left:0; top:0; bottom:0;
  width:var(--riki-lasche-w);
  border:0; padding:0; cursor:pointer;
  background:#134a63; color:#e8f1f6;
  display:flex; align-items:center; justify-content:center;
}
.rikiAngedockt .rikiLasche span{
  writing-mode:vertical-rl; transform:rotate(180deg);
  font-size:12px; letter-spacing:1.3px;
}
.rikiAngedockt .rikiLasche:hover{ background:#0e3a4e }

/* Die aktuelle Station als kleine Marke neben dem Namen - im DBKR-Vorbild steht
   dort "SEITE 1/13". Hier ist die Station die ehrlichere Angabe: sie kommt aus
   FE_SCHRITTE und muss nicht gepflegt werden. */
.rikiAngedockt .rikiStation{
  font-size:11px; color:var(--muted);
  border:1px solid var(--line); border-radius:11px; padding:2px 9px;
  white-space:nowrap;
}

/* Der Editor macht Platz. calc statt fester Zahl: aendert sich die Spaltenbreite
   oben, zieht der Abstand mit (§28.4). */
body.rikiAngedocktOffen{ padding-right:min(var(--riki-dock-w), 92vw) }

/* Schmaler Schirm: eine 340px-Spalte neben einer Erfassungsmaske ist dort kein
   Nebeneinander mehr, sondern zwei zu enge Spalten. Dann deckt das Panel ab -
   und der Editor bekommt KEINEN Platzhalter, weil er ohnehin verdeckt ist. */
@media (max-width:900px){
  #rikiPanel.rikiAngedockt{ width:min(var(--riki-dock-w), 100vw) }
  body.rikiAngedocktOffen{ padding-right:0 }
}
@media (prefers-reduced-motion:reduce){
  #rikiPanel.rikiAngedockt,
  .rikiAngedockt.rikiSchliesst{ animation:none; transform:none }
}


/* ============================================================================
   PRODUKTEDITOR · KARTEN MIT TITELBALKEN  (.feKarte)  — Work #133 E4, 20.08.2026
   ----------------------------------------------------------------------------
   Ralphs DBKR-Vorlage: jede Karte traegt einen grauen Titelbalken mit Trennlinie
   statt einer freistehenden Kleinschrift-Zeile. Vorlage:
   bereiche/mockup-erfassung-dbkr.html

   Erzeugt von card() und cardF() in app.js (Z. ~22981). Bis zum 20.08. standen
   die Werte dort als Inline-Styles, waehrend HIER schon Regeln fuer .feKarte
   warteten, die nie greifen konnten - die Klasse wurde nie vergeben. Zwei Orte
   fuers Aussehen, einer davon tot.

   DER BALKEN KOMMT UEBER NEGATIVE RAENDER aus dem Kartenpolster heraus. Das ist
   Absicht: so bleibt die DOM-Struktur wie vorher (Titel und Inhalt sind
   Geschwister, kein Wrapper dazwischen), und Selektoren wie
   ".feKtxInhalt > #fe_colRef > div > div:first-child" greifen weiter.

   WO SCHRAUBEN?
   · Kartenpolster ....... --fk-pad     (Balken zieht automatisch nach)
   · Farbe des Balkens ... --fk-balken
   · Radius .............. --fk-radius
   Wer eine dieser Zahlen ein zweites Mal irgendwo findet, hat einen Fehler
   gefunden - der Balken rechnet ausschliesslich mit ihnen.
   ============================================================================ */
.feKarte{
  --fk-pad:12px;
  --fk-radius:12px;
  --fk-balken:var(--bg);
  background:var(--card);
  border:1px solid var(--line);
  border-radius:var(--fk-radius);
  padding:var(--fk-pad);
  margin-bottom:12px;
}
.feKartenTitel{
  /* Aus dem Polster heraus nach oben, links und rechts - dadurch sitzt der
     Balken buendig an der Kartenkante, ohne dass die Karte ihr Polster verliert. */
  margin:calc(var(--fk-pad) * -1) calc(var(--fk-pad) * -1) var(--fk-pad);
  padding:9px 14px;
  background:var(--fk-balken);
  border-bottom:1px solid var(--line);
  border-radius:calc(var(--fk-radius) - 1px) calc(var(--fk-radius) - 1px) 0 0;
  font-size:12px;
  font-weight:600;
  letter-spacing:.3px;
  text-transform:uppercase;
  color:var(--karten-titel,var(--green));
  display:flex;
  align-items:center;
  gap:8px;
  flex-wrap:wrap;
}
/* Die Zusatzangabe im Titel ist Beiwerk, nicht Ueberschrift - sie war schon
   vorher kleingeschrieben (Z. 573 ff.), bekommt hier aber die Gewichtung dazu. */
.feKartenTitel .feKartenZusatz{ font-weight:400; letter-spacing:0 }

/* Flex-Variante fuer die Spaltenansicht in Station 3: Titel behaelt seine Hoehe,
   der Inhalt nimmt den Rest und scrollt fuer sich. */
.feKarteFlex{
  display:flex;
  flex-direction:column;
  min-height:0;
  height:100%;
  overflow:auto;
  margin-bottom:0;
}
.feKarteFlex > .feKartenTitel{ flex:0 0 auto }
.feKarteFlex > .cardFB{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column }


/* ============================================================================
   PRODUKTEDITOR · RAHMEN UND LINKER STREIFEN  (#feRahmen, #feRail)
   ----------------------------------------------------------------------------
   Zweispaltiger Rahmen: links der Streifen mit Stationsschiene, Root-Index,
   Freigabe-Ampel und Quelle — rechts die Arbeitsflaeche.

   WO SCHRAUBEN?
   · Breite des linken Streifens .. #feRahmen → erster Wert in grid-template-columns
   · Abstand der beiden Spalten ... #feRahmen → gap
   · Streifen klebt ab Hoehe ...... #feRail   → top

   NICHT hier: grid-template-rows und die Zeilen-Spanne des Streifens. Die setzt
   feKachelBreiteSync zur Laufzeit, weil sie vom gemessenen Platz abhaengen.
   ============================================================================ */
/* ============================================================================
   🔴 DER RASTERVERTRAG · HANDY ZUERST   (Work #181 Stufe 1, 23.08.2026)
   ----------------------------------------------------------------------------
   🔴 PRAEZISIERT 23.08. DURCH RALPH: "handy eher nicht. fast immer am laptop,
   ggf. noch ipad, admin per handy sehr selten bis garnicht."
   Damit gilt fuer DIESEN Bereich (Produkt erfassen ist Adminarbeit):
   Laptop ist der Hauptfall, iPad muss ordentlich gehen, Handy ist der Rueckfall.
   Der fruehere Entscheid F2 "Handy zuerst" stammt aus der Planung und galt fuer
   die Consumer-Seite; fuer den Editor ist er hiermit ueberholt.

   EINSPALTIG BLEIBT TROTZDEM DER GRUNDZUSTAND - aber als Rueckfall, nicht als
   Zielbild. Der Grund ist unveraendert: der kleinste Editor-Umbruchpunkt lag bei
   1399px und liess die 180px-Leiste auch auf einem 390px-Schirm stehen; dem
   Arbeitsbereich blieben 192px. Ein Grundzustand, der bei jeder Breite haelt,
   ist billiger als eine Sonderregel je Geraet.

   DIE DREI STUFEN, eine Definition je Stufe:
     Grundzustand   alles untereinander           (Rueckfall, schmale Fenster)
     ab  700px      Leiste + Arbeitsbereich       (iPad hochkant und alles darueber)
     ab 1400px      zusaetzlich die Kontextspalte (Laptop - der Hauptfall)

   WARUM 700 UND NICHT 900: gemessen an den Geraeten, die Ralph wirklich benutzt.
   Bei 900 fielen iPad hochkant (768px) und iPad Pro 11 hochkant (834px) in den
   einspaltigen Rueckfall - auf einem iPad ist das verschenkter Platz, dort reicht
   es fuer Leiste (180) plus Arbeitsbereich (564). Mit 700 greift zweispaltig ab
   dem kleinsten iPad; einspaltig bleibt fuer Handy und sehr schmale Fenster.

   WAS SICH GEGENUEBER VORHER GEAENDERT HAT: die Zwischenraeume waren eigene
   GRID-SPALTEN, weil CSS Grid nur ein column-gap kennt und Ralph links 43px und
   rechts 20px wollte. Deshalb standen die Kinder in Spalte 1, 3 und 5. Am 23.08.
   hat Ralph zugestimmt, dass beide Abstaende gleich sein duerfen - damit ist es
   ein einziges gap und die Kinder stehen wieder in 1, 2, 3.
   Das ist keine Kosmetik: ein Element, das in keiner Placement-Regel stand, landete
   per Auto-Placement im Zwischenraum, wurde auf 43px gequetscht und sah aus wie ein
   Balken hinter dem Inhalt. Diese Fehlerquelle gibt es jetzt nicht mehr.
   ========================================================================== */
#feRahmen{
  display:grid;
  grid-template-columns:minmax(0,1fr);   /* Handy: alles untereinander */
  gap:16px;
  align-items:start;
}
@media (min-width:700px){
  /* Altansicht (ohne Fokus): Leiste 242px, Rest Arbeitsbereich. */
  #feRahmen{ grid-template-columns:242px minmax(0,1fr); gap:12px }
}
#feRail{
  display:flex;
  flex-direction:column;
  gap:10px;
  position:sticky;
  /* Work #51: Der weisse Datenstatus darueber ist selbst sticky und kann je
     nach Produkt umbrechen. Sein gerendertes Mass wird von feStickyKopfBinden
     als gemeinsame Variable gesetzt; hier steht keine zweite Kopfhoehe. */
  top:var(--fe-sticky-kopf, 0px);
  min-width:0;
  /* 🔴 15.08.2026 (Work #23, Ralph: „linker bereich soll auch optisch getrennter sein,
     auch als art menue"). Die Rail war bisher nur eine Spalte MIT Inhalt — ohne
     eigenen Grund und ohne Kante sah sie aus wie loser Text neben dem Formular.
     Seit im Adminbereich links eine echte Menueleiste steht, faellt das doppelt auf:
     dieselbe Stelle des Bildschirms, zwei verschiedene Sprachen.
     Jetzt hat sie einen eigenen Grund und eine Kante nach rechts — dieselbe Rolle,
     dieselbe Optik. Kein Rahmen ringsum: sie beginnt am Bildschirmrand und soll dort
     auch anliegen, nicht als Kaestchen schweben. */
  /* 🔴 15.08.2026 abends, Ralph: „was aber nicht passt, ist das menue, das soll
     auch weiss hinterlegt sein." Hier stand `--bg-2` (#f6f7f9) — ein Grauton, der
     die Rail vom Rest ABSETZEN sollte. Genau das war der Fehler: sie ist kein
     Beiwerk neben den Karten, sie IST eine Karte. Auf dem Bild von Ralph steht sie
     als einziger Block grau zwischen lauter weissen — das liest sich wie
     „ausgegraut, nicht benutzbar", und das ist das Gegenteil ihrer Rolle.
     Jetzt derselbe Grund wie jede andere Karte (`--card`), damit die Farbe nicht
     doppelt gepflegt wird und beim naechsten Themenwechsel mitzieht.
     Der Ausgangspunkt aus Work #23 bleibt: Kante rechts, links am Bildschirmrand
     anliegend, kein Rahmen ringsum. Geaendert wird die FARBE, nicht die Form. */
  background:var(--card);
  border-right:1px solid var(--line);
  border-radius:10px 0 0 10px;
  padding:12px 12px 16px 12px;
  /* Der Rahmen rechnet mit 180px Spaltenbreite (§ Kommentar bei #feRahmen) — mit
     border-box bleibt diese Zahl trotz Innenabstand richtig. */
  box-sizing:border-box;
  align-self:start;
}
/* Die Gruppentitel tragen die Menue-Anmutung: kleiner, ruhiger, mit Abstand darueber. */
#feRail .feRailGrpTit{ letter-spacing:.07em }
#feRail .feRailGrpTit + *{ margin-top:2px }


/* ============================================================================
   PRODUKTEDITOR · STATIONSSCHIENE  (#feTabBar, .feSt)
   ----------------------------------------------------------------------------
   Die drei Arbeitsstationen stehen senkrecht im linken Streifen (Etappe 3a).

   Die aktive Station ist die Klasse .on am Knopf — sonst nichts.
   Vorher schrieb feTabWechsel fuenf Inline-Stile je Knopf und noch zwei an den
   Ring; jetzt schaltet es EINE Klasse um, das Aussehen steht vollstaendig hier.

   WO SCHRAUBEN?
   · Abstand der Stationen ...... #feTabBar → gap / padding
   · Knopfhoehe ................. .feSt     → padding
   · Ringgroesse ................ .feStNr   → width / height / flex
   · Farbe der aktiven Station .. .feSt.on
   ============================================================================ */
#feTabBar{
  background:var(--card);
  border:1px solid var(--line);
  border-radius:12px;
  padding:9px 8px;
  display:flex;
  flex-direction:column;
  gap:3px;
}

/* Ueberschrift "Stationen". */
#feTabBar .feStTitel{
  font-size:10px;
  letter-spacing:.09em;
  text-transform:uppercase;
  color:var(--muted);
  font-weight:700;
  padding:2px 9px 6px;
}

/* Eine Station. */
.feSt{
  display:flex;
  align-items:center;
  gap:9px;
  width:100%;
  text-align:left;
  border:0;
  border-left:3px solid transparent;
  background:none;
  border-radius:8px;
  padding:8px 9px;
  font-size:13px;
  font-weight:600;
  cursor:pointer;
  color:var(--muted);
}
.feSt .feStTxt{ min-width:0; line-height:1.25 }

/* Der nummerierte Ring. */
.feStNr{
  width:21px;
  height:21px;
  flex:0 0 21px;
  border-radius:50%;
  border:2px solid var(--line);
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:10.5px;
  background:var(--card);
  color:var(--muted);
}

/* Aktive Station: linker Balken, gruener Ring, heller Grund. */
.feSt.on{
  color:var(--k-166534);
  border-left-color:var(--k-16a34a);
  background:var(--greenlt,#ecfdf5);
}
.feSt.on .feStNr{
  border-color:var(--k-16a34a);
  color:var(--k-166534);
}

/* Zahlenperlen an den Stationen. Die Klasse sagt den Zustand:
   ohne Zusatz = versteckt · .warn = etwas offen · .ok = erledigt · .gelb = Hinweis.
   Die Badge-Funktionen in app.js setzen nur noch className und Text. */
.feStBadge{
  display:none;
  border-radius:999px;
  padding:1px 8px;
  font-size:11px;
  font-weight:800;
}
.feStBadge.warn{ display:inline; background:var(--k-fff7ed,#fff7ed); color:var(--k-d97706,#d97706) }
.feStBadge.ok  { display:inline; background:var(--greenlt,#ecfdf5);  color:var(--k-166534,#166534) }
.feStBadge.gelb{ display:inline; background:#fef9c3;                 color:#854d0e }


/* ============================================================================
   PRODUKTEDITOR · KOPFBEREICH  (#feKopfGrid)
   ----------------------------------------------------------------------------
   Die Vierspalten-Eingabetabelle aus Etappe 2 (Vorlage: Mockup H).
   Aufbau:  #feKopfGrid  >  .mzr (das Raster)  >  .mz (eine Zelle je Feld)
            .mz-2 / .mz-4 = Zelle ueber zwei bzw. vier Spalten
            <k> = die kleine Grossbuchstaben-Beschriftung ueber dem Feld

   WO SCHRAUBEN?
   · Zelle groesser/kleiner ......... .mz            → padding
   · mehr/weniger Spalten ........... .mzr           → grid-template-columns
   · Umbruchpunkt ................... @media unten   → max-width
   · Eingabefeld allgemein .......... .fld
   · Produktname (Schlagzeile) ...... #fe_name
   ============================================================================ */

#feKopfGrid{
  border:1px solid var(--line);
  border-radius:12px;
  overflow:hidden;
  background:var(--card);
  margin-bottom:12px;
}

/* 🔴 20.08.2026, Work #133 E9: der Titelbalken des Kopfrasters.
   Er braucht KEINE negativen Raender - anders als .feKarte hat #feKopfGrid
   selbst kein Polster (die Zellen bringen ihres mit) und overflow:hidden
   schneidet den Balken sauber an der Rundung ab. Deshalb hier ein eigener,
   kurzer Block statt eines Sonderfalls in .feKartenTitel: zwei verschiedene
   Kartenbauarten, zwei Regeln - eine gemeinsame waere ein Kompromiss, der
   beiden nicht passt. */
#feKopfGrid > .feKopfTitel{
  margin:0;
  border-radius:0;
  border-bottom:1px solid var(--line);
  background:var(--bg);
}

/* Das Raster selbst. Spaltenzahl hier aendern, nicht an den Zellen.
   07.08.2026 (Ralph): von VIER auf ZWEI Spalten - rechts steht jetzt die
   Bildspalte, das Formular hat nur noch die halbe Breite. Die Zellen sind in
   app.js in der Reihenfolge Produktname / EAN / EAN-Status / Marke / Kategorie
   / Bio / Verzehr angeordnet; damit steht Marke unter EAN und Bio darunter. */
#feKopfGrid .mzr{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
}

/* Eine Zelle = ein Feld. Der Innenabstand bestimmt die Zeilenhoehe des Kopfes. */
#feKopfGrid .mz{
  padding:8px 12px 10px;
  border-right:1px solid var(--line);
  border-bottom:1px solid var(--line);
  min-width:0;
}

/* Letzte Spalte traegt keinen rechten Strich. */
#feKopfGrid .mz:nth-child(2n){ border-right:0 }

/* Zellen ueber mehrere Spalten.
   BEWUSST mit .mzr > .mz.mz-N (Spezifitaet 1-3-0): sie muessen die
   :nth-child-Regeln (1-2-0) schlagen — auch die im @media-Block ganz unten,
   der spaeter in der Datei steht. Vorher stand das als Inline-Stil am Element
   und gewann dadurch immer; dieses Verhalten bleibt unveraendert. */
#feKopfGrid .mzr > .mz.mz-2{ grid-column:1 / -1 }
#feKopfGrid .mzr > .mz.mz-4{ grid-column:1 / -1; border-right:0 }

/* Beschriftung ueber dem Feld. */
#feKopfGrid .mz k{
  display:block;
  font-size:9.5px;
  letter-spacing:.09em;
  text-transform:uppercase;
  color:var(--muted);
  font-weight:700;
  margin-bottom:3px;
}

/* Felder fuellen ihre Zelle. */
#feKopfGrid .mz input[type=text],
#feKopfGrid .mz select{ width:100%; box-sizing:border-box }

/* Grundform eines Eingabefeldes im Kopf. */
#feKopfGrid .fld{
  width:100%;
  box-sizing:border-box;
  padding:6px 8px;
  border:1px solid var(--line);
  border-radius:8px;
  background:var(--bg);
  color:var(--ink);
  font-size:13px;
}

/* Produktname — die Schlagzeile des Kopfes, bewusst ohne Kasten. */
#feKopfGrid #fe_name{
  width:100%;
  box-sizing:border-box;
  padding:5px 4px;
  border:0;
  border-bottom:2px solid var(--line);
  border-radius:0;
  font-size:18px;
  font-weight:800;
  color:var(--ink);
  background:transparent;
}

/* Ankreuzfeld mit Beschriftung in einer Zelle (EAN-Status). */
#feKopfGrid .mzCheck{
  display:flex;
  align-items:center;
  gap:6px;
  font-size:12px;
  color:var(--muted);
  cursor:pointer;
  margin-top:6px;
}
#feKopfGrid .mzCheck input{ width:15px; height:15px; flex:0 0 auto }

/* Bio- und EAN-Status-Chips (08.08.2026, Ralph: beides auf dieselbe Chip-Form
   wie die Ernaehrungsform).
   VORHER war #fe_bioSw ein Segmentbalken: display:grid mit drei gleichen
   Spalten in einem gemeinsamen Rahmen. Die Chips tragen ihren Rahmen und ihre
   Rundung selbst - der gemeinsame Kasten muss deshalb weg, sonst steckten drei
   runde Chips in einem eckigen Balken.
   display steht BEWUSST hier und nicht inline: Umschalten per
   element.style.display="" wuerde einen Inline-Wert loeschen — der bekannte
   Fall aus CLAUDE.md-Chronik §1.11n-dd. Aus dem Stylesheet kommt er zurueck. */
#feKopfGrid #fe_bioSw,
#feKopfGrid #fe_eanChips{
  display:flex;
  flex-wrap:wrap;
  gap:5px;
  align-items:center;
  margin-top:2px;
}

/* Kleine Erklaerzeile unter einem Feld. */
#feKopfGrid .mzHint{
  font-size:11.5px;
  color:var(--muted);
  line-height:1.4;
  margin-top:3px;
}

/* Fusszeile des Kopfes (Bio-Hinweis, wird zur Laufzeit gefuellt). */
#feKopfGrid #fe_bioHint{
  font-size:11.5px;
  line-height:1.4;
  padding:7px 12px;
  border-top:1px solid var(--line);
  color:var(--muted);
}

/* Der frueher hier stehende @media-Block regelte den Sprung von vier auf zwei
   Spalten. Den gibt es nicht mehr - zwei ist die Grundeinstellung. Der neue
   Umbruch (Bildspalte unter das Formular) steht am DATEIENDE, direkt hinter
   der Regel fuer #feKopfLayout. Grund: gleiche Spezifitaet, da gewinnt die
   spaetere Regel - stuende der @media-Block hier oben, waere er wirkungslos. */


/* ============================================================================
   PRODUKTEDITOR · KACHELSTREIFEN "ENTHALTENE NAEHRSTOFFE"  (#fe_naehrReihe)
   ----------------------------------------------------------------------------
   Der Streifen ist in der Hoehe gedeckelt und scrollt intern; fuer den vollen
   Blick gibt es den Knopf "Details".

   Der Deckel stand bis 07.08.2026 DREIMAL als Zahl 196 in app.js — im Template,
   im Reset und in der Aufstockung. Dieselbe Regel an drei Orten (§4.2).
   Jetzt steht er hier, einmal:

        --naehr-reihe-hoehe   ← DIESE Zahl aendern, sonst nichts

   app.js liest den Wert und stockt ihn nur noch um den freien Platz an der
   Fussleiste auf. Faellt ui.css aus, greift in app.js weiter der Altwert 196.

   Anhaltswerte: 196px war der bisherige Deckel (zwei volle Kachelreihen).
   300px ist auf drei Reihen GESCHAETZT, nicht gemessen — bitte am Bildschirm
   nachstellen, dafuer steht die Zahl hier.
   ============================================================================ */
#fe_naehrReihe{
  --naehr-reihe-hoehe:300px;
  display:flex;
  gap:8px;
  flex-wrap:wrap;
  max-height:var(--naehr-reihe-hoehe);
  overflow:auto;
}


/* ============================================================================
   VOLLBILD-EDITOR · LUFT UEBER DER KOPFLEISTE  (--editor-oben)
   ----------------------------------------------------------------------------
   BEFUND 07.08.2026, am Bildschirmfoto GEMESSEN (Ralph: "das schwebende Menue
   hat nach oben immer noch Abstand" - auch nach --admin-oben 112 -> 64):

   Der Produkteditor sitzt NICHT in .container. openFgEditor schaltet #overlay
   auf .fgEditorFull (padding:0, left:0, z-index:70) und legt sich damit UEBER
   #adminNav (z-index:59) - darum ist die Admin-Leiste im Editor unsichtbar und
   --admin-oben wirkt hier ueberhaupt nicht.

   Der Inhalt liegt in #panel. Die Vollbild-Umstellung setzt dort maxWidth,
   width, height, maxHeight, borderRadius und background - padding NICHT.
   Also galt weiter .panel{padding:24px} aus admin.html Z. 693.

   Gemessen (Bildschirmfoto 3410x250, Massstab 2x belegt an #frgGoTop mit
   CSS height:32px = 64 Bildpunkte): 32 CSS-Pixel leer ueber der ersten Tinte.
        24px Panel-Polster + 8px Polster der Leiste = 32px  ✓

   WO SCHRAUBEN? Nur hier, eine Zahl. Links, rechts und unten bleiben bei 24px.
   Die Regel trifft ausschliesslich den Vollbild-Editor - kein anderes Overlay,
   keine andere Admin-Seite. Spezifitaet 2-1-0 schlaegt .panel (0-1-0)
   unabhaengig von der Ladereihenfolge.
   ============================================================================ */
#overlay.fgEditorFull > #panel{ padding-top:var(--editor-oben,2px) }


/* ============================================================================
   PRODUKTEDITOR · REITER 2 "NAEHRWERTE & WIRKSTOFFE"  (Durchgang 2a)
   ----------------------------------------------------------------------------
   Umgezogen am 07.08.2026: 45 der 56 Inline-Stile aus dem Block feTab2.
   Block vorher 10.735 Zeichen, nachher 6.896.

   ⚠ ELF STILE BLEIBEN BEWUSST INLINE (Durchgang 2b, noch nicht ausgefuehrt).
   Es sind die Layout-Container, deren Eigenschaften eine Funktion ZUR LAUFZEIT
   schreibt. Ein Inline-Stil schlaegt jede Regel hier - eine Regel fuer diese
   Eigenschaften waere eine Luege in der Datei (Hausregel oben):

     feTab2            display              <- feTabWechsel
     feNwOben          grid-template-columns  <- @media unten (07.08. aufgeraeumt)
     fe_nwCard         display              <- feKatChange
     fe_wirkGrid       grid-template-columns  <- steht hier (07.08. aufgeraeumt)
     fe_naehrKacheln   marginTop            <- feGridHoeheSync
                       marginLeft, alignSelf, gridColumn + DOM-Umzug nach
                       #feRahmen             <- feKachelBreiteSync
     fe_mikroWrap      display              <- feKatChange
     fe_wirkFotoBox    height               <- feDreiReiterInit, fgFotoPlatzieren
     fe_wirkFotoImg    display, transform   <- fgWirkFotoRender, fgWirkFotoApply
     feNwLinks / fe_wirkCard / feNwFotoSlot: kein Schreiber gefunden, gehoeren
     aber als Layout-Container in denselben gepruefeten Durchgang.

   ⚠ DREI TEILUMZUEGE - dort steht noch ein Rest inline, weil die Laufzeit ihn
   schreibt:  fm_mikroVorschlag (display) · fm_mikroMsg (color) ·
              fe_wirkFotoLeer (display)

   ⚠ Alle Selektoren tragen bewusst das Praefix #feTab2. Grund: fm_mikroStoff,
   fm_mikroMenge und fm_mikroEinheit gibt es ein ZWEITES Mal im Mikro-Dialog
   (app.js ab Z. 13939). Ohne Praefix wuerde dieser Block den Dialog mitfaerben.
   Nebeneffekt: Spezifitaet 1-1-0 bzw. 2-0-0 - schlaegt die <style>-Bloecke in
   admin.html, die frueher nur vom Inline-Stil geschlagen wurden.

   NICHT ANGEFASST: keine ID, kein onclick/onchange/oninput, keine
   Speicherlogik, keine Fachlogik, card() und cardF() unveraendert.
   ============================================================================ */
/* Naehrwert-Karte: Bezugseinheit, Ballaststoff-Haken, Plausibilitaetszeile. */
#feTab2 .feNwEinheit{ display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:11.5px;color:var(--muted);margin:-2px 0 9px;padding:6px 9px;background:var(--k-f6f8f7,#f6f8f7);border:1px solid var(--line);border-radius:var(--fk-r-klein) }
#feTab2 #fe_mengenEinheit{ padding:3px 7px;border:1px solid var(--line);border-radius:var(--fk-r-klein);background:var(--card);color:var(--ink);font-size:12px;font-weight:700 }
#feTab2 #fe_ehHint{ font-weight:600 }
#feTab2 .feNwBallast{ display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--muted);cursor:pointer;padding:0 0 4px;margin-top:-3px }
#feTab2 #fe_ballast_nd{ width:14px;height:14px;flex:0 0 auto }
#feTab2 #fe_plaus{ font-size:12px;margin-top:6px;line-height:1.4 }
#feTab2 #fe_wirkAnker{ display:none }

/* Kleingedruckter Zusatz in einer Kartenueberschrift. Dreimal verwendet:
   Wirkstoffe & Dosis, Mikronaehrstoffe, Etikett zum Ablesen. */
#feTab1 .feKartenZusatz,
#feTab2 .feKartenZusatz,
#feTab3 .feKartenZusatz,
#fe_wirkFotoCol .feKartenZusatz{ text-transform:none;color:var(--muted) }

/* Wirkstoff-Tabelle: Hinweis, Spaltenkopf, "+ Wirkstoff", Legende, Fussschalter. */
#feTab2 .feWirkHinweis{ font-size:11.5px;color:var(--muted);line-height:1.5;margin-bottom:9px }
/* 🔴 15.08.2026 (Work #7): das Raster stand hier HART und noch einmal weiter unten
   als Variable — zwei Spaltenvertraege fuer dieselbe Tabelle (§4.2). Die spaetere
   Regel gewann fuer #feTab2, diese hier war stille Altlast und waere beim Zaehlen
   der Spalten auseinandergelaufen. Jetzt zeigt auch der Kopf auf --wirk-spalten. */
#feTab2 .feWirkKopf{ display:grid;grid-template-columns:var(--wirk-spalten,1fr 48px 70px 62px 56px 26px);gap:6px;padding:0 2px 4px;font-size:10.5px;color:var(--muted);font-weight:700;text-transform:uppercase;letter-spacing:.03em }
#feTab2 .feRe{ text-align:right }
#feTab2 .feBtnAdd{ margin-top:7px;padding:7px 12px;border:1px solid var(--k-16a34a);border-radius:8px;background:var(--greenlt,var(--k-ecfdf5));color:var(--k-166534);cursor:pointer;font-size:12.5px;white-space:nowrap }
#feTab2 .feWirkLegBox{ margin-top:10px;padding-top:9px;border-top:1px solid var(--line);font-size:11px;color:var(--muted);line-height:1.6 }
#feTab2 .feWirkLegReihe{ display:flex;gap:14px;flex-wrap:wrap }
#feTab2 .feWirkLegText{ margin-top:5px }
#feTab2 .feWirkNone{ display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted);cursor:pointer;margin-top:10px;padding-top:9px;border-top:1px solid var(--line);line-height:1.4 }
#feTab2 #fe_wirk_none{ width:15px;height:15px;flex:0 0 auto }

/* Die drei Farbpunkte der Wirkstoff-Ampel.
   gruen = wirksame Menge (>=15 % NRV) · gelb = EU-Nutzen, Dosis darunter ·
   grau  = keine zugelassene EU-Aussage. Die Farben stehen bewusst hier und
   nicht in einer gemeinsamen Regel mit Modifikator - so bleibt jede Zeile
   wortgleich zu dem, was vorher am Element stand. */
#feTab2 .feAmpelGr{ display:inline-block;width:10px;height:10px;border-radius:2px;background:#2e9e57;vertical-align:middle;margin-right:5px }
#feTab2 .feAmpelGe{ display:inline-block;width:10px;height:10px;border-radius:2px;background:#e0a32e;vertical-align:middle;margin-right:5px }
#feTab2 .feAmpelGra{ display:inline-block;width:10px;height:10px;border-radius:2px;background:#9aa7b2;vertical-align:middle;margin-right:5px }

/* Mikronaehrstoff-Karte: Hinweis, Riki-Vorschlag, Liste, Eingabezeile, USDA. */
#feTab2 .feMikroHinweis{ font-size:11.5px;color:var(--muted);line-height:1.4;margin-bottom:6px;flex:0 0 auto }
#feTab2 #fm_mikroVorschlag{ margin-bottom:8px }
#feTab2 #fm_mikroRows{ flex:1 1 auto;min-height:0;overflow:auto }
#feTab2 .feMikroLaedt{ color:var(--muted);font-size:12.5px }
#feTab2 .feMikroAddZeile{ display:grid;grid-template-columns:1fr 84px 46px auto;gap:6px;align-items:center;margin-top:9px }
#feTab2 #fm_mikroStoff{ padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--ink);font-size:12.5px }
#feTab2 #fm_mikroMenge{ padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--ink);font-size:12.5px;width:100%;box-sizing:border-box }
#feTab2 #fm_mikroEinheit{ font-size:12.5px;color:var(--muted);text-align:center }
#feTab2 .feMikroBtn{ padding:7px 11px;border:1px solid var(--k-16a34a);border-radius:8px;background:var(--greenlt,var(--k-ecfdf5));color:var(--k-166534);cursor:pointer;font-size:12.5px;white-space:nowrap }
#feTab2 #fm_mikroMsg{ font-size:12px;margin-top:6px }
#feTab2 .feUsdaZeile{ display:flex;gap:6px;margin-top:8px;flex:0 0 auto }
#feTab2 #fm_usdaSuche{ flex:1;min-width:0;padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--ink);font-size:12.5px }
#feTab2 .feUsdaBtn{ padding:7px 11px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--ink);cursor:pointer;font-size:12.5px;white-space:nowrap }
#feTab2 #fm_usdaErg{ max-height:180px;overflow:auto;margin-top:5px;flex:0 0 auto }

/* Etikett-Karte: Werkzeugzeile, Zoomknoepfe, Riki-Knopf, Leerhinweis, Fusszeile. */
#fe_wirkFotoCol .feFotoWerkzeuge{ display:flex;gap:6px;align-items:center;margin-bottom:8px;flex-wrap:wrap }
#fe_wirkFotoCol .feFotoZoom{ width:32px;height:30px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--ink);cursor:pointer;font-size:16px;font-weight:700;line-height:1 }
#fe_wirkFotoCol .feFotoBtn{ padding:6px 10px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--ink);cursor:pointer;font-size:12px }
#fe_wirkFotoCol .feBtnRiki{ padding:6px 11px;border:1px solid #cbc7f2;border-radius:8px;background:var(--k-eeedfe);color:var(--k-534ab7);cursor:pointer;font-size:12px;font-weight:700;white-space:nowrap }
#fe_wirkFotoCol #fe_wirkFotoNav{ display:flex;gap:6px;align-items:center;margin-left:auto }
#fe_wirkFotoCol #fe_wirkFotoLeer{ position:absolute;inset:0;align-items:center;justify-content:center;text-align:center;color:var(--muted);font-size:12.5px;padding:16px;line-height:1.5 }
#fe_wirkFotoCol .feFotoFuss{ font-size:11px;color:var(--muted);margin-top:6px }


/* ============================================================================
   PRODUKTEDITOR · REITER 2 — LAYOUT-CONTAINER  (Durchgang 2b)
   ----------------------------------------------------------------------------
   Der heikle Rest aus Reiter 2, ausgefuehrt am 07.08.2026 nach Ralphs Abnahme
   von 2a. Hier gilt die Sonderregel dieses Abschnitts:

   >>> EINE EIGENSCHAFT, DIE EINE FUNKTION ZUR LAUFZEIT SCHREIBT, DARF HIER
   >>> NICHT STEHEN. Ein Inline-Stil schlaegt jede Regel — die Datei wuerde
   >>> etwas behaupten, was am Bildschirm nicht gilt.

   Darum steht an diesen sieben Elementen weiterhin ein Rest inline. Das ist
   Absicht, kein vergessener Stil:

     feTab2           display:none              <- feTabWechsel
     fe_nwCard        display:block             <- feKatChange
     fe_naehrKacheln  margin-top:10px           <- feGridHoeheSync
                      (dazu marginLeft/alignSelf/gridColumn und der DOM-Umzug
                       nach #feRahmen durch feKachelBreiteSync — deshalb hat
                       dieser Streifen bewusst KEINE Regel mit #feTab2-Praefix)
     feNwOben  }  beide am 07.08. AUFGERAEUMT - die Rasterbreiten stehen jetzt
     fe_wirkGrid }  hier unten, nicht mehr inline. Siehe Block "AUFGERAEUMT".
     fe_mikroWrap     display:flex              <- feKatChange
     fe_wirkFotoBox   height:clamp(...)         <- feDreiReiterInit, fgFotoPlatzieren
     fe_wirkFotoImg   display + transform-origin
                      display  <- fgWirkFotoRender · transform <- fgWirkFotoApply
                      transform-origin bleibt BEWUSST daneben inline: es rechnet
                      mit transform zusammen, und ein halber Zoom aus zwei
                      Quellen ist schlimmer als ein Stil zu viel.

   ⚠ PRAEFIX #fe_wirkFotoCol STATT #feTab2 fuer die Etikett-Karte.
   fgFotoPlatzieren haengt fe_wirkFotoCol per appendChild um. Heute immer nach
   feNwFotoSlot (in feTab2) — aber #fe_fotoMount (app.js Z. 15656, die
   Flip-Rueckseite) und die Regel #fe_fotoMount #fe_wirkFotoBox (Z. 15836)
   stehen noch im Code. Wird der Flip je wieder angeschlossen, wandert die
   Karte aus feTab2 heraus. Mit dem Karten-Praefix wandert ihr Aussehen mit.
   Aus demselben Grund wurden am 07.08. acht Regeln aus 2a nachtraeglich
   umgehaengt (feFotoWerkzeuge, feFotoZoom, feFotoBtn, feBtnRiki, feFotoFuss,
   fe_wirkFotoNav, fe_wirkFotoLeer, feKartenZusatz).

   WO SCHRAUBEN?
   · Spaltenteilung oben ......... #feTab2 #feNwOben → grid-template-columns
   · Umbruchpunkt dafuer ......... @media ganz unten in dieser Datei
   · Abstand der beiden Spalten .. #feTab2 #feNwOben → gap
   · Klebehoehe der Etikettsaeule  #feTab2 #feNwFotoSlot → top
   · Etikett-Box: Rahmen, Grund .. #fe_wirkFotoCol #fe_wirkFotoBox
   ============================================================================ */
#feTab2 #feNwOben{ display:grid;gap:12px;align-items:start;
                   grid-template-columns:minmax(430px,1fr) minmax(360px,.9fr) }
#feTab2 #feNwLinks{ display:flex;flex-direction:column;gap:12px;min-width:0 }
#feTab2 #fe_wirkCard{ margin-top:2px }
#feTab2 #fe_wirkGrid{ display:grid;gap:12px;align-items:start;
                      grid-template-columns:minmax(0,1fr) }
#feTab2 #fe_mikroWrap{ min-height:0 }
/* 07.08.2026 (Ralph: "mikronaehrstoffe soll die selbe breite haben wie wirkstoffe").
   fe_mikroWrap ist display:flex in ZEILENRICHTUNG - das schreibt feKatChange inline,
   darum steht es nicht hier. Die Karte darin (cardF) hat keine Breitenangabe und
   bekam deshalb nur ihre Inhaltsbreite, waehrend die Wirkstoff-Karte in einem
   Raster sitzt, das volle Breite vorgibt. Ein Kind, eine Regel: */
#feTab2 #fe_mikroWrap > *{ flex:1 1 auto; min-width:0 }
#feTab2 #feNwFotoSlot{ min-width:0;position:sticky;top:8px }
#fe_wirkFotoCol #fe_wirkFotoBox{ position:relative;overflow:hidden;border:1px solid var(--line);border-radius:10px;background:#d9d2e9;cursor:grab;touch-action:none }
#fe_wirkFotoCol #fe_wirkFotoImg{ position:absolute;left:0;top:0;max-width:none;user-select:none;-webkit-user-drag:none }


/* ============================================================================
   AUFGERAEUMT 07.08.2026 · feEditorResponsive ist weg
   ----------------------------------------------------------------------------
   BEFUND (06.08. gefunden, 07.08. behoben):
   feEditorResponsive setzte bei JEDER Fenstergroessenaenderung zwei Rasterbreiten
   als Inline-Stil. Eine davon war seit Etappe 2 TOT: #feKopfGrid ist kein Raster
   mehr, das Raster ist sein Kind .mzr. Die Zuweisung lief ins Leere - waere aber
   sofort zur Falle geworden, sobald jemand #feKopfGrid hier ein display:grid gibt.
   Das Layout haette dann bei jedem Ziehen am Fenster gesprungen, und die Ursache
   stand 800 Zeilen entfernt in einer Funktion, die niemand verdaechtigt.

   Dieselbe Bauart hatte fe_wirkGrid: Template "1fr 1fr", aber feDreiReiterInit
   UND fgFotoPlatzieren schrieben bei jedem Lauf minmax(0,1fr) darueber. Seit dem
   Drei-Reiter-Umbau hat das Etikett einen festen Ort (feNwFotoSlot), die zweite
   Spalte wird nicht mehr gebraucht.

   Beides steht jetzt hier: die Grundbreiten oben an den Regeln, der Umbruch als
   @media. In app.js sind die Funktion, ihre Resize-Bindung, ihr Aufruf und beide
   Inline-Reste ersatzlos entfallen.

   ⚠ max-width:1179px entspricht dem frueheren w<1180 NICHT auf den Pixel:
   window.innerWidth zaehlt eine klassische Scrollleiste mit, die Media-Query je
   nach Browser nicht. Der Umbruch kann darum um deren Breite versetzt liegen.
   NICHT nachgemessen - wen es stoert, aendert die Zahl hier.

   WO SCHRAUBEN? Umbruchpunkt = die 1179 in der Zeile darunter.
   ============================================================================ */
@media(max-width:1179px){
  #feTab2 #feNwOben{ grid-template-columns:minmax(0,1fr) }
}


/* ============================================================================
   PRODUKTEDITOR · FUSSLEISTE  (#fe_fussLeiste)  ·  Durchgang 3a
   ----------------------------------------------------------------------------
   Die klebende Leiste am unteren Rand des Editors: Speicher-Meldung, Freigabe-
   Checkliste, "Bereit"-Zeile und die Knoepfe des Inline-Modus.

   ⚠ SIE IST EIN MESSPUNKT, NICHT NUR EIN KASTEN.
   feGridHoeheSync misst ihre Unterkante (app.js Z. 4036), um den Kachelstreifen
   "Enthaltene Naehrstoffe" bis zum Bildschirmrand aufzufuellen. Wer hier Polster
   oder Rahmen aendert, aendert damit die Hoehe des Streifens mit. Das ist kein
   Fehler, sondern gewollt - aber man sollte es wissen, bevor man schraubt.

   WO SCHRAUBEN?
   · Hoehe der Leiste ............ #fe_fussLeiste → padding
   · Abstand zum Inhalt darueber . #fe_fussLeiste → margin-top
   · Schatten nach oben .......... #fe_fussLeiste → box-shadow
   · Knopfgroessen ............... .feFussBtn / .feFussBtnGross / .feFussBtnZu

   ZWEI ZUSTAENDE, EINE STELLE:
   Im Vollbild sieht die Leiste anders aus als im Inline-Modus (Master-Detail-
   Liste). Das stand bis 07.08.2026 als fuenf Inline-Zuweisungen in openFgEditor
   (fe_ready verstecken, Rahmen/Schatten/Grund weg, Polster auf 2px). Der Zustand
   steckt aber laengst als Klasse am Overlay - also steht er jetzt hier, ganz
   unten in diesem Block. Kein JavaScript mehr fuer eine Aussehensfrage.

   INLINE GEBLIEBEN, weil die Laufzeit sie schreibt:
     fe_msg       font-weight  <- fgEditSave setzt 700 bei Teil-Fehlern
                               (dazu color, das im Template gar nicht stand)
     fe_riegelRow display      <- feFreigabeLeiste (Z. 17331) blendet die Zeile
                               am Ende JEDES Aufbaus aus. ⚠ Sie wird nirgends
                               wieder eingeblendet - das Template-display:flex
                               ist damit praktisch tot. Gleiche Bauart wie
                               feKopfGrid und fe_wirkGrid. NICHT mitrepariert
                               (§2.3), gehoert zu Durchgang 3b.
   ============================================================================ */
#fe_fussLeiste{ margin-top:8px;padding:10px 2px 8px;border-top:1px solid var(--line);position:sticky;bottom:0;z-index:15;background:var(--bg);box-shadow:0 -8px 10px -9px rgba(20,40,70,.35) }
#fe_msg{ font-size:13px;margin-bottom:8px }
#fe_riegelRow{ align-items:baseline;gap:8px 14px;flex-wrap:wrap;width:100%;margin-bottom:8px }
.feFussLabel{ font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);font-weight:800;flex:0 0 auto }
#fe_riegel{ display:flex;gap:5px 14px;flex-wrap:wrap;font-size:12px;line-height:1.35;flex:1 1 auto;min-width:0 }
.feFussZeile{ display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;width:100% }
.feFussLinks{ display:flex;gap:8px;align-items:center;flex-wrap:wrap }
#fe_ready{ font-size:12px;color:var(--muted) }
.feFussBtn{ padding:8px 12px;border:1px solid var(--line);border-radius:var(--fk-r-klein);background:var(--card);color:var(--ink);cursor:pointer;font-size:12.5px }
.feFussRechts{ display:flex;gap:8px;flex-wrap:wrap }
.feFussBtnRot{ padding:10px 14px;border:1px solid var(--line);border-radius:10px;background:var(--card);color:var(--k-cf5442,#cf5442);cursor:pointer;font-size:13px }
.feFussBtnGross{ padding:10px 14px;border:1px solid var(--line);border-radius:10px;background:var(--card);color:var(--ink);cursor:pointer;font-size:13px }
.feFussBtnZu{ padding:10px 16px;border:1px solid #d3dbe6;border-radius:10px;background:#fff;color:#1f2a44;font-weight:600;cursor:pointer }

/* Vollbild: knapper, ohne Rahmen und Schatten - die Leiste sitzt dort direkt auf
   dem Arbeitshintergrund. Spezifitaet 2-1-0 schlaegt die Grundregel oben (1-0-0).
   Greift NICHT im Inline-Modus, weil der Editor dort nicht in #overlay steckt. */
#overlay.fgEditorFull #fe_ready{ display:none }
#overlay.fgEditorFull #fe_fussLeiste{ border-top:0; box-shadow:none; background:transparent; padding:2px }


/* ============================================================================
   PRODUKTEDITOR · KNOPFLEISTE DER KOPFZEILE  (#frgTopBtns)  ·  Durchgang 3b
   ----------------------------------------------------------------------------
   Die vier Bedienelemente rechts oben im Editor: Status-Pille · Speichern
   (Diskette) · "✓ freigeben" · Loeschen. Sie werden von feFreigabeLeiste zur
   Laufzeit erzeugt und in den Slot #fe_frgSlot der Kopfleiste gehaengt.

   ⚠ ZWEI BEFUNDE, DIE DIESEN DURCHGANG AUSGELOEST HABEN

   1. Der LOESCHKNOPF stand ZWEIMAL WORTGLEICH im Code (213 Zeichen, app.js
      Z. 17289 und Z. 17303). Der zweite Ort ist die Nachruestung fuer den Fall,
      dass die Knopfleiste beim zweiten Produkt derselben Sitzung schon besteht.
      Zwei Kopien derselben Regel (§4.2) - wer eine aendert, aendert die andere
      nicht. Jetzt steht sie hier, einmal.

   2. Der FREIGEBEN-KNOPF bekam Farbe und Zeiger aus vier Inline-Zuweisungen
      (gruen/Zeigefinger bzw. grau/verboten). Der Zustand steht aber laengst im
      disabled-Attribut, das dieselbe Funktion ohnehin setzt. Statt einer neuen
      Klasse liest ui.css jetzt #frgGoTop:disabled. Keine zweite Zustandsquelle.

   WO SCHRAUBEN?
   · Knopfhoehe ............ #frgGoTop / #frgSaveTop / #frgDelTop → height
   · Abstand der Knoepfe ... #frgTopBtns → gap
   · Abstand vor Loeschen .. #frgDelTop → margin-left (Ralph 02.08.: "er soll
                             gefunden, nicht getroffen werden")
   · Gruen bzw. Grau ....... #frgGoTop → background · #frgGoTop:disabled

   NICHT HIER, BEWUSST: die Klartext-Ampel im linken Streifen (#feRailAmpel) und
   die Punkte in frgDots/frgList. Ihre Farben kommen aus _FRG_COL (app.js
   Z. 17049) - EINE Quelle fuer drei Ansichten. Sie hierher zu kopieren waere
   eine zweite Wahrheit (§4.2). Wo die Ampelfarben leben sollen, ist eine
   Regelfrage und braucht eine Entscheidung, keinen Optik-Durchgang.

   NICHT HIER, WEIL UNSICHTBAR: die Rand-Fahne #frgRail und die Schublade
   #frgPanel. Beide werden weiter aufgebaut und befuellt, sind im heutigen
   Editor aber ausgeblendet (Z. 17242 setzt cssText auf display:none, das Panel
   ist seit 28q abgeschafft). Sie umzuziehen waere Risiko ohne Nutzen - das ist
   eine Altcode-Frage wie beim Dashboard am 06.08.
   ============================================================================ */
#frgTopBtns{ display:flex; gap:6px; align-items:center; margin-left:6px; flex:0 0 auto }
#frgStatusPill{ flex:0 0 auto }

#frgSaveTop{
  width:36px; height:32px;
  border:1px solid var(--k-bfdbfe,#bfdbfe); border-radius:9px;
  background:var(--card); color:#2563eb; cursor:pointer;
  display:flex; align-items:center; justify-content:center; padding:0;
}

#frgGoTop{
  height:32px; padding:0 14px;
  border:0; border-radius:9px;
  background:#2e9e57; color:#fff;
  font-weight:800; font-size:12.5px;
  cursor:pointer; white-space:nowrap;
}
/* Blockiert: das disabled-Attribut ist die Wahrheit, nicht eine zweite Klasse. */
#frgGoTop:disabled{ background:#c7d2cc; cursor:not-allowed }

/* Loeschknopf. display:none ist der Grundzustand - fgStatusLoad setzt ihn auf
   flex, sobald es etwas zu loeschen gibt. Der Inline-Wert schlaegt diese Regel,
   genau so ist es gemeint. */
/* 🔴 15.08.2026 SPAET — RALPH: "mein loesch button ist auch nicht richtig sichtbar",
   praezisiert auf "produkt loesch knopf", Entscheid A: kraeftiger, bleibt ein Symbol.

   WAS HIER STAND: weisser Grund (var(--card)) und ein blassrosa Rand #f0b8b4. Der Knopf
   war damit nicht unsichtbar, sondern LEISE — 36x32 px, kein Wort, heller Grund zwischen
   kraeftigen Nachbarn. Genau so liest sich in diesem Editor ein DEAKTIVIERTER Knopf
   (vgl. #frgGoTop:disabled zwei Regeln darueber: blasser Grund, kein Kontrast). Ein
   scharfer Knopf, der aussieht wie ein stumpfer, ist schlimmer als ein fehlender.

   RICHTIGSTELLUNG, damit die falsche Fassung nicht wiederkommt: ich hatte zuerst
   gemeldet, der Knopf trage GAR KEINE Optik und haenge an einer fehlenden CSS-Regel.
   Das war falsch — diese Regel gibt es seit jeher. `display:none` ist ihr gewollter
   Grundzustand, `fgStatusLoad` schaltet auf flex, sobald es etwas zu loeschen gibt.
   Geaendert wird deshalb NUR die Farbe, nicht die Mechanik (§28.5).

   Grund und Rand kommen aus dem Ton, den das Loeschen im System schon traegt:
   #fdeceb ist der Hoverton der Loeschzeile im Statusmenue (app.js 25329). Kein neuer
   Farbton, nur derselbe an einer zweiten Stelle. */
#frgDelTop{
  display:none;
  height:32px; width:36px; margin-left:10px;
  border:1px solid var(--k-e08a82,#e08a82); border-radius:9px;
  background:var(--k-fdeceb,#fdeceb); color:var(--k-b91c1c,#b91c1c); cursor:pointer;
  align-items:center; justify-content:center; padding:0; flex:0 0 auto;
}
#frgDelTop:hover{
  background:var(--k-f8cfca,#f8cfca); border-color:var(--k-cf5442,#cf5442);
}


/* ============================================================================
   PRODUKTEDITOR · REITER 1 · REST  (Daten holen · Produktbild · Etiketten)
   ----------------------------------------------------------------------------
   Durchgang 4, 07.08.2026. Alle 49 Inline-Stile aus feTab1 ausserhalb des
   Kopfbereichs: die Riki-Zeile "Daten holen" (URL, Einfuegefeld, JSON, die
   sechs Chip-Knoepfe), die Produktbild-Karte und der Etiketten-Kasten.

   VIER TEILUMZUEGE - dort steht ein Rest inline, weil die Laufzeit ihn schreibt:
     fe_urlLbl      cursor      <- feUrlLblSync (dazu textDecoration)
     fe_jsonIn      background, border <- die Einfuege-Rueckmeldung faerbt das Feld
     fe_pullMsg     color       <- Meldungsfarbe je Ergebnis
     fe_bildMsg     color       <- dito
     fe_etikettGrid display     <- Z. 16316
   Alles andere an diesen Elementen ist umgezogen.

   ZWEI FUNDE BEIM SCHNEIDEN, die eine Zusicherung abgefangen hat:
   · Zwei Kastentitel sahen gleich aus, unterscheiden sich aber um margin-bottom
     -> .feKastenTitel und .feEtikettTitel, beide wortgleich zum Original.
   · Zwei der sechs Chip-Knoepfe waren zeichengleich -> eine Klasse .feChipHell.

   .feVersteckt fasst vier display:none zusammen: die drei Datei-Auswahlfelder
   (fe_res_up, fe_eti_up, fe_etikett_up) und das versteckte Bio-Select fe_bio.
   Sie sind FUNKTIONALE Verstecker - ein sichtbares Datei-Feld waere ein
   Bedienfehler, kein Schoenheitsfehler.

   WO SCHRAUBEN?
   · Kasten "Daten holen" ..... .feHolBox
   · Umbruch der zwei Spalten . .feHolGrid -> grid-template-columns (auto-fit)
   · Chip-Knoepfe ............. .feChipLila / .feChipHell / .feChipGruen / .feChipBg
   · Produktbild-Vorschau ..... .feBildVorschau -> max-height
   ============================================================================ */
/* #feKopfLayout: siehe Abschnitt "KOPFBEREICH ZWEISPALTIG" am Dateiende -
   dort steht die EINE Regel dafuer (07.08.2026, war bis dahin flex-column). */
/* 🔴 20.08.2026, Work #133 E9 — STATION 1 BEKOMMT DIESELBEN TITELBALKEN.
   Ralph nach dem Screenshot: "bis jetzt sind wir noch weit von deinem entwurf
   entfernt."

   Er hat recht, und der Grund ist gemessen: E4 hat die Kartenhilfe card()
   umgestellt - Station 2 nutzt sie viermal, Station 3 zweimal, STATION 1 GENAU
   EINMAL (das Produktbild). Die beiden Blöcke, die er staendig vor sich hat,
   bauen ihre Karte selbst und haben von E4 nichts abbekommen.

   Sie sind bereits Karten MIT Titel - der Titel schwebt nur frei darin, statt
   auf einem Balken zu sitzen. Geaendert wird deshalb nur das: Polster raus aus
   der Karte, rein in die Bereiche, und der Titel bekommt den Balken. Kein
   Element, keine ID, kein Knopf wird angefasst.

   Dieselben Variablen wie .feKarte (--fk-pad, --fk-radius), damit es EINE
   Kartenform gibt und nicht zwei, die sich aehneln (§4.2). */
#feTab1 .feHolBox{ background:var(--card);border:1px solid var(--line);
  border-radius:var(--fk-radius,12px);padding:0 0 var(--fk-pad,12px);margin-bottom:12px }
#feTab1 .feHolKopf{ display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 0 var(--fk-pad,12px);padding:9px 14px;
  background:var(--bg);border-bottom:1px solid var(--line);
  border-radius:calc(var(--fk-radius,12px) - 1px) calc(var(--fk-radius,12px) - 1px) 0 0 }
/* Der Inhalt behaelt sein Polster - es ist nur aus der Karte in die Bereiche
   gewandert, damit der Balken buendig an der Kante sitzt. */
#feTab1 .feHolGrid, #feTab1 .feHolBox > :not(.feHolKopf){ padding-left:11px;padding-right:11px }
#feTab1 .feHolTitel{ font-size:12px;text-transform:uppercase;letter-spacing:.3px;color:var(--karten-titel,var(--green));font-weight:600;flex:1 1 auto;min-width:0 }
#feTab1 .feHolTitelZus{ text-transform:none;font-weight:400 }
#feTab1 .feNurLeerLbl{ display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--ink);cursor:pointer;background:var(--k-f6f8f7,#f6f8f7);border:1px solid var(--line);border-radius:999px;padding:3px 9px;flex:0 0 auto;white-space:nowrap }
#feTab1 #fe_nurLeer{ width:14px;height:14px;flex:0 0 auto;accent-color:var(--k-16a34a) }
#feTab1 .feHolGrid{ display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:8px;align-items:stretch }
#feTab1 .feHolZeile{ display:flex;gap:6px;align-items:center;min-width:0 }
#feTab1 #fe_urlLbl{ font-size:15px;flex:0 0 auto }
#feTab1 #fe_url{ flex:1 1 auto;min-width:0;box-sizing:border-box;padding:7px 8px;border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--ink);font-size:12.5px }
#feTab1 .feBtnLila{ flex:0 0 auto;padding:7px 11px;border:1px solid #cbc7f2;border-radius:8px;background:var(--k-eeedfe);color:var(--k-534ab7);font-weight:700;cursor:pointer;font-size:12.5px;white-space:nowrap }
#feTab1 #fe_pasteZone{ border:2px dashed #b9b3e8;border-radius:8px;padding:6px 10px;background:var(--k-f6f5fd,#f6f5fd);color:var(--k-534ab7);font-size:12.5px;cursor:text;outline:none;display:flex;align-items:center;gap:7px;min-width:0 }
#feTab1 .feFlex0{ flex:0 0 auto }
#feTab1 .feEllipsis{ min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
#feTab1 .feHolZeile2{ display:flex;gap:6px;align-items:stretch;min-width:0 }
#feTab1 #fe_jsonIn{ flex:1 1 auto;min-width:0;height:34px;box-sizing:border-box;padding:7px 8px;border-radius:8px;color:var(--ink);font-size:12px;font-family:ui-monospace,monospace;white-space:pre;overflow:auto;resize:none }
#feTab1 .feBtnGruenHell{ flex:0 0 auto;padding:7px 11px;border:1px solid #9fc6a8;border-radius:8px;background:var(--k-eaf5ee,#eaf5ee);color:var(--k-166534);font-weight:700;cursor:pointer;font-size:12.5px;white-space:nowrap }
#feTab1 #fe_jsonMsg{ font-size:11.5px;line-height:1.45;margin-top:-2px }
#feTab1 .feHolAuch{ display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:7px;font-size:11.5px;color:var(--muted) }
#feTab1 .feChipLila{ padding:4px 10px;border:1px solid #cbc7f2;border-radius:20px;background:var(--k-eeedfe);color:var(--k-534ab7);font-weight:600;cursor:pointer;font-size:11.5px }
#feTab1 .feChipHell{ padding:4px 10px;border:1px solid var(--line);border-radius:20px;background:var(--card);color:var(--k-534ab7);cursor:pointer;font-size:11.5px }
#feTab1 .feChipGruen{ padding:4px 10px;border:1px solid var(--k-16a34a);border-radius:20px;background:var(--greenlt,var(--k-ecfdf5));color:var(--k-166534);font-weight:600;cursor:pointer;font-size:11.5px }
#feTab1 .feChipBg{ padding:4px 10px;border:1px solid var(--line);border-radius:20px;background:var(--bg);color:var(--ink);cursor:pointer;font-size:11.5px }
#feTab1 .feVersteckt,
#feTab3 .feVersteckt{ display:none }
#feTab1 #fe_pullMsg{ font-size:12px;margin-top:0 }
#feTab1 .feMinw0{ min-width:0 }
#feTab1 #fe_bildPreview{ margin-bottom:6px }
#feTab1 .feBildVorschau{ max-height:150px;border-radius:8px }
#feTab1 .feHinweisGrau{ color:var(--muted);font-size:13px }
#feTab1 .feDateiFeld{ font-size:13px }
#feTab1 .feBtnRot{ margin-left:8px;padding:5px 10px;border:1px solid var(--k-fca5a5,#fca5a5);border-radius:8px;background:var(--card);color:var(--k-dc2626);cursor:pointer;font-size:12.5px }
#feTab1 #fe_bildMsg{ font-size:12px;margin-top:4px }
#feTab1 #fe_bildOff{ margin-top:12px;padding:9px 10px;border:1px dashed var(--line);border-radius:10px;background:var(--k-f6f8f7,#f6f8f7) }
#feTab1 .feKastenTitel{ font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--muted);font-weight:700;margin-bottom:6px }
#feTab1 .feBildOffImg{ max-height:130px;border-radius:8px;display:block }
#feTab1 .feKastenFuss{ font-size:11.5px;color:var(--muted);margin-top:6px }
#feTab1 .feEtikettBox{ margin-top:14px;padding:11px 12px;border:1px solid var(--line);border-radius:10px;background:var(--k-f6f8f7,#f6f8f7) }
#feTab1 .feEtikettKopf{ display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:6px }
#feTab1 .feEtikettTitel{ font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--muted);font-weight:700 }
#feTab1 .feBtnLilaKlein{ padding:5px 10px;border:1px solid #cbc7f2;border-radius:8px;background:var(--k-eeedfe);color:var(--k-534ab7);cursor:pointer;font-size:12px;font-weight:600;white-space:nowrap }
#feTab1 #fe_etikettGrid{ gap:6px;flex-wrap:wrap }


/* ============================================================================
   PRODUKTEDITOR · REITER 3 "ZUTATEN & REFERENZ"  ·  Durchgang 5
   ----------------------------------------------------------------------------
   Die Drei-Spalten-Arbeitsflaeche: Zutaten · Zusatzstoffe+Mikros · Etikett und
   Referenzpruefung. Dazu die Riki-Klappe, die Stammsuche und die Legende.

   ⚠ EIN EINZIGER STIL BLEIBT INLINE, und zwar der wichtigste:

       #fe_gridA  grid-template-columns · height · min-height

   Alle drei schreibt feGridHoeheSync bei jedem Lauf - und `height` ist im
   Template ein calc() mit der eingesetzten Konstanten FE_GRID_BASIS. Das ist
   kein Stil, sondern eine Rechnung: die Arbeitsflaeche bekommt genau die
   Bildschirmhoehe minus Kopf, minus Kachelstreifen, und bei "mittel" eine
   zweite Zeile fuer die Referenzkarte. So etwas gehoert nicht in ein
   Stylesheet. display, gap, align-items und margin-top stehen jetzt hier.

   (feTab3 selbst behaelt display:none - feTabWechsel schaltet es.)

   WO SCHRAUBEN?
   · Abstand der drei Spalten .... #feTab3 #fe_gridA -> gap
   · Spaltenteilung .............. NICHT hier, sondern feSpalten()/feGridHoeheSync
   · Hoehe der Zutatenliste ...... #feTab3 #fe_pickList -> min-height
   · Riki-Klappe (lila Kasten) ... #feTab3 .feRikiBox
   · Farbpunkte der Zusatzstoff-Legende: .feZusPunktGr / -Rt / -Grau

   Die drei Legendenpunkte stehen bewusst als drei eigene Regeln statt als
   Grundform mit Modifikator - so bleibt jede Zeile wortgleich zu dem, was
   vorher am Element stand. Gleiches Vorgehen wie bei der Wirkstoff-Ampel.
   ============================================================================ */
#feTab3 #fe_quickBar{ display:none;gap:8px;align-items:center;margin:0 0 6px }
#feTab3 .feQuickIcon{ font-size:15px;flex:0 0 auto }
#feTab3 #fe_quickIn{ flex:1;min-width:0;padding:9px 11px;border:1px solid var(--line);border-radius:var(--fk-r-klein);background:var(--card);color:var(--ink);font-size:13px }
#feTab3 .feBtnZuordnen{ padding:9px 16px;border:0;border-radius:var(--fk-r-klein);background:var(--k-534ab7);color:#fff;font-weight:700;font-size:13px;cursor:pointer;white-space:nowrap;flex:0 0 auto }
#feTab3 #fe_quickMsg{ font-size:12.5px;line-height:1.6;margin:0 0 6px 27px }
#feTab3 #fe_gridA{ display:grid;gap:10px;align-items:stretch;margin-top:2px }
#feTab3 #fe_colZut{ min-height:0;display:flex;flex-direction:column }
#feTab3 .feRikiBox{ background:var(--k-f4f1fb);border:1px solid var(--k-cecbf6);border-radius:10px;padding:8px 10px;margin-bottom:10px }
#feTab3 .feRikiTitel{ font-weight:700;font-size:13px;color:var(--k-3c3489);cursor:pointer;list-style:none }
#feTab3 .feMt8{ margin-top:8px }
#feTab3 #rikiText{ width:100%;box-sizing:border-box;padding:8px;border:1px solid var(--k-cecbf6);border-radius:8px;font-size:13px;background:var(--k-ffffff) }
#feTab3 .feBtnReihe{ display:flex;gap:6px;flex-wrap:wrap;margin-top:6px }
#feTab3 .feBtnLilaVoll{ padding:7px 12px;border:0;border-radius:8px;background:var(--k-534ab7);color:var(--k-ffffff);font-weight:600;font-size:13px;cursor:pointer }
#feTab3 .feBtnGruenRand{ padding:7px 12px;border:1px solid var(--k-2e7d32);border-radius:8px;background:var(--k-fbf8f2);color:var(--k-2e7d32);cursor:pointer;font-size:13px }
#feTab3 .feBtnLilaHell{ padding:7px 10px;border:1px solid var(--k-cecbf6);border-radius:8px;background:var(--k-ffffff);color:var(--k-534ab7);font-size:12px;cursor:pointer }
#feTab3 #rikiMsg{ font-size:12.5px;margin-top:7px;line-height:1.5 }
#feTab3 #fe_zutSuche{ width:100%;box-sizing:border-box;padding:8px;border:1px solid var(--line);border-radius:8px;font-size:13px;background:var(--card);color:var(--ink);margin-bottom:8px;flex:0 0 auto }
/* 🔴 15.08.2026 BEFUND (Ralph: „die Ueberschriften ueberlagern sich"):
   Die Kopfzeile traegt ZWEI Klassen — `feListKopf fgBestKopf`. Diese Regel hier
   hat mit `#feTab3` eine hoehere Spezifitaet als `.fgBestKopf` und setzte deshalb
   DREI Spalten (22px 1fr 46px), waehrend die Datenzeile FUENF hatte. Fuenf
   <span> in drei Spalten heisst: die letzten beiden landen in Zeile 2, unter den
   ersten. Genau das war zu sehen.
   Das `grid-template-columns` ist hier ENTFERNT — die Spaltenzahl gehoert der
   Tabelle, nicht ihrer Schriftformatierung. */
#feTab3 .feListKopf{ display:grid;gap:8px;padding:0 8px 5px;font-size:10.5px;color:var(--muted);font-weight:700;text-transform:uppercase;letter-spacing:.03em;border-bottom:2px solid var(--line) }
/* Dreispaltiger Rueckfall NUR fuer die alte Pickliste ohne Fokusmodus (§17). */
#feTab3 .feListKopf:not(.fgBestKopf){ grid-template-columns:22px 1fr 46px }
#feTab3 .feMitte{ text-align:center }
#feTab3 #fe_pickList{ flex:1 1 auto;min-height:110px;overflow:auto;border:1px solid var(--line);border-top:0;border-radius:0 0 8px 8px;background:var(--card) }
#feTab3 .feNeuZeile{ display:flex;gap:6px;margin-top:6px }
#feTab3 #fe_zutNeu{ flex:1;min-width:0;padding:7px;border:1px solid var(--line);border-radius:8px;font-size:12.5px;background:var(--card);color:var(--ink) }
#feTab3 .feBtnStamm{ padding:7px 11px;border:1px solid var(--k-16a34a);border-radius:8px;background:var(--greenlt,var(--k-ecfdf5));color:var(--k-166534);cursor:pointer;font-size:12.5px;white-space:nowrap }
#feTab3 #fe_zutNeuInfo{ margin-top:6px }

/* ---- Riki-Sammelweg (08.08.2026, Ralph-Entscheid Weg C zu FAHRPLAN 14) ----------------
   Anlass: der Knopf "→ Riki" liegt in #fe_zutRows und ist durch .feVersteckt unerreichbar.
   Statt ihn freizulegen (Weg B haette die alte Doppelliste zurueckgebracht) sitzt hier ein
   Sammelknopf UEBER der Liste: alle Zeilen ohne Stamm-Treffer auf einmal einstufen lassen,
   danach eine Ergebnisliste zum Durchsehen mit Haken UND Kategorie je Zeile.
   Vorgehakt wird nur BESTAETIGT - PRUEFEN und AUSNAHME muss Ralph aktiv anhaken. */
#feTab3 #fe_zutSammelLeiste{ flex:0 0 auto;margin-bottom:8px }
#feTab3 .feSammelBtn{ width:100%;padding:8px 11px;border:1px solid var(--frg-rot,#c0392b);border-radius:8px;background:var(--card);color:var(--frg-rot,#c0392b);font-weight:700;font-size:12.5px;cursor:pointer;text-align:left }
#feTab3 .feSammelBtn:disabled{ opacity:.6;cursor:default }
#feTab3 #fe_zutSammelBox{ flex:0 0 auto }
#feTab3 .feSammelKasten{ margin-bottom:8px;border:1px solid var(--line);border-left:3px solid var(--k-534ab7);border-radius:8px;background:var(--k-f2f5f3);padding:8px 9px;font-size:12px;line-height:1.5;color:var(--ink) }
#feTab3 .feSammelKopf{ font-weight:700;font-size:12.5px;margin-bottom:6px }
#feTab3 .feSammelHinweis{ color:var(--muted);font-size:11.5px;margin-bottom:7px }
#feTab3 .feSammelZeile{ display:grid;grid-template-columns:18px 1fr;gap:7px;align-items:start;padding:6px 0;border-top:1px solid var(--line) }
#feTab3 .feSammelZeile input[type=checkbox]{ width:16px;height:16px;margin-top:2px;accent-color:var(--k-16a34a) }
#feTab3 .feSammelName{ font-weight:700;font-size:12.5px }
#feTab3 .feSammelMeta{ color:var(--muted);font-size:11.5px }
#feTab3 .feSammelKat{ width:100%;margin-top:4px;padding:5px 6px;border:1px solid var(--line);border-radius:var(--fk-r-klein);background:var(--card);color:var(--ink);font-size:11.5px }
#feTab3 .feSammelFuss{ display:flex;gap:6px;margin-top:9px;flex-wrap:wrap }
#feTab3 .feSammelOk{ padding:7px 12px;border:0;border-radius:8px;background:#2e9e57;color:#fff;font-weight:700;font-size:12.5px;cursor:pointer }
#feTab3 .feSammelOk:disabled{ opacity:.55;cursor:default }
#feTab3 .feSammelAbb{ padding:7px 12px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--ink);font-size:12.5px;cursor:pointer }

#feTab3 #fgOffBox{ margin-top:8px }
#feTab3 #fe_colZus{ min-height:0;display:grid;grid-template-rows:minmax(0,1.6fr) minmax(0,1fr);gap:10px }
#feTab3 .feSpalteFlex{ min-height:0;display:flex }
#feTab3 .feZusKeineLbl{ display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--muted);margin-bottom:8px;cursor:pointer;flex:0 0 auto }
#feTab3 #fe_zusKeine{ width:15px;height:15px;flex:0 0 auto }
#feTab3 #fe_zusSuche{ width:100%;box-sizing:border-box;padding:7px;border:1px solid var(--line);border-radius:8px;font-size:13px;background:var(--card);color:var(--ink);margin:8px 0 6px;flex:0 0 auto }
#feTab3 #fe_zusList{ flex:1 1 auto;min-height:110px;overflow:auto;border:1px solid var(--line);border-radius:8px;background:var(--card) }
#feTab3 .feNeuZeile2{ display:flex;gap:6px;margin-top:7px;flex:0 0 auto }
#feTab3 #fe_zusNeu{ flex:1;min-width:0;padding:7px;border:1px solid var(--line);border-radius:8px;font-size:12.5px;background:var(--card);color:var(--ink) }
#feTab3 .feZusLegende{ display:flex;gap:12px;flex-wrap:wrap;font-size:11px;color:var(--muted);margin-top:7px }
#feTab3 .feZusPunktGr{ display:inline-block;width:9px;height:9px;border-radius:50%;background:#2e9e57;vertical-align:middle;margin-right:4px }
#feTab3 .feZusPunktRt{ display:inline-block;width:9px;height:9px;border-radius:50%;background:#c0392b;vertical-align:middle;margin-right:4px }
#feTab3 .feZusPunktGrau{ display:inline-block;width:9px;height:9px;border-radius:50%;background:#9aa7b2;vertical-align:middle;margin-right:4px }
#feTab3 #fe_colRef{ min-height:0 }


/* ============================================================================
   PRODUKTEDITOR · FREIGABE-CHECK IN KLARTEXT  ·  Durchgang 3c (fePlaus)
   ----------------------------------------------------------------------------
   fePlaus schreibt in drei Kaesten: die Plausibilitaetszeile (#fe_plaus), die
   "Bereit / Fehlt"-Zeile (#fe_ready) und die Freigabe-Checkliste (#fe_riegel).
   29 Inline-Stile, fast alle nach demselben Muster: eine Farbe je Zustand.

   ⚠ BEFUND BEIM UMZUG — NICHT BEHOBEN, NUR SICHTBAR GEMACHT (§2.3)

   Dieselbe Aussage traegt im Code mehrere Farbtoene, und einer davon ist im
   Dunkelmodus kaputt. Die Farbvariablen sind Theme-Paare (hell/dunkel):

       --k-166534   #166534  /  #b8cec1      "erfuellt", dunkelgruen
       --k-16a34a   #16a34a  /  #36ca6d      "plausibel", helleres Gruen
       --k-b45309   #b45309  /  #dd8039      "offen"
       --k-b91c1c   #b91c1c  /  #e27878      "blockiert"

   1. GRUEN gibt es zweimal: die Checkliste nutzt --k-166534, die
      Plausibilitaetszeile --k-16a34a. Beide heissen "in Ordnung".
   2. ROT steht in DREI Schreibweisen: var(--k-b91c1c) · var(--k-b91c1c,#b91c1c)
      · und einmal ROH als #b91c1c (im Dubletten-Hinweis, Klasse .rDubRoh).
      Der rohe Wert kennt kein Theme - im Dunkelmodus bleibt genau dieser eine
      Hinweis hart rot, waehrend alle anderen aufhellen.
   3. Der Tier-Warnkasten (.rTierWarnung) arbeitet komplett mit rohen Hexwerten.

   Alle vier Klassen unten sind WORTGLEICH zu dem, was vorher am Element stand.
   Vereinheitlichen waere eine Aussehensaenderung und braucht Ralphs Entscheid.

   WO SCHRAUBEN? Eine Zeile je Zustand. Wer die Toene angleichen will, aendert
   .pGruen auf denselben Wert wie .rOk - und traegt es im FAHRPLAN ein.
   ============================================================================ */

/* ⚠ ZWEI ORTE, EIN SATZ REGELN — feVorgangSync (app.js Z. 17408) kopiert die
   Punkte per outerHTML aus #fe_riegel in #feVorgangAmpel, die SICHTBARE
   Freigabe-Ampel im linken Streifen. Ein Selektor nur auf #fe_riegel haette dort
   nicht gegriffen: alle Punkte waeren schwarz statt gruen/gelb/rot - und zwar
   lautlos. Darum traegt jede Regel unten BEIDE Container. Wer eine Klasse
   ergaenzt, ergaenzt beide Selektoren.
   (Die Checkliste #fe_riegel selbst ist im Vollbild ausgeblendet - sichtbar ist
   praktisch nur die Spiegelung. Umso wichtiger, dass sie stimmt.) */

/* Plausibilitaetszeile #fe_plaus - ohne nowrap, eigene Toene. */
#fe_plaus .pGrau { color:var(--muted) }
#fe_plaus .pWarn { color:var(--k-b45309,#b45309) }
#fe_plaus .pRot  { color:var(--k-b91c1c) }
#fe_plaus .pGruen{ color:var(--k-16a34a) }

/* "Bereit / Fehlt"-Zeile #fe_ready. */
#fe_ready .rReady     { color:var(--k-166534); font-weight:600 }
#fe_ready .rFehlt     { color:var(--k-b45309) }
#fe_ready .rHintWarn  { color:var(--k-b45309); margin-top:4px }
#fe_ready .rHintGrau  { color:var(--muted); margin-top:4px }
#fe_ready .rGrauEinfach{ color:var(--muted) }

/* Checkliste #fe_riegel - hier gilt ueberall white-space:nowrap, damit die
   Punkte als geschlossene Marken umbrechen und nicht mitten im Wort. */
#fe_riegel .rOk,
#feVorgangAmpel .rOk    { color:var(--k-166534); white-space:nowrap }
#fe_riegel .rWarn,
#feVorgangAmpel .rWarn  { color:var(--k-b45309); white-space:nowrap }
#fe_riegel .rWarnF,
#feVorgangAmpel .rWarnF { color:var(--k-b45309); white-space:nowrap; font-weight:600 }
/* 08.08.2026 (Punkt 10b): "bewusst ohne" - z. B. ein Produkt ohne Barcode. Weder gruen
   (da fehlt nichts Erledigtes) noch gelb (es ist kein offener Punkt): jemand hat
   entschieden. Gleiche Farbe wie die blaue Punkt-Spalte in der Produktliste. */
#fe_riegel .rBlau,
#feVorgangAmpel .rBlau  { color:var(--frg-blau); white-space:nowrap; font-weight:600 }
#fe_riegel .rRot,
#feVorgangAmpel .rRot   { color:var(--k-b91c1c,#b91c1c); font-weight:600; white-space:nowrap }
#fe_riegel .rGrau,
#feVorgangAmpel .rGrau  { color:var(--muted); white-space:nowrap }
#fe_riegel .rLinkGrau,
#feVorgangAmpel .rLinkGrau{ color:var(--muted); font-weight:400 }

/* Dubletten-Hinweis: anklickbar, gepunktet unterstrichen. Die Farbe kam frueher
   als Zeichenkette in die Funktion _btn - jetzt als Klassenname. */
#fe_riegel .rDub,
#feVorgangAmpel .rDub    { white-space:nowrap; cursor:pointer; text-decoration:underline dotted }
#fe_riegel .rDubRoh,
#feVorgangAmpel .rDubRoh { color:#b91c1c; font-weight:600 }   /* ⚠ roh, ohne Theme - siehe Befund 2 oben */
#fe_riegel .rDubGrau,
#feVorgangAmpel .rDubGrau{ color:var(--muted) }
#fe_riegel .rDubWarn,
#feVorgangAmpel .rDubWarn{ color:var(--k-b45309); font-weight:600 }

/* Zwei Knoepfe in der Checkliste. */
#fe_riegel .rBtnLila,
#feVorgangAmpel .rBtnLila{
  padding:3px 9px; border:1px solid #cbc7f2; border-radius:var(--fk-r-klein);
  background:var(--k-eeedfe); color:var(--k-534ab7);
  cursor:pointer; font-size:11.5px; font-weight:700; white-space:nowrap;
}
#fe_riegel .rBtn0,
#feVorgangAmpel .rBtn0{
  border:1px solid var(--k-16a34a); background:var(--greenlt,#ecfdf5); color:var(--k-166534);
  border-radius:999px; padding:1px 9px; font-size:11px; font-weight:800;
  cursor:pointer; margin-left:3px;
}

/* Warnkasten "vegan, aber tierische Zutat" - volle Zeilenbreite, rohe Hexwerte
   wie im Original (siehe Befund 3 oben). */
#fe_riegel .rTierWarnung,
#feVorgangAmpel .rTierWarnung{
  flex-basis:100%; width:100%;
  color:#b91c1c; font-weight:700;
  background:#fde8e8; border:1px solid #f3b4b4;
  border-radius:8px; padding:6px 9px;
}

/* Nachgezogen: die zwei Stile, die in Z. 16848/16849 als ZWEITES style= auf
   derselben Zeile standen - der Knopf "kcal ist so belegt" und seine Beschriftung.
   Merksatz: eine Zeile kann mehr als einen Inline-Stil tragen; die Erhebung muss
   je Vorkommen zaehlen, nicht je Zeile. */
#fe_plaus .pLila{ color:var(--k-534ab7) }
#fe_plaus .pBtnLila{
  margin-left:4px; padding:3px 9px;
  border:1px solid #cbc7f2; border-radius:var(--fk-r-klein);
  background:var(--k-eeedfe); color:var(--k-534ab7);
  cursor:pointer; font-size:11.5px; font-weight:700;
}


/* ============================================================================
   FREIGABE-AMPEL · FARBEN UND KLARTEXT-ZEILEN  ·  Durchgang 3d (Teil 1)
   ----------------------------------------------------------------------------
   DIE DREI AMPELFARBEN, EINMAL FUER ALLES.
   app.js liest sie ueber _FRG_COL (Z. 17049) und faerbt damit die Punkte in
   frgDots und frgList; die Klartext-Zeilen im linken Streifen nehmen sie direkt
   aus den Regeln unten. _FRG_COL bleibt die EINE Quelle im Code - nur stehen
   die Werte jetzt hier statt als Hexzahlen im JavaScript.

   Werte unveraendert uebernommen. Wer die Ampel umfaerbt, aendert drei Zeilen -
   und trifft damit alle drei Ansichten gleichzeitig.
   ============================================================================ */
:root{
  --frg-gruen:#2e9e57;
  --frg-gelb :#e0a32e;
  --frg-rot  :#cf5442;
  --frg-leer :#c3ccd4;   /* "nicht noetig" - hohler Ring */
  --frg-blau :#3b56b0;   /* 08.08.2026: "bewusst ohne" - z. B. Produkt ohne Barcode.
                            Blau ist KEIN Mangel: es heisst, jemand hat entschieden.
                            Wert uebernommen aus den vorhandenen Blau-Zustaenden in app.js. */
}

/* ===== Freigabe-Punkte als Spalten in der Erfassungsliste (Ralph 08.08.2026) =====
   Dieselben sechs Punkte wie auf der Erfassungskarte, nur je Zeile statt je Produkt.
   Die Liste RECHNET NICHTS - sie zeigt, was v_erfassung_katalog liefert. */
.pePkt{ display:inline-block;width:11px;height:11px;border-radius:50%;vertical-align:middle }
.pePkt-g{ background:var(--frg-gruen) }
.pePkt-r{ background:var(--frg-rot) }
.pePkt-b{ background:var(--frg-blau) }
.pePkt-x{ background:transparent;border:2px solid var(--frg-leer);width:9px;height:9px }

/* Die Karte "Freigabe" im linken Streifen. Sie ist im klassischen Editor
   IMMER sichtbar - anders als die Checkliste #fe_riegel und die alte
   Rand-Fahne #frgRail, die beide ausgeblendet sind. */
.feRailKarte{
  background:var(--card);
  border:1px solid var(--line);
  border-radius:12px;
  padding:10px 12px;
}
.feRailKarteTitel{
  font-size:11px;
  text-transform:uppercase;
  letter-spacing:.5px;
  color:var(--green);
  margin:0 0 8px;
}
#feRailAmpel{ font-size:12px; line-height:1.5; color:var(--muted) }

/* Eine Zeile der Klartext-Ampel. Der Zustand steht als Klasse am Element:
   ra-g = erfuellt · ra-y = offen · ra-r = blockiert · ra-x = nicht noetig.
   Vorher baute feFreigabeLeiste daraus drei Zeichenketten und setzte sie als
   Inline-Stil ein - die Textfarbe kam aus einer verschachtelten Bedingung,
   die Punktfarbe aus _FRG_COL, die Sonderform fuer "x" aus einer vierten. */
#feRailAmpel .raZ{
  display:flex;
  align-items:flex-start;
  gap:7px;
  padding:2.5px 0;
  color:var(--ink);
}
#feRailAmpel .raZ.ra-r{ color:#cf5442 }
#feRailAmpel .raZ.ra-y{ color:#92400e }
#feRailAmpel .raZ.ra-x{ color:#9aa7b2 }

#feRailAmpel .raPunkt{
  width:9px; height:9px;
  border-radius:50%;
  flex:0 0 auto;
  margin-top:3px;
  background:var(--frg-leer);
}
#feRailAmpel .ra-g .raPunkt{ background:var(--frg-gruen) }
#feRailAmpel .ra-y .raPunkt{ background:var(--frg-gelb) }
#feRailAmpel .ra-r .raPunkt{ background:var(--frg-rot) }
#feRailAmpel .ra-x .raPunkt{ background:transparent; border:2px solid var(--frg-leer) }

#feRailAmpel .raTxt{ min-width:0 }
#feRailAmpel .raSub{
  display:block;
  font-size:10.5px;
  color:var(--muted);
  font-weight:400;
  line-height:1.35;
}


/* ============================================================================
   PRODUKTEDITOR · KOPFBEREICH ZWEISPALTIG  (#feKopfLayout)
   ----------------------------------------------------------------------------
   Ralph, 07.08.2026: "marke und bio sollte unter ean stehen, und rechts das
   produktbild und die angehaengten bilder."

   Der Kopfbereich hat genau DREI direkte Kinder, darum genuegt ein Raster:

     .feHolBox     Riki-Zeile "Daten holen"  -> ueber beide Spalten
     #feKopfGrid   das Formular              -> links
     .feMinw0      Produktbild, OFF-Bild,
                   angehaengte Fotos         -> rechts

   Damit ist ein Teil von Etappe 3b (Mockup H, "Anker rechts") erledigt - aber
   OHNE DOM-Verschiebung: kein Element wandert, nur die Anordnung aendert sich.
   Das Etikett (#fe_wirkFotoBox) bleibt in Reiter 2, wo fgFotoPlatzieren es
   hinhaengt; das umzuziehen ist der riskante Rest von 3b.

   WO SCHRAUBEN?
   · Breite der Bildspalte ... --kopf-bildspalte
   · Umbruchpunkt ............ @media weiter oben im Kopfbereich-Abschnitt
   ============================================================================ */
#feTab1 #feKopfLayout{
  --kopf-bildspalte:300px;
  display:grid;
  grid-template-columns:minmax(0,1fr) var(--kopf-bildspalte);
  gap:12px;
  align-items:start;
  min-width:0;          /* aus der frueheren flex-column-Regel uebernommen */
}
#feTab1 #feKopfLayout > .feHolBox{ grid-column:1 / -1 }

/* Schmales Fenster: die Bildspalte rutscht unter das Formular.
   MUSS NACH der Regel darueber stehen - gleiche Spezifitaet, die spaetere
   gewinnt. Umbruchpunkt = die Zahl hier. */
@media(max-width:1180px){
  #feTab1 #feKopfLayout{ grid-template-columns:minmax(0,1fr) }
}


/* ============================================================================
   FARBEN · KARTENTITEL UND ARBEITSGRUND  (Ralph 07.08.2026)
   ----------------------------------------------------------------------------
   Ralph: "das gruen bei z.b. wirkstoffe ist zu hell, ich moechte eine kraeftige
   farbe, blau, lila... der helle graublaue hintergrund ist auch zu hell."

   ⚠ WARUM NICHT EINFACH --green GEAENDERT WURDE
   var(--green) kommt 169 Mal vor: 119 in app.js, 27 in admin.html und 23 in
   index.html - der OEFFENTLICHEN Seite. Es haengt dort an Fortschrittsbalken,
   aktiven Reitern, Primaerknoepfen, der Premium-Kennzeichnung und Zahlenwerten.
   --green ist nicht die Farbe der Kartentitel, sondern die MARKENFARBE von
   Root Index. Sie auf Lila zu setzen haette die Consumer-Seite mitgefaerbt.

   Darum eine eigene Variable, die NUR die Kartentitel im Editor traegt.
   card() und cardF() in app.js lesen sie als var(--karten-titel,var(--green)) -
   faellt sie weg, steht wieder das alte Gruen da. Zurueck geht es mit dem
   Loeschen EINER Zeile.

   #534AB7 ist kein neuer Ton, sondern das Riki-Lila, das im System schon
   vorkommt: Einfuegefeld, Riki-Knoepfe, Dubletten-Chip, Zuordnen-Knopf.
   ============================================================================ */
body{ --karten-titel:#534AB7 }

/* Die Karte "Freigabe" im linken Streifen traegt denselben Titel-Stil. */
.feRailKarteTitel{ color:var(--karten-titel,var(--green)) }

/* ----------------------------------------------------------------------------
   ARBEITSGRUND  (--bg)
   --bg faerbt nicht nur die Flaeche, sondern auch ALLE Eingabefelder (.fld,
   fe_url, die Auswahlfelder) - dunkler heisst: die Felder heben sich staerker
   von den weissen Karten ab.

   ⚠ BEWUSST NUR IN DER PRODUKTERFASSUNG. body.peLightBg setzt app.js genau
   dann, wenn die Erfassung offen ist (Z. 10677). Dashboard, Listen und die
   oeffentliche Seite bleiben unberuehrt. Soll es ueberall gelten, wandert die
   Zeile von body.peLightBg nach body - eine Aenderung, eine Zeile.

   Vorher #f7f5fb. Neu #e8e4f2, rund 8 Prozent dunkler, im selben Lila-Grau.
   ---------------------------------------------------------------------------- */
/* 15.08. (Ralph P4): Flieder -> sehr helles Blaugrau. Keine gesaettigte Farbe,
   damit die weissen Karten klar darueber stehen. */
body.peLightBg{ --bg:#e6ecf4 }


/* ============================================================================
   PRODUKTEDITOR · ONE-PAGE MIT ANKERN  ·  07.08.2026 (Ralph-Konzeptkorrektur)
   ----------------------------------------------------------------------------
   Ralph: "es ist mit den drei seiten eher so gedacht, dass es ein one page ist
   und punkt 2 und drei ueber ankerpunkte erreichbar sind, nicht eigene seiten."

   Das ist Mockup H: die Stationen sind Sprungmarken, keine Reiter. feTabWechsel
   schaltet kein display mehr um, sondern springt (scrollIntoView). Die Knoepfe,
   ihre IDs und ihre onclick-Aufrufe sind unveraendert.

   ⚠ scroll-margin-top ist hier KEIN Schoenheitswert.
   #feNavLeiste klebt oben. Ohne diesen Abstand landet die angesprungene Station
   genau darunter und ihre Ueberschrift ist verdeckt - der Sprung sieht dann aus,
   als haette er das falsche Ziel getroffen. Die Zahl muss zur Hoehe der Leiste
   passen: aendert sich deren padding, aendert sich auch diese.

   WO SCHRAUBEN?
   · Abstand unter der Leiste beim Springen .. --station-anker
   · Luft zwischen den Stationen ............. #feTab2 / #feTab3 margin-top
   ============================================================================ */
#feTab1, #feTab2, #feTab3{
  --station-anker:64px;
  scroll-margin-top:var(--station-anker);
}

/* Luft zwischen den Stationen, damit man den Uebergang sieht.
   Station 1 braucht keinen - sie steht direkt unter der Leiste. */
#feTab2, #feTab3{ margin-top:22px }

/* ============================================================================
   FOKUS-EDITOR — Workflow-Leiste (Ralph-Auftrag 14.08.2026)
   Sieben Schritte, einer offen. Die Leiste ersetzt im Fokusmodus die
   Stationsschiene; #feTabBar bleibt im DOM und kommt beim Umschalten zurueck.
   ============================================================================ */
#feFokusNav{ display:flex; flex-direction:column; gap:2px; margin-bottom:12px }
#feFokusNav .feStTitel{ margin-bottom:4px }
.feFokusSt{ display:flex; align-items:flex-start; gap:8px; width:100%; text-align:left;
  background:transparent; border:1px solid transparent; border-radius:8px;
  padding:6px 8px; cursor:pointer; font:inherit; color:var(--ink); line-height:1.3 }
.feFokusSt:hover{ background:var(--k-f6f8f7,#f6f8f7) }
.feFokusSt.akt{ background:var(--k-eef6ff,#eef6ff); border-color:var(--k-2f6fd6,#2f6fd6) }
.feFokusIco{ flex:0 0 12px; font-size:12px; line-height:1.5; text-align:center }
.feFokusTxt{ min-width:0; display:flex; flex-direction:column }
.feFokusTxt b{ font-size:12.5px; font-weight:600 }
.feFokusSt.akt .feFokusTxt b{ font-weight:800 }
.feFokusSub{ font-size:10.5px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.feFokusAus{ margin-top:8px; background:transparent; border:1px solid var(--line);
  border-radius:var(--fk-r-klein); padding:4px 8px; font-size:10.5px; color:var(--muted); cursor:pointer }
.feFokusAus:hover{ color:var(--ink) }

/* ============================================================================
   BESTANDTEILTABELLE (Fokus-Editor, Schritt 4) — Ralph 14.08.2026
   STATUS | BESTANDTEIL | VERARBEITUNG | ZUSATZSTOFF | WERT
   Farbe traegt der Statuspunkt, nicht die Zeilenflaeche (§23).
   ============================================================================ */
/* Kopf und Zeile lesen DIESELBE Variable. Ein zweiter Spaltenvertrag waere
   genau der Fehler, der gerade behoben wurde (Ralph P1). */
.fgBestKopf{ display:grid; grid-template-columns:var(--best-spalten);
  gap:8px; font-size:10px; letter-spacing:.04em; color:var(--muted); font-weight:700;
  padding:5px 8px; border-bottom:1px solid var(--line) }
.fgBestZeile{ display:grid; grid-template-columns:var(--best-spalten);
  gap:8px; align-items:start; padding:7px 8px; border-bottom:1px solid var(--line);
  cursor:pointer; font-size:12.5px }
.fgBestZeile:hover{ background:var(--k-f6f8f7,#f6f8f7) }
.fgbSt{ display:flex; align-items:center; gap:5px }
.fgbSt input{ width:15px; height:15px; accent-color:var(--k-16a34a,#16a34a) }
.fgbIco{ font-size:12px; line-height:1 }
.fgbName{ min-width:0; overflow-wrap:anywhere; color:var(--ink) }
.fgbVerarb,.fgbZus{ min-width:0; font-size:11.5px; overflow-wrap:anywhere; line-height:1.45 }
.fgbWert{ text-align:right; font-weight:700; font-size:13px }

/* ============================================================================
   FOKUS-EDITOR — Schrittkopf, Weiter/Zurueck, Abschlussansicht (14.08.2026)
   ============================================================================ */
.feSchrittKopf{ display:flex; align-items:baseline; gap:10px; padding:2px 2px 12px }
.feSchrittNr{ flex:0 0 auto; width:24px; height:24px; border-radius:50%;
  background:var(--k-eef6ff,#eef6ff); color:var(--k-2f6fd6,#2f6fd6);
  display:flex; align-items:center; justify-content:center; font-size:12px; font-weight:800 }
.feSchrittKopf b{ font-size:16px; display:block; line-height:1.25 }
.feSchrittKurz{ display:block; font-size:11.5px; color:var(--muted); margin-top:1px }
.feSchrittFuss{ display:flex; justify-content:space-between; align-items:center;
  gap:10px; margin-top:16px; padding-top:12px; border-top:1px solid var(--line) }
/* 15.08. (Ralph P10): Pill-Sprache und weniger Hoehe — HIER, an der einzigen
   Definition. Ein Nachtrag am Dateiende waere die vierte Schicht gewesen. */
.feSchrittBtnPrim{ background:var(--k-2f6fd6,#2f6fd6); color:#fff; border:0; border-radius:999px;
  padding:6px 14px; font-size:12px; font-weight:700; cursor:pointer }
.feSchrittBtnSek{ background:var(--card); color:var(--muted); border:1px solid var(--line);
  border-radius:999px; padding:6px 14px; font-size:12px; font-weight:700; cursor:pointer }
.feFokusBreit{ grid-column:1/-1 !important }
.feFokusBreit > k{ font-size:13px; font-weight:700; color:var(--ink) }

/* 15.08.: der eigene 720er-Deckel ist ENTFERNT (Ralph P9). Die Abschlusskarte
   gilt nur noch in der Komplettansicht und folgt dort demselben Rahmen. */
#feAbschluss{ display:flex; flex-direction:column; gap:14px }
.feAbGr{ border:1px solid var(--line); border-radius:12px; background:var(--card); padding:14px 16px }
.feAbTit{ font-size:10.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); font-weight:800; margin-bottom:9px }
.feAbScore{ text-align:center; padding:4px 0 10px }
.feAbZahl{ font-size:52px; font-weight:800; line-height:1 }
.feAbBew{ font-size:14px; font-weight:700; margin-top:3px }
.feAbAchsen{ border-top:1px solid var(--line); padding-top:9px }
.feAbZeile{ display:flex; justify-content:space-between; gap:12px; padding:3px 0; font-size:12.5px }
.feAbZeile span{ color:var(--muted) }
.feAbSp{ font-size:11.5px; color:var(--muted); line-height:1.5 }
.feAbSatz{ font-size:14px; font-weight:700; margin-bottom:8px }
.feAbSatz.ok{ color:var(--k-166534,#166534) }
.feAbSatz.rot{ color:var(--k-b91c1c,#b91c1c) }
.feAbListe{ margin:0 0 6px; padding-left:18px; font-size:12.5px; line-height:1.6 }
.feAbListe span{ display:block; font-size:11px; color:var(--muted) }
.feAbDet summary{ cursor:pointer; font-size:11.5px; color:var(--muted); padding:4px 0 }
.feAbBtns{ display:flex; gap:9px; margin-top:12px; flex-wrap:wrap }
.feAbBtnPrim{ background:var(--k-16a34a,#16a34a); color:#fff; border:0; border-radius:var(--fk-r-klein);
  padding:10px 20px; font-size:13.5px; font-weight:700; cursor:pointer }
.feAbBtnPrim[disabled]{ background:var(--k-c3ccd4,#c3ccd4); cursor:not-allowed }
.feAbBtnSek{ background:transparent; border:1px solid var(--line); border-radius:var(--fk-r-klein);
  padding:9px 16px; font-size:12.5px; color:var(--ink); cursor:pointer }

/* ============================================================================
   SCHRITT 1 „QUELLE HINZUFÜGEN" + TOPBAR (Ralph 14.08.2026)
   Drei Eingaenge, sonst nichts. OFF/USDA/JSON/Kundenfoto/Foto→Seite sind im
   Fokusmodus ausgeblendet — im DOM und im Code unveraendert vorhanden.
   ============================================================================ */
/* Innenbreite, KEIN Rahmenmass: ein Link-Feld ueber die volle Arbeitsflaeche zu
   ziehen hilft niemandem. Der aeussere Rahmen (.feHolBox) folgt dem Raster.
   Nur EIN Wert, an genau dieser Stelle (Ralph P9). */
.feHolGrid.feQuelleFokus{ display:flex; flex-direction:column; gap:9px; max-width:640px }
.feHolGrid.feQuelleFokus .feHolZeile{ display:flex; gap:8px; align-items:center }
.feHolGrid.feQuelleFokus #fe_pasteZone{ padding:14px 12px; border:2px dashed var(--line);
  border-radius:10px; cursor:text; display:flex; gap:8px; align-items:center }
.feHolGrid.feQuelleFokus #fe_pasteZone:focus{ border-color:var(--k-2f6fd6,#2f6fd6); outline:none }
.feQuelleBtn{ display:flex; align-items:center; justify-content:center; gap:8px;
  padding:13px 12px; border:1px solid var(--line); border-radius:10px; background:var(--bg);
  color:var(--ink); font-size:13px; font-weight:600; cursor:pointer; width:100% }
.feQuelleBtn:hover{ border-color:var(--k-2f6fd6,#2f6fd6) }
.feQuelleFertig{ display:flex; align-items:center; gap:10px; padding:10px 12px; max-width:640px;
  border:1px solid var(--k-16a34a,#16a34a); border-radius:10px;
  background:var(--greenlt,#eef7f0); margin-bottom:10px; max-width:560px }
.feQuelleHaken{ color:var(--k-16a34a,#16a34a); font-weight:800 }
.feQuelleFertig b{ display:block; font-size:12.5px }
.feQuelleFertig span span{ display:block; font-size:11px; color:var(--muted) }
.feQuelleWechsel{ margin-left:auto; background:transparent; border:1px solid var(--line);
  border-radius:var(--fk-r-klein); padding:4px 10px; font-size:11.5px; color:var(--muted); cursor:pointer }

#feTopbar{ display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:9px 14px; border:1px solid var(--line); border-radius:10px;
  background:var(--card); margin-bottom:10px }
.feTbLinks{ display:flex; align-items:baseline; gap:10px; min-width:0 }
.feTbId{ font-size:11px; color:var(--muted); font-weight:700 }
.feTbName{ font-size:15px; font-weight:700; color:var(--ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.feTbZust{ font-size:11px; color:var(--muted); white-space:nowrap }
.feTbBtn{ background:var(--k-2f6fd6,#2f6fd6); color:#fff; border:0; border-radius:8px;
  padding:8px 16px; font-size:12.5px; font-weight:700; cursor:pointer }

/* ============================================================================
   KONTEXTSPALTE (Fokus-Editor, Ralph 14.08.2026)
   Dritte Spalte. Sie erscheint NUR im Fokusmodus und nur, wenn der aktuelle
   Schritt etwas zu zeigen hat — in Schritt 5 leer, in Schritt 6 gar nicht.
   Die zweispaltige Grundvorlage von #feRahmen bleibt unveraendert; die dritte
   Spalte kommt ueber :has() dazu und faellt weg, sobald #feKontext aus ist.
   ============================================================================ */
/* 15.08. ENTFERNT (Ralph P12): tote Regel. Die Kontextspalte entsteht NUR im
   Fokusmodus — `feKontextRender` setzt sie ausserhalb auf display:none. Diese
   242/260-Fassung konnte deshalb nie greifen und war ein Breitenbesitzer auf
   Vorrat. Der Fokus-Zweig steht weiter unten im Arbeitsraster. */
#feKontext{ display:flex; flex-direction:column; gap:10px; align-self:start; position:sticky; top:var(--fe-sticky-kopf, 0px) }
.feKtxBlock{ border:1px solid var(--line); border-radius:10px; background:var(--card); padding:10px 12px }
.feKtxTit{ font-size:9.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); font-weight:800; margin-bottom:5px }
.feKtxWert{ font-size:12.5px; font-weight:600; color:var(--ink) }
.feKtxSub{ font-size:10.5px; color:var(--muted); margin-top:3px; line-height:1.45 }
.feKtxLink{ display:inline-block; margin-top:5px; font-size:11px; color:var(--k-2f6fd6,#2f6fd6) }
.feKtxImg{ width:100%; border-radius:8px; display:block; background:var(--bg) }
.feKtxLeer{ font-size:11.5px; color:var(--muted); line-height:1.5 }
.feKtxRoh{ font-size:11.5px; line-height:1.55; color:var(--ink); max-height:340px;
  overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
  background:var(--k-f6f8f7,#f6f8f7); border-radius:var(--fk-r-klein); padding:8px 9px }
.feKtxStill{ min-height:1px }

/* ============================================================================
   SCHRITT 6 — GEGENUEBERSTELLUNG (Ralph 14.08.2026)
   Kompakte Zeilen, wenig Farbe, keine Kartenlawine. Uebereinstimmung ist dezent,
   Abweichung faellt auf — nicht umgekehrt.
   ============================================================================ */
#feAbgleich{ max-width:100% }
/* 15.08.2026 (Work #20): der Befund in einem Satz, VOR den Reitern. Gruen ist
   ruhig und ohne Rahmenfarbe – es ist kein Signal, sondern eine Bestaetigung.
   Gelb bekommt einen Balken, weil dort wirklich etwas zu tun ist. */
.feAbgFazit{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  border-radius:10px; padding:9px 12px; margin-bottom:10px;
  font-size:13px; font-weight:700 }
.feAbgFazit span{ font-size:11.5px; font-weight:500; color:var(--muted) }
.feAbgFazit.ok{ background:var(--greenlt,#eef7f0); color:var(--k-166534,#166534) }
.feAbgFazit.warn{ background:var(--k-fef3c7,#fef3c7); color:var(--k-92400e,#92400e);
  box-shadow:inset 3px 0 0 var(--k-e0a32e,#e0a32e) }
.feAbgAlle > summary{ cursor:pointer; font-size:11.5px; color:var(--muted);
  padding:4px 2px; list-style:revert }
.feAbgAlle[open] > summary{ margin-bottom:4px }
.feAbgTabs{ display:flex; gap:6px; margin-bottom:12px }
.feAbgTab{ background:transparent; border:1px solid var(--line); border-radius:8px;
  padding:7px 14px; font-size:12.5px; color:var(--muted); cursor:pointer }
.feAbgTab.akt{ background:var(--k-eef6ff,#eef6ff); border-color:var(--k-2f6fd6,#2f6fd6);
  color:var(--k-2f6fd6,#2f6fd6); font-weight:700 }
.feAbgZahl{ background:var(--k-e0a32e,#e0a32e); color:#fff; border-radius:999px;
  padding:0 6px; font-size:10.5px; font-weight:800; margin-left:4px }
.feAbgTab.akt .feAbgZahl{ background:var(--k-2f6fd6,#2f6fd6) }
.feAbgTab_ { }
table.feAbgTab{ width:100%; border-collapse:collapse; font-size:12.5px }
table.feAbgTab th{ text-align:left; font-size:9.5px; letter-spacing:.05em; text-transform:uppercase;
  color:var(--muted); font-weight:800; padding:5px 8px; border-bottom:1px solid var(--line) }
table.feAbgTab td{ padding:7px 8px; border-bottom:1px solid var(--line); vertical-align:top }
.feAbgZ{ cursor:pointer }
.feAbgZ:hover{ background:var(--k-f6f8f7,#f6f8f7) }
.feAbgZ.abw td:first-child{ box-shadow:inset 3px 0 0 var(--k-e0a32e,#e0a32e) }
.feAbgKopfZ td{ color:var(--muted) }
.feAbgBer{ color:var(--ink) }
.feAbgBer span{ display:block; font-size:10px; color:var(--muted) }
.feAbgBer span.feAbgWarn{ color:var(--k-b45309,#b45309) }
.feAbgNote{ display:block; font-size:10px; color:var(--muted) }
.feAbgStill{ color:var(--muted) }
.feAbgSt{ font-size:10.5px; font-weight:700; white-space:nowrap; padding:2px 7px; border-radius:999px }
.feAbgSt.ok{ color:var(--muted); background:transparent; font-weight:600 }
.feAbgSt.info{ color:var(--k-1d4ed8,#1d4ed8); background:var(--k-dbeafe,#dbeafe) }
.feAbgSt.warn{ color:var(--k-92400e,#92400e); background:var(--k-fef3c7,#fef3c7) }
.feAbgSt.rot{ color:#fff; background:var(--k-dc2626,#dc2626) }
.feAbgSt.still{ color:var(--muted) }
.feAbgLeer{ border:1px solid var(--line); border-radius:10px; background:var(--card);
  padding:16px; font-size:13px; color:var(--ink) }
.feAbgLeer div{ font-size:11.5px; color:var(--muted); margin-top:4px; line-height:1.5 }
.feAbgRoh{ margin-top:14px }
.feAbgRoh summary{ cursor:pointer; font-size:11.5px; color:var(--muted); padding:4px 0 }
.feAbgRohTxt{ font-size:11.5px; line-height:1.55; white-space:pre-wrap; overflow-wrap:anywhere;
  background:var(--k-f6f8f7,#f6f8f7); border-radius:8px; padding:10px; margin-top:6px; max-height:300px; overflow:auto }

/* ============================================================================
   DESKTOP-FEINSCHLIFF · FOKUS-EDITOR  (Ralph-Auftrag 14.08.2026)

   KEINE neue Funktion, KEINE neue Regel — nur Darstellung. Dieser Block steht
   bewusst am ENDE der Datei und ueberschreibt die Werte der vorherigen
   Fokus-Abschnitte. So bleibt nachvollziehbar, WAS am 14.08. beruhigt wurde,
   ohne dass die urspruenglichen Regeln aus der Datei verschwinden (§17).

   Leitsatz fuer die Farben (Ralph P12):
     gruen = bestaetigt/fertig — NICHT „dieses Element existiert"
     blau  = Fokus und Aktion
     gelb  = Entscheidung noetig
     rot   = echter Blocker
     grau  = Standard
   ============================================================================ */

/* --- 3. Arbeitsflaeche: lesbare Breite statt voller Bildschirm ------------- */
/* 15.08.: max-width 1080 ENTFERNT (Ralph P9: nicht noch einen Override drueber).
   Die Breite gehoert allein dem Arbeitsraster weiter unten. */
/* 15.08.: der 820er-Deckel ist ENTFERNT. Er war der Hauptgrund dafuer, dass
   Kopf, Abgleich und Quellbox verschieden breit wirkten. */
/* 15.08.: dito - Kopf und Fuss folgen jetzt der Mittelspalte. */

/* --- 1./13. Dichte und Abstaende vereinheitlichen -------------------------- */
.feSchrittKopf{ padding:0 0 10px }
.feSchrittKopf b{ font-size:15px }
.feSchrittNr{ width:21px; height:21px; font-size:11px }
.feSchrittFuss{ margin-top:14px; padding-top:10px }
/* 15.08. ENTFERNT (Ralph P10): der 8px-Wert von 1740 stand nach dem neuen
   Pill-Block und gewann bei gleicher Spezifitaet ueber die Quellreihenfolge.
   Zwei Groessen fuer denselben Knopf — dieselbe Sorte Konflikt wie bei den
   Tabellenspalten, nur kleiner. Die Pill-Regel unten ist jetzt die einzige. */
/* 15.08. ENTFERNT: zweiter Groessenwert aus dem Feinschliff von 1740. Er stand
   NACH der Basisdefinition und gewann bei gleicher Spezifitaet - der Zurueck-
   Knopf blieb deshalb eckig, waehrend Weiter schon rund war. Genau die Sorte
   Rest, die mit `keine fuenfte Schicht` gemeint ist. */

/* --- 2. Schrittleiste: ruhig, kein farbiger Block -------------------------- */
.feFokusSt{ padding:5px 7px; border-radius:var(--fk-r-klein); border-left:2px solid transparent }
.feFokusSt.akt{ background:transparent; border-color:transparent;
  border-left-color:var(--k-2f6fd6,#2f6fd6) }
.feFokusSt.akt .feFokusTxt b{ font-weight:700; color:var(--k-2f6fd6,#2f6fd6) }
.feFokusTxt b{ font-size:12px; font-weight:500 }
.feFokusSub{ font-size:10px }
.feFokusIco{ font-size:11px }
#feFokusNav{ gap:1px; margin-bottom:10px }

/* --- 4. Schritt 1: die drei Wege sind eine Entscheidung, kein Werkzeug ----- */
/* 15.08.: der ZWEITE Wert (520px) ist ENTFERNT. Zwei max-width fuer dasselbe
   Element an zwei Stellen - genau der Konflikt, den Ralph gemessen hat. */
.feHolGrid.feQuelleFokus{ gap:7px }
.feHolGrid.feQuelleFokus .feHolZeile input{ padding:10px 11px; font-size:13px }
.feHolGrid.feQuelleFokus #fe_pasteZone{ padding:12px; font-size:13px }
.feQuelleBtn{ padding:11px 12px; font-size:13px }
.feHolBox .feHolKopf{ margin-bottom:8px }

/* --- 5. Schritt 2: Kopfdaten kompakt -------------------------------------- */
#feKopfGrid .mz k{ font-size:10px; letter-spacing:.02em }
#feKopfGrid .mz input, #feKopfGrid .mz select{ padding:7px 9px; font-size:12.5px }
#feKopfGrid .mzr{ gap:8px }

/* --- 7. Schritt 4: Tabelle verdichten, Rohtext sekundaer ------------------- */
.fgBestZeile{ padding:5px 8px; font-size:12px }
.fgbWert{ font-size:12.5px }
.fgbVerarb,.fgbZus{ font-size:11px }
.fgbName span{ font-size:10px }
.feKtxRoh{ font-size:11px; line-height:1.5; color:var(--muted) }

/* --- 8. Schritt 5: hier DARF es auffallen — es ist der aktuelle Schritt ---- */
.feFokusBreit{ padding:14px 0 }
.feFokusBreit > k{ font-size:13.5px; font-weight:700; margin-bottom:8px; display:block }
.feFokusBreit #fe_ernaehrChips button,
.feFokusBreit #fe_bioSw button{ padding:9px 16px; font-size:13px; border-radius:var(--fk-r-klein) }
.feFokusBreit #fe_ernaehrChips{ gap:7px }

/* --- 9. Schritt 6: Abweichungen zuerst lesbar ----------------------------- */
table.feAbgTab td{ padding:6px 8px }
.feAbgTab{ padding:6px 12px; font-size:12px }
.feAbgSt{ font-size:10px }

/* --- 10. Schritt 7: ruhig, erfuellte Bedingungen nicht betonen ------------- */
.feAbGr{ padding:12px 14px; border-radius:10px }
.feAbZahl{ font-size:44px }
.feAbBew{ font-size:13px }
.feAbZeile{ padding:2px 0; font-size:12px }
.feAbBtnPrim{ padding:9px 18px; font-size:13px; border-radius:8px }
.feAbBtnSek{ padding:8px 14px; font-size:12px; border-radius:8px }
.feAbSatz{ font-size:13px }

/* --- 11. Topbar schlank --------------------------------------------------- */
#feTopbar{ padding:7px 12px; border-radius:8px; margin-bottom:8px }
.feTbName{ font-size:14px }
.feTbBtn{ padding:7px 14px; font-size:12px }

/* --- 12. Gruen sparsam: keine Flaechen, nur Zeichen ----------------------- */
.feQuelleFertig .feKtxTit{ color:var(--muted) }

/* --- Kontextspalte etwas leiser ------------------------------------------ */
.feKtxBlock{ padding:9px 11px; border-radius:var(--fk-r-klein) }
.feKtxTit{ font-size:9px }

/* ============================================================================
   🔴 FESTE ARBEITSPOSITION IM FOKUSMODUS (Ralph, Live-Abnahme 1740, Punkt 1+12)

   BEFUND: die Schritte wurden nur ein- und ausgeblendet, blieben aber an ihren
   historischen Y-Positionen der alten One-Page. Beim Wechsel sprang die Seite
   oben -> weit unten -> oben. Das ist kein Step-by-Step.

   WARUM HIER NICHT GEMOUNTET WIRD: ueber 100 CSS-Regeln haengen an den Pfaden
   `#feTab1 …`, `#feTab2 …`, `#feTab3 …`. Ein in einen neuen Container
   verschobener Knoten verliert sie alle. Ralph nennt die Alternative selbst:
   „alle sieben Schrittcontainer dieselbe Grid-Zelle belegen lassen".

   Genau das passiert hier — ohne einen einzigen Knoten zu bewegen und ohne
   einen einzigen bestehenden Selektor zu aendern:
     #feEditorBody wird zum Raster mit drei Zeilen
       Zeile 1  Schrittkopf
       Zeile 2  ALLE Schrittcontainer uebereinander (grid-area 2/1)
       Zeile 3  Weiter/Zurueck
   Der jeweils sichtbare Container beginnt damit immer an derselben Oberkante.
   Ohne Fokusmodus (Klasse fehlt) gilt die alte One-Page unveraendert.
   ============================================================================ */
body.riFokus #feEditorBody{
  display:grid;
  grid-template-rows:auto minmax(0,1fr) auto;
  grid-template-columns:minmax(0,1fr);
  align-content:start;
}
body.riFokus #feEditorBody > #feSchrittKopf{ grid-area:1 / 1 }
body.riFokus #feEditorBody > #feTab1,
body.riFokus #feEditorBody > #feTab2,
body.riFokus #feEditorBody > #feTab3,
body.riFokus #feEditorBody > #feAbgleich,
body.riFokus #feEditorBody > #feAbschluss{ grid-area:2 / 1; align-self:start; min-width:0 }
body.riFokus #feEditorBody > #feSchrittFuss{ grid-area:3 / 1 }

/* Die Stationsschiene und die alten Rail-Karten gehoeren nicht in den Fokus. */
body.riFokus #feTabBar{ display:none }
body.riFokus #feTopbar{ display:none !important }

/* Produktkopf in der Rail — klein, keine Karte. */
#feProdKopf{ padding:0 0 12px; border-bottom:1px solid var(--line); margin-bottom:12px }
.feProdZeile{ display:flex; align-items:flex-start; gap:6px }
.feProdTxt{ min-width:0; flex:1 1 auto }
.feProdId{ display:block; font-size:10px; color:var(--muted); font-weight:700 }
.feProdTxt b{ display:block; font-size:13px; line-height:1.3; overflow-wrap:anywhere }
.feProdZust{ display:block; font-size:10px; color:var(--muted); margin-top:2px }
.feProdMehr{ flex:0 0 auto; background:transparent; border:1px solid var(--line);
  border-radius:var(--fk-r-klein); padding:2px 7px; font-size:13px; color:var(--muted); cursor:pointer; position:relative }
.feProdMenuBox{ position:absolute; right:0; top:26px; z-index:30; min-width:170px;
  background:var(--card); border:1px solid var(--line); border-radius:var(--fk-r-klein);
  box-shadow:0 6px 20px rgba(0,0,0,.14); padding:4px; display:flex; flex-direction:column }
.feProdMenuBox button{ text-align:left; background:transparent; border:0; border-radius:6px;
  padding:7px 9px; font-size:12px; color:var(--ink); cursor:pointer }
.feProdMenuBox button:hover{ background:var(--k-f6f8f7,#f6f8f7) }
.feProdMenuBox button.rot{ color:var(--k-b91c1c,#b91c1c) }
.feProdSave{ width:100%; margin-top:9px; background:var(--k-2f6fd6,#2f6fd6); color:#fff;
  border:0; border-radius:8px; padding:7px 12px; font-size:12px; font-weight:700; cursor:pointer }

/* ============================================================================
   KONTEXTREITER (Ralph, Live-Abnahme 1950, Punkt 2-5)
   Ein Platz, wechselnder Inhalt. Der grosse Lesekasten wird hierher umgehaengt.
   ============================================================================ */
.feKtxTabs{ display:flex; gap:3px; margin-bottom:8px; flex-wrap:wrap }
.feKtxTab{ background:transparent; border:1px solid var(--line); border-radius:var(--fk-r-klein);
  padding:4px 9px; font-size:10.5px; color:var(--muted); cursor:pointer; white-space:nowrap }
.feKtxTab.akt{ background:var(--k-eef6ff,#eef6ff); border-color:var(--k-2f6fd6,#2f6fd6);
  color:var(--k-2f6fd6,#2f6fd6); font-weight:700 }

/* 🔴 20.08.2026, Work #133 E6b — DER REITER SAGT, OB DAHINTER ETWAS IST.
   Ralphs Ausgangskritik: "nicht befüllt, irgendwelche buttons, referenz,
   etikett, rohtext?" Drei gleich aussehende Reiter, hinter denen dreimal nichts
   lag - man musste klicken, um das zu erfahren.

   Ein leerer Reiter wird BLASSER, aber NICHT gesperrt: er ist eine Aussage
   ("hier ist nichts"), kein Verbot. Wer hinsehen will, darf. Ein deaktivierter
   Knopf haette dieselbe Information mit einer Bevormundung verbunden.

   Die Marke bleibt klein und ohne Farbe - sie ist eine Angabe, kein Alarm. Rot
   heisst in dieser App "ueber dem Hoechstwert"; "kein Etikett" ist kein Verstoss,
   sondern ein Arbeitsstand. */
.feKtxTab.leer{ opacity:.62 }
.feKtxTab.leer.akt{ opacity:1 }          /* angesehen wird immer voll gezeigt */
.feKtxMarke{
  margin-left:5px; font-weight:600; font-size:9.5px;
  padding:1px 5px; border-radius:8px;
  background:var(--k-eef3f8,#eef3f8); color:var(--muted);
}
.feKtxTab.akt .feKtxMarke{ background:var(--k-ffffff,#fff); color:var(--k-2f6fd6,#2f6fd6) }
.feKtxMarke.leer{ background:transparent; font-weight:400; font-style:italic }
.feKtxInhalt{ display:flex; flex-direction:column; gap:9px; min-width:0 }
/* Der umgehaengte Lesekasten fuellt den Kontextplatz statt seiner alten Spalte. */
.feKtxInhalt > #fe_wirkFotoCol{ width:100%; min-width:0 }
.feKtxInhalt #fe_wirkFotoBox{ height:clamp(180px,32vh,420px) }

/* ============================================================================
   EIN GEMEINSAMES ARBEITSRASTER (Ralph 15.08., Punkte 8-12)

   „Kopf 780, Analyse 660, Bestandteile 1000, Abgleich 1200 — das wirkt wie
    verschiedene Anwendungen."  Stimmt: es waren gewachsene Einzelwerte aus
   verschiedenen Durchgaengen, und jeder hatte fuer sich recht.

   Ab hier gibt es GENAU EIN Raster. Alle Hauptkarten fuellen die Mittelspalte
   (`width:100%`), und wie breit die ist, entscheidet ausschliesslich dieses
   Raster — nicht die Karte. Damit haben alle vier Schritte dieselbe Startkante,
   dieselbe Breite und denselben Abstand nach rechts.

   `app.js` setzt nur `data-fe-schritt` und rechnet keine Pixel (§4.2).
   ============================================================================ */
/* 🔴 BUGFIX 15.08.2026 (Ralph: „der Kontext haengt in der falschen Grid-Zeile").
   Das stimmte. ZWEI belegte Ursachen:

   ── URSACHE A: der `:has()`-Selektor war eine Zufallsregel ──────────────────
   Er lautete `:has(> #feKontext:not([style*="display:none"]))` — er suchte den
   Text `display:none` OHNE Leerzeichen. Das TEMPLATE schreibt genau so
   (`style="display:none"`), aber sobald JavaScript `el.style.display="none"`
   setzt, serialisiert der Browser `display: none;` MIT Leerzeichen. Der Selektor
   traf danach nicht mehr — und umgekehrt: nach `display=""` blieb je nach
   Reihenfolge mal ein leeres, mal gar kein Attribut stehen.
   Ob die dritte Spalte existierte, hing also davon ab, wer zuletzt geschrieben
   hatte. Ohne dritte Spalte landet `#feKontext` als drittes Kind per
   AUTO-PLACEMENT in Zeile 2 — und dort ueber die volle Breite. Genau Ralphs Bild.
   → Ab jetzt eine KLASSE, die `feKontextRender` selbst setzt: derselbe Ort, der
     ueber die Sichtbarkeit entscheidet, entscheidet auch ueber die Spalte (§4.2).
     Eine Klasse ist messbar; eine Attribut-Textsuche ist eine Vermutung.

   ── URSACHE B: 1444 px Mindestbreite in Schritt 2 ──────────────────────────
   `220 + minmax(820px,1fr) + 360 + 2x22 = 1444 px`. Eine Spalte mit 820 px
   Minimum kann NICHT schrumpfen — darunter passt das Raster schlicht nicht.
   → `--mitte-min` ist ERSATZLOS entfernt. Die Mitte ist wieder `minmax(0,1fr)`
     und nimmt, was uebrig bleibt. Ralphs Wunschbreite von 800-850 px entsteht
     ab etwa 1400 px Fensterbreite von selbst — ohne Zwang, der bei schmaleren
     Fenstern das ganze Raster sprengt.

   ── KEIN AUTO-PLACEMENT MEHR ───────────────────────────────────────────────
   Alle drei Bereiche stehen ausdruecklich in Zeile 1, Spalte 1/2/3. Damit KANN
   nichts mehr in eine zweite Zeile rutschen, auch wenn eine kuenftige Regel die
   Spaltenzahl versehentlich aendert. */
/* +=======================================================================+
   |  DER EINE DESKTOP-RASTERVERTRAG (Ralph 15.08., Punkte 1-5, 12)        |
   +=======================================================================+
   180px | 18 | minmax(0,1fr) | 20 | 480px

   EIN Kontextwert fuer ALLE Schritte. Die schrittabhaengigen Werte
   (380 / 430 / 450) sind entfernt - sie waren der Grund, warum das Layout
   immer wieder auseinanderlief (Ralph P12 woertlich).

   WARUM DIE GAPS EIGENE SPALTEN SIND: Ralph will 18px links und 20px rechts.
   CSS Grid kennt nur EIN column-gap fuer alle Spalten. Zwei verschiedene
   Abstaende gehen deshalb nur als echte Spalten - gap:0 und die Zwischenraeume
   ausgeschrieben. Das ist kein Trick, sondern die einzige Form, in der beide
   Zahlen wirklich stimmen. Folge: Rail=1, Mitte=3, Kontext=5. */
/* 🔴 15.08.2026 — WORK #23 (Ralph: „linker container also produkt bestandteile ist viel
   zu breit. ein drittel weniger breit."), Entscheid A: der Platz geht an die Etikettkarte.

   GEMESSENE URSACHE: die Mitte war `minmax(0,1fr)` und nahm damit ALLEN Restplatz. Sie
   war nicht zu breit eingestellt — sie hatte gar keine Obergrenze. Bei Ralphs Fenster
   (1908px) wurde sie 1162px, bei 1512px nur 766px. Derselbe Code, zwei Welten.

   GERECHNET, nicht geschaetzt (feRahmen bei Ralph rund 1860):
     vorher:  180 + 18 + 1162 + 20 + 480 = 1860
     jetzt:   180 + 18 +  780 + 20 + 640 = 1638, Rest 222 als Aussenrand
   Mitte -33 %, Kontext +33 %.

   WARUM NICHT EINFACH `.55fr` FUER DEN KONTEXT, wie ich es zuerst vorgeschlagen hatte:
   das haette die Mitte nur auf 1059 gebracht (-8 %) — Ralphs Wunsch waere nicht erfuellt
   gewesen. Und ein Kontext ganz ohne Obergrenze waere bei Zielbreite 867px geworden,
   breiter als die Bestandteiltabelle daneben; fuer eine Liste aus Text und Plakette ist
   das absurd. Beide Spalten brauchen deshalb eine Obergrenze, und der Rest wird Rand.

   🔴 `--kontext-breite` war als „Ralph P4: fest 480" markiert. Das ist mit diesem
   Entscheid ueberholt: 480 ist ab jetzt die UNTERgrenze, 640 die Obergrenze. Der Wert
   wird nirgends sonst ueberschrieben — die Zeile steht hier, damit niemand die alte
   Festlegung im naechsten Durchgang wiederherstellt (§28.5).

   Die Zwischenraeume bleiben echte Spalten bei gap:0 — siehe der Kommentarblock
   darueber. Wer das aendert, bringt die Rechnung durcheinander. */
body.riFokus #feRahmen{
  /* 🔴 23.08.2026, Work #181 — VON 180px AUF 0.
     Ralph: "der obere bereich ist immer noch viel zu breit, maximal so breit wie
     der untere bereich."

     GEMESSEN, und die Ursache war nicht der Kopf:
       grid-template-columns: 180px 700px 603px, gap 24px
       Der Inhalt begann dadurch bei 228px, der Kopf bei 24px.
     Die ersten 204px waren die Spalte des linken Streifens - und der steht im
     Fokusmodus auf display:none. Eine leere Spalte fuer ein verstecktes Element.

     🔴 MEIN EIGENER FEHLER, EINEN DURCHGANG VORHER: ich hatte gemeldet, die Rail
     koste "0 Pixel". Gemessen hatte ich ihre HOEHE (0) und daraus auf ihren
     Platzbedarf geschlossen. Ihre Spalte war die ganze Zeit 180px breit.
     Wer eine Flaeche beurteilt, muss beide Kanten messen.

     Ralph P3 ("fest 180") galt fuer den sichtbaren Streifen. Der Streifen ist im
     Fokusmodus weg, damit auch seine Spalte. Ausserhalb des Fokusmodus bleibt der
     Wert unveraendert - dort steht die Rail noch. */
  --rail-breite:    0px;     /* Fokusmodus: die Rail ist versteckt, ihre Spalte auch */
  /* 🔴 15.08.2026 abends — RALPHS EIGENE WERTE aus dem Stellrad, von ihm am Bild
     eingestellt und von mir im Browser gegengeprueft (Ueberlauf 0). Sie loesen
     meine Schaetzungen 780/640 ab: die waren gerechnet, diese sind gesehen. */
  --kontext-breite: 480px;   /* Untergrenze (Ralph P4) */
  /* 🔴 15.08.2026 SPAET — `--kontext-max` BLEIBT BEI 603. Ralph hatte Entscheid A
     getroffen (Deckel weg, Spalte nimmt den Rest), ich habe es gebaut, ANGESEHEN
     und wieder zurueckgenommen. Der Grund steht ganz unten unter ZURUECKGENOMMEN
     und ist wichtiger als der Rest dieses Blocks.

     Ausgangslage, die zu dem Entscheid gefuehrt hat:

     GEMESSEN an Ralphs Fenster (1919, Rahmen rund 1871):
       180 + 43 + 700 + 20 + 603 = 1546  ->  RUND 325 PX LAGEN RECHTS BRACH.
     Ralph hat das am Inspektor von Hand umbaut (.feKtxBlock auf 692, dazu
     margin-left 127) — also den Deckel umgangen statt ihn zu aendern. Genau das
     ist der Fehlertyp, den §4.2 meint: die Regel bleibt falsch, und daneben steht
     eine Handkorrektur, die beim naechsten Fenster nicht mehr passt.

     GEMESSEN vor dem Ablegen, per Style-Injektion im laufenden Browser
     (Build 3110, P73618, Viewport 1710, Rahmen 1662):
       vorher   180px 43px 700px 20px 603px   Kontext 603   Brache 116
       nachher  180px 43px 700px 20px 719px   Kontext 719   Brache 0
       Injektion entfernt, Rueckfall geprueft: wieder 603. Kein Rest.

     🔴 WAS DAS BEI 1919 BEDEUTET, damit es niemand uebersieht: dort werden aus
     603 rund 928. Die Kontextspalte ist dann BREITER als die Arbeitsmitte (700).
     Das ist die logische Folge von "nimm den Rest" und war so entschieden — aber
     es ist eine Formentscheidung, keine Rechenfolge. Soll die Nebenspalte nicht
     breiter werden als die Hauptspalte, ist der Weg NICHT ein neuer Deckel hier,
     sondern `minmax(var(--kontext-breite), min(1fr, var(--mitte-max)))`. Dann
     haengt die Grenze an der Mitte statt an einer zweiten Zahl, die jemand pflegen
     muss (§28.4).

     🔴 ZURUECKGENOMMEN — UND DAS IST DIE EIGENTLICHE LEHRE DIESES BLOCKS.
     Ralph: "schau es dir selber live mal an, kann doch nicht sein, dass du nicht
     siehst und messen kannst, was nicht passt." Er hatte recht. Beim ANSEHEN des
     Bildschirmfotos (Build 3110, P73618, Schritt 3, beide Aenderungen injiziert):

       Kontextspalte   719 px breit  ·  57 px HOCH
       Mitte           700 px breit  ·  1016 px hoch
       Inhalt der Kontextspalte: die eine Zeile "Referenzkarte nicht geladen."

     DIE BRACHE IST NICHT VERSCHWUNDEN, SIE IST IN DIE KARTE UMGEZOGEN. Meine
     Messung "Brache 116 -> 0" war richtig und trotzdem wertlos: gemessen wurde
     der Abstand zum Fensterrand, nicht die Leere. Eine Zahl kann gruen werden,
     waehrend das Bild schlechter wird — genau davor warnt §10.4 ("erst an der
     ausgelieferten Seite messen"), und ich habe es zum zweiten Mal an einem Tag
     uebersehen.

     DER TIEFERE FEHLER: die Spalte ist leer, WEIL DIE REFERENZKARTE NICHT LAEDT
     (Work #55). Ich habe eine Spaltenbreite an einem Zustand bemessen, in dem der
     Inhalt fehlt. Solange #55 offen ist, ist JEDE Breitenentscheidung fuer diese
     Spalte eine Messung am kaputten Zustand.

     REIHENFOLGE, DIE DARAUS FOLGT: erst #55 (Referenzkarte laedt), dann die
     Spalte mit echtem Inhalt ansehen, dann entscheiden. Nicht umgekehrt (§19.4,
     Daten vor Optik). */
  --kontext-max:    603px;   /* Ralph am Stellrad, 15.08. abends (vorher 640). Wirksam. */
  /* 🔴 15.08.2026 SPAET — WORK #43, Ralph-Entscheid A. 600 -> 690.
     GEMESSEN an RALPHS Fenster (1908x913), Browser-Build 2940, P73617 Schritt 3:
       .fgBestKopf brauchte 56+200+143+141+84 + 4x8 gap = 656 px.
       Bei --mitte-max 600 blieben #fe_pickList clientWidth 572 -> scrollWidth 664,
       also 92 px Ueberlauf. Alle fr-Anteile waren auf ihr Minimum kollabiert und
       die 5. Spalte (84px, Zeile entfernen) war ABGESCHNITTEN — es gab in Schritt 3
       keinen erreichbaren Entfernen-Knopf.
     WOHER DIE 90 px KOMMEN: aus dem Brachland rechts. Das Raster belegte
       180+43+600+20+603 = 1446 von 1860 px, 414 px lagen bei justify-content:start
       ungenutzt am rechten Rand. Niemand verliert Platz; --kontext-max 603 und
       Ralphs Spaltenwerte 200/143/141 aus Work #39 bleiben unangetastet.
     WARUM 700 UND NICHT 690: die ZEILE traegt column-gap 10 (Zeile 2224), der KOPF
       8 — gemessener scrollWidth 664, nicht 656. Bei 690 waere die Rechnung
       690-24-2 = 664 gegen 664 auf den Pixel aufgegangen, also ohne jede Reserve.
       700 gibt 674 gegen 664 = 10 px Luft. Eine Zahl, die exakt aufgeht, kippt beim
       naechsten laengeren Wort — und dann sucht wieder jemand einen halben Tag.
     WARUM DIE 600 UEBERHAUPT ZU ENG WAREN: bis 15.08. nachmittags standen hier
       780 px — da passte die Tabelle mit 752 px. Die Verkleinerung aus Work #23
       ("viel zu breit, ein drittel weniger breit") hat sie unter ihren Bedarf
       gedrueckt. Der Nebeneffekt war nie gemessen: die Pruefung "Ueberlauf 0" zu
       Work #39 stammt aus einem Versuch, bei dem der Tab noch auf Build 2720 lief
       und gar kein Produkt geladen war — alle Breiten kamen als 0 zurueck. */
  /* 🔴 23.08.2026, Work #181 — 700 auf 880.
     Ralph zweimal: "der obere bereich ist noch viel zu hoch."

     WARUM DAS EINE BREITENFRAGE IST: der Kopf ist an die Inhaltsbreite
     gekoppelt (er soll "maximal so breit wie der untere bereich" sein). Die
     Bedienelemente darin brauchen zusammen rund 1480px. Bei Mitte 700 ist der
     Kopf 1327 breit - es fehlen gut 150px, also bricht die Zeile um, und jede
     Umbruchzeile kostet 33px Hoehe. Die Hoehe war die Folge der Breite.

     WOHER DIE 180px KOMMEN: die Spalte des linken Streifens ist heute entfallen
     (er ist im Fokusmodus versteckt). Der Platz war schon frei, er lag nur
     ungenutzt rechts als Rand. 700 + 180 = 880.

     ⚠ 700 war Ralphs eigener Wert (Work #43, Entscheid A). Ich aendere ihn,
     weil seine Grundlage - die 180px-Spalte daneben - nicht mehr existiert und
     weil Ralph zweimal die Folge dieser Zahl bemaengelt hat. Rueckbau ist eine
     Zeile: hier wieder 700 eintragen. */
  --mitte-max:      880px;   /* 23.08. von 700 (Work #43 A); davor 600, davor 780 */
  /* 🔴 23.08.2026, Work #181 Stufe 1 — Ralph-Entscheid: die Abstaende links und
     rechts duerfen gleich sein. Damit fallen --gap-rail und --gap-kontext weg und
     werden zu EINEM echten gap. Vorher waren die Zwischenraeume eigene GRID-SPALTEN,
     weil CSS Grid nur ein column-gap kennt und Ralph zwei verschiedene Werte wollte.
     Das ist der Grund, warum die Kinder in Spalte 1, 3 und 5 standen - und warum ein
     Element, das in keiner Placement-Regel stand, im Zwischenraum landete und wie ein
     Balken aussah. Mit einem gap sind es wieder Spalte 1, 2, 3. */
  --raster-gap:      24px;   /* EIN Abstand fuer beide Seiten (vorher 43 und 20) */

  /* 🔴 23.08.2026, Work #181 — DIE RADIENSKALA.
     Gemessen waren im Editorbereich 21 verschiedene border-radius-Werte, darunter
     fuenf, die praktisch dasselbe meinen: 7, 8, 9, 10 und 12 Pixel. Das sieht man
     nicht als Fehler, aber man sieht die Unruhe - jeder Kasten ist minimal anders
     gerundet als sein Nachbar.
     Drei Stufen reichen, und sie haben eine Bedeutung:
       klein  Knoepfe, Eingabefelder, Reiter        -> das, was man anfasst
       mittel Kaesten INNERHALB einer Karte          -> das, was gruppiert
       gross  die Karte selbst                       -> das, was umschliesst
     Dieser Durchgang stellt NUR die Werte 7px und 9px auf klein um: 20 Regeln,
     alle Knoepfe/Felder/Reiter, optisch kaum unterscheidbar - aber die Uneinheit
     ist weg. 10px und 12px bleiben absichtlich stehen; das sind Kartenradien und
     eine eigene Entscheidung. Eine Sammelersetzung ueber alle Werte auf einmal
     waere genau der zu weite Schnitt, der am 15.08. zwei Dateien beschaedigt hat. */
  --fk-r-klein:       8px;
  --fk-r-mittel:     10px;
  --fk-r-gross:      12px;   /* EIN Abstand fuer beide Seiten (vorher 43 und 20) */
  gap: var(--raster-gap);
  grid-template-columns: minmax(0,var(--mitte-max));
  grid-template-rows: auto;
  /* 🔴 15.08.2026, NACHBESSERUNG am selben Tag — hier stand `justify-content:center`.
     GEMESSENE FOLGE bei Ralphs Fenster: (1908 − 1638) / 2 = 135 px Rand LINKS, und
     die Bedienleiste rutschte damit von der Bildschirmkante weg. Ralph: „links ist
     jetzt zu weit weg, abstand zu gross."
     Er hat recht, und der Denkfehler war meiner: ich habe den Rest „schoen verteilt",
     obwohl die Rail eine MENUELEISTE ist. Ein Menue gehoert an den Rand, nicht in die
     Mitte — sonst schwebt es. Der Rest gehoert nach rechts, wo nichts steht. */
  /* 🔴 23.08.2026, Work #181 — WIEDER AUF center, und diesmal mit Grund.
     Ralph heute: "es ist alles links ausgerichtet nicht mittig auf der seite."
     Am 15.08. hatte er das Gegenteil gesagt ("links ist jetzt zu weit weg") und
     der Wert wurde auf start gestellt. Beides war richtig - die Lage hat sich
     dazwischen geaendert:
       15.08.: links sass die Rail, eine MENUELEISTE. Ein Menue gehoert an den
               Rand, sonst schwebt es.
       23.08.: die Rail ist im Fokusmodus weg und ihre Spalte auf 0. Was jetzt
               links klebt, ist kein Menue, sondern der Arbeitsbereich - und der
               gehoert in die Mitte, mit gleichem Rand auf beiden Seiten.
     Der alte Wert war keine Fehlentscheidung, sondern eine, deren Grundlage
     entfallen ist. Wer ihn zurueckdreht, holt die Rail mit zurueck. */
  justify-content: center;
}
body.riFokus #feRahmen.riDrei{
  /* 23.08., Work #181 Stufe 1: drei Spalten statt fuenf. Die beiden Zwischenraum-
     Spalten sind zu einem gap geworden (Ralph-Entscheid: gleiche Abstaende).
     15.08. — `1fr` war hier fuer wenige Minuten eingebaut (Ralph-Entscheid A)
     und ist ZURUECKGENOMMEN. Warum, steht beim Variablenblock oben. */
  grid-template-columns:
    minmax(0,var(--mitte-max))
    minmax(var(--kontext-breite),var(--kontext-max));
}
/* 🔴 15.08.2026, NACHBESSERUNG — die Grenze stand zuerst bei 1400px und war FALSCH
   GERECHNET. Sie prueft den VIEWPORT, der Platz wird aber im RAHMEN verteilt, und der
   ist rund 48px schmaler.

   GEMESSEN an meinem eigenen Fenster (1512px Viewport, 1464px Rahmen):
     180 + 18 + Mitte + 20 + 640 = 1464  ⇒  Mitte = 606
   Die Mitte war damit SCHMALER als die 766 vor meiner Aenderung — der Kontext nimmt
   sich seine 640 zuerst, und der Rest bleibt der Mitte. Belegt am Ueberlauf:
   `fe_name` lief 120px heraus, der Produktname war abgeschnitten, die EAN-Chips
   brachen um. Aus „ein Drittel schmaler" war an schmalen Schirmen „die Haelfte
   schmaler und kaputt" geworden.

   > Eine Obergrenze fuer die eine Spalte ist eine Untergrenze fuer die andere.
   > Wer nur eine der beiden Zahlen prueft, misst die Haelfte.

   Die Deckelung greift jetzt erst ab 1700px Viewport — also genau dort, wo Ralphs
   Problem sitzt (1908) und wo wirklich Platz zu verteilen ist. Darunter gilt
   unveraendert der Stand vor dem 15.08.: Kontext fest 480, Mitte nimmt den Rest. */
@media (max-width: 1700px){
  body.riFokus #feRahmen{ justify-content:stretch;
    grid-template-columns: minmax(0,1fr); }
  body.riFokus #feRahmen.riDrei{
    grid-template-columns: minmax(0,1fr) var(--kontext-breite); }
}
/* Explizites Placement - kein Auto-Placement, in keinem Zustand. */
/* 🔴 23.08. Die Rail hat im Fokusmodus KEINE Spalte mehr (sie ist versteckt,
   und ihre 180px-Spur war der Grund, warum der Inhalt 204px weiter rechts
   begann als der Kopf). Sie behaelt ein Placement, damit sie nicht ins
   Auto-Placement faellt und eine neue Spur aufmacht - sie liegt auf derselben
   Zelle wie der Arbeitsbereich und ist display:none. */
body.riFokus #feRahmen > #feRail{       grid-column:1; grid-row:1 }
body.riFokus #feRahmen > #feEditorBody{ grid-column:1; grid-row:1; min-width:0 }
body.riFokus #feRahmen.riDrei > #feKontext{
  grid-column:2; grid-row:1; width:100%; max-width:100%; min-width:0 }
/* 🔴 15.08.2026 — DER „KOMISCHE BALKEN", den Ralph zweimal gemeldet hat.
   GEMESSEN: `#fe_naehrKacheln` ist ein direktes Kind von `#feRahmen`, steht aber in
   KEINER der drei Placement-Regeln darueber. Der Kommentar dort verspricht „kein
   Auto-Placement, in keinem Zustand" — fuer dieses eine Element galt das nie.
   Folge: es landete automatisch in Spalte 2, und Spalte 2 ist der ZWISCHENRAUM
   (`--gap-rail` als echte Spalte). Die Kacheln wurden also auf 18 px zusammen-
   gequetscht und sahen aus wie ein Streifen hinter dem Inhalt. Mit Ralphs neuen
   43 px Abstand wurde der Streifen breiter und damit noch auffaelliger.

   Warum ich es nicht selbst gefunden habe: in Schritt 3 steht das Element auf
   `display:none`, und ich habe an Schritt 3 gemessen. Es erscheint nur in Schritt 2.
   Ich hatte den Balken als „nicht reproduziert" offengelassen statt eine Ursache zu
   behaupten — richtig so, denn ich haette die falsche geraten.

   Es liegt jetzt in derselben Spalte wie der Editorinhalt, unter ihm. Das ist die
   Stelle, an die es fachlich gehoert: es sind Kennzahlen ZU den Naehrwerten darueber.
   (Ralphs Wunsch „mini oben in die weisse Leiste, Klick vergroessert" ist die
   naechste Stufe und steht als Work #39 — hier wird erst der Fehler geschlossen.) */
body.riFokus #feRahmen > #fe_naehrKacheln{ grid-column:1; grid-row:2; min-width:0 }
/* Ralph P9: ohne Kontext KEIN reservierter Leerraum - die Spalte existiert nicht,
   die Mitte nimmt den Platz mit. */
body.riFokus #feRahmen:not(.riDrei) > #feKontext{ display:none !important }
/* Schritt 2 Analyse — das Etikett rechts muss LESBAR sein (Ralph: 380-420). */
/* 15.08. ENTFERNT: 410 wurde unten von 360 ueberschrieben, war also tot. */
/* Schritt 3 Bestandteile — Referenz rechts (Ralph: 360-400), Tabelle nicht quetschen. */
/* Schritt 1 Kopf & Quelle — Formularfelder brauchen rechts weniger. */

/* --- Die Mitte: EINE Breite fuer alle Karten ------------------------------- */
/* Ohne rechte Spalte darf sie wachsen (Ralph: 1100-1200), sonst fuellt sie das
   Raster. Der alte 820er-Deckel ist damit abgeloest — er stand fuer alle Schritte
   gleich und liess rechts Leerraum stehen. */
/* 15.08. ENTFERNT (Ralph P5): keine 820/900/1080/1180px im Fokusmodus innerhalb
   der mittleren Spalte. Der aeussere Grid-Vertrag bestimmt die Breite. */
body.riFokus #feEditorBody{ max-width:none; width:100%; min-width:0 }
/* 🔴 ZWEITE Stelle mit demselben fragilen Selektor — vom Test gefunden, nicht
   von mir erinnert. Sie hing an derselben Textsuche und war damit genauso
   zufaellig. Jetzt an derselben Klasse wie das Raster. */
/* (Sonderfall gegenstandslos - die Mitte hat generell keinen Deckel) */
body.riFokus #feKopfGrid,
body.riFokus #feAbschluss,
body.riFokus #feAbgleich,
body.riFokus #fe_gridA,
body.riFokus .feHolBox,
body.riFokus #feNwOben,
body.riFokus #fe_naehrKacheln,
body.riFokus #fe_mikroWrap,
body.riFokus #feSchrittKopf,
body.riFokus #feSchrittFuss{ width:100%; max-width:none; box-sizing:border-box }
/* Gleiche Innenabstaende und gleicher Radius fuer die Hauptkarten aller Schritte.
   🔴 23.08.2026 — HIER STAND `border-radius:12px` FEST. Das war ein zweiter Besitzer:
   .feKarte fuehrt die Variable --fk-radius, und diese Regel hat sie mit einem harten
   Wert ueberschrieben. Live gemessen: --fk-radius stand auf 16px, berechnet kamen 12px
   heraus - die Variable war wirkungslos, ohne dass man es ihr ansieht.
   Das ist die schlimmere Sorte Doppelbesitz: wer die Variable aendert, sieht keine
   Wirkung und sucht den Fehler an der falschen Stelle. Genau dagegen habe ich heute
   frueh einen Test gebaut - fuer den RAHMEN, nicht fuer die Karten.
   Jetzt liest auch diese Regel die Variable. */
body.riFokus #feEditorBody .feKarte,
body.riFokus #feEditorBody .cardF{ border-radius:var(--fk-radius,12px) }

/* --- Schritt 4: zwei Abschnitte UNTEREINANDER ------------------------------ */
/* `#feTab1` und `#feAbgleich` teilen sich sonst die Zelle 2/1 und laegen
   uebereinander. Hier bekommt der Abgleich eine eigene Zeile. */
body.riFokus[data-fe-schritt="bestand"] #feEditorBody{
  grid-template-rows:auto auto auto auto;
}
body.riFokus[data-fe-schritt="bestand"] #feEditorBody > #feAbgleich{
  grid-area:3 / 1; align-self:start; margin-top:6px;
}
body.riFokus[data-fe-schritt="bestand"] #feEditorBody > #feSchrittFuss{ grid-area:4 / 1 }
/* Die beiden Abschnitte bekommen sichtbare Ueberschriften — sonst geht Bio in der
   Abgleichtabelle unter, und genau das soll nicht passieren (Ralph Punkt 2). */
body.riFokus[data-fe-schritt="bestand"] #fe_gridA::before,
body.riFokus[data-fe-schritt="bestand"] #feAbgleich::before{
  display:block; font-size:9.5px; letter-spacing:.07em; text-transform:uppercase;
  font-weight:800; color:var(--muted); margin:0 0 8px;
}
body.riFokus[data-fe-schritt="bestand"] #fe_gridA::before{ content:"A · Bestandteile"; grid-column:1/-1 }
body.riFokus[data-fe-schritt="bestand"] #feAbgleich::before{ content:"B · Etikett & Abgleich" }

/* --- Navigation oben links in der Rail ------------------------------------ */
#feRailNav{ display:flex; flex-direction:column; gap:7px; padding:0 0 11px;
  margin-bottom:11px; border-bottom:1px solid var(--line) }
#feRailNav #feNavPost{ width:100%; text-align:left }
/* 🔴 16.08.2026 — RALPH: "weiterschalten chip ragt ueber weissen kasten hinaus."
   URSACHE: die drei Teile („‹ Vorheriges", „1 / 100", „Naechstes ›") standen in einer
   Zeile, die weder umbrechen noch schrumpfen durfte — `flex:0 0 auto` an den Knoepfen
   und kein `flex-wrap` am Container. Zusammen brauchen sie mehr als die Rail innen breit
   ist (180 px minus 2x12 Innenabstand = 156 px), also liefen sie ueber die Kartenkante.
   Sichtbar wurde es erst, seit die Rail eine weisse Karte mit Kante IST (Work #48, heute
   frueh) — vorher lief derselbe Ueberlauf ueber einen unsichtbaren Rand und fiel nicht auf.
   Ein Fehler wird nicht dadurch neu, dass man ihn endlich sieht.

   GELOEST OHNE FESTE ZAHL: umbrechen erlaubt und schrumpfen erlaubt. Passt es, bleibt es
   einzeilig wie bisher; passt es nicht, rutscht „Naechstes ›" in die zweite Zeile statt
   aus der Karte. Damit haelt es auch bei einer breiteren oder schmaleren Rail, ohne dass
   jemand eine Breite nachpflegen muss (§28.4). */
#feRailNav #feNavBlaett{ display:flex; align-items:center; gap:5px;
  justify-content:space-between; flex-wrap:wrap; min-width:0 }
#feRailNav #feNavBlaett button{ padding:5px 8px !important; font-size:11.5px !important;
  border-radius:7px !important; flex:0 1 auto; min-width:0 }
#feRailNav #feNavBlaett > span{ font-size:11.5px !important; flex:0 0 auto }
body.riFokus #feNavLeiste{ display:none !important }

/* --- Quelle: der Aufklappzustand ist sichtbar ------------------------------ */
.feQuelleFertig.offen{ border-style:dashed }
.feQuelleFertig.offen + .feHolGrid{ margin-top:8px }

/* ============================================================================
   RUECKWEG AUS DER KOMPLETTANSICHT (Ralph 14.08.2026)
   Sie ist seit diesem Build fluechtig. Der Rueckweg steht deshalb sichtbar oben
   im Arbeitsbereich — ein Modus ohne Ausgang waere eine Falle.
   ============================================================================ */
.feZurueckFokus{ display:flex; align-items:center; gap:11px; flex-wrap:wrap;
  padding:9px 12px; margin-bottom:12px; border:1px solid var(--k-2f6fd6,#2f6fd6);
  border-radius:10px; background:var(--k-eef6ff,#eef6ff) }
.feZurueckFokus button{ flex:0 0 auto; border:0; border-radius:8px; cursor:pointer;
  background:var(--k-2f6fd6,#2f6fd6); color:#fff; font-size:12.5px; font-weight:700;
  padding:7px 13px }
.feZurueckFokus span{ font-size:11.5px; color:var(--muted); line-height:1.45; min-width:0 }
body.riFokus .feZurueckFokus{ display:none !important }

/* ============================================================================
   STATUSSTREIFEN IN ZWEI ZONEN + PRODUKTKOPF DER RAIL (Ralph 15.08.)
   ============================================================================ */
.feStStreifen{ display:flex; gap:14px; flex-wrap:wrap; align-items:center;
  padding:8px 12px; border:1px solid var(--line); border-radius:10px;
  background:var(--card); margin-bottom:12px }
.feStLinks{ display:flex; gap:6px; flex-wrap:wrap; align-items:center; flex:1 1 auto; min-width:0 }
/* 🔴 20.08.2026, Work #133 E6 — RALPH-ENTSCHEID A.
   Zur Wahl standen: (A) Streifen behalten, nur die Index-Kachel absetzen ·
   (B) den ganzen Streifen zur Label/Wert-Zeile umbauen wie im DBKR-Entwurf ·
   (C) beides untereinander. Ralph: "a".

   Der Grund fuer A ist nicht Bequemlichkeit: der Streifen ist Ralphs eigener
   Entwurf vom 15.08., in dreizehn Punkten abgestimmt — zwei Zonen, die Gruppen
   "Datenstatus" und "Pruefung", Hinweise UNTER den Chips statt daneben,
   "nicht wie eine Reihe Bonbons". Ihn umzubauen haette diese Arbeit
   ueberschrieben, um eine Vorlage zu treffen.

   GEAENDERT WIRD NUR DIE RECHTE ZONE: Trennstrich, Label oben, Zahl gross,
   Freigabechip darunter — die Index-Kachel aus dem DBKR-Vorbild. Am HTML
   aendert sich NICHTS; _feStreifenBewertung bleibt unangetastet. */
.feStRechts{ display:flex; flex-direction:column; align-items:flex-end; gap:5px;
  flex:0 0 auto; margin-left:auto; text-align:right;
  border-left:1px solid var(--line); padding-left:16px; align-self:stretch;
  justify-content:center }
.feStFuss{ flex:1 1 100%; display:flex; gap:8px; flex-wrap:wrap }
/* Die Kachel: Label ueber der Zahl statt daneben. Aus dem inline-flex mit
   baseline wird eine Spalte — deshalb steht em jetzt auf display:block. */
.feStBew{ display:flex; flex-direction:column; align-items:flex-end; gap:1px; white-space:nowrap }
.feStBew em{ font-style:normal; font-size:9.5px; letter-spacing:.07em;
  text-transform:uppercase; font-weight:800; color:var(--muted); display:block }
.feStBew b{ font-size:26px; font-weight:800; line-height:1.05 }
.feStBew i{ font-style:normal; font-size:11.5px; font-weight:700 }
.feStBew.still b, .feStBew.still i{ color:var(--muted) }
.feStBew.still b{ font-size:15px }
.feStBew.fehlt b{ font-size:12.5px; color:var(--k-92400e,#92400e) }
.feStBew.fehlt i{ color:var(--muted) }
/* Zahl und Wort nebeneinander, wenn beide da sind — "58 schwach" liest sich als
   eine Aussage. Bei "still" und "fehlt" traegt b den ganzen Satz, dann bleibt es
   untereinander. */
.feStBew:not(.still):not(.fehlt){ flex-direction:column }
.feStBew:not(.still):not(.fehlt) b{ display:inline }
.feStBew:not(.still):not(.fehlt) i{ display:inline; margin-left:6px }
.feStDub{ flex:1 1 100%; font-size:11px; color:var(--muted); line-height:1.5 }
.feStDub.rot{ color:var(--k-b91c1c,#b91c1c); font-weight:700 }

/* --- Produktkopf: Status, Speichern, Freigeben ----------------------------- */
#feProdStatusPfeil{ opacity:.6 }
.feProdStatus{ display:flex; align-items:center; justify-content:space-between;
  width:100%; margin:8px 0 4px; padding:6px 10px; border-radius:8px; cursor:pointer;
  font-size:12px; font-weight:700; border:1px solid var(--line); background:var(--card) }
.feProdStatus.entwurf{ background:var(--k-fbf3e2,#fbf3e2); color:var(--k-c88616,#c88616);
  border-color:var(--k-eddcb6,#eddcb6) }
.feProdStatus.aktiv{ background:var(--k-e7f6ec,#e7f6ec); color:var(--k-1f7d43,#1f7d43);
  border-color:var(--k-bfe3cb,#bfe3cb) }
.feProdStatus[disabled]{ opacity:.5; cursor:default }
.feProdStatusPfeil{ opacity:.55; font-weight:400 }
.feProdZust{ font-size:10.5px; color:var(--muted); margin-bottom:8px }
.feProdFrei{ width:100%; margin-top:7px; padding:8px 12px; border:0; border-radius:8px;
  background:var(--k-16a34a,#16a34a); color:#fff; font-size:12.5px; font-weight:700; cursor:pointer }
.feProdFrei[disabled]{ background:var(--k-eef1f4,#eef1f4); color:var(--muted); cursor:default }
.feProdFrgTxt{ font-size:10.5px; margin-top:4px; line-height:1.4 }
.feProdFrgTxt.ok{ color:var(--muted) }
.feProdFrgTxt.rot{ color:var(--k-b91c1c,#b91c1c) }

/* --- Die ausgeliehene Referenzkarte fuellt den Kontextplatz ---------------- */
/* 🔴 15.08.2026 BEFUND (Ralph P4: „nur ein flacher weisser Streifen mit Titel"):
   URSACHE, gemessen — eine Kette aus drei Elementen, die alle ihre Hoehe vom
   Elternteil beziehen:
     `#fe_colRef`      hat im Kontextplatz KEINE Hoehe (im Original kam sie von
                        `fe_gridA` mit `height:calc(100vh - X)`)
     `#fe_flipWrap`    inline `height:100%`  → also 0
     die Karte `cardF` inline `height:100%`  → also 0
     `#fe_refFront`    `position:absolute; inset:0` in 0 Hoehe → unsichtbar
   Uebrig blieb genau der Titel, den `cardF` ausserhalb der Flaeche zeichnet.

   Meine Regel von 0215 (`#fe_flipWrap{ height:clamp(...) }`) konnte NIE greifen:
   inline schlaegt jede Stylesheet-Regel. Das ist die DRITTE Stelle dieser Art an
   einem Tag — nach dem Wirkstoffraster und den Tabellenkoepfen.

   LOESUNG ohne !important: die Hoehe kommt an `#fe_colRef`. Damit hat `height:100%`
   endlich einen Bezug, und die ganze Kette rechnet von selbst richtig. */
.feKtxInhalt > #fe_colRef{ width:100%; min-width:0; display:flex; flex-direction:column;
  height:clamp(340px,56vh,640px) }

/* ============================================================================
   DESKTOP-FEINSCHLIFF 15.08.2026 (Ralph, Punkte 2-8, 10, 12-14)
   Nur Optik und Raum. Keine Regel, keine Schwelle, keine Logik.
   ============================================================================ */

/* --- 2+3. Der weisse Balken IST der Produktkopf --------------------------- */
.feStStreifen{ align-items:flex-start; padding:11px 14px; gap:16px }
/* 🔴 20.08.2026, Work #133 E3b: HIER STANDEN .feStIdent, .feStPid, .feStMarke,
   .feStName und .feStMeta - die Identitaetsspalte des Streifens (Work #23,
   Ralph 15.08.). Sie sind mit ihrer Funktion _feStreifenIdent GELOESCHT: die
   fuenf Angaben stehen jetzt im dunklen Kopfband (#feKopfband, weiter oben in
   dieser Datei). Totes CSS ist die naechste Stelle, die jemand fuer gueltig
   haelt und wiederbelebt. */
.feStLinks{ padding-top:2px }

/* --- Work #23: der Kopfstreifen bleibt beim Scrollen stehen ----------------
   Ralph 15.08.: „obere weisse zeile fixieren".
   GEMESSEN, welches Element wirklich scrollt: `#panel` hat `overflow-y:auto`
   (scrollHeight 951 gegen clientHeight 813) — NICHT das Fenster und nicht
   `#overlay`. `position:sticky` wirkt nur im scrollenden Vorfahren, deshalb
   haette `top:0` an einem beliebigen Container nichts getan. Nachgesehen,
   nicht angenommen.
   Der Streifen ist 76px hoch; er bekommt einen eigenen Hintergrund, sonst
   scrollt der Inhalt sichtbar durch ihn hindurch. */
#panel > #fe_gesamtstatus{
  position:sticky; top:0; z-index:40;
  background:var(--card,#fff);
  box-shadow:0 1px 0 var(--line), 0 6px 14px -12px rgba(0,0,0,.35);
}

/* ============================================================================
   🔴 17.08.2026 — RALPHS VERDICHTUNG, Inspektor 13:56 an Build 3790 (1919x935).
   Option A gilt: seine Zahlen sind die Messung. Bei diesen vier Werten IST der
   Abstand die Ursache — es gibt keine versteckte Regel dahinter, nur Luft, die
   sich ueber mehrere Umbauten aufaddiert hat. Deshalb stehen sie hier GEBUENDELT
   und dokumentiert statt als sechs verstreute Inspektor-Margins:
     Statusstreifen   17 px hoeher   (in das Panel-Polster hinein)
     Rahmen           10 px hoeher   (an den Streifen heran, Luecke 12 -> 2)
     A·Bestandteile   22 px hoeher   (margin-top 2 -> -20, die Sektionsluft)
     Kontext-Reiter   48 px tiefer   (Referenz/Etikett/Rohtext beginnen jetzt
                       auf Hoehe der weissen Karte, nicht auf Hoehe des
                       Schrittkopfs — vorher hingen sie oben im Leeren)
   Gemessen vor dem Ablegen per Injektion an 1710; Ralphs Werte stammen von 1919.
   Beides sind Margins, keine Breiten — fensterunabhaengig. */
#panel > #fe_gesamtstatus{ margin-top:-17px }
body.riFokus #feRahmen{ margin-top:-10px }
body.riFokus[data-fe-schritt="bestand"] #feTab3 #fe_gridA{ margin-top:-20px } /* zwei IDs — muss Zeile 912 (#feTab3 #fe_gridA, mt 2px) schlagen; vierter Spezifitaets-Fall dieser Art */
body.riFokus #feKontext .feKtxTabs{ margin-top:48px }
/* Flip-Karte, oberes Kind 7 px hoeher — Ralphs Punkt 3. Der Pfadselektor ist
   von seinem eigenen Werkzeug als bruchgefaehrdet markiert; es gibt an diesem
   Kind keine Klasse. Bricht der naechste Umbau ihn, faellt nur diese eine
   Feinjustierung weg, nichts Tragendes. */
#fe_flipInner > div:nth-of-type(1) > div{ margin-top:-7px }

/* --- 13. Score deutlich, aber kompakt ------------------------------------- */
.feStRechts{ flex-direction:column; align-items:flex-end; gap:5px }
.feStBew{ align-items:baseline; gap:5px }
.feStBew em{ font-size:9px }
.feStBew b{ font-size:17px }          /* 0215 hatte 19 - Ralph: „kein riesiger Score" */
.feStFrg{ display:flex }

/* --- 5+6+7. Rail-Aktionen als Pills --------------------------------------- */
#feProdKopf{ padding:0 0 12px }
.feProdZeile{ margin-bottom:2px }
.feProdStatus{ width:auto; display:inline-flex; gap:7px; margin:9px 0 3px;
  padding:4px 11px; border-radius:999px; font-size:11.5px }
.feProdStatus::before{ content:"●"; font-size:9px; line-height:1 }
.feProdStatus.aktiv::before{ content:"✓" }
.feProdZust{ margin-bottom:9px }
.feProdSave, .feProdFrei{ width:auto; display:inline-flex; align-items:center; gap:6px;
  padding:6px 14px; border-radius:999px; font-size:12px; font-weight:700 }
.feProdSave::before{ content:"💾"; font-size:11px }
.feProdFrei{ margin-top:7px }
.feProdFrei::before{ content:"✓"; font-size:11px }
.feProdFrei[disabled]::before{ opacity:.5 }

/* --- 7+8. Navigation als Chips, echtes Disabled ---------------------------- */
#feRailNav{ gap:9px; padding-bottom:12px; margin-bottom:12px }
#feRailNav #feNavPost{ width:auto !important; display:inline-flex;
  padding:5px 13px !important; border-radius:999px !important;
  font-size:12px !important; font-weight:600 !important }
#feRailNav #feNavBlaett{ gap:4px }
#feRailNav #feNavBlaett button{ padding:4px 9px !important; border-radius:999px !important;
  font-size:11px !important; font-weight:600 !important }
/* Ralph P8: nicht so tun, als waeren sie klickbar. */
#feRailNav #feNavBlaett button[disabled],
#feRailNav #feNavBlaett button:disabled{
  opacity:.42; cursor:default !important; pointer-events:none;
  background:transparent !important; border-color:var(--line) !important }
#feRailNav #feNavBlaett button:not([disabled]):hover{
  border-color:var(--k-2f6fd6,#2f6fd6) !important; color:var(--k-2f6fd6,#2f6fd6) !important }

/* --- 14. Rail ruhiger: Trennlinien statt Kartenoptik ---------------------- */
/* 🔴 15.08.2026 SPAET — DIESE ZEILE HAT WORK #48 STILL AUFGEHOBEN. Dritter Fall
   desselben Fehlertyps an einem Abend (nach #feKopfLayout und feKachelBreiteSync):
   eine spaetere, spezifischere Regel loescht eine fruehere, ohne dass es jemand merkt.

   WAS RALPH WOLLTE (Work #48, 15.08. abends, mit Bild): "was aber nicht passt, ist das
   menue, das soll auch weiss hinterlegt sein." Daraufhin bekam #feRail (ui.css 115)
   background:var(--card), border-right und padding — die Rail sollte eine Karte sein
   wie jede andere, weil sie als einziger grauer Block zwischen weissen wie
   "ausgegraut, nicht benutzbar" gelesen wurde.

   WAS HIER STAND: `body.riFokus #feRail{ background:transparent; border:0; padding:0 }`
   Spezifitaet (1,1,1) gegen (1,0,0), und ausserdem 2000 Zeilen spaeter. Im Fokusmodus —
   also in JEDER Ansicht, die Ralph benutzt — war die Rail damit weiterhin durchsichtig,
   randlos und ohne Innenabstand. Work #48 stand seit Stunden auf "open" und niemand
   wusste, warum die Aenderung nichts bewirkt.

   ES BLEIBT KEIN DRITTER ORT: die Rail-Optik steht ab jetzt ausschliesslich bei
   #feRail (ui.css 115). Wer sie aendern will, aendert sie dort — hier steht nichts
   mehr, was ihr widerspricht (§4.2).

   Der Abschnittstitel "Trennlinien statt Kartenoptik" bezog sich auf die Karten INNEN
   in der Rail (#feProdKopf, die Gruppentitel) — nicht auf die Rail selbst. Diese Regeln
   stehen unveraendert darunter und tun weiterhin genau das. */
body.riFokus #feRail{ /* Optik bewusst leer — sie gehoert zu #feRail, ui.css 115 */ }
#feProdKopf{ border-bottom:1px solid var(--line); margin-bottom:13px }
#feFokusNav{ padding-top:2px }
#feFokusNav .feStTitel{ margin-bottom:7px }

/* --- 10. Schritt 4 optisch zusammenziehen --------------------------------- */
/* 0215 liess die Rasterzeile 2 auf `1fr` wachsen — daher die grosse Luecke
   zwischen Eigenschaften und Abgleich. Jetzt folgen beide ihrem Inhalt. */
body.riFokus[data-fe-schritt="bestand"] #feEditorBody{
  grid-template-rows:auto auto auto 1fr; align-content:start;
}
body.riFokus[data-fe-schritt="bestand"] #feEditorBody > #feTab3{ align-self:start }
body.riFokus[data-fe-schritt="bestand"] #feEditorBody > #feAbgleich{ margin-top:24px }
body.riFokus[data-fe-schritt="bestand"] #feEditorBody > #feSchrittFuss{ align-self:end }


/* --- 12. Statusstreifen farbruhiger --------------------------------------- */
.feStLinks > span{ font-weight:600 }

/* ============================================================================
   LAYOUTKORREKTUR 15.08.2026 (Ralph nach Live-Blick)

   „Alte interne Grid-Regeln funken noch durch das neue aeussere Raster."
   Genau so war es. Zwei Ursachen, beide an der Wurzel behoben:

     1. `#feTab3 .feListKopf` setzte DREI Spalten, `.fgBestZeile` FUENF —
        die Kopfzeile traegt beide Klassen, und der ID-Selektor gewann.
     2. Das Wirkstoffraster stand INLINE im style-Attribut und schlug damit
        jede Stylesheet-Regel. Inline gewinnt immer.

   Ab hier haben beide Tabellen genau EINEN Spaltenvertrag, als Variable.
   ============================================================================ */

/* --- 1+2. Bestandteiltabelle: ein Vertrag, Ralphs Masse -------------------- */
/* 🔴 15.08.2026 — RALPHS WERTE AUS DEM STELLRAD, im Browser gegengeprueft.
   Er hat sie selbst eingestellt und abgelesen; ich habe sie nachgemessen, statt sie
   nur zu uebernehmen: Tabellenkopf Ueberlauf 0, Liste Ueberlauf 0.

   🔴 DIE SECHSTE ZAHL, die im Stellrad KEINEN Regler hatte: die Namensspalte stand
   auf 260 und wurde vom Werkzeug still auf 200 gesenkt. Ralphs Werte gelten NUR
   zusammen damit — ohne sie braucht die Tabelle 60px mehr und kippt bei Mitte 600
   sofort in den Scrollbalken. Haette ich nur seine fuenf Zahlen eingebaut, waere das
   Layout gekippt und die Ursache unauffindbar gewesen.
   > Jede Zahl, die ein Werkzeug veraendert, braucht einen Regler. Keine stillen Werte.
   Das Stellrad bekommt den sechsten Regler nachgereicht (Work #39).

   Rechnung: 56 + 200 + 143 + 141 + 84 = 624 plus Gaps — passt in die 600er Mitte,
   weil die fr-Anteile nachgeben; die MINIMA sind das, was kippt. */
/* 🔴 16.08.2026 — WORK #37, RALPH-ENTSCHEID A: "Spaltenminima senken statt Mitte
   verbreitern." Nur die beiden MITTLEREN Minima gehen herunter, sonst nichts.

     VERARBEITUNG   143 -> 110
     ZUSATZSTOFF    141 -> 118

   WARUM GERADE DIESE ZWEI: sie sind bei den meisten Produkten LEER. Gemessen an
   P73618 stand bei ALLEN 13 Bestandteilen in beiden Spalten nur "–". Sie belegten
   also 284 px Mindestbreite fuer einen Gedankenstrich, waehrend BESTANDTEIL und WERT
   den Platz brauchen. 110 traegt "unspecified_processing" nicht aus — muss es auch
   nicht, das ist der Fall, in dem "–" steht. Der laengste ECHTE Wert, den die Spalte
   heute zeigt, ist ein Verarbeitungsbegriff plus Stift; dafuer reicht es.

   RECHNUNG, Minima plus vier Gaps a 10 (body.riFokus setzt column-gap:10, ui.css 2375):
     vorher   56 + 200 + 143 + 141 + 84 + 40 = 664
     jetzt    56 + 200 + 110 + 118 + 84 + 40 = 608
   Bei der heutigen Mitte von 700 sind das 92 px Luft statt 36. Die fr-Anteile
   (1.8 / .8 / .9) bleiben unangetastet — bei genug Platz sieht die Tabelle also aus
   wie bisher, sie kippt nur nicht mehr, wenn es eng wird.

   RALPHS URSPRUENGLICHE ZAHLEN 200/143/141 aus Work #39 BLEIBEN STEHEN, wo sie
   tragen: die Namensspalte hat er selbst am Stellrad eingestellt, und die faellt
   hier nicht an. Geaendert wird nur, was fuer leere Zellen reserviert war.

   🔴 NICHT AM BILD GEPRUEFT. Die Rechnung sagt, es passt; ob 110 px fuer den
   laengsten echten Verarbeitungsbegriff reichen, entscheidet der Bildschirm.
   Wer das abnimmt, sucht ein Produkt MIT gefuellter Verarbeitungsspalte — bei
   P73618 sind alle 13 leer und beweisen daher nichts. */
#fe_colZut{
  --best-spalten: 56px minmax(200px,1.8fr) minmax(110px,.8fr) minmax(118px,.9fr) 84px;
}
/* Rueckfall fuer die alte Ansicht ohne Fokus - dort ist die Karte schmaler. */
body:not(.riFokus) #fe_colZut{
  --best-spalten: 44px minmax(0,1.5fr) minmax(0,1fr) minmax(0,1.3fr) 52px;
}
.fgBestKopf, .fgBestZeile{ width:100%; min-width:0 }
/* Bestandteil waechst zuerst, Wert bleibt kompakt (Ralph P2). */
.fgbName{ min-width:0; overflow-wrap:anywhere }
.fgbWert{ white-space:nowrap }
.fgbVerarb, .fgbZus{ min-width:0; overflow-wrap:anywhere }
/* KORREKTUR an mir selbst (15.08.): `.fgbOrig` gibt es nicht — die Etikettzeile
   wird als <span> mit Inline-Style erzeugt. Geregelt wird deshalb der Kindknoten,
   nicht eine erfundene Klasse. Eine CSS-Regel auf einen nicht existierenden
   Selektor ist kein harmloser Rest, sondern eine Behauptung, die nie greift. */
.fgbName > span{ display:block; white-space:normal; overflow-wrap:anywhere }
body.riFokus #fe_colZut .feListe,
body.riFokus #fe_pickList{ min-width:0 }

/* --- 5. Mineralstoff-/Wirkstofftabelle: ein Vertrag, Ralphs Masse ---------- */
#fe_wirkCard{
  /* 15.08. (Ralph P1): EINHEIT von 80 auf 92px. Die Liste enthaelt `I.E.` und
     `µg` — bei 80px war die Auswahl kaum lesbar, und genau das laesst eine
     echte Auswahl wie ein festes `mg` aussehen. Die LISTE selbst ist
     unveraendert: WIRK_EINHEITEN, an genau einem Ort. */
  /* 15.08. (Work #7): ZEICHEN-Spalte vor der Menge, 58px. Ralph: „<0,5 g darf
     nicht zu 0,5 g werden." Das Zeichen gehoert neben die Zahl, nicht in sie —
     `fwMenge` ist ein type=number-Feld und wuerde „<0,5" komplett verwerfen
     (derselbe Fehler wie beim %NRV-Feld am 13.08.). */
  --wirk-spalten: minmax(0,1fr) 58px 100px 92px 90px 40px;
}
body:not(.riFokus) #fe_wirkCard{
  --wirk-spalten: 1fr 48px 70px 62px 56px 26px;
}
#feTab2 .feWirkKopf{ grid-template-columns:var(--wirk-spalten) }
#feTab2 .feWirkRow .fwName,
#feTab2 .feWirkRow .fwNameCell{ min-width:0 }
/* Die erklaerende Zeile darunter bricht um, statt zu ueberlagern. */
#feTab2 .feWirkRow .fwNote{ grid-column:1 / -1; white-space:normal;
  overflow-wrap:anywhere; line-height:1.45 }

/* --- 4. Schritt 2: Mitte breiter, Etikett Kontext statt Hauptinhalt -------- */
/* Das zweispaltige `#feTab2 #feNwOben` reservierte im Fokus weiter eine
   360px-Spalte fuer den Etikettplatz — obwohl der laengst als Reiter rechts
   haengt. Das war der grosse Leerraum in der Mitte. */
body.riFokus #feTab2 #feNwOben{ grid-template-columns:minmax(0,1fr) }
/* (abgeloest 0930 — siehe Bugfix-Block) */

/* --- 3. Referenzkarte rechts vollstaendig sichtbar ------------------------- */
/* Nur noch das, was oben nicht steht — zwei Regeln fuer dasselbe Element waeren
   genau die Schicht, die vermieden werden soll. */
.feKtxInhalt > #fe_colRef{ overflow:visible }
.feKtxInhalt > #fe_colRef .feKarte,
.feKtxInhalt > #fe_colRef > div{ width:100%; min-width:0; max-width:none }
.feKtxInhalt > #fe_colRef #fe_enthalten{ min-width:0; overflow-wrap:anywhere }
/* Der Kartentitel darf umbrechen statt abgeschnitten zu werden. */
.feKtxInhalt > #fe_colRef .feKartenTitel,
.feKtxInhalt > #fe_colRef > div > div:first-child{ white-space:normal; min-width:0 }

/* --- 8. Rail schmaler, Name darf umbrechen -------------------------------- */
/* 15.08. ENTFERNT: 220px steht seit dem Bugfix in der Basisdefinition des
   Rasters. Ein zweiter Ort fuer denselben Wert ist eine Schicht, kein Feinschliff. */
.feProdTxt b{ white-space:normal; overflow-wrap:anywhere; line-height:1.3 }
/* 11. Die P-Nummer der Rail bleibt klein - gross steht sie oben im Kopf. */
.feProdId{ font-size:10.5px; font-weight:600; color:var(--muted) }

/* --- 7. Statusstreifen: zwei benannte Gruppen ------------------------------ */
.feStLinks{ gap:18px; align-items:flex-start }
.feStGrp{ display:flex; flex-direction:column; gap:4px; min-width:0 }
.feStGrpTit{ font-size:8.5px; letter-spacing:.09em; text-transform:uppercase;
  font-weight:800; color:var(--muted); opacity:.75 }
.feStGrpChips{ display:flex; gap:5px; flex-wrap:wrap; align-items:center }

/* --- 9. Schrittueberschrift: Untertitel einzeilig -------------------------- */
/* KORREKTUR: die Klasse heisst `feSchrittKurz`, nicht `feSchrittSub`. Gemessen
   in `feFokusKopfFuss`, nicht geraten. */
.feSchrittKopf .feSchrittKurz{ display:block; white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; color:var(--muted); font-size:11px; margin-top:2px }

/* --- 10. Weiter/Zurueck als kompakte Pills -------------------------------- */
/* Die Knopfmasse stehen an ihrer EINEN Definition weiter oben, nicht hier.
   Hier bleibt nur der Abstand der Leiste. */
.feSchrittFuss{ padding-top:9px; gap:8px }

/* --- 6. Tooltips duerfen nichts ueberdecken ------------------------------- */
/* Native title-Tooltips lassen sich per CSS NICHT positionieren — das ist eine
   Browserfunktion. Der einzige wirksame Hebel ist der AUFHAENGER: er wurde in
   `app.js` vom ganzen <label> auf das Statuszeichen verkleinert. Damit erscheint
   der Tooltip nur noch ueber dem Zeichen, das ihn erklaert, und nicht mehr ueber
   Ueberschrift oder Eingabefeld. Hier steht deshalb bewusst KEINE Regel — eine
   leere Regel haette so ausgesehen, als sei das Problem in CSS geloest worden. */

/* ============================================================================
   LETZTER DESKTOP-FEINSCHLIFF 15.08.2026 (Ralph, Punkte 1-8)
   ============================================================================ */

/* --- 1. Schritt 1: Quelle und Kopf in EINER weissen Karte ----------------- */
/* Kein DOM-Umbau: `.feHolBox` und `#feKopfGrid` bleiben Geschwister. Die Karte
   wandert nur nach AUSSEN auf ihren gemeinsamen Elternteil, und die beiden
   verlieren innen ihre eigene Kartenoptik. Aus zwei Karten wird eine. */
/* 🔴 15.08.2026 SPAET — `#feTab1` IM SELEKTOR ERGAENZT. Ohne das war diese Regel
   zur Haelfte wirkungslos, und zwar seit sie existiert.

   GEMESSEN (Spezifitaet, nicht geschaetzt):
     ui.css 1191  #feTab1 #feKopfLayout                              = (2,0,0)
     hier         body.riFokus[data-fe-schritt="kopf"] #feKopfLayout = (1,2,1)
   (2,0,0) schlaegt (1,2,1). `display:flex` und `flex-direction:column` kamen also
   NIE an — der Kopfbereich blieb das Zweispaltenraster aus 1191 mit fester 300px
   Bildspalte. `background`, `border` und `padding` griffen weiter, weil 1191 sie
   nicht deklariert: es SAH aus wie eine Karte und rechnete als Raster. Genau
   deshalb hat es niemand gesehen. Der Kommentar darueber beschrieb einen Zustand,
   den es nie gab.

   BELEG, im laufenden Browser gemessen (Build 3110, P73618, Schritt 1, per
   Style-Injektion vor dem Ablegen — die Ablauftests rendern nicht, Work #37):
     vorher   display:grid   grid-template-columns 354px 300px   #feKopfGrid = 354
     nachher  display:flex   grid-template-columns none          #feKopfGrid = 666
   Ralph hatte am Inspektor 680 eingestellt. Seine Zahl war keine Wunschbreite,
   sondern die richtige Diagnose: er wollte das Formular ueber die volle Breite,
   und genau das war die Absicht dieser Regel.

   `grid-template-columns:none` steht ausdruecklich dabei, damit die geerbte
   Spaltenangabe aus 1191 nicht als Leiche stehenbleibt, falls jemand spaeter
   wieder auf `display:grid` schaltet. */
body.riFokus[data-fe-schritt="kopf"] #feTab1 #feKopfLayout,
body.riFokus[data-fe-schritt="kopf"] #feKopfLayout{
  background:var(--card); border:1px solid var(--line); border-radius:12px;
  padding:14px 16px; display:flex; flex-direction:column; gap:0;
  grid-template-columns:none;
}
body.riFokus[data-fe-schritt="kopf"] .feHolBox{
  background:transparent; border:0; border-radius:0; padding:0 0 12px; margin:0;
  border-bottom:1px solid var(--line); box-shadow:none;
}
body.riFokus[data-fe-schritt="kopf"] #feKopfGrid{
  background:transparent; border:0; border-radius:0; padding:12px 0 0; margin:0;
  box-shadow:none;
}
/* Die Sektionsueberschrift „QUELLE" — die Kopfdaten tragen ihre Feldnamen selbst. */
body.riFokus[data-fe-schritt="kopf"] .feHolTitel{
  font-size:9.5px; letter-spacing:.07em; text-transform:uppercase;
  font-weight:800; color:var(--muted); margin-bottom:8px }
body.riFokus[data-fe-schritt="kopf"] .feHolTitelZus{ display:none }
/* Die Fertig-Zeile ist jetzt eine Zeile, kein Kasten mehr. */
body.riFokus[data-fe-schritt="kopf"] .feQuelleFertig{
  border:0; padding:0; background:transparent; max-width:none }

/* --- 2. Schritt 2: Mitte breiter, rechts unveraendert schmal --------------- */
/* Schritt 2: die Mitte bekommt ihre Breite dadurch, dass rechts wenig steht —
   nicht durch ein Minimum, das das Raster sprengt (Ursache B). */
#feTab2 .feWirkRow .fwNote{ margin-top:1px }
#feTab2 .feWirkHinweis, #feTab2 .feKartenZusatz{ white-space:normal; line-height:1.5 }

/* --- 3. Schritt 3: Kopfzeile visuell auf die Datenzeile ziehen ------------- */
/* Der Spaltenvertrag bleibt unangetastet — nur Abstaende und Ausrichtung. */
body.riFokus .fgBestKopf{ padding-left:0; padding-right:0; gap:inherit }
body.riFokus .fgBestKopf, body.riFokus .fgBestZeile{ column-gap:10px }
body.riFokus .fgBestKopf > span:first-child{ font-size:9px }
body.riFokus .fgBestKopf > span:last-child,
body.riFokus .fgbWert{ text-align:right }
body.riFokus .fgBestZeile{ padding-left:0; padding-right:0 }

/* --- 4. WORK #43: die Verarbeitungszelle ist bearbeitbar ------------------- */
/* Ralph: „nicht bearbeitbar". Eine Zelle, die man anklicken kann, muss auch so
   aussehen — sonst findet sie niemand. Der Stift steht dauerhaft da (blass) und
   wird beim Darueberfahren kraeftig; ein Element, das erst bei Hover ERSCHEINT,
   ist auf einer Tabelle mit vielen Zeilen nicht auffindbar. */
body.riFokus .fgbVerarbEdit{ cursor:pointer; border-radius:5px; padding:1px 3px;
  margin:-1px -3px; transition:background .12s ease }
body.riFokus .fgbVerarbEdit:hover{ background:var(--k-eef6ff,#eef6ff);
  box-shadow:inset 0 0 0 1px var(--k-2f6fd6,#2f6fd6) }
body.riFokus .fgbStift{ font-size:10px; color:var(--muted); margin-left:4px; opacity:.45 }
body.riFokus .fgbVerarbEdit:hover .fgbStift{ color:var(--k-2f6fd6,#2f6fd6); opacity:1 }

/* --- 5. Schritt 4: gleiche Aussenkante, engerer Abstand ------------------- */
body.riFokus[data-fe-schritt="bestand"] #feEditorBody > #feTab3,
body.riFokus[data-fe-schritt="bestand"] #feEditorBody > #feAbgleich{
  margin-left:0; margin-right:0; width:100% }
body.riFokus[data-fe-schritt="bestand"] #feEditorBody > #feAbgleich{ margin-top:18px }

/* --- 6. Rail kompakter ---------------------------------------------------- */
#feRailNav{ gap:6px; padding-bottom:9px; margin-bottom:10px }
#feRailNav #feNavPost{ padding:4px 11px !important; font-size:11.5px !important }
#feRailNav #feNavBlaett button{ padding:3px 7px !important; font-size:10.5px !important }
#feRailNav #feNavBlaett > span{ font-size:10.5px !important }
#feProdKopf{ padding-bottom:10px; margin-bottom:11px }
.feProdZeile{ margin-bottom:0 }
.feProdStatus{ margin:7px 0 2px }
.feProdZust{ margin-bottom:7px }
/* Speichern und Freigeben nebeneinander statt untereinander. */
.feProdAkt{ display:flex; gap:7px; flex-wrap:wrap; align-items:center }
.feProdSave, .feProdFrei{ margin-top:0 }
.feProdId{ font-size:10px }

/* ============================================================================
   RESPONSIVE-GRENZE (Ralph P5) — vorerst NUR die untere Kante.
   Der volle Responsive-Durchgang kommt danach; hier geht es allein darum, dass
   auf Desktop NICHTS umbricht und bei wirklich schmalen Fenstern etwas
   Sinnvolles passiert statt eines Ueberlaufs.

   Rechnung fuer die Grenze (Ralph P2, nachgerechnet): 180 (Rail) + 18 (Gap)
   + 700 (sinnvolle Mitte) + 20 (Gap) + 480 (Kontext) = 1398. Der Drei-Spalten-
   Modus gilt deshalb ab 1400 px. Darunter kommt spaeter Responsive - nicht
   versuchen, bei 1200 px dieselben drei Spalten zu erzwingen.
   ============================================================================ */
@media (max-width:1399px){
  /* Zwei Spalten: Rail bleibt, der Kontext geht UNTER den Hauptbereich.
     Das ist hier ausdruecklich gewollt — auf Desktop passiert es nicht mehr. */
  body.riFokus #feRahmen.riDrei{
    grid-template-columns: minmax(0,1fr) }
  body.riFokus #feRahmen.riDrei > #feKontext{ grid-column:1; grid-row:2; margin-top:0 }
  body.riFokus #feKontext{ position:static }
}

/* ============================================================================
   LETZTER STRUKTURELLER FEINSCHLIFF 15.08.2026 (Ralph, Punkte 2, 4, 5)
   ============================================================================ */

/* --- 4. Die Rail in DREI benannten Gruppen -------------------------------- */
/* „Klare Abstaende bzw. feine Trennlinien. Keine Kartenwand." */
.feRailGrpTit{ font-size:8.5px; letter-spacing:.1em; text-transform:uppercase;
  font-weight:800; color:var(--muted); opacity:.7; margin:0 0 7px }
#feRailNav{ gap:6px; padding-bottom:11px; margin-bottom:12px;
  border-bottom:1px solid var(--line) }
#feProdKopf{ padding-bottom:12px; margin-bottom:12px;
  border-bottom:1px solid var(--line) }
#feFokusNav{ padding-top:0 }
/* Die alte Zwischenueberschrift entfaellt — die Gruppe traegt jetzt ihren Namen. */
#feFokusNav .feStTitel{ display:none }

/* --- 2. Eigenschaften als Chips ------------------------------------------- */
.feRailEigen{ display:flex; gap:5px; flex-wrap:wrap; margin:0 0 9px }
.feEigChip{ display:inline-flex; align-items:center; gap:5px; cursor:pointer;
  border:1px solid var(--line); border-radius:999px; background:var(--card);
  padding:3px 9px; font-size:10.5px; font-weight:700; color:var(--muted) }
.feEigChip::before{ content:"○"; font-size:8px }
.feEigChip.ok{ color:var(--k-166534,#166534); border-color:var(--k-bfe3cb,#bfe3cb);
  background:var(--k-e7f6ec,#e7f6ec) }
.feEigChip.ok::before{ content:"✓" }
/* „automatisch abgeleitet" ist wahr, aber nicht bestaetigt — also nicht gruen. */
.feEigChip.auto{ color:var(--k-1d4ed8,#1d4ed8); border-color:var(--k-c7d9f7,#c7d9f7);
  background:var(--k-eef4ff,#eef4ff) }
.feEigChip.auto::before{ content:"◐" }
.feEigChip.still{ opacity:.75 }
.feEigChip:hover{ border-color:var(--k-2f6fd6,#2f6fd6) }
/* Kurzes Aufblinken, wenn der Chip den Bereich oeffnet — kein Dauerzustand. */
.feEigBlink{ animation:feEigBlink 1.6s ease-out }
@keyframes feEigBlink{
  0%,100%{ box-shadow:none }
  20%,60%{ box-shadow:0 0 0 3px var(--k-dbeafe,#dbeafe) }
}

/* --- 5. Arbeitsschritte deutlicher markieren ------------------------------ */
.feFokusSt{ border-left:3px solid transparent; border-radius:8px;
  padding:7px 9px; gap:9px }
.feFokusSt.akt{ background:var(--k-eef4ff,#eef4ff);
  border-left-color:var(--k-2f6fd6,#2f6fd6) }
.feFokusSt.akt .feFokusTxt b{ color:var(--k-1d4ed8,#1d4ed8) }
.feFokusSt .feFokusTxt b{ font-weight:700; font-size:12px }
/* 🔴 16.08.2026 — Ralph-Entscheid B: das Statuszeichen ist weg, das Statuswort steht
   in der Unterzeile. `white-space:nowrap` muss deshalb fallen — "zu prüfen · 3 offen"
   ist laenger als "1/1", und abgeschnitten waere ausgerechnet die Zahl weg, wegen der
   man hinsieht. Zwei Zeilen sind besser als eine halbe Aussage. */
.feFokusSub{ display:block; font-size:10px; color:var(--muted); margin-top:1px;
  font-weight:400; line-height:1.35 }
.feFokusWort{ font-weight:700 }
.feFokusDet{ color:var(--muted); font-weight:400 }
/* Erledigt: nur der Haken ist gruen, keine Flaeche. */
.feFokusSt:not(.akt){ background:transparent }
.feFokusIco{ font-size:12px; line-height:1; flex:0 0 auto }

/* --- 3+8. Schritt 3: Tabelle oben, Abgleich darunter ---------------------- */
/* `#feTab3` und `#feAbgleich` teilen sich sonst die Zelle 2/1. */
body.riFokus[data-fe-schritt="bestand"] #feEditorBody > #feAbgleich::before{
  content:"B · Etikett & Abgleich" }
/* 🔴 15.08.2026: DER EINE ORT fuer das Innenraster von Schritt 3.
   Im Fokusmodus ist `fe_gridA` EINSPALTIG — die Referenz steht rechts im Kontext,
   der Zusatzstoffkasten ist seit 13.08. `display:none`. Es gibt hier also nichts
   mehr, was eine zweite oder dritte Spalte fuellen koennte; sie waeren nur Leere.

   Das Template setzt inline zwei Spalten und eine Bildschirmhoehe — beides wird
   im Fokus von `feFokusSchritt` und `feGridHoeheSync` GELOESCHT, damit diese
   Regel ueberhaupt greifen kann. Inline schlaegt Stylesheet; das war heute
   dreimal die Ursache.

   Der ALTE Modus behaelt sein Raster vollstaendig (Ralph P5) — diese Regel haengt
   an `body.riFokus` und gilt dort nicht. */
body.riFokus #fe_gridA{
  grid-template-columns:minmax(0,1fr) !important;
  height:auto !important; min-height:0 !important;
}
/* Die Bestandteilkarte fuellt die ganze Spalte — keine Reservebreite. */
body.riFokus #fe_colZut{ grid-column:1; width:100%; min-width:0 }
/* 6. Der Abgleich darunter bekommt dieselbe Aussenbreite wie die Tabelle. */
body.riFokus #feAbgleich{ width:100%; min-width:0 }


/* ============================================================================
   RAIL-GRUPPEN FERTIG (Ralph 15.08., Punkt 10)
   NAVIGATION · PRODUKT · AKTIONEN · EIGENSCHAFTEN · ARBEITSFLUSS
   Feine Trennlinien, keine Kartenwand.
   ============================================================================ */
.feRailGrpTit{ margin-top:0 }
.feProdAkt{ margin-top:2px }
/* Bio und Ernaehrungsform nebeneinander, solange 180px es tragen. */
.feRailEigen{ gap:4px }
.feEigChip{ padding:3px 8px; font-size:10px }
/* Bei 180px Rail darf beides umbrechen statt abzuschneiden (Ralph P3). */
.feProdTxt b{ white-space:normal; overflow-wrap:anywhere }
.feFokusTxt b{ white-space:normal; overflow-wrap:anywhere }
.feFokusSub{ white-space:normal }

/* ============================================================================
   ⌘V-HINWEIS IM ETIKETTBEREICH (Ralph 15.08., Punkt 7)
   „Sehr dezent unter/bei den Werkzeugen. Nicht als grosser Button noetig."
   ============================================================================ */
.feEtikettPasteTip{ display:flex; align-items:baseline; gap:6px; flex-wrap:wrap;
  margin-top:7px; font-size:10.5px; font-weight:700; color:var(--muted);
  letter-spacing:.01em }
.feEtikettPasteTip span{ font-weight:400; opacity:.8 }

/* ============================================================================
   STAMMWAECHTER + STAMMTABELLEN (Ralph 15.08.2026)
   Canonical und Legacy sehen bewusst NICHT gleich aus.
   ============================================================================ */
.fgStammWaechter{ display:flex; flex-direction:column; gap:10px; margin-bottom:14px }
.fgSwGrp{ border:1px solid var(--line); border-radius:12px; padding:10px 13px; background:var(--card) }
.fgSwGrp.neu{ border-left:3px solid var(--k-16a34a,#16a34a) }
.fgSwGrp.alt{ border-left:3px solid var(--muted); background:transparent }
.fgSwKopf{ display:flex; align-items:center; gap:9px; margin-bottom:7px; flex-wrap:wrap }
.fgSwKopf b{ font-size:12.5px }
.fgSwTag{ font-size:9.5px; font-weight:800; letter-spacing:.05em; text-transform:uppercase;
  padding:2px 8px; border-radius:999px }
.fgSwTag.canon{ background:var(--k-dcfce7,#dcfce7); color:var(--k-166534,#166534) }
.fgSwTag.legacy{ background:var(--k-eef1f4,#eef1f4); color:var(--muted) }
.fgSwZeile{ display:flex; gap:14px; flex-wrap:wrap; align-items:baseline }
.fgSwZahl{ font-size:11.5px; color:var(--muted) }
.fgSwZahl b{ font-size:15px; font-weight:800; color:var(--ink); margin-right:2px }
.fgSwZahl.offen b{ color:var(--k-92400e,#92400e) }
.fgSwZahl.warn b{ color:var(--k-b45309,#b45309) }
.fgSwZahl.rot b{ color:var(--k-b91c1c,#b91c1c) }
.fgSwHinweis{ font-size:10.5px; color:var(--muted); margin-top:7px; line-height:1.5 }
.fgSwLad, .fgSwFehl{ font-size:12px; color:var(--muted); padding:9px 2px }
.fgSwFehl{ color:var(--k-b91c1c,#b91c1c) }
.fgSwFuss{ display:flex }
.fgSwFuss button{ border:1px solid var(--line); border-radius:999px; background:var(--card);
  color:var(--ink); padding:5px 13px; font-size:11.5px; font-weight:700; cursor:pointer }

/* --- Der Bereich STAMM --------------------------------------------------- */
.fgStKopf{ display:flex; gap:9px; align-items:center; flex-wrap:wrap; margin-bottom:11px }
.fgStTabs{ display:flex; gap:4px }
.fgStTab{ border:1px solid var(--line); border-radius:999px; background:var(--card);
  color:var(--muted); padding:5px 13px; font-size:12px; font-weight:700; cursor:pointer }
.fgStTab.akt{ background:var(--k-eef6ff,#eef6ff); border-color:var(--k-2f6fd6,#2f6fd6);
  color:var(--k-2f6fd6,#2f6fd6) }
.fgStKopf input, .fgStKopf select{ padding:5px 9px; border:1px solid var(--line);
  border-radius:8px; font-size:12px; background:var(--card); color:var(--ink) }
.fgStKopf input{ min-width:200px }
.fgStZahl{ font-size:11px; color:var(--muted); margin-left:auto }
.fgStTabelle{ overflow:auto; border:1px solid var(--line); border-radius:10px }
.fgStTab{ width:100%; border-collapse:collapse; font-size:12px }
.fgStTab th{ text-align:left; font-size:9.5px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--muted); font-weight:800; padding:7px 8px; border-bottom:2px solid var(--line);
  position:sticky; top:0; background:var(--card) }
.fgStTab td{ padding:4px 8px; border-bottom:1px solid var(--line); vertical-align:middle }
.fgStTab.legacy th{ color:var(--muted); opacity:.85 }
.fgStTab.legacy td{ background:transparent }
.fgStTab input, .fgStTab select{ width:100%; padding:4px 6px; border:1px solid transparent;
  border-radius:6px; font-size:12px; background:transparent; color:var(--ink) }
.fgStTab input:hover, .fgStTab select:hover{ border-color:var(--line) }
.fgStTab input:focus, .fgStTab select:focus{ border-color:var(--k-2f6fd6,#2f6fd6);
  background:var(--card); outline:none }
.fgStOk{ background:var(--k-dcfce7,#dcfce7) !important }
.fgStBew input{ text-align:right; font-weight:700 }
.fgStNum{ text-align:right; color:var(--muted); white-space:nowrap }
.fgStId{ font-size:10.5px; color:var(--muted); white-space:nowrap }
.fgStLc{ font-size:10px; font-weight:800; padding:1px 7px; border-radius:999px;
  background:var(--k-eef1f4,#eef1f4); color:var(--muted) }
.fgStLc.active{ background:var(--k-dcfce7,#dcfce7); color:var(--k-166534,#166534) }
.fgStLc.retired{ background:var(--k-fee2e2,#fee2e2); color:var(--k-b91c1c,#b91c1c) }
.fgStAss{ display:block; font-size:9.5px; color:var(--muted); margin-top:1px }
.fgStFuss{ display:flex; gap:7px; margin-top:10px }
.fgStFuss button{ border:1px solid var(--line); border-radius:999px; background:var(--card);
  color:var(--ink); padding:5px 13px; font-size:11.5px; font-weight:700; cursor:pointer }

/* ============================================================================
   EIGENSCHAFTEN IN DER RAIL: ECHTE AUSWAHL (Ralph 15.08., Punkte 2-5)
   „Nicht nur zwei Mini-Chips" — kompakte Segmented Controls, die bei 180px
   sauber umbrechen duerfen.
   ============================================================================ */
.feRailEigen{ display:flex; flex-direction:column; gap:3px; margin:0 0 10px }
.feSegTitel{ font-size:8.5px; letter-spacing:.08em; text-transform:uppercase;
  font-weight:800; color:var(--muted); opacity:.75; margin:6px 0 3px }
.feSeg{ display:flex; flex-wrap:wrap; gap:3px }
.feSegBtn{ border:1px solid var(--line); border-radius:var(--fk-r-klein); background:var(--card);
  color:var(--muted); padding:3px 7px; font-size:10px; font-weight:700;
  cursor:pointer; line-height:1.35; white-space:nowrap }
.feSegBtn:hover{ border-color:var(--k-2f6fd6,#2f6fd6) }
/* 🔴 24.08.2026, Ralph: "aber nicht weiss sondern ein helleres gruen."
   Der gewaehlte Chip war blassblau — im dunklen Kopfband sah das aus wie WEISS
   und stach heraus wie ein Fehler. Jetzt ein helles Gruen: hell genug, dass die
   Schrift dunkel bleiben kann, kraeftig genug, um im Dunkeln als "das ist es"
   gelesen zu werden.
   GILT FUER BEIDE FAELLE, so wie Ralph es wollte: von Hand gesetzt und aus der
   Automatik abgeleitet sehen gleich aus. Der Unterschied steht im Tooltip —
   eine zweite Farbe fuer denselben Sachverhalt waere eine Unterscheidung, die
   niemand erklaeren kann.

   🔴 DIE DREI FARBEN SIND NICHT NEU ERFUNDEN. Mein erster Entwurf hatte eigene
   Werte (--k-dcf5e3, --k-2e9e57) — die sind in KEINER der beiden HTML-Dateien
   definiert, es haetten also nur meine Rueckfallwerte gegriffen, und im
   Dunkelmodus waere die Farbe stehengeblieben, waehrend alles andere umschaltet.
   Gemessen und ersetzt durch den vorhandenen Gruen-Dreiklang des Projekts:
     --k-dcfce7 (Flaeche) · --k-16a34a (Rand) · --k-166534 (Schrift)
   Alle drei sind in admin.html UND index.html je zweimal gesetzt, hell und
   dunkel. Dieselbe Kombination benutzen die gruenen Knoepfe in Station 2. */
.feSegBtn.akt{ background:var(--k-dcfce7); border-color:var(--k-16a34a);
  color:var(--k-166534) }
/* Abgeleitet aus der Automatik: gleiche Farbe, aber die Schrift traegt keinen
   vollen Fettdruck — ein leiser Unterschied fuer den, der genau hinsieht,
   ohne eine neue Bedeutung aufzumachen. */
.feSegBtn.akt.autoakt{ font-weight:600 }

/* 🔴 16.08.2026 — WORK #67, Braten-Eignung in der Rail.
   BEWUSST KEIN .feSegBtn: die Segmentknoepfe daneben sind BEDIENBAR, dieser Chip ist
   eine ANZEIGE des Serverurteils. Saehe er aus wie ein Knopf, wuerde Ralph darauf
   klicken und nichts passierte — eine Attrappe (Ralph P12). Deshalb kein Zeigefinger,
   kein Hover-Rand, und `cursor:help`, weil die ganze Begruendung samt Beleg im Titel
   haengt.
   Drei Zustaende, drei Toene — alle drei aus dem vorhandenen Farbvorrat, kein neuer Ton:
     gut   gruen  wie eine erfuellte Freigabebedingung
     warn  rot    wie ein Blocker — das ist die Haelfte, die Menschen schuetzt
     offen grau   sichtbar unbekannt, NICHT gruen und NICHT rot (§3.4) */
.feRailBraten{ display:inline-flex; align-items:center; align-self:flex-start;
  border:1px solid var(--line); border-radius:var(--fk-r-klein); background:var(--card);
  padding:3px 7px; font-size:10px; font-weight:700; line-height:1.35;
  white-space:nowrap; cursor:help; color:var(--muted) }
.feRailBraten.gut{  background:var(--k-eaf5ee,#eaf5ee); border-color:var(--k-9fc6a8,#9fc6a8);
  color:var(--k-166534) }
.feRailBraten.warn{ background:var(--k-fdeceb,#fdeceb); border-color:var(--k-e08a82,#e08a82);
  color:var(--k-b91c1c) }
.feRailBraten.offen{ background:var(--card); border-style:dashed; color:var(--muted) }

/* 🔴 16.08.2026 — WORK #81: die vier Arbeitswege an einer offenen Zutatzeile.
   HIERARCHIE IST DIE GANZE AUSSAGE dieses Blocks (Ralph: "Neu anlegen darf nicht
   der Standardweg sein"):
     .fgOffPrimaer  Weg 1 Binden   — blau gefuellt, der Normalfall, zuerst
     .fgOffBtn      Weg 2 und 3    — neutral umrandet
     .fgOffLeise    Weg 4 Neuanlage — nur Text, kein Kasten. Absichtlich der
                    leiseste: er ist erreichbar, aber er wirbt nicht. Vorher war
                    er der einzige sichtbare Weg und damit faktisch der Standard. */
.fgOffBtn{ border:1px solid var(--k-b9d2f0,#b9d2f0); border-radius:7px;
  background:var(--card); color:var(--k-1e40af,#1e40af); padding:3px 8px;
  font-size:11px; font-weight:600; cursor:pointer; line-height:1.4 }
.fgOffBtn:hover{ border-color:var(--k-2f6fd6,#2f6fd6) }
.fgOffBtn:disabled{ opacity:.55; cursor:default }
.fgOffPrimaer{ background:var(--k-2f6fd6,#2f6fd6); border-color:var(--k-2f6fd6,#2f6fd6);
  color:#fff }
.fgOffPrimaer:hover{ background:var(--k-1d4ed8,#1d4ed8) }
.fgOffLeise{ border-color:transparent; background:transparent; color:var(--muted);
  text-decoration:underline dotted; font-weight:400 }
.fgOffLeise:hover{ color:var(--ink); border-color:transparent }
/* Der abgeleitete Zustand ist eine Rechnung, keine Bestaetigung — deshalb grau. */
.feSegAuto{ font-size:9.5px; color:var(--muted); margin-top:3px; line-height:1.4 }
.feSegAuto b{ color:var(--ink) }

/* ============================================================================
   PRODUKTEDITOR · KARTE "QUELLE & BELEG"   (Work #181 Stufe 2, 22.08.2026)
   ----------------------------------------------------------------------------
   Ralph-Entscheid F1: die Quellenwahl steht im mittleren Arbeitsbereich als
   ERSTER Kasten von Schritt 1 - erst die Quelle, dann die Daten. Der Server
   verlangt sie ohnehin fuer jede Freigabe (cb_quelle_belegt).

   WARUM SIE VORHER UNSICHTBAR WAR - damit es niemand rueckgaengig macht:
   Sie stand im linken Streifen. feRailAufraeumen() blendet dort JEDES direkte
   Kind aus, dessen id nicht in FE_RAIL_ERLAUBT steht (genau drei: feRailNav,
   feProdKopf, feFokusNav). card() vergibt keine id -> die Karte war im
   Fokusmodus in JEDEM Schritt weg. Wer sie zurueck in die Rail schiebt,
   blendet sie wieder aus.

   HANDY ZUERST (Ralph-Entscheid F2): eine Spalte ist der Grundzustand, zwei
   Spalten sind die Erweiterung ab 620px. Nicht andersherum - ein Umbruchpunkt,
   der von oben nach unten denkt, vergisst das Handy.
   ========================================================================== */
#fe_quelleCard{ margin-bottom:12px }
.feQuelleGrid{ display:grid; grid-template-columns:minmax(0,1fr); gap:10px }
@media (min-width:620px){
  .feQuelleGrid{ grid-template-columns:minmax(0,1fr) minmax(0,1fr) }
}
/* Beschriftung ueber dem Feld, dicht daran - nicht mit space-between
   auseinandergezogen wie die Naehrwertzeilen (Befund B3). */
.feQuelleGrid > label{ display:block; font-size:13px; min-width:0 }
.feQuelleGrid > label > select,
.feQuelleGrid > label > input{ margin-top:3px }

/* ============================================================================
   PRODUKTEDITOR · NÄHRWERTFELDER   (Work #181 Stufe 4, 23.08.2026)
   ----------------------------------------------------------------------------
   Ralphs Befund: "Die Naehrwert-Eingabefelder sind zu breit."
   Gemessen war es anders herum: das Feld war 110px, der ABSTAND war das Problem.
   Jede Zeile stand als eigenes Flex-Element mit justify-content:space-between -
   Beschriftung ganz links, Feld ganz rechts, dazwischen Leere. Bei zwoelf Zeilen
   untereinander springt der Blick zwoelfmal ueber diese Luecke.

   JETZT: mehrspaltiges Raster, Beschriftung und Feld dicht beieinander, Zahl
   rechtsbuendig. Rechtsbuendig ist kein Geschmack: so stehen die Kommastellen
   untereinander, und ein Tippfehler wie 58,7 statt 5,87 faellt beim Ueberfliegen auf.

   🔴 RALPH 23.08., NACH DEM ERSTEN LIVE-BLICK: "ich will sie untereinander, nicht
   nebeneinander - wie auf dem Etikett." Meine erste Fassung hatte drei Spalten.
   Das war Platzoptimierung auf Kosten des Ablesens: wer die Werte vom Etikett
   abtippt, liest von oben nach unten. Drei Spalten zwingen den Blick in Zickzack
   und man verliert die Zeile. Ralph hat recht, die Spalten sind raus.
   ES BLEIBT IMMER EINSPALTIG - auch auf breiten Schirmen. Die Reihenfolge ist die
   des Etiketts (LMIV Anhang XV): Energie, Fett, davon gesaettigte, Kohlenhydrate,
   davon Zucker, Eiweiss, Salz - mit den freiwilligen Angaben an ihrem Platz.

   ⚠ NICHT ANGEFASST: die IDs fe_kcal … fe_salz. An ihnen haengen der Pflichtfeld-
   Check (nwReq), das Speichern, alle sechs Lesewege (OFF, USDA, Riki, JSON, Rohtext,
   Etikett) und die Plausibilitaetspruefung. Eine umbenannte ID waere ein stiller Bruch.
   ========================================================================== */
#feTab2 .feNwRaster{
  display:grid;
  grid-template-columns:minmax(0,1fr);   /* IMMER einspaltig - siehe Kommentar oben */
  gap:0;
}
#feTab2 .feNwFeld{
  display:grid;
  /* Der Kern: die Beschriftung bekommt eine BEGRENZTE Spalte, dann kommt sofort das
     Feld. Ohne die Grenze zoege eine 700px breite Karte beides wieder auseinander -
     genau der Fehler, der behoben werden sollte. Der Rest der Zeile bleibt leer. */
  grid-template-columns:minmax(0,230px) 76px;
  justify-content:start;
  align-items:center;
  gap:10px;
  font-size:12.5px;
  padding:2px 0;
  min-width:0;
}
/* "davon …" gehoert sichtbar zur Zeile darueber - eingerueckt und leiser, genau wie
   auf dem Etikett. */
/* 🔴 23.08. am Live-Stand gemessen und korrigiert: hier stand padding-left auf der
   ganzen ZEILE. Das hat die eingerueckten "davon …"-Zeilen samt Zahlenfeld um 14px
   verschoben - gemessen zwei linke Kanten, 500px und 514px. Damit war genau das
   kaputt, was diese Aenderung versprochen hat: die Zahlenflucht.
   Die Einrueckung gehoert an die BESCHRIFTUNG, nicht an die Zeile. */
#feTab2 .feNwFeld.unter{ color:var(--muted) }
#feTab2 .feNwFeld.unter > span{ padding-left:14px }
#feTab2 .feNwFeld.unter > span::before{ content:"└ "; opacity:.45 }
#feTab2 .feNwFeld > span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
/* Die Einheit ist Beiwerk, nicht Teil des Namens. */
#feTab2 .feNwFeld i{ font-style:normal; color:var(--muted); font-size:11px }
#feTab2 .feNwFeld > input{
  width:76px; padding:5px 7px; text-align:right;
  border:1px solid var(--line); border-radius:var(--fk-r-klein);
  font-size:12.5px; background:var(--card); color:var(--ink);
}
#feTab2 .feNwFeld > input:focus{ border-color:var(--k-2f6fd6,#2f6fd6); outline:none }
#feTab2 .feNwRaster > .feNwBallast{ margin:2px 0 6px 14px }
/* Auf sehr schmalen Schirmen darf die Beschriftung schrumpfen, aber nie umbrechen -
   sonst verrutscht die Zahlenflucht. */
@media (max-width:420px){
  #feTab2 .feNwFeld{ grid-template-columns:minmax(0,1fr) 68px }
  #feTab2 .feNwFeld > input{ width:68px }
}

/* ============================================================================
   RASTERVERTRAG · DER HANDY-ZUSTAND DES FOKUSEDITORS
   (Work #181 Stufe 1, 23.08.2026 — gehoert zum Block "DER RASTERVERTRAG" oben)
   ----------------------------------------------------------------------------
   Die Regeln oben setzen die Spalten fuer den Fokusmodus ohne Untergrenze. Ohne
   diesen Block stuende die 180px-Leiste auch auf einem 390px-Schirm - gemessen
   blieben dem Arbeitsbereich dann 192px. Das war Befund B2.

   UNTER 700px gilt deshalb: alles untereinander, in der Reihenfolge, in der man
   es braucht. 700 statt 900, damit iPad hochkant (768px) noch zweispaltig bleibt -
   siehe Begruendung im Hauptblock oben. Die Arbeitsschritte gehoeren nach OBEN (man waehlt sie zuerst),
   der Arbeitsbereich in die Mitte, der Kontext ans Ende (man sieht ihn nach.
   Reihenfolge ueber grid-row, nicht ueber DOM-Umbau: ein Umbau des DOM haette
   jede Fremdlogik getroffen, die per ID sucht.
   ========================================================================== */
@media (max-width:699px){
  body.riFokus #feRahmen,
  body.riFokus #feRahmen.riDrei{
    grid-template-columns:minmax(0,1fr) !important;
    gap:14px;
  }
  body.riFokus #feRahmen > #feRail{           grid-column:1; grid-row:1 }
  body.riFokus #feRahmen > #feEditorBody{     grid-column:1; grid-row:2 }
  body.riFokus #feRahmen.riDrei > #feKontext{ grid-column:1; grid-row:3; margin-top:0 }
  body.riFokus #feRahmen > #fe_naehrKacheln{  grid-column:1; grid-row:4 }

  /* Die Leiste ist auf dem Handy eine Kopfzeile, keine Spalte: sie klebt nicht,
     sie nimmt die volle Breite, und die Arbeitsschritte liegen nebeneinander
     statt untereinander - sonst scrollt man vor dem ersten Feld dreimal. */
  body.riFokus #feRail{
    position:static; top:auto; width:100%; max-width:100%;
    border-bottom:1px solid var(--line); padding-bottom:10px;
  }
  body.riFokus #feFokusNav{ display:flex; flex-wrap:wrap; gap:6px }
  body.riFokus #feFokusNav .feStTitel{ flex:1 0 100%; }
  body.riFokus .feFokusSt{ flex:1 1 auto; border-left:0; border-bottom:3px solid transparent }
  body.riFokus .feFokusSt.akt{ border-left:0; border-bottom-color:var(--k-2f6fd6,#2f6fd6) }
}

/* ============================================================================
   🔴 DIE FIXIERTE KOPFZONE  (#feKopfZone)   ·  Work #181, 23.08.2026
   ----------------------------------------------------------------------------
   Ralph: "die navi soll auch oben sein und fixiert beim scrollen. bitte keine
   buttons und funktionen vergessen." Und danach: "ich meinte auch die
   eigenschaften und die freigabe."

   HIER STEHT NUR DIE ANORDNUNG. Die Bloecke selbst baut weiterhin das JavaScript -
   feRailNav, feProduktKopf und feFokusNav haengen sich ueber _feZielZone() ein.
   Deshalb konnte beim Umzug kein Bedienelement verlorengehen.

   GEMESSEN VOR DEM UMBAU an P32667: 12 Bedienelemente ohne die Stationen brauchen
   956px, mit Abstaenden 1052px, mit Freigabe rund 1310px. Bei 1440 und 1710px ist
   das eine Zeile, bei 1024px (iPad quer) werden es zwei - die Gruppen brechen um.
   Der Streifen kostete 180px Breite ueber die VOLLE Seitenhoehe; die Zone kostet
   rund 150px Hoehe. Der Arbeitsbereich waechst dadurch von 700 auf etwa 900px.
   ========================================================================== */
/* 🔴 23.08. ZWEITE NACHBESSERUNG — Ralph: "oberer balken noch nicht wie im mockup".
   Nachgemessen an P73634: der Kopf war 380px hoch, das Mockup ist rund 150.
   Zwei Ursachen, beide hier behoben:
     1. Die Zone stand als SPALTE, also Navigation und Produktblock untereinander -
        im Mockup sind sie EINE Zeile (Zeile B). Jetzt row mit Umbruch: auf breiten
        Schirmen eine Zeile, auf schmalen bricht sie von selbst um.
     2. Die Stationen brauchen die volle Breite und bekommen sie ausdruecklich
        (flex:1 0 100%), sonst haengen sie sich hinten an Zeile B an. */
#feKopfZone{
  position:sticky; top:0; z-index:60;
  background:var(--bg,#eef3f8);
  padding:10px 0 8px;
  margin-bottom:4px;
  box-shadow:0 10px 18px -12px #0f172a26;
  display:flex; flex-direction:row; flex-wrap:wrap; align-items:center;
  column-gap:10px; row-gap:8px;
}
#feKopfZone > #feFokusNav{ flex:1 0 100%; order:2 }
/* 🔴 23.08. NACHGEBESSERT — die erste Fassung setzte nur `display:flex` und liess
   damit die INNEREN Regeln der Rail stehen. Live gemessen war das Ergebnis kaputt:
     #feRailNav hatte weiterhin flex-direction:column und align-items:center
       -> "NAVIGATION" stand zentriert UEBER dem Posteingang-Knopf, mitten auf der Seite
     #feFokusNav bekam repeat(3,1fr), hat aber VIER Kinder - die Ueberschrift belegte
       Spalte 1, die drei Stationen rutschten auf 2, 3 und Zeile 2
     .feRailEigen behielt ihre schmale Breite aus der 180px-Spalte
   Lehre: wer einen Block aus einer schmalen Spalte in eine breite Zeile hebt, muss
   die Richtung ausdruecklich umstellen. `display:flex` allein aendert sie nicht -
   flex-direction wird vererbt, nicht zurueckgesetzt. */
#feKopfZone > #feRailNav,
#feKopfZone > #feProdKopf{
  display:flex !important;
  flex-direction:row !important;
  align-items:center !important;
  justify-content:flex-start;
  gap:7px; flex-wrap:wrap;
  border:0; padding:0; margin:0;
  /* 🔴 23.08. hier stand width:100%. Genau das zwang die beiden Bloecke in zwei
     Zeilen - jeder nahm die volle Breite, auch wenn er 300px brauchte. Der
     Navigationsblock nimmt jetzt, was er braucht; der Produktblock fuellt den
     Rest und bricht bei Bedarf um.
     ⚠ Geaendert wurde die BESTEHENDE Regel, nicht eine zweite daruntergesetzt.
     Zwei Regeln fuer dieselbe Breite waren heute schon zweimal die Fehlerquelle. */
  width:auto;
}
/* 🔴 order, weil die REIHENFOLGE im DOM nicht die gewuenschte ist: feProduktKopf()
   haengt sich vor feRailNav() ein, also stand "Speichern · Bio · Freigabe" ueber
   "← Posteingang". Am Live-DOM gemessen und mit order korrigiert - das ist eine
   Anzeigefrage, kein Grund, die Aufbaureihenfolge im JavaScript umzustellen. */
#feKopfZone > #feRailNav{ flex:0 0 auto; order:0 }
/* 🔴 23.08. `flex:1 1 0` statt `1 1 auto`. Mit `auto` nimmt der Produktblock
   seine Inhaltsbreite als Ausgangsgroesse - passt die nicht neben den
   Navigationsblock, bricht er als GANZES um, und "← Posteingang" steht allein
   in einer eigenen Zeile. Mit `0` darf er schrumpfen und bricht INNEN um.
   Gemessen: Bedienzeile 118 -> 97px, Kasten 284 -> 263px. */
#feKopfZone > #feProdKopf{ flex:1 1 0; min-width:0; order:1 }
/* 🔴 Vier Gruppenwoerter, die nichts erklaeren: NAVIGATION 69px, PRODUKT 53px,
   AKTIONEN 67px, EIGENSCHAFTEN 102px - zusammen 291px Breite, live gemessen.
   Ein Knopf "← Posteingang" braucht keine Ueberschrift "NAVIGATION", und was
   ueber einem Speichern-Knopf steht, ist erkennbar eine Aktion. Im Mockup gibt
   es sie deshalb nicht.
   Stehen bleiben die, die wirklich unterscheiden: BIO, ERNÄHRUNGSFORM und
   FREIGABE (letzterer traegt .feKzTrenn) - ohne sie waeren die Chips daneben
   nicht zuzuordnen. */
#feKopfZone > #feRailNav > .feRailGrpTit,
#feKopfZone > #feProdKopf > .feRailGrpTit:not(.feKzFrgTit){ display:none }
/* 🔴 Die Eigenschaften-Gruppe war fuer 180px gebaut: Bio und Ernaehrungsform standen
   UNTEREINANDER. Sie allein machte den Produktblock 109px hoch und damit die ganze
   Zone 218px statt der geplanten 150. `width:auto` reichte nicht - die Richtung
   musste umgestellt werden. Live gemessen nach dem Fix: Produktblock 109 -> 37px,
   Zone 218 -> 145px, alles in einer Zeile. */
#feKopfZone .feRailEigen{
  display:flex !important; flex-direction:row !important; flex-wrap:wrap;
  align-items:center; gap:6px; width:auto; max-width:none; margin:0; flex:0 1 auto;
}
#feKopfZone .feRailEigen > *{ margin:0 }
#feKopfZone .feRailEigen .feRailGrpTit{ margin:0 3px 0 8px }
#feKopfZone > #feProdKopf > .feRailGrpTit{ margin:0 2px 0 10px }
/* Der Produktzustand ("gespeichert") und der Freigabehinweis sind Text, kein Block. */
#feKopfZone .feProdZust{ display:inline-block; white-space:nowrap }
/* Die Gruppenueberschriften der Rail waren Zeilen - hier sind sie Beschriftungen
   VOR ihrer Gruppe. Ohne sie wuesste niemand, wozu drei Chips nebeneinander gehoeren. */
#feKopfZone .feRailGrpTit{
  margin:0 2px 0 0; font-size:9px; opacity:.75; white-space:nowrap;
}
/* Trennstriche zwischen den Gruppen - sonst ist es eine Reihe aus 17 Knoepfen. */
#feKopfZone > #feProdKopf > .feRailGrpTit:not(:first-child)::before{
  content:""; display:inline-block; width:1px; height:16px;
  background:var(--line); margin:0 8px -3px 0;
}
/* Die Stationen: drei gleich breite Karten nebeneinander.
   ⚠ #feFokusNav hat VIER Kinder - die Gruppenueberschrift zaehlt mit. Ohne die Regel
   darunter belegt sie Spalte 1 und schiebt die dritte Station in eine zweite Zeile.
   Genau so sah es live aus. */
/* 🔴 23.08. Die Stationen sind aus #feKopfZone in den gemeinsamen Rahmen
   #feKopfFix gezogen (sie stehen im Entwurf NEBEN dem dunklen Kasten, nicht
   darin). Alle Regeln unten galten nur fuer den alten Ort - live sah man
   sofort, was fehlt: "ARBEITSFLUSS" belegte wieder Spalte 1, die dritte
   Station rutschte in eine zweite Zeile, und die Kartenoptik war weg.
   Erweitert statt kopiert: dieselbe Regel gilt jetzt an beiden Orten. Zwei
   getrennte Blöcke waeren beim naechsten Umzug wieder auseinandergelaufen. */
#feKopfZone > #feFokusNav,
#feKopfFix > #feFokusNav{
  display:grid !important; grid-template-columns:repeat(3,1fr); gap:7px;
  border:0; padding:0; margin:0;
}
#feKopfZone > #feFokusNav > .feRailGrpTit,
#feKopfFix > #feFokusNav > .feRailGrpTit{ display:none }
#feKopfZone .feStTitel,
#feKopfFix .feStTitel{ display:none }   /* die Ueberschrift "Stationen" braucht es waagerecht nicht */
#feKopfZone .feFokusSt,
#feKopfFix .feFokusSt{
  border:1px solid var(--line); border-left:0; border-top:3px solid transparent;
  border-radius:var(--fk-r-mittel,10px); background:var(--card);
  padding:7px 11px; box-shadow:0 5px 16px #0f172a0d;
}
#feKopfZone .feFokusSt.akt,
#feKopfFix .feFokusSt.akt{ border-top-color:var(--k-2f6fd6,#2f6fd6); background:#f8fbff }

/* Unter 700px bricht alles um - Rueckfall, kaum genutzt (Adminarbeit am Laptop). */
@media (max-width:699px){
  #feKopfZone > #feFokusNav,
  #feKopfFix > #feFokusNav{ grid-template-columns:1fr }
  #feKopfZone{ position:static }   /* fixiert waere auf schmalen Schirmen zu viel Hoehe */
}

/* Die Rail ist im Fokusmodus leer, seit ihre drei Bloecke oben stehen - sie hinterliess
   einen 28px hohen weissen Rest. Sie bleibt im DOM (Rueckfall der Weiche), wird aber
   nicht mehr gezeigt. Entfernt wird sie erst, wenn die Zone nachgezaehlt ist. */
body.riFokus #feRahmen > #feRail{ display:none }

/* ============================================================================
   KOPFZONE · FREIGABE UND GRUPPENTRENNUNG   (Work #181 Schritt 2, 23.08.2026)
   ----------------------------------------------------------------------------
   Zwei Dinge, die nach dem Umzug fehlten:
   1) Die Gruppen liefen ohne Trennung ineinander - siebzehn Bedienelemente in einer
      Reihe sind ohne Gliederung eine Wand. Der Strich steht VOR der Ueberschrift,
      nicht dazwischen, damit die Ueberschrift zu ihrer Gruppe gehoert und nicht zur
      vorigen.
   2) Die Freigabe war im Fokusmodus gar nicht sichtbar: ihre Rail-Karte wurde
      ausgeblendet, und der Knopf lag nur in der Abschlusskarte am Ende von Station 3.
   ========================================================================== */
#feKopfZone .feKzTrenn::before{
  content:""; display:inline-block; width:1px; height:15px;
  background:var(--line); margin:0 9px -3px 0; vertical-align:middle;
}
#feKopfZone .feProdFrg{ display:inline-flex; align-items:center; gap:7px; flex-wrap:nowrap; min-width:0 }
#feKopfZone .feKzChip{
  display:inline-flex; align-items:center; gap:4px; white-space:nowrap;
  border-radius:999px; padding:3px 10px; font-size:11px; font-weight:800;
  border:1px solid var(--line); background:var(--card); color:var(--muted);
}
#feKopfZone .feKzChip.ok{ background:#ecfdf5; color:#166534; border-color:#bfe3cb }
#feKopfZone .feKzChip.rot{ background:#fdeeeb; color:#b91c1c; border-color:#f3c9c1 }
/* Der Grund wird gekuerzt, aber nie weggelassen - Ralphs Regel: bei einer Blockade
   steht der Grund daneben. Der volle Wortlaut haengt als Mausanzeige daran. */
#feKopfZone .feKzGrund{
  font-size:10.5px; color:var(--muted); line-height:1.25;
  max-width:230px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* 🔴 23.08. .feKzFrgBtn ist ersatzlos weg. Der Knopf, den diese Regel bemalt hat,
   war der ZWEITE "✓ Freigeben" auf dem Schirm - derselbe Aufruf wie feProdFrei im
   Aktionsblock. Der aeltere bleibt, dieser ist entfernt. Eine Regel ohne Element
   ist kein Schaden, aber sie sieht beim naechsten Lesen aus wie ein fehlendes
   Element - deshalb faellt sie mit. */
/* Der alte Freigabe-Satz ist durch den Chip ersetzt. */
#feKopfZone .feProdFrgTxt{ display:none }

/* ============================================================================
   🔴 VERA-OPTIK FUER DEN EDITOR   (Work #181, 23.08.2026)
   ----------------------------------------------------------------------------
   Ralph: "darstellung der produktkarte wie im fähigkeitsbericht von vera."
   Die Werte hier sind aus VERA_Vision_Equipment_Reports_Analysis_v2.34.html
   AUSGELESEN, nicht erfunden - jeder ist dort belegbar:
     Karten            border-radius 16px + box-shadow 0 5px 16px #0f172a0d
     Innenkaesten      12px, Grund #f8fbff, Rahmen #c7d8ea
     Kopf              linear-gradient(120deg,#12395a,#1f4e78)

   WARUM DAS HIER STEHT UND NICHT IN DEN EINZELREGELN: der Editor hat EINE
   Kartenvariable --fk-radius und EINE Klasse .feKarte. Vier Werte aendern die
   ganze Optik. Haette ich stattdessen 49 Einzelregeln angefasst, waere es die
   Sammelersetzung geworden, die am 15.08. zwei Dateien beschaedigt hat.

   NICHT ANGEFASST: Schriftgroessen, Abstaende, Farben der Statuszeichen. Eine
   Optikaenderung auf einmal reicht - sonst weiss hinterher niemand, welcher
   Wert den Unterschied gemacht hat.
   ========================================================================== */
/* 🔴 HIER STAND EIN ZWEITER .feKarte-BLOCK, der --fk-radius und --fk-balken erneut
   setzte. Zwei Dauertests haben ihn gefangen: "--fk-radius genau einmal gesetzt" und
   "--fk-balken genau einmal gesetzt". Sie hatten recht, und der Fehler ist derselbe,
   den ich zwei Absaetze weiter unten gerade an der Fokus-Regel behoben habe - nur
   diesmal von mir selbst gebaut. Die Werte gehoeren in die EINE Definition, nicht
   in eine zweite daneben. Sie stehen jetzt oben im Originalblock von .feKarte.
   Was hier bleibt, sind Eigenschaften, die .feKarte vorher gar nicht hatte. */
.feKarte{
  box-shadow:0 5px 16px #0f172a0d;   /* VERA: der Schatten macht die Karte zur Karte */
  border-color:#d9e2ef;              /* VERA: --line */
}
/* Die Kaesten INNERHALB einer Karte - bei VERA .derivedBox / .grpPanel / .statusStrip */
#feEditorBody .feHolBox,
#feEditorBody .feSammelKasten,
#feKopfZone .feKzChip{
  border-color:#c7d8ea;
}
#feEditorBody .feHolBox{ background:#f8fbff }
/* Der Produktkopf: VERAs Verlauf statt Volltonfarbe. Die Textfarben bleiben,
   sie waren fuer dunklen Grund gebaut. */
#feKopfband{
  background:linear-gradient(120deg,#12395a,#1f4e78);
  box-shadow:0 5px 16px #0f172a1a;
}
/* Der Warnchip fuer "freigegeben, aber noch ein offener Punkt". Gelb, nicht rot:
   das Produkt ist live, es ist kein Fehler - aber es ist auch nicht sauber. */
#feKopfZone .feKzChip.warn{ background:#fffbeb; color:#a16207; border-color:#fde68a }

/* ============================================================================
   KOPFBAND · BILD UND INDEX   (Work #181, Mockup Zeile A, 23.08.2026)
   ----------------------------------------------------------------------------
   Beides fehlte: das Bild kam im Kopf gar nicht vor, obwohl _fgEdit ein Feld
   bild_url fuehrt, und der Index stand nur als Wort im Statusstreifen.
   Im VERA-Bericht traegt der Kopf beides - links das Objekt, rechts die Kennzahl.
   ========================================================================== */
/* 🔴 Erst mit vier Spalten gebaut - live gemessen wuchs das Kopfband dadurch von
   63 auf 108px, weil es FUENF sichtbare Kinder hat: Bild, Textblock, Statuszeichen,
   P-Nummer und Index. Das fuenfte brach um. Zaehlen statt schaetzen: der versteckte
   h2 zaehlt nicht mit, die anderen fuenf schon. */
#feKopfband{ display:grid; grid-template-columns:auto 1fr auto auto auto;
  align-items:center; gap:14px }
#feKopfband .fkbBild{
  width:52px; height:52px; border-radius:var(--fk-r-mittel,10px);
  background:#ffffff1a; border:1px dashed #ffffff4d;
  display:flex; align-items:center; justify-content:center; overflow:hidden; flex:0 0 auto;
}
#feKopfband .fkbBild img{ width:100%; height:100%; object-fit:cover; display:block }
#feKopfband .fkbBild span{ font-size:9px; color:#ffffffb3; text-align:center; line-height:1.2 }
/* 🔴 23.08. der Index im Kopf zeigt jetzt das MARKUP der vorhandenen Funktion
   _feStreifenBewertung() - .feStBew mit em/b/i. Vorher hatte er eigene Klassen
   und eine eigene, aermere Fallunterscheidung; die 61 stand dadurch zweimal auf
   dem Schirm. Hier steht deshalb nur noch, was der dunkle Grund braucht:
   helle Schrift. Groessen und Aufbau kommen aus .feStBew und bleiben dort. */
/* ============================================================================
   🔴 DER DUNKLE KOPFBLOCK  ·  Work #181, 23.08.2026
   ----------------------------------------------------------------------------
   Ralph, mit dem Entwurf daneben: "das war dein mockup. aktuell noch nicht so."

   DER UNTERSCHIED IN EINEM SATZ: im Entwurf sind Produktkopf und Bedienzeile
   EIN dunkler Kasten. Gebaut war der Kopf dunkel und die Bedienzeile darunter
   auf hellem Grund - zwei Bloecke, wo einer gemeint war.

   WARUM DAS MEHR IST ALS FARBE: die Bedienzeile stand als "Werkzeugleiste der
   Seite" da. Im Entwurf gehoert sie sichtbar zu DIESEM Produkt - deshalb ein
   Kasten, der oben den Namen traegt und unten die Knoepfe dazu.

   ⚠ WARUM HIER SO VIELE !important STEHEN: die Knoepfe in dieser Zeile tragen
   ihre Farben INLINE im JavaScript ("style=background:var(--card);color:..."),
   teils seit Monaten. Inline schlaegt jede Regel im Stylesheet - ohne
   !important bliebe eine dunkelgraue Schrift auf dunkelblauem Grund stehen.
   Die saubere Loesung waere, die Inline-Farben im JavaScript zu entfernen. Das
   sind rund zwanzig Stellen quer durch eine 8000-Zeilen-Datei, jede davon eine
   Gelegenheit, etwas anderes kaputtzumachen. Hier wird die Farbe an EINER
   Stelle ueberschrieben statt an zwanzig entfernt. Nicht schoen, aber ehrlich
   umkehrbar: dieser Block loescht sich in einem Stueck.
   ========================================================================== */
/* 🔴 23.08. BREITE UND POSITION KOMMEN AUS DER MESSUNG, nicht aus einer Zahl.
   feKopfMassSync() setzt --fe-kopf-links und --fe-kopf-breite auf die linke
   Kante und die Breite des Inhalts darunter. Ralph: "maximal so breit wie der
   untere bereich". Die Werte haben Rueckfallwerte, damit eine ausgefallene
   Messung keinen unsichtbaren Kopf ergibt - lieber zu breit als weg. */
/* 🔴 23.08. EIN RAHMEN, EINE FIXIERUNG. Ralph: "grauer balken oben, menue oben
   ist getrennt, soll ja eins sein."

   VORHER waren Kopfband, Statusstreifen und Bedienzeile EINZELN fixiert, mit
   gestaffelten Abstaenden von oben. Live gemessen: Band endet bei 78, Streifen
   klebt bei 122, Zeile bei 149 - dazwischen 44px heller Seitengrund (Ralphs
   "grauer balken") und darunter eine Ueberlappung.

   Ein sticky-Element klebt an SEINER Position. Drei davon ergeben drei Balken,
   die unabhaengig voneinander haengenbleiben - nie einen Block. Man kann die
   Abstaende nachrechnen, bis es bei einer Fensterbreite und einem Produkt
   passt; beim naechsten steht die Luecke wieder da.

   Jetzt umschliesst #feKopfFix alle drei, und NUR er ist fixiert. Die Luecke
   ist nicht wegberechnet - es gibt nichts mehr, wozwischen sie entstehen
   koennte. Die Innenteile brauchen dadurch weder eigene Position noch eigene
   Breite: sie fuellen den Rahmen. */
body.riFokus #feKopfFix{
  position:sticky; top:0; z-index:60;
  width:var(--fe-kopf-breite,auto);
  margin:0 auto 4px;
  max-width:100%;
  box-sizing:border-box;
  background:var(--bg,#eef3f8);   /* Seitengrund - der dunkle Kasten sitzt DARIN */
  padding-bottom:8px;
}
/* 🔴 23.08. EINE FARBE FUER DEN GANZEN KASTEN. Ralph: "farbe unterschiedlich."
   Gemessen und er hat recht:
     Kopfband       linear-gradient(120deg,#12395a,#1f4e78)   - ein Verlauf
     Bedienzeile    #134a63                                    - ein Vollton
   Zwei verschiedene Blaus uebereinander sehen aus wie zwei Kaesten, auch wenn
   keine Fuge mehr dazwischen ist. Der Verlauf liegt jetzt auf dem gemeinsamen
   Kasten und laeuft ueber alle drei Teile durch; die Teile selbst sind
   durchsichtig. Damit gibt es die Ungleichheit nicht mehr, statt sie an zwei
   Stellen gleich einzustellen und beim naechsten Mal wieder auseinanderlaufen
   zu lassen. */
/* 🔴 23.08. ZWEITE FASSUNG DER FARBE. Ralph: "nur noch den farblichen
   unterschied anpassen."
   Erster Versuch: Band bekam den Verlauf, die Bedienzeile den Endton als
   Vollton. Zwei Werte, aufeinander abgestimmt - und genau deshalb wieder
   verschieden, sobald einer angefasst wird. Ralph hat den Unterschied prompt
   gesehen.
   Jetzt traegt der KASTEN den Verlauf, und Band und Bedienzeile sind
   durchsichtig. Es gibt nur noch eine Farbangabe. Sie kann nicht mehr
   auseinanderlaufen, weil es nichts gibt, wovon sie abweichen koennte. */
body.riFokus #feKopfFix{
  --fkf-bg:linear-gradient(150deg,#12395a,#1f4e78);
}
body.riFokus #feKopfFix > #feKopfband,
body.riFokus #feKopfFix > #fe_gesamtstatus,
body.riFokus #feKopfFix > #feKopfZone{
  background:var(--fkf-bg);
  background-attachment:fixed;   /* ein Verlauf ueber alle drei, nicht drei eigene */
}
body.riFokus #feKopfFix > #feKopfband{
  position:static; margin:0; width:auto; max-width:none;
  border-radius:10px 10px 0 0;
  box-shadow:none;
}
body.riFokus #feKopfFix > #feKopfZone{
  position:static; margin:0; width:auto; max-width:none;
  border-radius:0 0 10px 10px;
  padding:6px 18px 8px;
  box-shadow:0 10px 18px -12px #0f172a26;
}
/* 🔴 Die Stationen stehen jetzt NEBEN dem Kasten, als eigene helle Reihe -
   so wie im Entwurf. Vorher lagen sie im Kasten und haben seine untere
   Rundung verdeckt. */
/* Aufbau und Kartenoptik der Stationen stehen oben bei #feKopfZone > #feFokusNav
   und gelten jetzt auch hier. Hier bleibt nur der Abstand zum Kasten. */
body.riFokus #feKopfFix > #feFokusNav{
  margin:10px 0 0 !important; background:transparent;
}
/* 🔴 Der Statusstreifen zwischen Band und Bedienzeile: sein Innenteil bringt
   margin-bottom:12px mit. Live gemessen war das die letzte sichtbare Fuge im
   Kasten - 12px heller Streifen quer durch das Dunkelblau. Ich haette sie fast
   als "sieht doch gut aus" durchgehen lassen; gemessen ist sie eindeutig. */
body.riFokus #feKopfFix > #fe_gesamtstatus{
  position:static; margin:0; width:auto; max-width:none; border-radius:0; top:auto;
}
/* 🔴 23.08.2026, Ralph-Entscheid: "da ist aber immer noch ein zwischenbalken.
   die information ist gut, aber gehoert zu blockiert als begruendung neben den
   roten blockiert button. dann kann die zeile komplett weg."

   DER STREIFEN IST IM FOKUSMODUS UNSICHTBAR. Nicht geloescht - das waere der
   Unterschied zwischen "weg" und "verloren":
   - Sein Inhalt steht jetzt neben dem Freigabe-Chip (Blockadegruende zuerst,
     dann Hinweise), also an der Stelle, an der man ihn braucht.
   - Der Baustein selbst stammt aus Work #133 und bleibt vollstaendig erhalten.
     Ausserhalb des Fokusmodus zeigt er unveraendert alles.
   - Rueckbau: diese eine Regel entfernen.

   ⚠ WAS ICH VORHER GEPRUEFT HABE, damit nichts still verschwindet:
     Etikett-Blocker            -> Freigabegrund, steht neben dem Chip
     Naehrwerte unvollstaendig  -> Freigabegrund, ebenso
     Freigabe blockiert         -> ist der Chip selbst
     Speichern fehlgeschlagen   -> steht in Zeile A hinter der P-Nummer
     Dublettentreffer           -> Chip "⚠ 1× ähnlich" im Kopfband, anklickbar
     Hinweise                   -> neben dem Chip
   Kein Punkt ohne zweiten Ort. */
body.riFokus #panel > #fe_gesamtstatus,
body.riFokus #fe_gesamtstatus{ display:none }

/* 🔴 23.08. HOEHE. Ralph: "der obere bereich ist noch viel zu hoch."
   Gemessen an P32667: der Streifen war 59px hoch fuer EINEN Satz - "· 1
   Bestandteil(e) ohne Verarbeitungsnote". Das Innenteil bringt 11px Polster
   oben und unten mit, dazu die Abstaende der leeren Gruppen daneben.
   Im Kasten braucht er das nicht: er hat weder Rahmen noch eigene Flaeche,
   die Polsterung trennte ihn von nichts. */
body.riFokus #feKopfFix > #fe_gesamtstatus .feStStreifen{
  margin-bottom:0; padding:4px 0; gap:6px;
}
/* 🔴 Der Fusstext ("· 1 Bestandteil(e) ohne Verarbeitungsnote") stand in
   var(--muted) - auf dunklem Grund praktisch unsichtbar. Im Screenshot war er
   nur zu ahnen. Er ist die einzige Aussage, die dieser Streifen ueberhaupt
   noch traegt; sie darf nicht die blasseste auf der Seite sein. */
body.riFokus #feKopfFix > #fe_gesamtstatus .feStFuss{
  padding-top:0; margin:0; color:#d7e7f2 !important; font-size:11.5px;
}
body.riFokus #feKopfFix > #fe_gesamtstatus .feStFuss *{ color:#d7e7f2 !important }
/* Das Kopfband: 12px Polster oben und unten um ein 52px hohes Bild ergaben 76px.
   Das Bild traegt die Hoehe, das Polster muss sie nicht verdoppeln. */
body.riFokus #feKopfFix > #feKopfband{ padding:9px 18px }
body.riFokus #feKopfFix > #feKopfband .fkbBild{ width:44px; height:44px }
/* 🔴 23.08. DER WEISSE BALKEN. Ralph: "der weisse balken oben muss weg."
   Das war der Statusstreifen: weisser Grund, volle Fensterbreite, zwischen dem
   dunklen Kopf und der dunklen Bedienzeile. Er sass ausserdem mit
   margin-top:-17px unter dem Band - im Zusammenspiel mit den beiden fixierten
   Baendern ergab das die Ueberlappung beim Scrollen.
   Er gehoert jetzt zum Block: dieselbe Farbe, dieselbe Breite, kein eigener
   Rahmen. Sichtbar ist er ohnehin nur noch, wenn er etwas zu melden hat. */
/* 🔴 Der Selektor heisst `body.riFokus #panel > #fe_gesamtstatus` und nicht
   einfach `body.riFokus #fe_gesamtstatus`. Grund, live gemessen: es gibt
   bereits `#panel > #fe_gesamtstatus{ background:var(--card,#fff) }`. Zwei IDs
   schlagen eine ID plus Klasse - meine kuerzere Regel stand im Stylesheet und
   hatte keine Wirkung. Der Balken blieb weiss.
   Aufgefallen ist es nur, weil ich den TATSAECHLICHEN Wert abgefragt habe und
   nicht, ob die Regel dasteht. Eine Regel, die existiert, ist noch keine, die
   gilt. */
body.riFokus #panel > #fe_gesamtstatus,
body.riFokus #fe_gesamtstatus{
  position:sticky; top:calc(var(--fe-kopf-hoehe,0px) + 44px); z-index:59;
  margin-top:0;
  background:#134a63; color:#e8f2f7;
  border:0; border-radius:0; box-shadow:none;
  padding:0 18px;
}
body.riFokus #fe_gesamtstatus .feStStreifen{ background:transparent; border:0; box-shadow:none }
body.riFokus #fe_gesamtstatus .feStGrpTit{ color:#a8cfe0 }
body.riFokus #fe_gesamtstatus .feStFuss{ color:#ffffffb3 }
/* Solange der Streifen steht, endet der Block erst unter ihm. */
body.riFokus #fe_gesamtstatus:not(.leer){ border-radius:0 }
body.riFokus #feKopfZone{ border-radius:0 0 10px 10px }
/* Die Stationen gehoeren NICHT in den dunklen Kasten - im Entwurf sind es drei
   helle Karten darunter. Sie holen sich den Seitengrund zurueck und ziehen ihn
   ueber die volle Breite, damit der dunkle Kasten sauber endet. */
body.riFokus #feKopfZone > #feFokusNav{
  background:var(--bg,#eef3f8);
  margin:0 -18px; padding:10px 0 0;
}
/* Zeile B braucht Luft nach oben und unten, seit der Kasten kein Aussenpadding
   mehr hat. */
body.riFokus #feKopfZone > #feRailNav,
body.riFokus #feKopfZone > #feProdKopf{ padding:9px 0 !important }

/* --- Schrift und Trenner auf dunklem Grund ---------------------------------
   🔴 NICHT GESCHAETZT, SONDERN GERECHNET. Nach dem ersten Versuch habe ich den
   Kontrast jedes Textelements in dieser Zeile gegen SEINEN tatsaechlichen
   Hintergrund gemessen (nicht gegen den der Zone - die Stationen stehen hell
   und waeren sonst als Fehler gezaehlt worden; genau das ist mir beim ersten
   Anlauf passiert und meldete 16 Probleme statt 6).
   Gefunden wurden sechs Stellen unter 4.5:1 - der Wert, ab dem normaler Text
   als lesbar gilt:
     "gespeichert"       1.6   feProdZust
     "Bio"               1.6   feSegTitel
     "Ernaehrungsform"   1.6   feSegTitel
     "berechnet: vegan"  1.6   feSegAuto
     "vegan" (Auto-Wort) 1.3
     "Freigeben"         3.3   weisse Schrift auf Gruen - grenzwertig, deshalb
                               dunkleres Gruen statt hellerer Schrift
   Alle sechs stehen unten. Wer hier etwas aendert, misst bitte nach, statt
   sich die Farbe anzusehen: auf dunklem Grund sieht Grau laenger gut aus,
   als es lesbar ist. */
body.riFokus #feKopfZone .feRailGrpTit{ color:#a8cfe0 !important }
body.riFokus #feKopfZone .feProdZust,
body.riFokus #feKopfZone .feSegTitel,
body.riFokus #feKopfZone .feSegAuto{ color:#a8cfe0 !important }
/* Das Auto-Wort ("berechnet: vegan") faerbt sich nach der Ernaehrungsform und
   traegt seine Farbe inline - auf dunklem Grund bleibt davon nichts uebrig. */
body.riFokus #feKopfZone .feSegAuto *{ color:#e8f2f7 !important }
/* Gruen mit weisser Schrift kam auf 3.3:1. Eine Stufe dunkler bringt 4.6:1,
   ohne dass der Knopf seine Signalwirkung verliert. */
body.riFokus #feKopfZone .feProdFrei{ background:#127a3c !important }
body.riFokus #feKopfZone .feKzGrund{ color:#ffffffb3 !important }
body.riFokus #feKopfZone .feKzTrenn{ border-color:#ffffff2e !important }

/* --- Knoepfe: heller Rahmen auf dunklem Grund ------------------------------ */
body.riFokus #feKopfZone #feNavPost,
body.riFokus #feKopfZone .feProdMehr,
body.riFokus #feKopfZone #feNavBlaett button{
  background:#ffffff1a !important; color:#fff !important;
  border-color:#ffffff40 !important;
}
body.riFokus #feKopfZone #feNavBlaett button:disabled{
  color:#ffffff59 !important; background:#ffffff0d !important;
}
body.riFokus #feKopfZone #feNavBlaett{ color:#a8cfe0 }
/* Der Neuladen-Knopf traegt seine Farben ebenfalls inline. */
body.riFokus #feKopfZone button[onclick^="adminNeuLaden"]{
  background:#ffffff1a !important; color:#fff !important; border-color:#ffffff40 !important;
}
/* 🔴 23.08. ALLES IN DIESER ZEILE IST EINE PILLE. Ralph: "die buttons wieder
   schoener machen als chips."
   Gemessen war es gemischt: "← Posteingang", der Statusknopf und "Speichern"
   hatten 999px Rundung, das "⋯" und alle Bio-/Ernaehrungs-Chips 0px - also
   Rechtecke. Nebeneinander sieht das aus, als gehoerten sie nicht zusammen.
   Eine Regel fuer alle statt sieben einzelne: was in dieser Zeile klickbar
   ist, ist rund. */
body.riFokus #feKopfZone button,
body.riFokus #feKopfZone .feKzChip,
body.riFokus #feKopfZone .feSegBtn{
  border-radius:999px !important;
}
body.riFokus #feKopfZone .feProdMehr{ padding:4px 11px !important }
/* 🔴 Der Freigabe-Knopf: EIN Element, zwei Zustaende (Ralph-Entscheid 23.08.).
   Rot und nicht klickbar, solange etwas blockiert - gruen und klickbar, sobald
   es passt. Die Groesse ist in beiden Zustaenden gleich, damit die Zeile beim
   Umschalten nicht springt. */
body.riFokus #feKopfZone .feFrgKnopf{
  border-radius:999px !important;
  padding:5px 13px; font-size:12.5px; font-weight:800; white-space:nowrap;
  border:1px solid transparent; cursor:pointer; line-height:1.35;
}
body.riFokus #feKopfZone .feFrgKnopf.ok{
  background:#127a3c !important; color:#fff !important; border-color:#1c9451 !important;
}
body.riFokus #feKopfZone .feFrgKnopf.ok:hover{ background:#158c46 !important }
body.riFokus #feKopfZone .feFrgKnopf.rot{
  background:#7a2230 !important; color:#ffd9de !important; border-color:#a33146 !important;
  cursor:default;
}
/* ⚠ KEIN opacity auf dem gesperrten Zustand: er soll nicht "ausgegraut"
   aussehen, sondern rot und eindeutig. Ausgegraut heisst "kaputt oder egal",
   rot heisst "gesperrt, und daneben steht warum". */
body.riFokus #feKopfZone .feSegBtn{ padding:4px 10px !important }
/* Die Segmentknoepfe (Bio, Ernaehrungsform): ausgewaehlt bleibt hell hervor-
   gehoben, nicht ausgewaehlt wird durchscheinend. */
body.riFokus #feKopfZone .feSegBtn{
  background:#ffffff14 !important; color:#e8f2f7 !important; border-color:#ffffff33 !important;
}
body.riFokus #feKopfZone .feSegBtn.akt{
  background:#fff !important; color:#134a63 !important; border-color:#fff !important;
}
/* 🔴 23.08. Ralph: "entwurf koennte wieder farbig sein."
   Meine Umstellung auf dunklen Grund hatte den Statuschip auf durchscheinendes
   Weiss gesetzt - dieselbe Optik wie "← Posteingang" und "⋯". Damit sah der
   wichtigste Zustand des Produkts aus wie ein Hilfsknopf.
   Er traegt seine Bedeutung jetzt wieder in der Farbe: Entwurf gelb, Aktiv
   gruen. Gedeckte Toene, damit sie auf Dunkelblau nicht leuchten wie Warnungen -
   der Zustand ist ja keiner. */
body.riFokus #feKopfZone .feProdStatus{
  background:#7a5a16 !important; color:#ffeec2 !important; border-color:#a37c1f !important;
}
body.riFokus #feKopfZone .feProdStatus.aktiv{
  background:#1c6b47 !important; color:#d9f2e2 !important; border-color:#2b8c60 !important;
}
/* Speichern und Freigeben behalten ihre Signalfarben - sie sollen sich vom
   Rest abheben, das ist auf dunklem Grund genauso richtig wie auf hellem. */
body.riFokus #feKopfZone .feProdSave{ box-shadow:0 0 0 1px #ffffff26 }
body.riFokus #feKopfZone .feProdFrei{ box-shadow:0 0 0 1px #ffffff26 }
/* Statuschips der Freigabe: gedeckte Flaechen, damit sie auf dunkel nicht
   leuchten wie Warnlampen. */
body.riFokus #feKopfZone .feKzChip.ok{ background:#1c6b47 !important; color:#d9f2e2 !important; border-color:#2b8c60 !important }
body.riFokus #feKopfZone .feKzChip.rot{ background:#7a2230 !important; color:#ffd9de !important; border-color:#a33146 !important }
body.riFokus #feKopfZone .feKzChip.warn{ background:#7a5a16 !important; color:#ffeec2 !important; border-color:#a37c1f !important }
@media (max-width:699px){
  body.riFokus #feKopfZone{ padding:0 12px }
  body.riFokus #feKopfZone > #feFokusNav{ margin:0 -12px }
}

/* 🔴 23.08. Der Statusstreifen blendet sich aus, wenn nach dem Aussortieren der
   Doppelungen nichts uebrig ist. Gemessen an P73634: 159px fuer acht Angaben,
   von denen sieben woanders standen. Er bleibt im DOM und ist beim naechsten
   Blocker sofort wieder da - er ist versteckt, nicht abgebaut. */
#fe_gesamtstatus.leer{ display:none }
/* 🔴 23.08. nach der Live-Abnahme von 4383: die Gruppenwoerter DATENSTATUS und
   PRÜFUNG standen noch da, obwohl beide Chip-Faecher leer waren - 14px je
   Ueberschrift plus Abstand fuer eine Ankuendigung, der nichts folgt.
   :has() faellt auf einen leeren Container zurueck; kann ein Browser es nicht,
   sieht man wie vorher zwei Woerter zu viel - nichts geht kaputt. */
#fe_gesamtstatus .feStGrp:has(.feStGrpChips:empty){ display:none }
/* 🔴 23.08. order:9 — im Mockup steht die Index-Zahl ganz aussen rechts.
   Im DOM haengt sie VOR Statuspille und P-Nummer, weil sie dort in die Vorlage
   eingefuegt wurde; live stand sie deshalb mitten zwischen Name und ENTWURF.
   Verschoben wird die ANZEIGE, nicht die Vorlage: an der Reihenfolge im
   Markup haengen der versteckte h2 und der Dublettenchip. */
#feKopfband .fkbIndex{ text-align:right; line-height:1.1; min-width:64px; order:9 }
#feKopfband .feStBew{ align-items:flex-end }
#feKopfband .feStBew em{ color:#ffffffb3 }
#feKopfband .feStBew.still b, #feKopfband .feStBew.still i,
#feKopfband .feStBew.fehlt b, #feKopfband .feStBew.fehlt i{ color:#ffffffb3 }
@media (max-width:699px){
  #feKopfband{ grid-template-columns:auto 1fr auto; gap:10px }
  #feKopfband .fkbId{ grid-column:2/-1; text-align:left }
}
