@rslsp1/fa-app-tools 10.3.2 → 10.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -17,12 +17,12 @@
17
17
 
18
18
 
19
19
 
20
- var _chunkHFX6D53Wjs = require('./chunk-HFX6D53W.js');
20
+ var _chunkVSHSZEGVjs = require('./chunk-VSHSZEGV.js');
21
21
  require('./chunk-FTLEDU6C.js');
22
- require('./chunk-ACB2543O.js');
22
+ require('./chunk-DDH2SGZM.js');
23
23
 
24
24
  // package.json
25
- var version = "10.3.2";
25
+ var version = "10.3.4";
26
26
 
27
27
  // src/hooks/useOnClickOutside.ts
28
28
  var _react = require('react'); var _react2 = _interopRequireDefault(_react);
@@ -61,7 +61,7 @@ function useKeyboardNavigation(history, currentResult, setCurrentResult) {
61
61
  }
62
62
 
63
63
  // src/features/szenen/szenenViewStyles.generated.ts
64
- var SZENEN_VIEW_STYLES = '/* ==========================================================================\n SZENEN VIEW\n ========================================================================== */\n\n.szenen-view {\n display: grid;\n gap: var(--space-md);\n width: 100%;\n min-width: 0;\n font-family: var(--font-sans);\n padding: var(--space-md);\n}\n\n@media (max-width: 760px) {\n .szenen-view {\n padding: var(--space-sm);\n gap: var(--space-sm);\n }\n}\n\n/* Kette `szenen-design`, P1 \u2014 Bild zuerst, Text auf Abruf. Der Kopf ist nur\n * noch Titel und \u24D8; die Erklaerung klappt darunter auf. */\n.szenen-view__intro {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n gap: var(--space-sm);\n color: var(--color-text-primary);\n}\n\n.szenen-view__titel {\n display: grid;\n gap: 0.1rem;\n min-width: 0;\n}\n\n.szenen-view__intro h2,\n.szenen-view__intro p {\n margin: 0;\n}\n\n.szenen-view__intro h2 {\n font-size: clamp(1.5rem, 3vw, 1.9rem);\n font-weight: 700;\n letter-spacing: -0.01em;\n line-height: 1.15;\n}\n\n.szenen-view__eyebrow {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.szenen-view .szenen-view__info {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n min-height: 2.75rem;\n padding: 0;\n border-radius: var(--radius-full);\n}\n\n.szenen-view .szenen-view__info[aria-expanded="true"] {\n color: var(--color-text-primary);\n border-color: var(--color-accent-teal, #2dd4bf);\n}\n\n.szenen-view__intro-text {\n margin: 0;\n padding: var(--space-sm) var(--space-md);\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n font-size: 0.85rem;\n line-height: 1.4;\n}\n\n.szenen-icon {\n flex: none;\n}\n\n/* Fuer Screenreader sichtbar, fuer das Auge nicht \u2014 Status-Punkte und\n * Node-Symbole tragen ihre Bedeutung als Text. */\n.szenen-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n/* Die Bereiche als Pill-Leiste. Sie scrollt in sich, nie die Seite: `min-width:\n * 0` haelt sie in der Spalte, `overflow-x: auto` macht jeden Bereich\n * erreichbar, auch wenn nicht alle nebeneinander passen. */\n.szenen-view__nav {\n display: flex;\n flex-wrap: nowrap;\n gap: var(--space-xs);\n min-width: 0;\n padding: 0 0 var(--space-xs);\n overflow-x: auto;\n scrollbar-width: thin;\n}\n\n.szenen-view__nav button,\n.szenen-view button {\n min-height: 2.25rem;\n padding: 0.45rem 0.75rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n cursor: pointer;\n}\n\n.szenen-view button:hover:not(:disabled) {\n color: var(--color-text-primary);\n background: var(--color-bg-surface-hover);\n border-color: var(--color-border-hover);\n}\n\n.szenen-view button:focus-visible,\n.szenen-view input:focus-visible,\n.szenen-view select:focus-visible,\n.szenen-view textarea:focus-visible {\n outline: 2px solid var(--color-accent-blue);\n outline-offset: 2px;\n}\n\n.szenen-view button:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.szenen-view .szenen-view__nav button {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 0.4rem;\n min-height: 2.25rem;\n padding: 0 0.9rem;\n white-space: nowrap;\n border-radius: var(--radius-full);\n font-size: 0.875rem;\n}\n\n.szenen-view .szenen-view__nav button.is-active,\n.szenen-view .szenen-view__nav button[aria-selected="true"] {\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border-color: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-view__area {\n min-width: 0;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-view__capability-note,\n.szenen-area__lead {\n margin: 0;\n padding: var(--space-sm) var(--space-md);\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border-left: 3px solid var(--color-accent-purple);\n border-radius: var(--radius-sm);\n}\n\n.szenen-view__host-notes {\n color: var(--color-text-secondary);\n}\n\n.szenen-view__host-notes > summary {\n cursor: pointer;\n font-size: 0.8rem;\n}\n\n/* `box-sizing` steht hier und nicht beim Host: Die React-App bringt in\n * `master.css` einen globalen `* { box-sizing: border-box }` mit, Flow **nicht**\n * \u2014 dort ragte `width: 100%` plus Innenabstand um die Randbreite aus dem\n * Elternelement heraus und erzeugte auf ~390 px einen horizontalen Scroll. Die\n * gemeinsame Ansicht darf sich auf keinen Host-Reset verlassen. */\n.szenen-view input:not([type="checkbox"]),\n.szenen-view select,\n.szenen-view textarea {\n box-sizing: border-box;\n width: 100%;\n min-height: 2.25rem;\n padding: 0.5rem 0.65rem;\n color: var(--color-text-primary);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n font: inherit;\n}\n\n.szenen-view textarea {\n min-height: 7rem;\n resize: vertical;\n font-family: var(--font-mono);\n font-size: 0.8rem;\n}\n\n.szenen-view label {\n display: grid;\n gap: var(--space-xs);\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n}\n\n.szenen-view code,\n.szenen-view pre {\n font-family: var(--font-mono);\n overflow-wrap: anywhere;\n}\n\n.szenen-view h3,\n.szenen-view h4,\n.szenen-view h5 {\n margin-top: 0;\n}\n\n.szenen-view ul,\n.szenen-view ol {\n padding-left: 1.25rem;\n}\n\n.szenen-elements,\n.szenen-detail,\n.szenen-scene,\n.szenen-setup,\n.szenen-erweitert,\n.szenen-prompts,\n.szenen-shot,\n.szenen-media,\n.szenen-runs {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n}\n\n/* Arbeitsoberflaeche: Liste links, Bearbeitung rechts.\n *\n * Breit stehen beide Spalten nebeneinander \u2014 die Auswahl bleibt sichtbar,\n * waehrend bearbeitet wird. Schmal rendert die Komponente nur eine der beiden;\n * hier steht deshalb keine Regel, die die andere versteckt. */\n@media (min-width: 761px) {\n .szenen-elements {\n grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);\n align-items: start;\n }\n\n .szenen-elements__master,\n .szenen-elements__detail {\n min-width: 0;\n }\n}\n\n.szenen-elements__master,\n.szenen-elements__detail {\n display: grid;\n gap: var(--space-sm);\n align-content: start;\n min-width: 0;\n}\n\n.szenen-elements__toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-elements__heading {\n margin: 0;\n font-size: 1.05rem;\n}\n\n.szenen-elements__scope {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n min-width: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-elements__scope > select {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.szenen-elements__new {\n flex: none;\n font-weight: 700;\n}\n\n.szenen-elements__create {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-accent-blue);\n border-radius: var(--radius-sm);\n}\n\n.szenen-elements__create label {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-elements__create-actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n}\n\n.szenen-elements__options > summary {\n color: var(--color-text-tertiary);\n font-size: 0.78rem;\n cursor: pointer;\n}\n\n.szenen-elements__back {\n justify-self: start;\n font-weight: 700;\n}\n\n.szenen-elements__empty-detail {\n margin: 0;\n color: var(--color-text-tertiary);\n}\n\n.szenen-elements__filter,\n.szenen-detail__actions,\n.szenen-runs__start,\n.szenen-scene-editor__add,\n.szenen-scene-editor__add-relation {\n display: flex;\n flex-wrap: wrap;\n align-items: end;\n gap: var(--space-sm);\n}\n\n.szenen-elements__filter > label,\n.szenen-runs__start > label,\n.szenen-scene-editor__add > input {\n flex: 1 1 16rem;\n}\n\n.szenen-elements__filter > label:has(input[type="checkbox"]) {\n display: flex;\n flex: 1 1 16rem;\n flex-direction: row;\n align-items: center;\n}\n\n.szenen-elements__filter input[type="checkbox"] {\n width: 1rem;\n height: 1rem;\n accent-color: var(--color-accent-blue);\n}\n\n.szenen-elements__list {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-elements__list > li > button {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs) var(--space-sm);\n width: 100%;\n height: 100%;\n text-align: left;\n}\n\n.szenen-elements__list > li > button > .szenen-elements__title {\n flex: 1 1 100%;\n}\n\n.szenen-elements__list > li > button.is-selected,\n.szenen-elements__list > li > button[aria-current="true"] {\n background: var(--color-accent-blue-dim);\n border-color: var(--color-accent-blue);\n}\n\n.szenen-elements__type {\n color: var(--color-accent-blue);\n font-size: 0.75rem;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.szenen-elements__title {\n color: var(--color-text-primary);\n font-size: 0.95rem;\n}\n\n.szenen-elements__subtype,\n.szenen-elements__retired {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-elements__retired {\n color: var(--color-warning);\n}\n\n.szenen-detail {\n margin-top: 0;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n@media (min-width: 761px) {\n .szenen-detail {\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n }\n}\n\n.szenen-detail > header,\n.szenen-detail__heads,\n.szenen-detail__draft,\n.szenen-capability {\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n/* .szenen-runs ist ein eigenst\xE4ndiger sichtbarer Bereich, beh\xE4lt Styling auf Desktop */\n@media (min-width: 761px) {\n .szenen-runs {\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n }\n}\n\n@media (max-width: 760px) {\n .szenen-runs {\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n }\n}\n\n.szenen-detail__ids {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n margin-bottom: 0;\n color: var(--color-text-secondary);\n}\n\n.szenen-detail__heads ul,\n.szenen-scene-editor ul,\n.szenen-runs > ol,\n.szenen-capability > ul {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-detail__heads li,\n.szenen-scene-editor li,\n.szenen-runs > ol > li,\n.szenen-capability > ul > li {\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n\n/* Stufe 6.7.2 (D-126) \u2014 Advanced-/Debug-Fl\xE4che f\xFCr die rohe, schema-getriebene\n * Feldliste einer Szene. Gestrichelt wie die anderen \u201EAngebot statt\n * Auskunft"-Bereiche, aber ohne Akzentfarbe: sie ist kein Vorschlag, sondern\n * ein Eskalationsweg. */\n.szenen-detail__technical {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md) var(--space-md);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__technical > summary {\n margin-bottom: var(--space-sm);\n color: var(--color-text-secondary);\n font-weight: 600;\n cursor: pointer;\n}\n\n.szenen-detail__technical[open] > summary {\n margin-bottom: var(--space-md);\n}\n\n.szenen-detail__field small,\n.szenen-capability small {\n color: var(--color-text-tertiary);\n}\n\n.szenen-detail__preview-errors,\n.szenen-detail__notice--error,\n.szenen-view [role="alert"] {\n color: #fecaca;\n background: var(--color-accent-red-dim);\n border-color: var(--color-accent-red);\n}\n\n.szenen-detail__notice {\n padding: var(--space-sm) var(--space-md);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__notice--success,\n.szenen-view [data-tone="success"] {\n color: #bbf7d0;\n background: var(--color-accent-green-dim);\n border-color: var(--color-accent-green);\n}\n\n.szenen-scene-editor {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--space-md);\n margin-bottom: 0;\n}\n\n.szenen-scene-editor > section {\n min-width: 0;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n/* \u2500\u2500 Stufe 6.7.2 (D-126): Node-/Relationskarten \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Nodes und Beziehungen sind `<details>` \u2014 dieselbe Interaktionssprache wie\n * \u201ERohantwort (Diagnose)" und \u201EBilder zu diesem Lauf" in RunsPanel.tsx. Kopf\n * (immer sichtbar) tr\xE4gt Inhalt zuerst, Technik zuletzt; Body (nur bei\n * ge\xF6ffneter Karte) tr\xE4gt die Bearbeitungscontrols. Padding wandert von der\n * `<li>` in Kopf/Body, damit die Karte keinen doppelten Rand bekommt. */\n.szenen-scene-editor li {\n padding: 0;\n overflow: hidden;\n}\n\n.szenen-node-karte__kopf,\n.szenen-relation-karte__kopf {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs) var(--space-sm);\n padding: var(--space-sm);\n cursor: pointer;\n list-style: none;\n}\n\n.szenen-node-karte__kopf::-webkit-details-marker,\n.szenen-relation-karte__kopf::-webkit-details-marker {\n display: none;\n}\n\n.szenen-node-karte__titel {\n flex: 1 1 12rem;\n min-width: 0;\n color: var(--color-text-primary);\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n\n.szenen-node-karte__typ {\n flex: none;\n padding: 0.15rem 0.55rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.72rem;\n white-space: nowrap;\n}\n\n/* node_id klein, monospace, sekund\xE4r \u2014 sichtbar auch bei zugeklappter Karte,\n * aber optisch klar hinter Beschreibung und Typ. */\n.szenen-node-karte__meta {\n flex: 1 1 100%;\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n color: var(--color-text-tertiary);\n font-size: 0.75rem;\n}\n\n.szenen-node-karte__meta code {\n font-size: inherit;\n}\n\n.szenen-node-karte__body,\n.szenen-relation-karte__body {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-sm) var(--space-sm) var(--space-sm);\n border-top: 1px solid var(--color-border);\n}\n\n/* \xA74 \u2014 Prim\xE4raktion und destruktive Aktion optisch getrennt: \u201ENode/Beziehung\n * entfernen" bekommt einen eigenen, warnenden Ton statt gleichgewichtig neben\n * der normalen Bearbeitung zu stehen. */\n.szenen-node-karte__entfernen,\n.szenen-relation-karte__entfernen {\n justify-self: start;\n color: #fecaca;\n background: var(--color-accent-red-dim);\n border-color: var(--color-accent-red);\n}\n\n.szenen-relation-karte__kopf {\n font-size: 0.9rem;\n}\n\n.szenen-relation-karte__kopf code {\n overflow-wrap: anywhere;\n}\n\n.szenen-relation-karte__pfeil {\n flex: none;\n color: var(--color-text-secondary);\n}\n\n/* Die Composer-\xD6ffner (\u201E+ Node hinzuf\xFCgen", \u201E+ Beziehung hinzuf\xFCgen") sind\n * Angebote, keine Ausk\xFCnfte \u2014 dasselbe gestrichelte Muster wie beim Folgelauf\n * und der Fehlerrettung (\xA73.3/\xA73.5). */\n.szenen-scene-editor__oeffnen {\n width: 100%;\n border-style: dashed;\n}\n\n.szenen-refpicker {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n margin: var(--space-sm) 0;\n padding: var(--space-sm) 0;\n border: none;\n border-radius: 0;\n}\n\n.szenen-refpicker legend {\n padding: 0 var(--space-xs);\n color: var(--color-text-secondary);\n font-weight: 600;\n}\n\n.szenen-capability > ul > li {\n display: grid;\n grid-template-columns: minmax(10rem, 1fr) auto minmax(14rem, 2fr);\n align-items: start;\n gap: var(--space-sm);\n}\n\n.szenen-capability__state {\n padding: 0.1rem 0.5rem;\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.szenen-capability__state--yes {\n color: #bbf7d0;\n background: var(--color-accent-green-dim);\n}\n\n.szenen-capability__state--no {\n color: #fecaca;\n background: var(--color-accent-red-dim);\n}\n\n.szenen-capability__state--unknown {\n color: #fef08a;\n background: rgba(234, 179, 8, 0.2);\n}\n\n.szenen-runs > ol > li {\n display: grid;\n gap: var(--space-sm);\n}\n\n/* B1 \u2014 die geschlossene Runde. Vorher stand die `run_id` als erstes und war\n die einzige Information, die niemand liest; jetzt beantwortet die Kopfzeile\n welche Runde, ob sie durchging, mit welchem Modell und was ungef\xE4hr\n herauskam. */\n.szenen-runs__hinweis {\n margin: var(--space-xs) 0 0;\n color: var(--color-text-secondary);\n font-size: 0.78rem;\n}\n\n.szenen-runs__kopf {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-sm);\n width: 100%;\n padding: var(--space-xs) 0;\n text-align: left;\n color: var(--color-text-secondary);\n background: transparent;\n border: none;\n cursor: pointer;\n}\n\n.szenen-runs__marke {\n font-weight: 700;\n color: var(--color-text-primary);\n}\n\n.szenen-runs__status {\n padding: 0.05rem 0.4rem;\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n border-radius: var(--radius-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n}\n\n.szenen-runs__status[data-status="succeeded"] {\n border-color: var(--color-success);\n}\n\n.szenen-runs__status[data-status="failed"] {\n border-color: var(--color-danger);\n}\n\n.szenen-runs__modell {\n font-size: 0.75rem;\n}\n\n/* Der Auszug ist die Inhaltsvorschau der Runde. Er bekommt eine eigene Zeile,\n damit er nicht mit Marke und Modell um dieselbe Zeile ringt. */\n.szenen-runs__auszug {\n flex: 1 1 100%;\n min-width: 0;\n color: var(--color-text-tertiary);\n font-size: 0.8125rem;\n}\n\n/* B2 \u2014 ein Fehler steht ausserhalb der aufklappbaren Fl\xE4che: Wer eine rote\n Runde sieht, soll nicht erst klicken m\xFCssen, um zu erfahren, woran sie\n gescheitert ist. */\n.szenen-runs__fehler {\n display: grid;\n gap: var(--space-xs);\n padding: var(--space-sm);\n border-radius: var(--radius-sm);\n}\n\n.szenen-runs__fehler p {\n margin: 0;\n}\n\n.szenen-runs__inhalt {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-runs__prompt > h5,\n.szenen-runs__sekundaer > h5 {\n margin: 0 0 var(--space-xs);\n}\n\n/* Im Kopf traegt die Zeile selbst den Abstand \u2014 sonst kaeme er doppelt. */\n.szenen-runs__promptkopf > h5 {\n margin: 0;\n}\n\n/* Ueberschrift und Kopierknopf in einer Zeile. Der Knopf gehoert an den Text,\n den er kopiert \u2014 nicht an den Rand der Runde, wo er neben dem falschen\n Abschnitt stuende. */\n.szenen-runs__promptkopf {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-sm);\n margin: 0 0 var(--space-xs);\n}\n\n/* Ein kompakter Knopf, kein zweiter Titel: Der Prompt ist die Hauptsache des\n Abschnitts, die Aktion daneben darf ihn nicht ueberstimmen. Rahmen und\n Hintergrund kommen aus `.szenen-view button` und bleiben \u2014 dieselbe Optik wie\n jeder andere Knopf der Ansicht; hier wird nur die Groesse zurueckgenommen.\n Zwei Klassen im Selektor, weil `.szenen-view button` sonst spezifischer ist. */\n.szenen-runs__promptkopf .szenen-runs__kopieren {\n min-height: 0;\n padding: 0.1rem 0.45rem;\n font-size: 0.72rem;\n}\n\n/* Regel 11: die Bestaetigung nennt die Zahl, nicht nur \u201EErfolgreich". */\n.szenen-runs__kopiert {\n color: var(--color-text-tertiary, var(--color-text-secondary));\n font-size: 0.72rem;\n}\n\n.szenen-runs__prompt > p {\n margin: 0;\n white-space: pre-wrap;\n}\n\n.szenen-runs__prompt--negativ > p,\n.szenen-runs__sekundaer > p {\n margin: 0;\n color: var(--color-text-secondary);\n white-space: pre-wrap;\n}\n\n.szenen-runs__mehr {\n justify-self: start;\n margin-top: var(--space-xs);\n padding: 0;\n color: var(--color-accent-teal, var(--color-text-secondary));\n background: transparent;\n border: none;\n font-size: 0.75rem;\n text-decoration: underline;\n cursor: pointer;\n}\n\n.szenen-runs > ol > li[data-status="succeeded"] {\n border-left: 3px solid var(--color-success);\n}\n\n.szenen-runs > ol > li[data-status="failed"] {\n border-left: 3px solid var(--color-danger);\n}\n\n.szenen-runs details pre {\n max-height: 20rem;\n overflow: auto;\n padding: var(--space-sm);\n white-space: pre-wrap;\n color: var(--color-text-secondary);\n background: var(--color-bg-app);\n border-radius: var(--radius-sm);\n}\n\n.szenen-media > section {\n display: grid;\n gap: var(--space-sm);\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-media__lookup,\n.szenen-media__attach {\n display: flex;\n flex-wrap: wrap;\n align-items: end;\n gap: var(--space-sm);\n}\n\n.szenen-media__lookup > label,\n.szenen-media__attach > label:first-child {\n flex: 1 1 18rem;\n}\n\n.szenen-media__list {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-media__list > li {\n display: grid;\n grid-template-columns: minmax(12rem, 1fr) auto auto auto;\n align-items: center;\n gap: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n@media (max-width: 760px) {\n .szenen-view {\n gap: var(--space-sm);\n }\n\n /* C1 \u2014 auf 390 px bleiben drei Kacheln je Reihe gross genug zum Erkennen\n und klein genug, dass vier Bilder eine Reihe sind und keine Seite. */\n .szenen-bildgalerie {\n grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));\n }\n\n /* Der Viewer bekommt den ganzen Bildschirm; die Bl\xE4tterkn\xF6pfe bleiben am\n Rand, wo der Daumen sie erreicht. */\n .szenen-bildviewer {\n padding: var(--space-xs);\n }\n\n .szenen-bildviewer__blaettern {\n width: 2.25rem;\n height: 4rem;\n }\n\n .szenen-view__nav {\n position: sticky;\n top: 0;\n z-index: 2;\n padding: var(--space-xs) 0;\n background: var(--color-bg-app);\n }\n\n\n .szenen-scene-editor {\n grid-template-columns: 1fr;\n }\n\n .szenen-capability > ul > li {\n grid-template-columns: 1fr;\n }\n\n .szenen-derive,\n .szenen-elements,\n .szenen-scene,\n .szenen-setup,\n .szenen-shot,\n .szenen-media,\n .szenen-runs {\n gap: var(--space-sm);\n }\n\n .szenen-elements__filter {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--space-sm);\n }\n\n .szenen-elements__filter > label {\n width: 100%;\n min-width: 0;\n flex: none;\n }\n\n .szenen-elements__filter > label:has(input[type="checkbox"]) {\n flex: none;\n grid-column: 1 / -1;\n }\n\n /* Schmal ist die Liste eine Spalte, und die Auswahl fuehrt weiter \u2014 der\n * Eintrag ist deshalb ein Ziel fuer den Finger, keine Kachel. */\n .szenen-elements__list {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .szenen-elements__list > li > button {\n min-height: 2.75rem;\n }\n\n .szenen-elements__back {\n justify-self: stretch;\n min-height: 2.5rem;\n }\n\n .szenen-detail__actions,\n .szenen-runs__start,\n .szenen-scene-editor__add,\n .szenen-scene-editor__add-relation {\n align-items: stretch;\n flex-direction: column;\n }\n\n .szenen-runs__start > *,\n .szenen-scene-editor__add > *,\n .szenen-scene-editor__add-relation > * {\n width: 100%;\n flex: none;\n }\n}\n\n/* \u2500\u2500 Kette `szenen-design`, P2: Szenen-\xDCbersicht als Bildgalerie \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Kacheln wie in der Library: quadratisch, Deckbild, Titel ueber einem\n * Verlauf, Bildzahl als Plakette. Eine Szene ohne Bild zeigt ihre\n * Node-Symbole; ein nicht ladbares Deckbild nennt den Grund. Die Schrift auf\n * dem Bild ist hell auf dunklem Verlauf \u2014 unabhaengig vom Hostthema, weil das\n * Bild es auch ist. */\n.szenen-galerie {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-galerie__kopf > .szenen-elements__heading {\n flex: 1 1 auto;\n margin: 0;\n}\n\n.szenen-galerie__anzahl,\n.szenen-galerie__sortierung {\n color: var(--color-text-secondary);\n font-weight: 400;\n}\n\n.szenen-galerie__sortierung {\n font-size: 0.8rem;\n}\n\n.szenen-galerie__raster {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr));\n gap: 0.625rem;\n min-width: 0;\n}\n\n/* Die Kacheln sind Zellen desselben Rasters wie die Neu-Kachel. */\n.szenen-view .szenen-galerie__liste {\n display: contents;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-galerie__kachel {\n min-width: 0;\n}\n\n.szenen-view .szenen-galerie__kachel > button,\n.szenen-view .szenen-galerie__neu,\n.szenen-view .szenen-galerie__zuletzt {\n position: relative;\n display: block;\n width: 100%;\n min-width: 0;\n padding: 0;\n overflow: hidden;\n color: var(--color-text-primary);\n text-align: left;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-view .szenen-galerie__kachel > button {\n aspect-ratio: 1 / 1;\n}\n\n.szenen-view .szenen-galerie__kachel > button[aria-current="true"],\n.szenen-view .szenen-galerie__zuletzt[aria-current="true"] {\n border-color: var(--color-accent-blue);\n box-shadow: 0 0 0 1px var(--color-accent-blue);\n}\n\n.szenen-galerie__bild {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.szenen-galerie__scrim {\n position: absolute;\n inset: 0;\n background: linear-gradient(to top, rgba(0, 0, 0, 0.88) 0%, rgba(0, 0, 0, 0.4) 40%, rgba(0, 0, 0, 0) 65%);\n}\n\n.szenen-galerie__ohnebild {\n position: absolute;\n inset: 0;\n padding: 0.75rem;\n background:\n radial-gradient(var(--color-border) 1px, transparent 1px) 0 0 / 14px 14px,\n var(--color-bg-surface);\n}\n\n.szenen-galerie__bildfehler {\n position: absolute;\n inset: 0;\n /* Oben Platz fuer Status-Punkte und Bildzahl, die darueber liegen. */\n padding: 2.25rem 0.75rem 0.75rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n font-size: 0.75rem;\n line-height: 1.3;\n}\n\n.szenen-galerie__text {\n position: absolute;\n right: 0.75rem;\n bottom: 0.7rem;\n left: 0.75rem;\n display: grid;\n gap: 0.25rem;\n}\n\n.szenen-galerie__kachel--mitbild .szenen-galerie__text,\n.szenen-galerie__zuletzt--mitbild .szenen-galerie__zuletzt-text {\n color: #fff;\n}\n\n.szenen-galerie__titel {\n display: -webkit-box;\n overflow: hidden;\n font-size: 0.875rem;\n font-weight: 650;\n line-height: 1.25;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 3;\n overflow-wrap: anywhere;\n}\n\n.szenen-galerie__meta {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-galerie__kachel--mitbild .szenen-galerie__meta,\n.szenen-galerie__zuletzt--mitbild .szenen-galerie__meta {\n color: rgba(255, 255, 255, 0.82);\n}\n\n.szenen-galerie__tags {\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n min-width: 0;\n}\n\n.szenen-galerie__tag {\n max-width: 100%;\n padding: 0.05rem 0.4rem;\n overflow: hidden;\n color: inherit;\n background: var(--color-bg-elevated);\n border-radius: var(--radius-full);\n font-size: 0.68rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-galerie__kachel--mitbild .szenen-galerie__tag {\n background: rgba(0, 0, 0, 0.5);\n}\n\n.szenen-galerie__status {\n position: absolute;\n top: 0.7rem;\n left: 0.7rem;\n display: flex;\n gap: 0.3rem;\n}\n\n.szenen-galerie__punkt {\n width: 0.625rem;\n height: 0.625rem;\n background: var(--color-text-secondary);\n border-radius: 50%;\n box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.55);\n}\n\n.szenen-galerie__punkt[data-ton="info"] { background: var(--color-accent-blue); }\n.szenen-galerie__punkt[data-ton="ok"] { background: var(--color-success); }\n.szenen-galerie__punkt[data-ton="fertig"] { background: var(--color-warning); }\n/* Unvollstaendig ist ein Ring: Die Form unterscheidet es von \u201Evollstaendig",\n * nicht nur der Farbton (P8). */\n.szenen-galerie__punkt[data-ton="warn"] {\n background: transparent;\n box-shadow: inset 0 0 0 2px var(--color-accent-orange), 0 0 0 2px rgba(0, 0, 0, 0.55);\n}\n\n/* Die Legende der Punkte \u2014 einmal je Ansicht. */\n.szenen-statuslegende {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem 0.85rem;\n margin: 0;\n padding: 0;\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n list-style: none;\n}\n\n.szenen-statuslegende__eintrag {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.szenen-statuslegende .szenen-galerie__punkt {\n display: inline-block;\n width: 0.5rem;\n height: 0.5rem;\n}\n\n.szenen-galerie__bildzahl {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.15rem 0.5rem;\n color: #fff;\n background: rgba(0, 0, 0, 0.65);\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.szenen-galerie__symbole {\n display: flex;\n flex-wrap: wrap;\n gap: 0.3rem;\n}\n\n.szenen-galerie__symbol {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 1.875rem;\n height: 1.875rem;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: 50%;\n}\n\n.szenen-galerie__symbol[data-node-type="light"] {\n color: var(--color-warning);\n}\n\n.szenen-galerie__symbol--rest {\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n}\n\n.szenen-view .szenen-galerie__neu {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.6rem;\n aspect-ratio: 1 / 1;\n text-align: center;\n background: var(--color-bg-app);\n border: 1.5px dashed var(--color-border-hover, var(--color-border));\n}\n\n.szenen-galerie__neu-plus {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 3.25rem;\n height: 3.25rem;\n color: var(--color-bg-app);\n background: var(--color-accent-teal, #2dd4bf);\n border-radius: 50%;\n}\n\n.szenen-galerie__neu-titel {\n font-size: 0.95rem;\n font-weight: 600;\n}\n\n.szenen-galerie__neu-text {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-galerie__zuletzt-bild {\n position: relative;\n display: block;\n aspect-ratio: 4 / 3;\n max-height: 17rem;\n width: 100%;\n}\n\n.szenen-galerie__chip {\n position: absolute;\n top: 0.75rem;\n left: 0.75rem;\n padding: 0.3rem 0.6rem;\n color: #fff;\n background: rgba(0, 0, 0, 0.6);\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n}\n\n.szenen-galerie__zuletzt .szenen-galerie__status {\n right: 0.75rem;\n left: auto;\n top: 1rem;\n}\n\n/* Die Symbole einer Szene ohne Bild stehen unter dem Chip, nicht darauf. */\n.szenen-galerie__zuletzt .szenen-galerie__ohnebild {\n padding-top: 3rem;\n}\n\n.szenen-galerie__zuletzt-text {\n position: absolute;\n right: 1rem;\n bottom: 0.9rem;\n left: 1rem;\n display: grid;\n gap: 0.35rem;\n}\n\n.szenen-galerie__zuletzt-text .szenen-galerie__titel {\n font-size: 1.3rem;\n font-weight: 700;\n line-height: 1.2;\n}\n\n.szenen-galerie__zuletzt-fuss {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n padding: 0.75rem 0.9rem;\n}\n\n.szenen-galerie__oeffnen {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 0.25rem;\n color: var(--color-accent-teal, #2dd4bf);\n font-size: 0.875rem;\n font-weight: 600;\n}\n\n/* \u2500\u2500 Stufe 6.5: Rekonstruktion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Der Bereich zeigt drei Dinge nebeneinander: den Vorschlag, das nicht\n * Ableitbare und die Widerspr\xFCche. Die Diagnosen sind deshalb bewusst nicht\n * kleiner gesetzt als der Vorschlag \u2014 wer sie \xFCbersieht, \xFCbernimmt Geratenes.\n */\n\n.szenen-derive {\n display: grid;\n gap: var(--space-md);\n}\n\n.szenen-form {\n display: grid;\n gap: var(--space-sm);\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-field {\n display: grid;\n gap: var(--space-xs);\n}\n\n.szenen-field > span {\n color: var(--color-text-secondary);\n font-size: 0.875rem;\n}\n\n.szenen-error {\n padding: var(--space-sm) var(--space-md);\n color: var(--color-danger);\n background: var(--color-accent-red-dim);\n border: 1px solid var(--color-accent-red);\n border-radius: var(--radius-sm);\n}\n\n.szenen-empty {\n padding: var(--space-md);\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-diagnose {\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-left: 3px solid var(--color-warning);\n border-radius: var(--radius-sm);\n}\n\n/* Ein Widerspruch ist der schwerste der drei Befunde: dort steht eine\n * Entscheidung aus, die das System bewusst nicht getroffen hat (D-74). */\n.szenen-diagnose--konflikt {\n border-left-color: var(--color-danger);\n}\n\n.szenen-diagnose > h4 {\n margin: 0 0 var(--space-sm);\n font-size: 0.9375rem;\n}\n\n.szenen-diagnose ul {\n display: grid;\n gap: var(--space-xs);\n margin: 0;\n padding-left: var(--space-md);\n}\n\n.szenen-proposal {\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-proposal > h4 {\n margin: 0 0 var(--space-sm);\n font-family: var(--font-mono);\n font-size: 0.9375rem;\n}\n\n.szenen-proposal__payload {\n max-height: 18rem;\n margin: 0 0 var(--space-sm);\n padding: var(--space-sm);\n overflow: auto;\n /* Ein erzeugter Prompt ist ein einziger langer Satz \u2014 ohne Umbruch\n verschwindet er nach rechts aus dem Bild. JSON-Payloads bringen ihre\n eigenen Zeilenumbrueche mit und leiden nicht darunter. */\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n font-family: var(--font-mono);\n font-size: 0.8125rem;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-proposal__done {\n margin: var(--space-sm) 0 0;\n color: var(--color-success);\n}\n\n/* Die Belege eines Laufs: Rohantwort und Systemprompt. Zum Lesen und Kopieren,\n nicht zum Bedienen \u2014 deshalb voll markierbar und in Monospace. */\n.szenen-beleg__text {\n width: 100%;\n margin: var(--space-sm) 0 0;\n padding: var(--space-sm);\n font-family: var(--font-mono);\n font-size: 0.8125rem;\n line-height: 1.5;\n white-space: pre;\n background: var(--color-bg-app);\n color: var(--color-text);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n resize: vertical;\n}\n\n/* Der Folgelauf (D-87): abgesetzt, damit er nicht wie Teil des Ergebnisses\n aussieht \u2014 er ist eine Frage, keine Auskunft. */\n.szenen-folgelauf {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md) var(--space-md);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-folgelauf > h4 {\n margin: var(--space-sm) 0 0;\n}\n\n.szenen-run__herkunft {\n margin: 0 0 var(--space-sm);\n font-size: 0.875rem;\n color: var(--color-text-muted, inherit);\n}\n\n/* Widerspricht das Modell, ist das das Wichtigste auf der Seite. */\n.szenen-diagnose--antwort {\n border-left: 3px solid var(--color-accent, var(--color-border));\n}\n\n/* Der Bildw\xE4hler (D-92) \u2014 Browser und Inspector, dem Labs-Tab nachgebildet,\n aber mit dem CSS dieser Ansicht: eine gemeinsame Komponente \xFCber zwei\n Dom\xE4nengrenzen w\xE4re eine Kopplung, die keiner gewollt hat.\n\n Der Review vom 2026-08-22 (R12.1/R12.2) hat den Ma\xDFstab gesetzt: Der Bestand\n ist ein **Browser**, kein Seiteninhalt. Vierzig Werke d\xFCrfen die Szenenseite\n nicht meterlang machen, und zw\xF6lf Varianten eines Werkes keine zw\xF6lf\n Bildschirmseiten. Deshalb steht hier alles unter zwei Regeln \u2014 begrenzte\n Fl\xE4che mit eigenem Scroll, und Kacheln statt Karten. */\n\n/* \u2500\u2500 Ebene 1: der Browser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-bildwahl {\n /* Dieselbe Begr\xFCndung wie beim Inspector: Als Grid-Element w\xFCrde der\n W\xE4hler sonst so breit wie sein breitester Inhalt. */\n min-width: 0;\n}\n\n.szenen-bildwahl__browser {\n /* Die eigene Scrollfl\xE4che ist der ganze Punkt: Der Bestand w\xE4chst nach\n innen, nicht nach unten. Dieselbe Gr\xF6\xDFenordnung wie `max-h-[300px]` im\n Labs-Browser. */\n max-height: 19rem;\n overflow-y: auto;\n overscroll-behavior: contain;\n margin-top: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-bildwahl__raster {\n display: grid;\n /* Vier Spalten auf schmalen Displays \u2014 der gemeldete Screenshot zeigte eine\n einzige Spalte gro\xDFer Karten. Breiter wird automatisch dichter. */\n grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bildwahl__karte {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n overflow: hidden;\n background: var(--color-bg-surface);\n text-align: left;\n cursor: pointer;\n}\n\n/* Das fokussierte Werk ist klar markiert \u2014 sonst wei\xDF niemand, wessen Galerie\n der Inspector unten zeigt. */\n.szenen-bildwahl__karte.is-fokus {\n border-color: var(--color-accent, var(--color-text-primary));\n box-shadow: 0 0 0 2px var(--color-accent, var(--color-text-primary));\n}\n\n/* \u2500\u2500 Die Kachel selbst \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Der Platz steht, bevor das Bild da ist \u2014 sonst springt das Raster, sobald\n die erste Vorschau eintrifft. */\n.szenen-bildkachel {\n display: block;\n width: 100%;\n aspect-ratio: 1;\n overflow: hidden;\n background: var(--color-bg-app);\n}\n\n.szenen-bildkachel img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n}\n\n.szenen-bildkachel__leer {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: linear-gradient(135deg, var(--color-bg-app), var(--color-bg-surface));\n}\n\n/* R12.3: Eine fehlende Vorschau bleibt kachelgro\xDF. Vorher fiel die Karte auf\n ihren Prompttext zur\xFCck \u2014 und ein Prompt hat im echten Bestand mehrere\n hundert Zeichen. */\n.szenen-bildkachel__zeichen {\n font-size: 0.875rem;\n font-weight: 700;\n color: var(--color-text-secondary);\n opacity: 0.6;\n}\n\n/* Wie viele Varianten das Werk hat \u2014 klein und \xFCberlagernd, nie als\n dominanter Text. */\n.szenen-bildwahl__anzahl {\n position: absolute;\n top: 0.15rem;\n right: 0.15rem;\n padding: 0.05rem 0.3rem;\n font-size: 0.625rem;\n font-weight: 700;\n line-height: 1.4;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n/* Eine Zeile, dann Schluss. Der Prompt eines Werkes ist oft mehrere hundert\n Zeichen lang und w\xE4re als Prim\xE4rdarstellung genau die Textw\xFCste, gegen die\n der Review antritt. */\n.szenen-bildwahl__kacheltitel {\n display: block;\n padding: 0.15rem 0.3rem;\n font-size: 0.625rem;\n line-height: 1.3;\n color: var(--color-text-secondary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 Ebene 2: der Inspector \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-bildwahl__inspector {\n /* Ohne `min-width: 0` gewinnt der Inhalt: Der W\xE4hler ist Element eines\n Grids (`.szenen-form`), und dort ist `min-width: auto` die Vorgabe. Der\n Streifen unten ist rund 1000 px breit \u2014 gemessen am 2026-08-22 im echten\n Browser zog er die Auswahl von 374 px auf 1088 px auf und schob die\n ganze Seite waagerecht heraus, statt selbst zu scrollen. */\n min-width: 0;\n margin-top: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n /* Sichtbar abgesetzt vom Browser: zwei Ebenen, nicht eine lange Liste. */\n border: 1px solid var(--color-border);\n border-left: 3px solid var(--color-accent, var(--color-border));\n border-radius: var(--radius-sm);\n}\n\n.szenen-bildwahl__inspektorkopf {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n margin-bottom: var(--space-sm);\n}\n\n.szenen-bildwahl__werktitel {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--color-text-primary);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-bildwahl__zurueck {\n flex: 0 0 auto;\n font-size: 0.6875rem;\n padding: 0.15rem 0.5rem;\n}\n\n/* Der Streifen: waagerecht scrollend, feste kleine Kacheln \u2014 zw\xF6lf Varianten\n bleiben ein \xDCberblick statt zw\xF6lf Bildschirmseiten. */\n.szenen-bildwahl__streifen {\n /* Die Breite kommt vom Elter, nie vom Inhalt \u2014 sonst scrollt hier nichts. */\n max-width: 100%;\n display: flex;\n gap: var(--space-sm);\n margin: 0;\n padding: 0 0 0.25rem;\n list-style: none;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n}\n\n.szenen-bildwahl__streifen > li {\n flex: 0 0 auto;\n width: 5rem;\n}\n\n.szenen-bildwahl__variante {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n overflow: hidden;\n background: var(--color-bg-app);\n cursor: pointer;\n}\n\n.szenen-bildwahl__variante.is-gewaehlt {\n border-color: var(--color-accent, var(--color-text-primary));\n box-shadow: 0 0 0 2px var(--color-accent, var(--color-text-primary));\n}\n\n.szenen-bildwahl__nummer {\n position: absolute;\n bottom: 0.15rem;\n left: 0.15rem;\n padding: 0.05rem 0.3rem;\n font-size: 0.625rem;\n line-height: 1.4;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border-radius: var(--radius-sm);\n}\n\n/* \u2500\u2500 Das Gew\xE4hlte \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-bildwahl__gewaehlt {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n margin: var(--space-sm) 0 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bildwahl__gewaehlt li {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.25rem 0.5rem;\n font-size: 0.8125rem;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n max-width: 100%;\n}\n\n/* Das gew\xE4hlte Bild wird best\xE4tigt, nicht nur benannt: eine kleine Vorschau\n neben dem Titel. */\n.szenen-bildwahl__gewaehlt .szenen-bildkachel {\n width: 2.25rem;\n flex: 0 0 auto;\n border-radius: var(--radius-sm);\n}\n\n.szenen-bildwahl__gewaehlt .szenen-bildwahl__kacheltitel {\n min-width: 0;\n max-width: 12rem;\n font-size: 0.75rem;\n}\n\n.szenen-beleg__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n margin-top: var(--space-sm);\n}\n\n.szenen-diagnose > details + details {\n margin-top: var(--space-sm);\n}\n\n.szenen-diagnose > details > summary {\n cursor: pointer;\n font-weight: 600;\n}\n\n/* \u2500\u2500 Die Fehlerrettung (Stufe 6.6, A5) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Sie steht im Fehlerblock und muss trotzdem als Werkzeug lesbar sein, nicht\n * als weitere Fehlermeldung. Deshalb abgesetzt wie der Folgelauf \u2014 und aus\n * demselben Grund: Beides sind Angebote, keine Ausk\xFCnfte.\n *\n * Der wichtigste optische Punkt ist die Trennung von Original und\n * Arbeitskopie. Das Original bekommt den ruhigen, \u201Efesten" Hintergrund der\n * Belege; die Kopie sieht aus wie ein normales Eingabefeld, weil sie eines\n * ist. */\n.szenen-rettung {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md) var(--space-md);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-rettung > h4 {\n margin: var(--space-sm) 0 0;\n}\n\n.szenen-rettung textarea[readonly] {\n background: var(--color-bg-surface);\n color: var(--color-text-secondary);\n font-family: var(--font-mono, monospace);\n font-size: 0.8125rem;\n}\n\n.szenen-rettung textarea:not([readonly]) {\n font-family: var(--font-mono, monospace);\n font-size: 0.8125rem;\n}\n\n.szenen-rettung__aktionen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n margin: var(--space-sm) 0;\n}\n\n/* Ein Befund tr\xE4gt Code, Bezug und Meldung. Der Code steht klein und\n * monospaced davor: Er ist die Kennung, nicht die Aussage. */\n.szenen-diagnose__liste {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding-left: var(--space-md);\n}\n\n.szenen-diagnose__liste code {\n font-size: 0.8125rem;\n}\n\n.szenen-diagnose__liste > li[data-severity=\'warning\'] {\n color: var(--color-text-secondary);\n}\n\n/* \u2500\u2500 Die Draft-Kette (Stufe 6.6, C4) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Der Hauptweg. Er steht nach den Einzel\xFCbernahmen und muss als das erkennbar\n * sein, was er ist: nicht eine weitere Option, sondern der k\xFCrzere Weg zum\n * selben Ziel. Deshalb durchgezogener Rahmen statt gestricheltem \u2014 er ist\n * Angebot **und** Empfehlung. */\n.szenen-kette {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md) var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-left: 3px solid var(--color-accent, var(--color-border));\n border-radius: var(--radius-sm);\n}\n\n.szenen-kette > h4 {\n margin: var(--space-sm) 0 0;\n}\n\n.szenen-kette ul {\n display: grid;\n gap: var(--space-xs);\n margin: 0 0 var(--space-sm);\n padding-left: var(--space-md);\n}\n\n.szenen-kette code {\n font-size: 0.8125rem;\n}\n\n/* Ein Hinweis, der eine Bedingung erklaert \u2014 nicht rot, weil er kein Fehler\n ist, aber abgesetzt, weil er eine Folge hat. */\n.szenen-detail__hint {\n margin: var(--space-sm) 0 0;\n padding: var(--space-sm);\n font-size: 0.875rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border-left: 3px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n/* \u2500\u2500 Stufe 6.7: Bilder am Prompt-Lauf (H0/H1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Der Bereich tr\xE4gt zwei Dinge, die man nie verwechseln darf: den **Eingang**\n * (woraus der Prompt entstand) und den **Ausgang** (was daraus wurde). Sie\n * bekommen deshalb verschiedene Akzentkanten statt nur verschiedener\n * \xDCberschriften \u2014 wer schnell liest, sieht die Trennung, bevor er sie liest.\n */\n.szenen-bilder {\n display: grid;\n gap: var(--space-md);\n margin-top: var(--space-sm);\n}\n\n.szenen-bilder__eingang,\n.szenen-bilder__ausgang {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-sm) var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__eingang {\n border-left: 3px solid var(--color-accent-purple, var(--color-border));\n}\n\n.szenen-bilder__ausgang {\n border-left: 3px solid var(--color-accent-teal, var(--color-border));\n}\n\n.szenen-bilder h5 {\n margin: 0;\n}\n\n.szenen-bilder__ids {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n margin: 0;\n align-items: baseline;\n color: var(--color-text-secondary);\n font-size: 0.875rem;\n}\n\n.szenen-bilder__eingangsliste,\n.szenen-bilder__batchliste,\n.szenen-bilder__auftraege {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bilder__eingangsliste > li,\n.szenen-bilder__batchliste > li,\n.szenen-bilder__auftraege > li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n font-size: 0.8125rem;\n}\n\n/* Ein unterbrochener Auftrag ist der Fall, f\xFCr den der Auftragssatz existiert.\n Er wird deshalb markiert \u2014 nicht rot, denn er ist kein Fehler, sondern eine\n offene Entscheidung. */\n.szenen-bilder__auftraege > li[data-status="started"] {\n border-left: 3px solid var(--color-warning);\n}\n\n.szenen-bilder__auftraege > li[data-status="succeeded"] {\n border-left: 3px solid var(--color-success);\n}\n\n.szenen-bilder__auftraege > li[data-status="partial"] {\n border-left: 3px solid var(--color-accent-blue, var(--color-border));\n}\n\n.szenen-bilder__auftraege > li[data-status="failed"] {\n border-left: 3px solid var(--color-danger);\n}\n\n/* Das Eingangsbild benutzt seit C3 dieselbe Kachel wie W\xE4hler und Galerie.\n Sie ist von Haus aus so breit wie ihr Platz \u2014 in dieser Zeile bekommt sie\n deshalb eine feste Gr\xF6sse, sonst sch\xF6be sie die Metadaten heraus. */\n.szenen-bilder__eingangsliste .szenen-bildkachel {\n flex: 0 0 auto;\n width: 4rem;\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__batch {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__batchkopf {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-bilder__herkunft {\n color: var(--color-text-tertiary);\n font-size: 0.75rem;\n}\n\n/* Review-Befund \u2014 ein transienter Bildfehler ist wiederholbar, kein\n endg\xFCltiges \u201Efehlt". Dezent wie ein Angebot, nicht wie ein Fehlerzustand. */\n.szenen-bilder__retry {\n justify-self: start;\n padding: 0.15rem 0.5rem;\n font-size: 0.75rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n cursor: pointer;\n}\n\n/* C4 \u2014 die Provenienz vollst\xE4ndig, aber sekund\xE4r. */\n.szenen-bilder__technik > summary {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n cursor: pointer;\n}\n\n.szenen-bilder__meta {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n font-size: 0.75rem;\n color: var(--color-text-secondary);\n}\n\n/* C5 \u2014 der Verlauf verdichtet, seine Ausreisser nicht. */\n.szenen-bilder__verlauf > summary {\n color: var(--color-text-secondary);\n font-size: 0.8125rem;\n cursor: pointer;\n}\n\n.szenen-bilder__verlauf[open] > summary {\n margin-bottom: var(--space-sm);\n}\n\n.szenen-bilder__auffaellig {\n margin: 0;\n padding: var(--space-sm);\n border-radius: var(--radius-sm);\n font-size: 0.8125rem;\n}\n\n.szenen-bilder__auftragskennung {\n flex-basis: 100%;\n color: var(--color-text-tertiary);\n font-size: 0.6875rem;\n}\n\n/* \u2500\u2500 C1/C2 \u2014 Galerie und grosse Ansicht \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Das Raster w\xE4chst mit dem Platz: auf 390 px drei bis vier Kacheln je Reihe,\n auf dem Desktop entsprechend mehr. Vorher war jedes Bild eine Zeile aus\n Daumennagel plus vier Metadatenfeldern \u2014 vier Bilder ergaben vier Textzeilen\n und das Protokoll war die Hauptsache. */\n.szenen-bildgalerie {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr));\n gap: var(--space-sm);\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bildgalerie__kachel {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n cursor: pointer;\n}\n\n.szenen-bildgalerie__kachel:hover,\n.szenen-bildgalerie__kachel:focus-visible {\n border-color: var(--color-accent-teal, var(--color-text-primary));\n}\n\n.szenen-bildgalerie__nummer {\n position: absolute;\n bottom: 0.15rem;\n left: 0.15rem;\n padding: 0.05rem 0.3rem;\n font-size: 0.625rem;\n line-height: 1.4;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border-radius: var(--radius-sm);\n}\n\n/* Die grosse Ansicht liegt \xFCber allem und bringt ihren eigenen Grund mit \u2014\n `position: fixed` bezieht sich im Flow-Canvas auf dessen Rahmen, in React auf\n das Fenster; in beiden F\xE4llen genau das Gew\xFCnschte. */\n.szenen-bildviewer {\n position: fixed;\n inset: 0;\n z-index: 1000;\n display: grid;\n grid-template-rows: auto 1fr auto;\n gap: var(--space-sm);\n padding: var(--space-sm);\n /* Deckend, nicht get\xF6nt: Bei 0.92 schimmerte der Laufbereich durch und man\n las Prompttext quer \xFCber dem Bild \u2014 im Browser gemessen. */\n background: #000;\n}\n\n/* Titel, Z\xE4hlung, Schliessen \u2014 drei Spalten, damit ein langer Werktitel die\n Z\xE4hlung nicht in die n\xE4chste Zeile und \xFCber das Bild schiebt. */\n.szenen-bildviewer__kopf {\n display: grid;\n /* Titel nimmt den Rest; Zaehler, eine optionale Bildaktion (P6) und\n Schliessen stehen rechts \u2014 mit und ohne Aktion in einer Zeile. */\n grid-template-columns: minmax(0, 1fr);\n grid-auto-columns: auto;\n grid-auto-flow: column;\n align-items: center;\n gap: var(--space-sm);\n color: var(--color-text-primary);\n}\n\n.szenen-bildviewer__titel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 600;\n}\n\n.szenen-bildviewer__zaehler {\n color: var(--color-text-secondary);\n font-size: 0.8125rem;\n}\n\n.szenen-bildviewer__buehne {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--space-sm);\n min-height: 0;\n min-width: 0;\n}\n\n/* Der Rahmen nimmt den Platz, der zwischen den Bl\xE4tterkn\xF6pfen \xFCbrig ist \u2014\n `min-width: 0`, damit er auch wirklich schrumpft statt sie hinauszuschieben. */\n.szenen-bildviewer__rahmen {\n flex: 1 1 auto;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 0;\n min-height: 0;\n height: 100%;\n}\n\n.szenen-bildviewer__bild {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n}\n\n.szenen-bildviewer__leer {\n color: var(--color-text-secondary);\n text-align: center;\n}\n\n/* Die Bl\xE4tterkn\xF6pfe sind daumengross und liegen an den R\xE4ndern \u2014 auf einem\n Telefon ist der Rand erreichbar, die Bildmitte nicht. */\n.szenen-bildviewer__blaettern {\n flex: 0 0 auto;\n width: 2.75rem;\n height: 3.5rem;\n font-size: 1.75rem;\n line-height: 1;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n cursor: pointer;\n}\n\n.szenen-bildviewer__details {\n max-height: 8rem;\n overflow-y: auto;\n color: var(--color-text-secondary);\n}\n\n/* Die Aktionen stehen abgesetzt: Sie sind Angebote, keine Ausk\xFCnfte \u2014 dasselbe\n Muster wie beim Folgelauf und bei der Fehlerrettung. */\n/* D \u2014 die Aktionen stehen abgesetzt und standardm\xE4ssig kompakt: Sie sind\n Angebote, keine Ausk\xFCnfte. Vorher hielten beide Formulare dauerhaft offen und\n machten aus jedem Lauf zwei zus\xE4tzliche Bildschirmseiten. */\n.szenen-bilder__aktion {\n min-width: 0;\n padding: var(--space-sm) var(--space-md);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__aktion > summary {\n color: var(--color-text-primary);\n font-weight: 600;\n cursor: pointer;\n}\n\n.szenen-bilder__aktion[open] > summary {\n margin-bottom: var(--space-sm);\n}\n\n.szenen-bilder__aktion-inhalt {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding-bottom: var(--space-sm);\n}\n\n.szenen-bilder__aktion h5 {\n margin: var(--space-sm) 0 0;\n}\n\n.szenen-bilder__aktion ol {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding-left: var(--space-md);\n font-size: 0.8125rem;\n}\n\n/* Regelwerk-UX Schritt 16 \u2014 der ZIP-Sammelimport.\n *\n * \xA78: Der gemeldete Einsatz ist mobil. Deshalb **ein** Seedfeld statt einer\n * gestapelten Eingabe je Bild, und die Zuordnung Bild -> Seed als umbrechende\n * Zeile statt als Tabelle: Eine Tabelle waere auf 390 px abgeschnitten, und\n * abgeschnitten heisst hier, dass der Nutzer die Zuordnung nicht mehr pruefen\n * kann \u2014 genau die Pruefung, wegen der die Vorschau existiert. */\n.szenen-bilder__zip {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-bilder__zipkopf {\n margin: 0;\n overflow-wrap: anywhere;\n}\n\n.szenen-bilder__zipvorlagen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n margin: 0;\n}\n\n/* Eine laengere Liste bleibt scrollbar, statt die Sektion und damit den\n * Import-Knopf aus dem Blick zu schieben (\xA78, letzter Punkt). */\n.szenen-bilder__zipliste {\n max-height: 16rem;\n overflow-y: auto;\n}\n\n.szenen-bilder__zipliste > li {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-bilder__zipliste > li > span:first-child {\n overflow-wrap: anywhere;\n}\n\n.szenen-bilder__zipliste > li > span:last-child {\n color: var(--color-text-secondary);\n white-space: nowrap;\n}\n\n/* ==========================================================================\n STUFE 6.10 \u2014 ELEMENTEDITOR UND VERSIONSNAVIGATION\n ========================================================================== */\n\n/* \xA74.2 \u2014 vier Sachverhalte, vier Marken. Die Marken stehen in einer eigenen\n * Spalte, damit ANGEZEIGT + BEVORZUGT nebeneinander lesbar bleiben, statt sich\n * durch den Text zu schieben. */\n.szenen-detail__heads li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-version__titel {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n min-width: 0;\n margin-right: auto;\n}\n\n/* V17 \u2014 Kennungen bleiben vollst\xE4ndig sichtbar, aber optisch sekund\xE4r. */\n.szenen-version__id,\n.szenen-ref__id,\n.szenen-detail__field-key {\n color: var(--color-text-tertiary);\n font-size: 0.78rem;\n overflow-wrap: anywhere;\n}\n\n.szenen-version__marken {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n}\n\n.szenen-version__marken > span {\n padding: 0.1rem 0.5rem;\n color: var(--color-text-primary);\n background: rgba(45, 212, 191, 0.12);\n border: 1px solid rgba(45, 212, 191, 0.35);\n border-radius: var(--radius-full);\n font-size: 0.7rem;\n font-weight: 800;\n letter-spacing: 0.08em;\n}\n\n.szenen-version--angezeigt {\n border-color: var(--color-accent-teal, #2dd4bf) !important;\n}\n\n/* V9 \u2014 der Basiswechsel ist eine Entscheidung, keine Nebenwirkung. */\n.szenen-detail__confirm {\n display: grid;\n gap: var(--space-sm);\n margin: var(--space-md) 0;\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-accent-amber, #f59e0b);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__confirm p {\n margin: 0;\n}\n\n/* Untergruppen von Objektfeldern (`prompt_render_settings`, `overrides`,\n `blender_render_settings`) \u2014 seit A1/A2 auf- und zuklappbar. Eine optionale\n Gruppe startet zu: Blender und `overrides` f\xFCllten auf einem 390-px-Display\n sonst mehrere Bildschirmseiten, obwohl die meisten Shots sie nie anfassen. */\n.szenen-detail__group {\n min-width: 0;\n margin: var(--space-md) 0;\n padding: var(--space-sm) var(--space-md);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__group > summary {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n color: var(--color-text-secondary);\n font-weight: 600;\n cursor: pointer;\n}\n\n.szenen-detail__group[open] > summary {\n margin-bottom: var(--space-sm);\n}\n\n/* A2 \u2014 dass eine zugeklappte Gruppe schon Werte tr\xE4gt, muss man sehen, ohne\n sie zu \xF6ffnen. Sonst \xFCbersieht man eine gesetzte Blender-Ausgabe genau so\n lange, bis sie im Ergebnis auftaucht. */\n.szenen-detail__group-status {\n padding: 0.05rem 0.4rem;\n font-size: 0.6875rem;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n color: var(--color-text-tertiary);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__group[data-konfiguriert="ja"] > summary .szenen-detail__group-status {\n color: var(--color-text-primary);\n border-color: var(--color-accent-teal, var(--color-border));\n}\n\n.szenen-detail__group-inhalt {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding-bottom: var(--space-sm);\n}\n\n/* A3 \u2014 die Kernaussage steht am Feld, die Begr\xFCndung dahinter. Nicht als\n Tooltip: Auf einem Telefon gibt es kein Hover, und was dort unerreichbar ist,\n ist gestrichen \u2014 nur ohne dass es jemand entschieden h\xE4tte. */\n.szenen-detail__warum > summary {\n color: var(--color-text-tertiary);\n font-size: 0.75rem;\n cursor: pointer;\n}\n\n.szenen-detail__warum > small {\n display: block;\n padding-top: var(--space-xs);\n color: var(--color-text-tertiary);\n}\n\n.szenen-detail__fieldrow {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n margin-bottom: var(--space-md);\n}\n\n/* A4 \u2014 der technische Feldname bleibt lesbar, tritt aber hinter das fachliche\n Label zur\xFCck. */\n.szenen-detail__field-label {\n color: var(--color-text-primary);\n}\n\n.szenen-detail__field {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-detail__field > span {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n}\n\n/* Mehrfachauswahl und Listeneditoren. */\n.szenen-feld__mehrfach,\n.szenen-feld__liste,\n.szenen-feld__reflist,\n.szenen-feld__ref,\n.szenen-feld__zielmodell,\n.szenen-bilder__modellwahl,\n.szenen-feld__kamera {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n/* \u201ENeues Modell hinzufuegen" im Importdialog \u2014 dieselben Abstaende wie jedes\n andere Formular dieser Ansicht, damit es kein Fremdkoerper wird. */\n.szenen-feld__zielmodell-neu {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n padding: var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-feld__zielmodell-neu-aktionen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n}\n\n.szenen-feld__mehrfach > label,\n.szenen-feld__null {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n}\n\n.szenen-feld__liste-zeile {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n}\n\n.szenen-feld__reflist ol {\n display: grid;\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-feld__reflist li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n padding: var(--space-xs) var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n/* \xA76.1 \u2014 Titel und Typ zuerst, Kennungen daneben. */\n.szenen-ref__anzeige {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-ref__typ {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-ref__warn {\n padding: 0.1rem 0.5rem;\n color: #fecaca;\n background: var(--color-accent-red-dim);\n border-radius: var(--radius-full);\n font-size: 0.72rem;\n font-weight: 700;\n}\n\n/* \xA76.5 \u2014 abgeleitete Angaben, ausdr\xFCcklich nur Anzeige. */\n.szenen-detail__derived {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__derived dl {\n display: grid;\n grid-template-columns: minmax(10rem, auto) 1fr;\n gap: var(--space-xs) var(--space-sm);\n margin: 0;\n}\n\n.szenen-detail__derived dt {\n color: var(--color-text-secondary);\n}\n\n.szenen-detail__derived dd {\n margin: 0;\n}\n\n.szenen-feld__abgeleitet {\n margin: 0;\n color: var(--color-text-tertiary);\n font-size: 0.78rem;\n}\n\n/* Bereich `Prompts` \u2014 die herkunftsuebergreifende Sicht (P1-A).\n *\n * Die Eintraege selbst rendert `RundenEintrag` und tragen damit die\n * `szenen-runs__*`-Regeln. Hier stehen nur Rahmen und Kennzeichen; eine zweite\n * Laufdarstellung gibt es nicht, also braucht sie auch kein zweites Aussehen. */\n.szenen-prompts__toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-prompts__heading {\n margin: 0;\n font-size: 1.05rem;\n margin-right: auto;\n}\n\n.szenen-view__fokus {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n margin-bottom: var(--space-sm);\n}\n\n.szenen-prompts__fokus {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n margin-bottom: var(--space-sm);\n padding: var(--space-xs) var(--space-sm);\n border: 1px solid var(--color-accent, #0d9488);\n border-radius: var(--radius-sm, 4px);\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-prompts__hinweis {\n font-style: italic;\n}\n\n.szenen-prompts__ausgeblendet {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n/* ==========================================================================\n Kette `szenen-design`, P8 \u2014 der Bereich `Prompts` als Bildraster\n ========================================================================== */\n\n/* Herkunfts-Chips: eine Zeile, die in sich scrollt \u2014 nie die Seite. */\n.szenen-prompts__chips {\n display: flex;\n flex-wrap: nowrap;\n gap: 0.375rem;\n min-width: 0;\n padding-bottom: 0.15rem;\n overflow-x: auto;\n scrollbar-width: thin;\n}\n\n.szenen-view .szenen-prompts__chip {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 0.35rem;\n min-height: 2.25rem;\n padding: 0 0.8rem;\n white-space: nowrap;\n border-radius: var(--radius-full);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-prompts__chip[aria-pressed="true"] {\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border-color: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-prompts__zeile {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.375rem;\n min-width: 0;\n}\n\n.szenen-prompts__anzahl {\n flex: 1 1 8rem;\n min-width: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-prompts__umschalter {\n min-height: 2rem;\n padding: 0 0.65rem;\n font-size: 0.75rem;\n}\n\n.szenen-prompts__raster-bereich {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n}\n\n/* Der neueste Lauf \u2014 gross, mit Promptzeile und Kopierknopf. */\n.szenen-prompts__neuester {\n min-width: 0;\n overflow: hidden;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-view .szenen-prompts__oeffnen {\n display: block;\n width: 100%;\n padding: 0;\n color: var(--color-text-primary);\n text-align: left;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-prompts__bild {\n position: relative;\n display: block;\n height: 17.5rem;\n overflow: hidden;\n}\n\n.szenen-prompts__neuester .szenen-galerie__status {\n top: 0.75rem;\n left: 0.75rem;\n padding: 0.35rem 0.5rem;\n background: rgba(0, 0, 0, 0.55);\n border-radius: var(--radius-full);\n}\n\n.szenen-prompts__neuester .szenen-galerie__bildzahl {\n top: 0.75rem;\n right: 0.75rem;\n}\n\n.szenen-prompts__promptzeile {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n padding: 0.6rem 0.5rem 0.6rem 0.9rem;\n}\n\n.szenen-prompts__prompt {\n flex: 1 1 auto;\n min-width: 0;\n margin: 0;\n overflow: hidden;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-view .szenen-kopieren--symbol {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n min-height: 2.75rem;\n padding: 0;\n color: var(--color-text-primary);\n border-radius: var(--radius-lg);\n}\n\n.szenen-prompts__promptzeile .szenen-lauf__kopieren {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 0.4rem;\n}\n\n/* Gruppe aufeinanderfolgender Laeufe derselben Szene. */\n.szenen-prompts__gruppe {\n display: grid;\n gap: 0.6rem;\n min-width: 0;\n}\n\n.szenen-prompts__gruppenkopf {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-prompts__gruppenkopf h4 {\n min-width: 0;\n margin: 0;\n font-size: 1rem;\n font-weight: 650;\n line-height: 1.3;\n overflow-wrap: anywhere;\n}\n\n.szenen-prompts__gruppenkopf span {\n flex: none;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n/* Zwei Spalten, Kacheln im Format 3:4. */\n.szenen-view .szenen-prompts__raster {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 0.625rem;\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n@media (min-width: 761px) {\n .szenen-view .szenen-prompts__raster {\n grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));\n }\n}\n\n.szenen-prompts__kachel {\n min-width: 0;\n}\n\n.szenen-view .szenen-prompts__kachel > button {\n position: relative;\n display: block;\n width: 100%;\n min-width: 0;\n aspect-ratio: 3 / 4;\n padding: 0;\n overflow: hidden;\n color: var(--color-text-primary);\n text-align: left;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-view .szenen-prompts__kachel.is-fokus > button,\n.szenen-view .szenen-prompts__neuester.is-fokus {\n border-color: var(--color-accent-blue);\n box-shadow: 0 0 0 1px var(--color-accent-blue);\n}\n\n.szenen-prompts__text {\n position: absolute;\n right: 0.75rem;\n bottom: 0.7rem;\n left: 0.75rem;\n display: grid;\n gap: 0.2rem;\n min-width: 0;\n}\n\n.szenen-prompts--mitbild .szenen-prompts__text {\n color: #fff;\n}\n\n.szenen-prompts__titel {\n display: -webkit-box;\n overflow: hidden;\n font-size: 1.25rem;\n font-weight: 700;\n line-height: 1.2;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow-wrap: anywhere;\n}\n\n.szenen-prompts__kachelrunde {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.95rem;\n font-weight: 700;\n}\n\n.szenen-prompts__meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.3rem;\n min-width: 0;\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-prompts--mitbild .szenen-prompts__meta {\n color: rgba(255, 255, 255, 0.82);\n}\n\n.szenen-prompts__statuspunkt {\n display: inline-block;\n flex: none;\n width: 0.5rem;\n height: 0.5rem;\n background: var(--color-success);\n border-radius: 50%;\n}\n\n.szenen-prompts__statuspunkt[data-status="failed"] {\n background: var(--color-danger);\n}\n\n/* Eine Kachel ohne Bild nennt ihren Grund \u2014 oben, damit der Text unten frei bleibt. */\n.szenen-prompts__grund {\n display: grid;\n align-content: start;\n gap: 0.3rem;\n padding-top: 2.25rem;\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n line-height: 1.3;\n}\n\n.szenen-prompts__fehlertext {\n display: -webkit-box;\n overflow: hidden;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 4;\n overflow-wrap: anywhere;\n}\n\n/* ==========================================================================\n ZIP-MODELLVORSCHLAG (modaler Best\xE4tigungsdialog)\n ========================================================================== */\n\n/* Wie die grosse Bildansicht: eigener Grund, `position: fixed`, damit der\n Dialog im Flow-Canvas und in React gleichermassen \xFCber allem liegt. */\n.szenen-zipmodell {\n position: fixed;\n inset: 0;\n z-index: 1100;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--space-md);\n background: rgba(0, 0, 0, 0.72);\n}\n\n.szenen-zipmodell__karte {\n display: grid;\n gap: var(--space-sm);\n width: min(34rem, 100%);\n max-height: 100%;\n overflow-y: auto;\n padding: var(--space-md);\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-zipmodell__titel {\n margin: 0;\n font-size: 1rem;\n}\n\n.szenen-zipmodell__quelle,\n.szenen-zipmodell__treffer,\n.szenen-zipmodell__vertrauen,\n.szenen-zipmodell__fallback {\n margin: 0;\n font-size: 0.85rem;\n}\n\n.szenen-zipmodell__quelle,\n.szenen-zipmodell__vertrauen {\n color: var(--color-text-secondary);\n}\n\n/* Ein schwacher oder mehrdeutiger Treffer muss sich vom sicheren unterscheiden,\n sonst ist die Warnung nur ein weiterer Satz. */\n.szenen-zipmodell__warnung {\n margin: 0;\n padding: var(--space-xs) var(--space-sm);\n color: var(--color-text-primary);\n background: rgba(234, 179, 8, 0.14);\n border-left: 3px solid #eab308;\n border-radius: var(--radius-sm);\n font-size: 0.85rem;\n}\n\n.szenen-zipmodell__alternativen {\n display: grid;\n gap: 0.2rem;\n margin: 0;\n padding: var(--space-xs) var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n font-size: 0.85rem;\n}\n\n.szenen-zipmodell__alternativen > label {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n}\n\n.szenen-zipmodell__aktionen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n}\n\n/* ==========================================================================\n MEHR LADEN \u2014 der gemeinsame Fuss jeder seitenweise geladenen Liste\n ========================================================================== */\n\n.szenen-mehr-laden {\n display: grid;\n gap: var(--space-xs);\n justify-items: start;\n padding: var(--space-xs) 0;\n}\n\n.szenen-mehr-laden__button {\n padding: var(--space-xs) var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n background: var(--color-bg-surface);\n color: var(--color-text-primary);\n font-size: 0.85rem;\n cursor: pointer;\n}\n\n.szenen-mehr-laden__button:disabled {\n cursor: progress;\n opacity: 0.6;\n}\n\n.szenen-mehr-laden__fehler {\n margin: 0;\n color: var(--color-danger, #f87171);\n font-size: 0.8rem;\n}\n\n/* ==========================================================================\n PROMPTKARTE \u2014 Tags, Vorschau und Bildzahl\n (Kette `szenen-prompt-anzeige-bilder-tags`)\n\n Der Zuschnitt ist der der Library-Karte (`.library-item` + der absolut\n gesetzte Bildstreifen in `LibraryTab`): Textteil links, Deckbild rechts am\n Rand ueber die ganze Kartenhoehe, Bildzahl als Plakette darauf. Dieselben\n Werte (7rem Streifenbreite, linke Trennlinie, Plakette unten rechts), nur\n hier statt in Tailwind-Klassen \u2014 die Szenen-Ansicht teilt dieses Stylesheet\n byteweise mit Flow, und Flow hat kein Tailwind.\n ========================================================================== */\n\n.szenen-promptkarte {\n position: relative;\n overflow: hidden;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: var(--space-sm);\n}\n\n/* Nur wo ein Bild liegt, wird Platz dafuer freigehalten. Ohne Bild nutzt der\n Textteil die ganze Breite \u2014 keine leere Spalte. */\n.szenen-promptkarte--mitbild .szenen-promptkarte__inhalt {\n padding-right: calc(7rem + var(--space-sm));\n}\n\n.szenen-promptkarte__bild {\n position: absolute;\n top: 0;\n right: 0;\n width: 7rem;\n height: 100%;\n /* Hoechstens so hoch wie breit \u2014 der Streifen bleibt eine Kachel.\n `height: 100%` allein band ihn an die **Kartenhoehe**, und die ist in der\n aufgeklappten Runde die Hoehe des ganzen Prompts: Das Deckbild sprang\n dann als mehrere hundert Pixel hoher, auf Streifenbreite beschnittener\n Balken an den rechten Rand. Geschlossen aendert die Grenze nichts \u2014 dort\n ist die Karte niedriger als 7rem. */\n max-height: 7rem;\n border-left: 1px solid var(--color-border);\n background: #000;\n}\n\n/* Die gemeinsame Kachel bringt `width: 100%` und `aspect-ratio: 1` mit \u2014 hier\n fuellt sie stattdessen den Streifen, genau wie das Library-Deckbild. */\n.szenen-promptkarte__bild .szenen-bildkachel {\n width: 100%;\n height: 100%;\n aspect-ratio: auto;\n}\n\n.szenen-promptkarte__bildzahl {\n position: absolute;\n right: 0.25rem;\n bottom: 0.25rem;\n padding: 0.1rem 0.35rem;\n border-radius: var(--radius-sm);\n background: rgba(0, 0, 0, 0.6);\n color: #fff;\n font-size: 0.62rem;\n font-weight: 700;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n/* Ein Kasten je Karte, nicht zwei.\n *\n * `.szenen-view button` (master.css) gibt **jedem** Knopf der Ansicht Rahmen\n * und Hintergrund und schlaegt dabei `.szenen-runs__kopf` (eine Klasse gegen\n * Klasse plus Element). In der Laufhistorie ist das richtig: Dort ist der Kopf\n * der Eintrag. In der Promptkarte ist die Karte der Eintrag \u2014 ein zweiter\n * Kasten darin waere die doppelte Umrandung, die die Library nicht hat.\n * Der Hover braucht eine eigene Zeile, weil die Regel dort spezifischer ist. */\n.szenen-promptkarte .szenen-runs__kopf,\n.szenen-promptkarte .szenen-runs__kopf:hover:not(:disabled) {\n min-height: 0;\n padding: var(--space-xs) 0;\n background: transparent;\n border: none;\n}\n\n/* Dieselbe Karte in der Elementliste.\n *\n * Dort ist der Auswahlknopf die Karte \u2014 er traegt Rahmen, Hintergrund und die\n * Auswahlmarkierung. Der Bildstreifen liegt deshalb **darueber** statt darin:\n * Ein `<button>` nimmt nur Phrasing Content auf, ein Streifen-`div` darin\n * waere ungueltiges Markup. Damit der rechte Kartenrand trotzdem auswaehlbar\n * bleibt, laesst der Streifen Klicks durch. */\n.szenen-elementkarte {\n position: relative;\n}\n\n.szenen-elementkarte--mitbild > button {\n padding-right: calc(7rem + var(--space-sm));\n}\n\n.szenen-elementkarte > .szenen-promptkarte__bild {\n border-radius: 0 var(--radius-sm) var(--radius-sm) 0;\n}\n\n.szenen-promptkarte__bild--durchklickbar {\n pointer-events: none;\n}\n\n/* Null Bilder: die Zahl, keine Flaeche. */\n/* Die Tagliste bricht um. Auf einem Telefon ist das der Unterschied zwischen\n einer kompakten Karte und einer Zeile, die seitlich herauslaeuft. */\n.szenen-tagliste {\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n align-items: center;\n margin: 0 0 var(--space-xs);\n padding: 0;\n list-style: none;\n}\n\n.szenen-tag {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.05rem 0.4rem;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n background: var(--color-bg-app);\n font-size: 0.72rem;\n line-height: 1.5;\n white-space: nowrap;\n}\n\n/* Herkunft sichtbar, aber ohne zweite Bedeutungsebene: Ein Prompt-Tag steht\n voll, ein reiner Library-Tag zurueckgenommen. Die Karte soll schnell lesbar\n sein, nicht zwei Farbcodes lehren. */\n.szenen-tag[data-herkunft="library"] {\n border-style: dashed;\n opacity: 0.85;\n}\n\n.szenen-tag--rest {\n border-style: none;\n opacity: 0.7;\n}\n\n.szenen-tag__weg {\n border: none;\n background: none;\n padding: 0;\n color: var(--color-text-secondary, inherit);\n font-size: 0.85rem;\n line-height: 1;\n cursor: pointer;\n}\n\n.szenen-tag__weg:disabled {\n cursor: progress;\n opacity: 0.5;\n}\n\n.szenen-taggeber {\n display: grid;\n gap: var(--space-xs);\n padding: var(--space-xs);\n margin-bottom: var(--space-xs);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-taggeber__zeile {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n margin: 0;\n}\n\n.szenen-taggeber__label {\n font-size: 0.72rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n opacity: 0.75;\n}\n\n.szenen-taggeber__leer,\n.szenen-taggeber__hinweis {\n font-size: 0.72rem;\n opacity: 0.75;\n}\n\n.szenen-taggeber input[type="text"] {\n flex: 1 1 8rem;\n min-width: 0;\n padding: var(--space-xs);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n background: var(--color-bg-surface);\n color: var(--color-text-primary);\n font-size: 0.8rem;\n}\n\n/* ==========================================================================\n BILDAUFTR\xC4GE \u2014 die bestandsweite Arbeitsqueue\n Kette `szenen-bildauftraege-arbeitsqueue`, Schritt 01.\n ========================================================================== */\n\n.szenen-bildauftraege {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-bildauftraege__steuerung,\n.szenen-bildauftraege__filter,\n.szenen-bildauftraege__aktionen,\n.szenen-bildauftraege__nachladen,\n.szenen-bildauftraege__blaettern {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n}\n\n/* Der manuelle Refresh \u2014 Schritt 03 \xA72. Er steht oben und sichtbar, weil er\n die einzige Stelle ist, an der dieser Bereich nachlaedt: Es gibt keinen\n Timer mehr, den er ersetzen koennte. */\n.szenen-bildauftraege__nachladen {\n justify-content: flex-start;\n}\n\n.szenen-bildauftraege__nachladen span {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n/* Die Blaetterleiste der Bildkontrolle \u2014 Schritt 03 \xA73.1. */\n.szenen-bildauftraege__blaettern {\n margin: 0;\n}\n\n/* \u201EWeitere Bilder" \u2014 seit Schritt 06 eine **Leiste in der Zeile**, kein\n aufklappbares Formular: Modell, Anzahl, Knopf nebeneinander. */\n.szenen-bildauftraege__weitere {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n margin: var(--space-xs) 0 0;\n font-size: 0.85rem;\n}\n\n.szenen-bildauftraege__weitere label {\n color: var(--color-text-secondary);\n}\n\n/* Der Lauf-Zaehler: sichtbar, aber nicht im Weg (Schritt 06). */\n.szenen-bildauftraege__laufzaehler {\n padding: 0.05rem var(--space-xs);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm, 4px);\n font-size: 0.8rem;\n font-variant-numeric: tabular-nums;\n}\n\n/* Die Vorschau steht oben und beh\xE4lt ihren Platz, auch solange noch kein Bild\n vorliegt \u2014 sie ist die Kontrollfl\xE4che des zweiten Browserfensters (\xA75). */\n.szenen-bildauftraege__letztes {\n display: grid;\n gap: var(--space-xs);\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-bildauftraege__letztes h3 {\n margin: 0;\n font-size: 0.95rem;\n}\n\n.szenen-bildauftraege__letztes .szenen-bildkachel {\n width: min(100%, 22rem);\n height: auto;\n}\n\n.szenen-bildauftraege__lauf {\n padding: var(--space-xs) var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-bildauftraege__lauf p {\n margin: 0.1rem 0;\n}\n\n.szenen-bildauftraege__liste {\n display: grid;\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bildauftraege__zeile {\n display: grid;\n gap: 0.25rem;\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-bildauftraege__kopf,\n.szenen-bildauftraege__prompt {\n margin: 0;\n}\n\n.szenen-bildauftraege__meta {\n display: flex;\n flex-wrap: wrap;\n gap: 0.15rem var(--space-sm);\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-bildauftraege__prompt {\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n}\n\n/* \u2500\u2500 Kette `szenen-design`, P4: Szene als Studio \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Kopf mit Speichern, Hero mit Titelbild und Versions-Pill, die B\xFChne auf\n * einem Punktraster, das Element-Sheet von unten, der Prompt-Start als ein\n * Block, L\xE4ufe als Bildstreifen, Aufklapper unten. Kn\xF6pfe in der B\xFChne und im\n * Sheet setzen die Grundoptik von `.szenen-view button` gezielt zur\xFCck \u2014 daher\n * die zwei Klassen in diesen Selektoren. */\n.szenen-studio {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n}\n\n.szenen-studio__kopf {\n position: sticky;\n top: 0;\n z-index: 3;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n min-height: 2.75rem;\n padding: var(--space-xs) 0;\n background: var(--color-bg-app);\n}\n\n.szenen-studio__kopf > .szenen-detail__ids {\n flex: 1 1 auto;\n margin: 0;\n}\n\n.szenen-studio__ungespeichert {\n color: var(--color-warning);\n font-size: 0.8rem;\n font-weight: 600;\n}\n\n.szenen-view .szenen-studio__speichern {\n min-height: 2.25rem;\n padding: 0 1rem;\n color: var(--color-accent-teal, #2dd4bf);\n background: transparent;\n border-color: var(--color-accent-teal, #2dd4bf);\n border-radius: var(--radius-full);\n font-weight: 650;\n}\n\n.szenen-studio__hero {\n position: relative;\n min-height: 12rem;\n overflow: hidden;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-studio__hero--mitbild {\n min-height: 16rem;\n border-color: transparent;\n}\n\n.szenen-studio__titelbild {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.szenen-studio__scrim {\n position: absolute;\n inset: 0;\n background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.45) 42%, rgba(0, 0, 0, 0) 70%);\n}\n\n.szenen-studio__ohnebild {\n position: absolute;\n inset: 0;\n padding: var(--space-md);\n background:\n radial-gradient(var(--color-border) 1px, transparent 1px) 0 0 / 16px 16px,\n var(--color-bg-surface);\n}\n\n.szenen-studio__symbole {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n color: var(--color-text-secondary);\n}\n\n.szenen-studio__bildfehler {\n margin: 0 0 var(--space-sm);\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-studio__herotext {\n position: absolute;\n right: var(--space-md);\n bottom: var(--space-md);\n left: var(--space-md);\n display: grid;\n gap: var(--space-sm);\n}\n\n.szenen-studio__herotext h3 {\n margin: 0;\n font-size: 1.5rem;\n line-height: 1.2;\n overflow-wrap: anywhere;\n}\n\n.szenen-studio__hero--mitbild .szenen-studio__herotext {\n color: #fff;\n}\n\n.szenen-studio__herometa {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-studio__pill {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n min-height: 2.25rem;\n padding: 0 0.75rem;\n color: inherit;\n background: rgba(0, 0, 0, 0.55);\n border: 1px solid rgba(255, 255, 255, 0.25);\n border-radius: var(--radius-full);\n}\n\n.szenen-studio__hero:not(.szenen-studio__hero--mitbild) .szenen-studio__pill {\n background: var(--color-bg-elevated);\n border-color: var(--color-border);\n}\n\n/* Kette `szenen-design`, P6 \u2014 Titelbild: \u22EF-Menue im Hero, Hinweis, Zeile\n unter \u201ETechnisch" und die Aktion im Bildviewer. */\n.szenen-studio__heromenu {\n position: relative;\n display: inline-flex;\n}\n\n.szenen-view .szenen-studio__menuknopf {\n justify-content: center;\n min-width: 2.25rem;\n padding: 0 0.5rem;\n}\n\n.szenen-studio__menu {\n position: absolute;\n top: calc(100% + 0.25rem);\n left: 0;\n z-index: 5;\n display: grid;\n min-width: 12rem;\n padding: var(--space-xs, 0.25rem);\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md, 0.5rem);\n}\n\n.szenen-studio__menu button {\n min-height: 2.25rem;\n padding: 0 0.75rem;\n text-align: left;\n color: inherit;\n background: transparent;\n border: 0;\n}\n\n.szenen-studio__menu button:disabled {\n color: var(--color-text-secondary);\n}\n\n.szenen-studio__titelbildhinweis {\n margin: 0;\n font-size: 0.8rem;\n color: var(--color-warning);\n}\n\n.szenen-studio__hero--mitbild .szenen-studio__titelbildhinweis {\n color: #fde68a;\n}\n\n.szenen-studio__titelbildzeile {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n padding: var(--space-sm) 0;\n font-size: 0.875rem;\n}\n\n.szenen-studio__titelbildref {\n display: block;\n overflow-wrap: anywhere;\n color: var(--color-text-secondary);\n}\n\n.szenen-view .szenen-bildviewer__aktion {\n min-height: 2.25rem;\n padding: 0 0.75rem;\n}\n\n.szenen-bildviewer__titelbild {\n color: var(--color-accent-teal, #2dd4bf);\n font-size: 0.8125rem;\n}\n\n.szenen-studio__komposition {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-studio__abschnittkopf {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-studio__abschnittkopf h4 {\n margin: 0;\n}\n\n.szenen-studio__umschalter {\n display: inline-flex;\n padding: 3px;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n}\n\n.szenen-view .szenen-studio__umschalter button {\n min-height: 2rem;\n padding: 0 0.75rem;\n background: transparent;\n border: none;\n border-radius: var(--radius-full);\n}\n\n.szenen-view .szenen-studio__umschalter button[aria-pressed="true"] {\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-studio__aufklapper {\n display: grid;\n min-width: 0;\n}\n\n.szenen-studio__aufklapper > details {\n min-width: 0;\n border-top: 1px solid var(--color-border);\n}\n\n.szenen-studio__aufklapper > details:last-child {\n border-bottom: 1px solid var(--color-border);\n}\n\n.szenen-studio__aufklapper > details > summary {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n min-height: 2.75rem;\n cursor: pointer;\n}\n\n.szenen-studio__zusammenfassung {\n margin-left: auto;\n overflow: hidden;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Die B\xFChne */\n.szenen-buehne {\n position: relative;\n width: 100%;\n aspect-ratio: 358 / 330;\n overflow: hidden;\n background:\n radial-gradient(var(--color-border) 1px, transparent 1px) 0 0 / 16px 16px,\n var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-buehne--leer {\n display: grid;\n place-items: center;\n aspect-ratio: auto;\n min-height: 8rem;\n color: var(--color-text-secondary);\n}\n\n.szenen-buehne__linien {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n}\n\n.szenen-buehne__linie {\n stroke: var(--color-text-tertiary);\n stroke-width: 1.5;\n}\n\n.szenen-buehne__linie--naehe {\n stroke-width: 1;\n stroke-dasharray: 3 4;\n}\n\n.szenen-buehne__linie--kontakt {\n stroke: var(--color-text-primary);\n stroke-width: 3;\n}\n\n.szenen-buehne__kegel-start {\n stop-color: var(--color-accent-amber, #f2c46d);\n stop-opacity: 0.35;\n}\n\n.szenen-buehne__kegel-ende {\n stop-color: var(--color-accent-amber, #f2c46d);\n stop-opacity: 0;\n}\n\n.szenen-view .szenen-buehne__node {\n position: absolute;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.3rem;\n min-height: 0;\n max-width: 6rem;\n padding: 0;\n color: var(--color-text-primary);\n background: transparent;\n border: none;\n transform: translate(-50%, -50%);\n}\n\n.szenen-view .szenen-buehne__node:hover:not(:disabled) {\n background: transparent;\n}\n\n.szenen-buehne__symbol {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: 50%;\n}\n\n.szenen-buehne__node--mitte .szenen-buehne__symbol {\n width: 4rem;\n height: 4rem;\n border: 2px solid var(--color-text-primary);\n}\n\n.szenen-buehne__node--light .szenen-buehne__symbol {\n color: var(--color-accent-amber, #f2c46d);\n}\n\n.szenen-buehne__node[aria-pressed="true"] .szenen-buehne__symbol {\n box-shadow: 0 0 0 2px var(--color-accent-blue);\n}\n\n.szenen-buehne__name {\n max-width: 100%;\n padding: 0 0.25rem;\n overflow: hidden;\n background: var(--color-bg-app);\n border-radius: var(--radius-sm);\n font-size: 0.75rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-buehne__node--mitte .szenen-buehne__name {\n font-weight: 650;\n}\n\n.szenen-buehne__legende {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs) var(--space-md);\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-buehne__legende > span {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.szenen-buehne__legende-hinweis {\n margin-left: auto;\n}\n\n.szenen-buehne__muster {\n display: inline-block;\n width: 1.1rem;\n border-top: 1px dashed var(--color-text-tertiary);\n}\n\n.szenen-buehne__muster--kontakt {\n border-top: 3px solid var(--color-text-primary);\n}\n\n/* Das Element-Sheet */\n.szenen-sheet {\n position: fixed;\n inset: 0;\n z-index: 50;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n}\n\n.szenen-view .szenen-sheet__hintergrund {\n position: absolute;\n inset: 0;\n padding: 0;\n background: rgba(0, 0, 0, 0.6);\n border: none;\n border-radius: 0;\n cursor: default;\n}\n\n.szenen-sheet__flaeche {\n position: relative;\n display: grid;\n gap: var(--space-md);\n width: 100%;\n max-width: 40rem;\n max-height: 85vh;\n padding: var(--space-sm) var(--space-md) var(--space-md);\n overflow-y: auto;\n box-sizing: border-box;\n background: var(--color-bg-surface);\n border-top: 1px solid var(--color-border);\n border-radius: 1.5rem 1.5rem 0 0;\n}\n\n.szenen-sheet__griff {\n justify-self: center;\n width: 2.5rem;\n height: 4px;\n background: var(--color-border);\n border-radius: 2px;\n}\n\n.szenen-sheet__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-sheet__symbol {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 3.5rem;\n height: 3.5rem;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: 50%;\n}\n\n.szenen-sheet__symbol--light {\n color: var(--color-accent-amber, #f2c46d);\n}\n\n.szenen-sheet__titel {\n display: grid;\n gap: 0.15rem;\n min-width: 0;\n}\n\n.szenen-sheet__titel strong {\n font-size: 1.25rem;\n}\n\n.szenen-sheet__titel code {\n overflow: hidden;\n color: var(--color-text-secondary);\n font-family: var(--font-mono);\n font-size: 0.75rem;\n text-overflow: ellipsis;\n}\n\n.szenen-view .szenen-sheet__schliessen {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n margin-left: auto;\n padding: 0;\n border-radius: 50%;\n}\n\n.szenen-sheet__abschnitt {\n display: grid;\n gap: var(--space-xs);\n}\n\n.szenen-sheet__abschnitt h5 {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n font-weight: 500;\n}\n\n.szenen-sheet__leer {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-sheet__beziehungen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-sheet__beziehungen li {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n min-height: 2.25rem;\n padding: 0 0.75rem;\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.85rem;\n}\n\n.szenen-sheet__beziehungsart {\n color: var(--color-text-secondary);\n}\n\n.szenen-sheet__bilder {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-sheet__bild {\n position: relative;\n aspect-ratio: 1 / 1;\n overflow: hidden;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-sheet__bild img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.szenen-sheet__bildtext {\n display: grid;\n gap: 0.2rem;\n padding: 0.35rem;\n color: var(--color-text-secondary);\n font-size: 0.65rem;\n line-height: 1.25;\n overflow-wrap: anywhere;\n}\n\n.szenen-sheet__bildtext code {\n font-family: var(--font-mono);\n}\n\n.szenen-view .szenen-sheet__fertig {\n min-height: 3rem;\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border: none;\n border-radius: var(--radius-md);\n font-weight: 700;\n}\n\n/* Der Prompt-Start als ein Block */\n.szenen-start {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-view .szenen-start__primaer {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n min-height: 3.25rem;\n color: var(--color-bg-app);\n background: var(--color-accent-teal, #2dd4bf);\n border: none;\n border-radius: var(--radius-md);\n font-size: 1.05rem;\n font-weight: 700;\n}\n\n.szenen-start__kosten {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n text-align: center;\n}\n\n.szenen-start__manuell {\n display: grid;\n gap: var(--space-sm);\n}\n\n.szenen-view .szenen-start__zweit {\n min-height: 2.75rem;\n background: transparent;\n}\n\n.szenen-start__erklaerung > summary {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n cursor: pointer;\n}\n\n.szenen-start__erklaerung[open] .szenen-start__chevron {\n transform: rotate(90deg);\n}\n\n/* L\xE4ufe als Bildstreifen */\n.szenen-streifen {\n display: grid;\n gap: 0.35rem;\n padding: 0 var(--space-sm) var(--space-sm);\n}\n\n.szenen-streifen__bilder {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 4px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-streifen__bild {\n position: relative;\n aspect-ratio: 3 / 4;\n overflow: hidden;\n background: var(--color-bg-elevated);\n border-radius: var(--radius-sm);\n}\n\n.szenen-streifen__bild img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.szenen-streifen__fehler {\n display: block;\n padding: 0.25rem;\n color: var(--color-text-secondary);\n font-size: 0.65rem;\n}\n\n.szenen-streifen__mehr {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #fff;\n background: rgba(0, 0, 0, 0.6);\n font-size: 0.95rem;\n font-weight: 700;\n}\n\n.szenen-streifen__anzahl {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n/* \xC4ltere Runden: kompakte Zeile mit \xFCberlappenden Miniaturen. */\n.szenen-streifen--zeile {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-streifen--zeile .szenen-streifen__bilder {\n display: flex;\n gap: 0;\n}\n\n.szenen-streifen--zeile .szenen-streifen__bild {\n width: 2.1rem;\n height: 2.75rem;\n aspect-ratio: auto;\n border: 2px solid var(--color-bg-surface);\n}\n\n.szenen-streifen--zeile .szenen-streifen__bild + .szenen-streifen__bild {\n margin-left: -0.75rem;\n}\n\n.szenen-runs__eintrag--karte {\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n/* Szenenst\xE4nde enthalten mehrere Runden derselben eingefrorenen Szene (#538). */\n.szenen-runs__stand > h5 {\n margin: 0;\n font-size: 1rem;\n}\n\n.szenen-runs__stand-laeufe {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-runs__stand-laeufe > li {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n/* ==========================================================================\n Kette `szenen-design`, P5 \u2014 der Prompt-Lauf als Ergebnisgalerie\n ========================================================================== */\n\n/* \u2500\u2500 Chips \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-chip,\n.szenen-view .szenen-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n min-height: 1.75rem;\n padding: 0 0.65rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n line-height: 1.2;\n white-space: nowrap;\n}\n\n.szenen-view .szenen-chip--knopf {\n min-height: 2.25rem;\n color: var(--color-text-primary);\n cursor: pointer;\n}\n\n.szenen-chip--library,\n.szenen-view .szenen-chip--library {\n color: var(--color-accent-teal, #2dd4bf);\n border-color: var(--color-accent-teal, #2dd4bf);\n}\n\n/* \u2500\u2500 Navigation der Laufansicht \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-lauf__nav {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n min-width: 0;\n scroll-margin-top: var(--space-md);\n}\n\n.szenen-view .szenen-lauf__zurueck {\n display: inline-flex;\n align-items: center;\n gap: 0.15rem;\n min-height: 2.75rem;\n padding: 0 0.6rem 0 0.25rem;\n color: var(--color-text-primary);\n background: transparent;\n border: none;\n}\n\n.szenen-lauf__blaettern {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.2rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-lauf__blaettern button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n min-height: 2.5rem;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: var(--radius-full);\n}\n\n/* \u2500\u2500 Kopf: Runde, Status, Chips \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-laufinhalt {\n gap: var(--space-md);\n}\n\n.szenen-lauf__kopf {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-lauf__szene {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-lauf__titelzeile {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-lauf__runde {\n margin: 0;\n color: var(--color-text-primary);\n font-size: 1.6rem;\n font-weight: 700;\n line-height: 1.15;\n}\n\n.szenen-lauf__status {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n min-height: 1.6rem;\n padding: 0 0.6rem;\n border: 1px solid currentColor;\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.szenen-lauf__status::before {\n content: "";\n width: 0.4rem;\n height: 0.4rem;\n border-radius: 50%;\n background: currentColor;\n}\n\n.szenen-lauf__status[data-status="succeeded"] { color: var(--color-success); }\n.szenen-lauf__status[data-status="failed"] { color: var(--color-danger); }\n\n.szenen-lauf__chips {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n min-width: 0;\n}\n\n.szenen-lauf__hinweis {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n}\n\n/* \u2500\u2500 Galerie \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-lauf .szenen-bilder__ausgang {\n padding: 0;\n background: none;\n border: none;\n}\n\n.szenen-lauf {\n gap: var(--space-md);\n margin-top: 0;\n}\n\n.szenen-lauf .szenen-bilder__batch {\n padding: 0;\n background: none;\n border: none;\n}\n\n.szenen-bildgalerie--ergebnis {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 4px;\n overflow: hidden;\n border-radius: var(--radius-md);\n}\n\n.szenen-bildgalerie--einzeln {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.szenen-bildgalerie--ergebnis .szenen-bildgalerie__kachel {\n border: none;\n border-radius: 0;\n}\n\n.szenen-bildgalerie--einzeln .szenen-bildgalerie__kachel {\n border-radius: var(--radius-md);\n}\n\n.szenen-bildgalerie--ergebnis .szenen-bildkachel {\n aspect-ratio: 3 / 4;\n}\n\n.szenen-bildgalerie__alle-text {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.1rem;\n color: #fff;\n background: rgba(0, 0, 0, 0.65);\n font-size: 0.75rem;\n}\n\n.szenen-bildgalerie__alle-text strong {\n font-size: 1.25rem;\n}\n\n/* P5-Akzeptanz: Eine leere Kachel nennt ihren Grund \u2014 lesbar, nicht nur im\n Tooltip. */\n.szenen-bildkachel__grund {\n display: -webkit-box;\n max-width: 90%;\n overflow: hidden;\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n line-height: 1.3;\n text-align: center;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n}\n\n/* \u2500\u2500 Karten: Prompt, Tags \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-lauf__karte {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding: var(--space-sm) var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-lauf__kartenkopf {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-lauf__label {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-lauf__legende {\n color: var(--color-text-tertiary, var(--color-text-secondary));\n font-size: 0.72rem;\n}\n\n.szenen-lauf__kopieren {\n display: inline-flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-lauf__prompttext {\n margin: 0;\n color: var(--color-text-primary);\n line-height: 1.5;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n/* Drei Zeilen Vorschau \u2014 der volle Text bleibt im Dokument (Kopieren,\n Markieren), gek\xFCrzt wird nur die Darstellung. */\n.szenen-lauf__prompttext--zu {\n display: -webkit-box;\n overflow: hidden;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n}\n\n.szenen-view .szenen-lauf__ganz {\n justify-self: start;\n min-height: 2.25rem;\n padding: 0;\n color: var(--color-accent-teal, var(--color-text-primary));\n background: transparent;\n border: none;\n}\n\n.szenen-lauf__negativ {\n display: grid;\n gap: var(--space-xs);\n}\n\n.szenen-lauf__negativ[hidden] {\n display: none;\n}\n\n.szenen-lauf__negativ p {\n margin: 0;\n color: var(--color-text-secondary);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.szenen-lauf__karte .szenen-taggeber {\n margin: 0;\n}\n\n.szenen-tagliste .szenen-tag__neu {\n min-height: 2rem;\n}\n\n/* \u2500\u2500 \u201ENeue Bilder" (Serverauftrag des Hosts) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-neuebilder {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg, var(--radius-md));\n}\n\n.szenen-neuebilder__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-neuebilder__kopf h4 {\n margin: 0;\n color: var(--color-text-primary);\n font-size: 1.05rem;\n}\n\n.szenen-neuebilder__symbol {\n color: var(--color-accent-teal, #2dd4bf);\n}\n\n.szenen-neuebilder__weg {\n margin-left: auto;\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-neuebilder__felder {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--space-sm);\n}\n\n.szenen-wahlfeld {\n display: grid;\n gap: 0.15rem;\n min-width: 0;\n padding: 0.4rem 0.6rem;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-wahlfeld__label {\n color: var(--color-text-secondary);\n font-size: 0.68rem;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n}\n\n.szenen-view .szenen-wahlfeld select {\n min-height: 1.75rem;\n padding: 0;\n color: var(--color-text-primary);\n background: transparent;\n border: none;\n font-weight: 600;\n}\n\n.szenen-umschalter {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n padding: 3px;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-view .szenen-umschalter button {\n min-height: 2.5rem;\n background: transparent;\n border: none;\n}\n\n.szenen-view .szenen-umschalter button[aria-pressed="true"] {\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n font-weight: 600;\n}\n\n.szenen-view .szenen-neuebilder__start {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--space-sm);\n min-height: 3.25rem;\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border: none;\n border-radius: var(--radius-md);\n font-size: 1rem;\n font-weight: 700;\n}\n\n.szenen-view .szenen-neuebilder__start:hover:not(:disabled) {\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n opacity: 0.9;\n}\n\n.szenen-neuebilder__laedt,\n.szenen-neuebilder__fehler {\n margin: 0;\n font-size: 0.85rem;\n}\n\n.szenen-neuebilder__laedt { color: var(--color-text-secondary); }\n\n/* Referenzbild eines Laufs (#569-Folge): eigener Bereich \xFCber den Ergebnissen. */\n.szenen-bilder__referenz {\n display: flex;\n gap: var(--space-md);\n align-items: center;\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-left: 3px solid var(--color-accent-blue);\n border-radius: var(--radius-md);\n}\n\n.szenen-bilder__referenzbild {\n flex: none;\n width: 9rem;\n}\n\n.szenen-bilder__referenzbild img {\n display: block;\n width: 100%;\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__referenzleer {\n display: grid;\n place-items: center;\n aspect-ratio: 4 / 3;\n color: var(--color-text-secondary);\n background: var(--color-bg-elevated);\n border-radius: var(--radius-sm);\n font-size: 0.8rem;\n}\n\n.szenen-bilder__referenztext {\n display: grid;\n gap: 0.2rem;\n min-width: 0;\n color: var(--color-text-secondary);\n font-size: 0.82rem;\n}\n\n.szenen-bilder__referenztext strong {\n color: var(--color-text-primary);\n}\n\n/* Referenzbild und Prompt am einzelnen Bildauftrag. */\n.szenen-zeitleiste__referenz {\n display: flex;\n gap: var(--space-sm);\n align-items: center;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-zeitleiste__referenz img,\n.szenen-zeitleiste__referenz-leer {\n display: block;\n width: 4.5rem;\n aspect-ratio: 4 / 3;\n object-fit: cover;\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-zeitleiste__prompt {\n white-space: pre-wrap;\n user-select: text;\n}\n\n/* Das mitgegebene Kamera-Preview (#569-Folge) \u2014 sichtbar, bevor bestellt wird. */\n.szenen-neuebilder__referenz {\n margin: 0;\n padding: 0.35rem 0.6rem;\n color: var(--color-text-primary);\n background: var(--color-accent-blue-dim);\n border-left: 2px solid var(--color-accent-blue);\n border-radius: var(--radius-sm);\n font-size: 0.82rem;\n}\n.szenen-neuebilder__fehler { color: var(--color-danger); }\n\n.szenen-neuebilder__warnung > summary {\n display: flex;\n align-items: flex-start;\n gap: var(--space-sm);\n color: var(--color-warning);\n font-size: 0.85rem;\n line-height: 1.45;\n cursor: pointer;\n list-style: none;\n}\n\n.szenen-neuebilder__warnung > summary::-webkit-details-marker { display: none; }\n\n.szenen-neuebilder__warnung > p,\n.szenen-neuebilder__zuordnung ul {\n margin: var(--space-xs) 0 0;\n color: var(--color-text-secondary);\n font-size: 0.78rem;\n line-height: 1.5;\n}\n\n.szenen-neuebilder__zuordnung > summary {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n cursor: pointer;\n}\n\n.szenen-neuebilder__zuordnung ul {\n padding-left: 1.1rem;\n}\n\n/* \u2500\u2500 Aufklapper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-aufklapper {\n display: grid;\n min-width: 0;\n border-bottom: 1px solid var(--color-border);\n}\n\n.szenen-aufklapper__eintrag,\n.szenen-aufklapper .szenen-bilder__aktion {\n min-width: 0;\n padding: 0;\n border: none;\n border-top: 1px solid var(--color-border);\n border-radius: 0;\n}\n\n.szenen-aufklapper__eintrag > summary,\n.szenen-aufklapper .szenen-bilder__aktion > summary {\n list-style: none;\n cursor: pointer;\n}\n\n.szenen-aufklapper__eintrag > summary::-webkit-details-marker { display: none; }\n\n.szenen-aufklapper .szenen-bilder__aktion[open] > summary {\n margin-bottom: 0;\n}\n\n.szenen-aufklapper__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n min-height: 2.75rem;\n padding: 0 var(--space-xs);\n color: var(--color-text-primary);\n font-weight: 400;\n}\n\n.szenen-aufklapper__pfeil {\n flex: none;\n transition: transform 0.15s ease;\n}\n\ndetails[open] > summary .szenen-aufklapper__pfeil {\n transform: rotate(90deg);\n}\n\n.szenen-aufklapper__titel {\n min-width: 0;\n}\n\n.szenen-aufklapper__meta {\n margin-left: auto;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-aufklapper__inhalt {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding: 0 var(--space-xs) var(--space-md) 2rem;\n}\n\n@media (max-width: 760px) {\n .szenen-aufklapper__inhalt {\n padding-left: var(--space-xs);\n }\n}\n\n.szenen-aufklapper__inhalt > p {\n margin: 0;\n}\n\n/* \u2500\u2500 Zeitleiste der Bildauftr\xE4ge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-zeitleiste {\n display: grid;\n gap: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-zeitleiste__schritt {\n position: relative;\n display: flex;\n gap: var(--space-sm);\n min-width: 0;\n padding-bottom: var(--space-md);\n}\n\n/* Die Linie zur n\xE4chsten Zeile. */\n.szenen-zeitleiste__schritt:not(:last-child)::before {\n content: "";\n position: absolute;\n top: 2.1rem;\n bottom: 0;\n left: calc(1rem - 1px);\n width: 2px;\n background: var(--color-border);\n}\n\n.szenen-zeitleiste__symbol {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n border: 1px solid var(--color-border);\n border-radius: 50%;\n background: var(--color-bg-elevated);\n color: var(--color-text-secondary);\n font-weight: 700;\n}\n\n.szenen-zeitleiste__symbol[data-zustand="fertig"] {\n color: var(--color-success);\n border-color: var(--color-success);\n background: var(--color-accent-green-dim, var(--color-bg-elevated));\n}\n\n.szenen-zeitleiste__symbol[data-zustand="fehlgeschlagen"] {\n color: var(--color-danger);\n border-color: var(--color-danger);\n background: var(--color-accent-red-dim, var(--color-bg-elevated));\n}\n\n.szenen-zeitleiste__symbol[data-zustand="teilweise"] {\n color: var(--color-warning);\n border-color: var(--color-warning);\n}\n\n.szenen-zeitleiste__inhalt {\n display: grid;\n gap: 0.15rem;\n min-width: 0;\n padding-top: 0.3rem;\n}\n\n.szenen-zeitleiste__titel {\n color: var(--color-text-primary);\n font-size: 0.9rem;\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n\n.szenen-zeitleiste__ergebnis,\n.szenen-zeitleiste__zusatz {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n overflow-wrap: anywhere;\n}\n\n.szenen-zeitleiste__ergebnis[data-zustand="fehlgeschlagen"] { color: var(--color-danger); }\n.szenen-zeitleiste__ergebnis[data-zustand="teilweise"] { color: var(--color-warning); }\n\n.szenen-zeitleiste__aktionen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n margin-top: var(--space-xs);\n}\n\n.szenen-zeitleiste__meldung > summary {\n min-height: 2rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n line-height: 2rem;\n cursor: pointer;\n}\n\n.szenen-zeitleiste__meldung p {\n margin: var(--space-xs) 0 0;\n color: var(--color-text-secondary);\n font-size: 0.78rem;\n overflow-wrap: anywhere;\n}\n\n.szenen-zeitleiste__meldung code {\n display: block;\n margin-top: var(--space-xs);\n color: var(--color-text-tertiary, var(--color-text-secondary));\n font-family: var(--font-mono);\n font-size: 0.72rem;\n overflow-wrap: anywhere;\n}\n\n/* \u2500\u2500 Annahmen \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-annahmen {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-annahmen__zeile {\n display: flex;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-annahmen__symbol {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border-radius: 50%;\n}\n\n.szenen-annahmen__text {\n display: grid;\n gap: 0.1rem;\n min-width: 0;\n font-size: 0.85rem;\n line-height: 1.45;\n overflow-wrap: anywhere;\n}\n\n.szenen-annahmen__art {\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n}\n\n.szenen-annahmen__text details > summary,\n.szenen-lauf__erlaeuterung > summary {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n cursor: pointer;\n}\n\n.szenen-annahmen__text details p,\n.szenen-lauf__erlaeuterung p {\n margin: var(--space-xs) 0 0;\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n line-height: 1.5;\n white-space: pre-wrap;\n}\n\n.szenen-lauf__handeingabe h5 {\n margin: 0 0 var(--space-xs);\n}\n\n.szenen-lauf__handeingabe p {\n margin: 0;\n font-size: 0.85rem;\n}\n\n/* Kette `szenen-design`, P7 (#533) \u2014 die Szene aus Bausteinen. Felder als\n Karten, Bausteine im Feld als Chips; die Leiste ist das vorhandene\n Bottom-Sheet mit Bildkacheln. Bedient wird durch Antippen, nicht Ziehen. */\n.szenen-bausteinfelder {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n}\n\n.szenen-bausteinfelder__liste {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bausteinfeld {\n display: grid;\n align-content: start;\n gap: var(--space-xs);\n min-width: 0;\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-bausteinfeld__kopf {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n}\n\n.szenen-bausteinfeld__leer,\n.szenen-bausteinfeld__gesperrt {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-bausteinfeld__refs {\n display: grid;\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bausteinchip {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-view .szenen-bausteinchip__name {\n min-height: 2.25rem;\n max-width: 100%;\n padding: 0 0.75rem;\n overflow: hidden;\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.85rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-bausteinchip__aktionen {\n display: inline-flex;\n gap: var(--space-xs);\n}\n\n.szenen-view .szenen-bausteinchip__aktionen button {\n min-width: 2.25rem;\n min-height: 2.25rem;\n padding: 0 0.6rem;\n border-radius: var(--radius-full);\n}\n\n.szenen-view .szenen-bausteinfeld__plus {\n display: inline-flex;\n align-items: center;\n justify-self: start;\n gap: 0.35rem;\n min-height: 2.25rem;\n padding: 0 0.75rem;\n background: transparent;\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-full);\n}\n\n.szenen-bausteinfelder__weitere {\n display: grid;\n gap: var(--space-xs);\n}\n\n.szenen-bausteinfelder__weitere h5 {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n font-weight: 500;\n}\n\n.szenen-bausteinfelder__weitere ul {\n display: grid;\n gap: 0.25rem;\n margin: 0;\n padding: 0;\n list-style: none;\n font-size: 0.85rem;\n}\n\n.szenen-bausteinfelder__ort {\n color: var(--color-text-secondary);\n}\n\n.szenen-view .szenen-bausteinleiste__suche {\n min-height: 2.75rem;\n width: 100%;\n box-sizing: border-box;\n}\n\n.szenen-bausteinleiste {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-view .szenen-bausteinkachel {\n display: grid;\n gap: 0.25rem;\n width: 100%;\n padding: 0;\n overflow: hidden;\n text-align: left;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-view .szenen-bausteinkachel[aria-pressed="true"] {\n border-color: var(--color-text-primary);\n}\n\n.szenen-view .szenen-bausteinkachel:disabled {\n cursor: default;\n opacity: 0.7;\n}\n\n.szenen-bausteinkachel__name {\n display: flex;\n align-items: center;\n gap: 0.3rem;\n padding: 0 0.4rem;\n overflow: hidden;\n font-size: 0.8rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-bausteinkachel__status,\n.szenen-bausteinkachel__grund {\n padding: 0 0.4rem 0.4rem;\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n line-height: 1.25;\n overflow-wrap: anywhere;\n}\n\n@media (min-width: 761px) {\n .szenen-bausteinleiste {\n grid-template-columns: repeat(4, minmax(0, 1fr));\n }\n}\n/* Issue #569: mobile stage controls and exact camera letterbox. */\n/* 3D-B\xFChne (#569): Ansicht zuerst, Werte als Karten darunter. */\n.szenen-3d {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-3d__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-3d__kopf h4 {\n margin: 0 auto 0 0;\n}\n\n/* Als Ansicht \u201E3D\u201C der Komposition: kein zweiter Rahmen im Abschnitt. */\n.szenen-3d--eingebettet {\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-3d__kopf {\n flex-wrap: wrap;\n}\n\n.szenen-3d .szenen-3d__aufbau {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n min-width: 0;\n margin-right: auto;\n}\n\n.szenen-3d .szenen-3d__aufbau select {\n width: auto;\n min-width: 0;\n max-width: 100%;\n}\n\n.szenen-3d__stand {\n min-width: 0;\n margin-right: auto;\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-3d__sync {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-3d__sync::before {\n width: 0.5rem;\n height: 0.5rem;\n background: var(--color-success);\n border-radius: var(--radius-full);\n content: "";\n}\n\n.szenen-3d__sync[data-state="speichert"]::before {\n background: var(--color-warning);\n}\n\n.szenen-3d__sync[data-state="ansicht"]::before {\n background: var(--color-accent-blue);\n}\n\n.szenen-3d__meldung,\n.szenen-3d__fehler {\n margin: 0;\n padding: var(--space-sm) var(--space-md);\n background: var(--color-bg-elevated);\n border-left: 3px solid var(--color-accent-blue);\n border-radius: var(--radius-sm);\n}\n\n.szenen-3d__fehler {\n border-left-color: var(--color-danger);\n}\n\n.szenen-3d__oeffnen {\n display: grid;\n gap: var(--space-sm);\n}\n\n.szenen-3d label {\n display: grid;\n gap: 0.3rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-3d__leiste {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-3d__katalog {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.35rem;\n}\n\n.szenen-3d__katalog > span {\n margin-right: 0.15rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-3d__katalog button,\n.szenen-view .szenen-3d__elemente button {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n min-height: 2rem;\n padding: 0 0.7rem;\n border-radius: var(--radius-full);\n font-size: 0.85rem;\n}\n\n.szenen-3d__katalog i,\n.szenen-3d__elemente i {\n flex: none;\n width: 0.6rem;\n height: 0.6rem;\n border-radius: 2px;\n}\n\n.szenen-view .szenen-3d__elemente button[aria-pressed="true"] {\n color: var(--color-text-primary);\n background: var(--color-bg-surface-hover);\n border-color: var(--color-text-primary);\n}\n\n/* Viewport: feste H\xF6he f\xFCr Drauf- und Seitenansicht; die Kameraansicht wird\n * darin auf das gespeicherte Kameraformat eingepasst (Letterbox). */\n.szenen-3d__viewport {\n position: relative;\n display: grid;\n place-items: center;\n height: clamp(320px, 58vh, 560px);\n overflow: hidden;\n background: #0d0f12;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n container-type: size;\n outline: none;\n}\n\n.szenen-3d__viewport:focus-visible {\n border-color: var(--color-accent-blue);\n box-shadow: 0 0 0 1px var(--color-accent-blue);\n}\n\n.szenen-3d__surface {\n position: relative;\n width: 100%;\n height: 100%;\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n}\n\n.szenen-3d__viewport[data-view="camera"] {\n background: #050607;\n}\n\n.szenen-3d__viewport[data-view="camera"] .szenen-3d__surface {\n width: min(100cqw, calc(100cqh * var(--seitenverhaeltnis)));\n height: min(100cqh, calc(100cqw / var(--seitenverhaeltnis)));\n}\n\n.szenen-3d__hud {\n position: absolute;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #d4d4d4;\n font-size: 0.78rem;\n font-variant-numeric: tabular-nums;\n pointer-events: none;\n}\n\n.szenen-3d__hud--werkzeuge {\n top: 0.6rem;\n right: 0.6rem;\n gap: 0.25rem;\n pointer-events: auto;\n}\n\n.szenen-view .szenen-3d__hud--werkzeuge button {\n min-width: 2rem;\n min-height: 2rem;\n padding: 0 0.6rem;\n color: #e5e5e5;\n background: rgba(23, 23, 23, 0.85);\n border-color: rgba(255, 255, 255, 0.12);\n backdrop-filter: blur(4px);\n}\n\n.szenen-3d__hud--kamera {\n top: 0.6rem;\n left: 0.6rem;\n padding: 0.2rem 0.55rem;\n background: rgba(0, 0, 0, 0.65);\n border-radius: var(--radius-full);\n}\n\n.szenen-3d__hud--info {\n bottom: 0.6rem;\n left: 0.6rem;\n max-width: calc(100% - 7rem);\n padding: 0.25rem 0.6rem;\n background: rgba(0, 0, 0, 0.6);\n border-radius: var(--radius-full);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.szenen-3d__hud--info strong {\n color: #ffffff;\n font-weight: 600;\n}\n\n.szenen-3d__hud i {\n font-style: normal;\n font-weight: 700;\n}\n\n.szenen-3d__hud--achsen {\n right: 0.75rem;\n bottom: 0.7rem;\n gap: 0.6rem;\n font-weight: 700;\n}\n\n.szenen-3d__labels {\n position: absolute;\n inset: 0;\n overflow: hidden;\n pointer-events: none;\n}\n\n.szenen-3d__label {\n position: absolute;\n padding: 0.05rem 0.4rem;\n color: #f5f5f5;\n background: rgba(10, 10, 10, 0.72);\n border-left: 2px solid var(--farbe, #9bafbc);\n border-radius: 3px;\n font: 500 0.72rem/1.4 var(--font-sans);\n white-space: nowrap;\n transform: translate(-50%, 6px);\n}\n\n.szenen-3d__label--side {\n transform: translate(-50%, calc(-100% - 6px));\n}\n\n.szenen-3d__label--kamera {\n color: #bfdbfe;\n border-left-color: #60a5fa;\n transform: translate(14px, -50%);\n}\n\n.szenen-3d__label--kamera.is-links {\n transform: translate(calc(-100% - 14px), -50%);\n}\n\n.szenen-3d__label.is-selected {\n color: #000000;\n background: #ffffff;\n}\n\n.szenen-3d__inspektor {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));\n gap: var(--space-sm);\n}\n\n.szenen-3d__karte {\n display: grid;\n align-content: start;\n gap: var(--space-sm);\n min-width: 0;\n padding: var(--space-sm) var(--space-md) var(--space-md);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-3d__karte h5 {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.72rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.szenen-3d__elemente {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem;\n}\n\n.szenen-3d__werte {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 0.4rem;\n margin: 0;\n padding: 0;\n border: none;\n}\n\n.szenen-3d__werte legend {\n margin-bottom: 0.4rem;\n padding: 0;\n color: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-3d__werte legend span {\n margin-left: 0.35rem;\n color: var(--color-text-secondary);\n font-size: 0.78rem;\n font-weight: 400;\n}\n\n.szenen-3d__zeilenkopf {\n grid-column: 1 / -1;\n margin-top: 0.2rem;\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-3d__werte > button {\n grid-column: 1 / -1;\n}\n\n.szenen-3d .szenen-3d__feld {\n position: relative;\n display: block;\n}\n\n.szenen-3d__achse {\n position: absolute;\n top: 50%;\n left: 0.55rem;\n font-size: 0.72rem;\n font-weight: 700;\n transform: translateY(-50%);\n pointer-events: none;\n}\n\n.szenen-3d__achse--x { color: #f87171; }\n.szenen-3d__achse--y { color: #4ade80; }\n.szenen-3d__achse--z { color: #60a5fa; }\n\n.szenen-view .szenen-3d__feld input {\n padding-left: 1.6rem;\n font-variant-numeric: tabular-nums;\n}\n\n.szenen-3d__hinweis {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.82rem;\n}\n\n.szenen-3d__abschluss {\n display: grid;\n gap: var(--space-sm);\n}\n\n.szenen-view .szenen-3d__primaer {\n min-height: 2.75rem;\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border-color: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-view .szenen-3d__primaer:hover:not(:disabled) {\n color: var(--color-bg-app);\n background: var(--color-primary-hover);\n}\n\n.szenen-view .szenen-3d__nebenaktion {\n justify-self: start;\n min-height: 2rem;\n padding: 0;\n background: none;\n border: none;\n font-size: 0.82rem;\n text-decoration: underline;\n}\n\n/* Hinweise passend zum Eingabeger\xE4t; ohne Angabe gilt die Maus-Variante. */\n.szenen-3d__nur-touch {\n display: none;\n}\n\n@media (hover: none) and (pointer: coarse) {\n .szenen-3d__nur-maus {\n display: none;\n }\n\n .szenen-3d__nur-touch {\n display: inline;\n }\n\n /* Fingergerechte Ziele (44 px) f\xFCr Ansichtssteuerung, Katalog und Elemente. */\n .szenen-view .szenen-3d__hud--werkzeuge button,\n .szenen-view .szenen-3d__katalog button,\n .szenen-view .szenen-3d__elemente button,\n .szenen-view .szenen-3d .szenen-studio__umschalter button {\n min-width: 2.75rem;\n min-height: 2.75rem;\n }\n}\n\n@media (max-width: 760px) {\n .szenen-3d {\n gap: var(--space-sm);\n padding: var(--space-sm);\n }\n\n .szenen-3d__leiste {\n display: grid;\n }\n\n .szenen-3d .szenen-studio__umschalter {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n }\n\n /* Katalog als eine Zeile, die in sich scrollt, statt die Ansicht nach unten zu schieben. */\n .szenen-3d__katalog {\n flex-wrap: nowrap;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n }\n\n .szenen-3d__katalog > * {\n flex: none;\n }\n\n .szenen-3d__viewport {\n height: clamp(300px, 62svh, 560px);\n margin: 0 calc(-1 * var(--space-sm));\n border-right: none;\n border-left: none;\n border-radius: 0;\n }\n\n .szenen-3d__hud--info {\n max-width: calc(100% - 1.2rem);\n bottom: 2.4rem;\n }\n\n .szenen-3d__hud--achsen {\n bottom: 0.8rem;\n left: 0.75rem;\n right: auto;\n }\n}\n\n/* One DOM canvas, no nested React renderer. */\n.szenen-3d__canvas { display: block; width: 100%; height: 100%; }\n\n/* Prompt choices before the 3D run; mobile buttons wrap within each category. */\n.szenen-3d__prompt details { margin-block: .65rem; }\n.szenen-3d__prompt summary { cursor: pointer; font-weight: 600; }\n.szenen-3d__prompt fieldset { border: 0; padding: .6rem 0; min-width: 0; }\n.szenen-3d__prompt legend { color: var(--color-text-secondary); font-size: .85rem; }\n.szenen-3d__prompt textarea { min-height: 6rem; width: 100%; box-sizing: border-box; }\n.szenen-3d__referenz { white-space: pre-wrap; overflow-wrap: anywhere; font-size: .9rem; }\n\n.szenen-3d__gemini img { display: block; width: 100%; max-height: 28rem; object-fit: contain; background: #eef0f3; border-radius: .4rem; }\n.szenen-3d__gemini pre { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 32rem; overflow: auto; font-size: .8rem; }\n.szenen-3d__gemini ul { list-style: none; padding: 0; }\n.szenen-3d__gemini li { margin-block: .6rem; overflow-wrap: anywhere; }\n.szenen-3d__gemini li i { display: inline-block; width: .9rem; height: .9rem; margin-right: .4rem; border-radius: .15rem; }\n';
64
+ var SZENEN_VIEW_STYLES = '/* ==========================================================================\n SZENEN VIEW\n ========================================================================== */\n\n.szenen-view {\n display: grid;\n gap: var(--space-md);\n width: 100%;\n min-width: 0;\n font-family: var(--font-sans);\n padding: var(--space-md);\n}\n\n@media (max-width: 760px) {\n .szenen-view {\n padding: var(--space-sm);\n gap: var(--space-sm);\n }\n}\n\n/* Kette `szenen-design`, P1 \u2014 Bild zuerst, Text auf Abruf. Der Kopf ist nur\n * noch Titel und \u24D8; die Erklaerung klappt darunter auf. */\n.szenen-view__intro {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n gap: var(--space-sm);\n color: var(--color-text-primary);\n}\n\n.szenen-view__titel {\n display: grid;\n gap: 0.1rem;\n min-width: 0;\n}\n\n.szenen-view__intro h2,\n.szenen-view__intro p {\n margin: 0;\n}\n\n.szenen-view__intro h2 {\n font-size: clamp(1.5rem, 3vw, 1.9rem);\n font-weight: 700;\n letter-spacing: -0.01em;\n line-height: 1.15;\n}\n\n.szenen-view__eyebrow {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.szenen-view .szenen-view__info {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n min-height: 2.75rem;\n padding: 0;\n border-radius: var(--radius-full);\n}\n\n.szenen-view .szenen-view__info[aria-expanded="true"] {\n color: var(--color-text-primary);\n border-color: var(--color-accent-teal, #2dd4bf);\n}\n\n.szenen-view__intro-text {\n margin: 0;\n padding: var(--space-sm) var(--space-md);\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n font-size: 0.85rem;\n line-height: 1.4;\n}\n\n.szenen-icon {\n flex: none;\n}\n\n/* Fuer Screenreader sichtbar, fuer das Auge nicht \u2014 Status-Punkte und\n * Node-Symbole tragen ihre Bedeutung als Text. */\n.szenen-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n/* Die Bereiche als Pill-Leiste. Sie scrollt in sich, nie die Seite: `min-width:\n * 0` haelt sie in der Spalte, `overflow-x: auto` macht jeden Bereich\n * erreichbar, auch wenn nicht alle nebeneinander passen. */\n.szenen-view__nav {\n display: flex;\n flex-wrap: nowrap;\n gap: var(--space-xs);\n min-width: 0;\n padding: 0 0 var(--space-xs);\n overflow-x: auto;\n scrollbar-width: thin;\n}\n\n.szenen-view__nav button,\n.szenen-view button {\n min-height: 2.25rem;\n padding: 0.45rem 0.75rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n cursor: pointer;\n}\n\n.szenen-view button:hover:not(:disabled) {\n color: var(--color-text-primary);\n background: var(--color-bg-surface-hover);\n border-color: var(--color-border-hover);\n}\n\n.szenen-view button:focus-visible,\n.szenen-view input:focus-visible,\n.szenen-view select:focus-visible,\n.szenen-view textarea:focus-visible {\n outline: 2px solid var(--color-accent-blue);\n outline-offset: 2px;\n}\n\n.szenen-view button:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.szenen-view .szenen-view__nav button {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 0.4rem;\n min-height: 2.25rem;\n padding: 0 0.9rem;\n white-space: nowrap;\n border-radius: var(--radius-full);\n font-size: 0.875rem;\n}\n\n.szenen-view .szenen-view__nav button.is-active,\n.szenen-view .szenen-view__nav button[aria-selected="true"] {\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border-color: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-view__area {\n min-width: 0;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-view__capability-note,\n.szenen-area__lead {\n margin: 0;\n padding: var(--space-sm) var(--space-md);\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border-left: 3px solid var(--color-accent-purple);\n border-radius: var(--radius-sm);\n}\n\n.szenen-view__host-notes {\n color: var(--color-text-secondary);\n}\n\n.szenen-view__host-notes > summary {\n cursor: pointer;\n font-size: 0.8rem;\n}\n\n/* `box-sizing` steht hier und nicht beim Host: Die React-App bringt in\n * `master.css` einen globalen `* { box-sizing: border-box }` mit, Flow **nicht**\n * \u2014 dort ragte `width: 100%` plus Innenabstand um die Randbreite aus dem\n * Elternelement heraus und erzeugte auf ~390 px einen horizontalen Scroll. Die\n * gemeinsame Ansicht darf sich auf keinen Host-Reset verlassen. */\n.szenen-view input:not([type="checkbox"]),\n.szenen-view select,\n.szenen-view textarea {\n box-sizing: border-box;\n width: 100%;\n min-height: 2.25rem;\n padding: 0.5rem 0.65rem;\n color: var(--color-text-primary);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n font: inherit;\n}\n\n.szenen-view textarea {\n min-height: 7rem;\n resize: vertical;\n font-family: var(--font-mono);\n font-size: 0.8rem;\n}\n\n.szenen-view label {\n display: grid;\n gap: var(--space-xs);\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n}\n\n.szenen-view code,\n.szenen-view pre {\n font-family: var(--font-mono);\n overflow-wrap: anywhere;\n}\n\n.szenen-view h3,\n.szenen-view h4,\n.szenen-view h5 {\n margin-top: 0;\n}\n\n.szenen-view ul,\n.szenen-view ol {\n padding-left: 1.25rem;\n}\n\n.szenen-elements,\n.szenen-detail,\n.szenen-scene,\n.szenen-setup,\n.szenen-erweitert,\n.szenen-prompts,\n.szenen-shot,\n.szenen-media,\n.szenen-runs {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n}\n\n/* Arbeitsoberflaeche: Liste links, Bearbeitung rechts.\n *\n * Breit stehen beide Spalten nebeneinander \u2014 die Auswahl bleibt sichtbar,\n * waehrend bearbeitet wird. Schmal rendert die Komponente nur eine der beiden;\n * hier steht deshalb keine Regel, die die andere versteckt. */\n@media (min-width: 761px) {\n .szenen-elements {\n grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);\n align-items: start;\n }\n\n .szenen-elements__master,\n .szenen-elements__detail {\n min-width: 0;\n }\n}\n\n.szenen-elements__master,\n.szenen-elements__detail {\n display: grid;\n gap: var(--space-sm);\n align-content: start;\n min-width: 0;\n}\n\n.szenen-elements__toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-elements__heading {\n margin: 0;\n font-size: 1.05rem;\n}\n\n.szenen-elements__scope {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n min-width: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-elements__scope > select {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.szenen-elements__new {\n flex: none;\n font-weight: 700;\n}\n\n.szenen-elements__create {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-accent-blue);\n border-radius: var(--radius-sm);\n}\n\n.szenen-elements__create label {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-elements__create-actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n}\n\n.szenen-elements__options > summary {\n color: var(--color-text-tertiary);\n font-size: 0.78rem;\n cursor: pointer;\n}\n\n.szenen-elements__back {\n justify-self: start;\n font-weight: 700;\n}\n\n.szenen-elements__empty-detail {\n margin: 0;\n color: var(--color-text-tertiary);\n}\n\n.szenen-elements__filter,\n.szenen-detail__actions,\n.szenen-runs__start,\n.szenen-scene-editor__add,\n.szenen-scene-editor__add-relation {\n display: flex;\n flex-wrap: wrap;\n align-items: end;\n gap: var(--space-sm);\n}\n\n.szenen-elements__filter > label,\n.szenen-runs__start > label,\n.szenen-scene-editor__add > input {\n flex: 1 1 16rem;\n}\n\n.szenen-elements__filter > label:has(input[type="checkbox"]) {\n display: flex;\n flex: 1 1 16rem;\n flex-direction: row;\n align-items: center;\n}\n\n.szenen-elements__filter input[type="checkbox"] {\n width: 1rem;\n height: 1rem;\n accent-color: var(--color-accent-blue);\n}\n\n.szenen-elements__list {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-elements__list > li > button {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs) var(--space-sm);\n width: 100%;\n height: 100%;\n text-align: left;\n}\n\n.szenen-elements__list > li > button > .szenen-elements__title {\n flex: 1 1 100%;\n}\n\n.szenen-elements__list > li > button.is-selected,\n.szenen-elements__list > li > button[aria-current="true"] {\n background: var(--color-accent-blue-dim);\n border-color: var(--color-accent-blue);\n}\n\n.szenen-elements__type {\n color: var(--color-accent-blue);\n font-size: 0.75rem;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.szenen-elements__title {\n color: var(--color-text-primary);\n font-size: 0.95rem;\n}\n\n.szenen-elements__subtype,\n.szenen-elements__retired {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-elements__retired {\n color: var(--color-warning);\n}\n\n.szenen-detail {\n margin-top: 0;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n@media (min-width: 761px) {\n .szenen-detail {\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n }\n}\n\n.szenen-detail > header,\n.szenen-detail__heads,\n.szenen-detail__draft,\n.szenen-capability {\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n/* .szenen-runs ist ein eigenst\xE4ndiger sichtbarer Bereich, beh\xE4lt Styling auf Desktop */\n@media (min-width: 761px) {\n .szenen-runs {\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n }\n}\n\n@media (max-width: 760px) {\n .szenen-runs {\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n }\n}\n\n.szenen-detail__ids {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n margin-bottom: 0;\n color: var(--color-text-secondary);\n}\n\n.szenen-detail__heads ul,\n.szenen-scene-editor ul,\n.szenen-runs > ol,\n.szenen-capability > ul {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-detail__heads li,\n.szenen-scene-editor li,\n.szenen-runs > ol > li,\n.szenen-capability > ul > li {\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n\n/* Stufe 6.7.2 (D-126) \u2014 Advanced-/Debug-Fl\xE4che f\xFCr die rohe, schema-getriebene\n * Feldliste einer Szene. Gestrichelt wie die anderen \u201EAngebot statt\n * Auskunft"-Bereiche, aber ohne Akzentfarbe: sie ist kein Vorschlag, sondern\n * ein Eskalationsweg. */\n.szenen-detail__technical {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md) var(--space-md);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__technical > summary {\n margin-bottom: var(--space-sm);\n color: var(--color-text-secondary);\n font-weight: 600;\n cursor: pointer;\n}\n\n.szenen-detail__technical[open] > summary {\n margin-bottom: var(--space-md);\n}\n\n.szenen-detail__field small,\n.szenen-capability small {\n color: var(--color-text-tertiary);\n}\n\n.szenen-detail__preview-errors,\n.szenen-detail__notice--error,\n.szenen-view [role="alert"] {\n color: #fecaca;\n background: var(--color-accent-red-dim);\n border-color: var(--color-accent-red);\n}\n\n.szenen-detail__notice {\n padding: var(--space-sm) var(--space-md);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__notice--success,\n.szenen-view [data-tone="success"] {\n color: #bbf7d0;\n background: var(--color-accent-green-dim);\n border-color: var(--color-accent-green);\n}\n\n.szenen-scene-editor {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--space-md);\n margin-bottom: 0;\n}\n\n.szenen-scene-editor > section {\n min-width: 0;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n/* \u2500\u2500 Stufe 6.7.2 (D-126): Node-/Relationskarten \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Nodes und Beziehungen sind `<details>` \u2014 dieselbe Interaktionssprache wie\n * \u201ERohantwort (Diagnose)" und \u201EBilder zu diesem Lauf" in RunsPanel.tsx. Kopf\n * (immer sichtbar) tr\xE4gt Inhalt zuerst, Technik zuletzt; Body (nur bei\n * ge\xF6ffneter Karte) tr\xE4gt die Bearbeitungscontrols. Padding wandert von der\n * `<li>` in Kopf/Body, damit die Karte keinen doppelten Rand bekommt. */\n.szenen-scene-editor li {\n padding: 0;\n overflow: hidden;\n}\n\n.szenen-node-karte__kopf,\n.szenen-relation-karte__kopf {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs) var(--space-sm);\n padding: var(--space-sm);\n cursor: pointer;\n list-style: none;\n}\n\n.szenen-node-karte__kopf::-webkit-details-marker,\n.szenen-relation-karte__kopf::-webkit-details-marker {\n display: none;\n}\n\n.szenen-node-karte__titel {\n flex: 1 1 12rem;\n min-width: 0;\n color: var(--color-text-primary);\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n\n.szenen-node-karte__typ {\n flex: none;\n padding: 0.15rem 0.55rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.72rem;\n white-space: nowrap;\n}\n\n/* node_id klein, monospace, sekund\xE4r \u2014 sichtbar auch bei zugeklappter Karte,\n * aber optisch klar hinter Beschreibung und Typ. */\n.szenen-node-karte__meta {\n flex: 1 1 100%;\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n color: var(--color-text-tertiary);\n font-size: 0.75rem;\n}\n\n.szenen-node-karte__meta code {\n font-size: inherit;\n}\n\n.szenen-node-karte__body,\n.szenen-relation-karte__body {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-sm) var(--space-sm) var(--space-sm);\n border-top: 1px solid var(--color-border);\n}\n\n/* \xA74 \u2014 Prim\xE4raktion und destruktive Aktion optisch getrennt: \u201ENode/Beziehung\n * entfernen" bekommt einen eigenen, warnenden Ton statt gleichgewichtig neben\n * der normalen Bearbeitung zu stehen. */\n.szenen-node-karte__entfernen,\n.szenen-relation-karte__entfernen {\n justify-self: start;\n color: #fecaca;\n background: var(--color-accent-red-dim);\n border-color: var(--color-accent-red);\n}\n\n.szenen-relation-karte__kopf {\n font-size: 0.9rem;\n}\n\n.szenen-relation-karte__kopf code {\n overflow-wrap: anywhere;\n}\n\n.szenen-relation-karte__pfeil {\n flex: none;\n color: var(--color-text-secondary);\n}\n\n/* Die Composer-\xD6ffner (\u201E+ Node hinzuf\xFCgen", \u201E+ Beziehung hinzuf\xFCgen") sind\n * Angebote, keine Ausk\xFCnfte \u2014 dasselbe gestrichelte Muster wie beim Folgelauf\n * und der Fehlerrettung (\xA73.3/\xA73.5). */\n.szenen-scene-editor__oeffnen {\n width: 100%;\n border-style: dashed;\n}\n\n.szenen-refpicker {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n margin: var(--space-sm) 0;\n padding: var(--space-sm) 0;\n border: none;\n border-radius: 0;\n}\n\n.szenen-refpicker legend {\n padding: 0 var(--space-xs);\n color: var(--color-text-secondary);\n font-weight: 600;\n}\n\n.szenen-capability > ul > li {\n display: grid;\n grid-template-columns: minmax(10rem, 1fr) auto minmax(14rem, 2fr);\n align-items: start;\n gap: var(--space-sm);\n}\n\n.szenen-capability__state {\n padding: 0.1rem 0.5rem;\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.szenen-capability__state--yes {\n color: #bbf7d0;\n background: var(--color-accent-green-dim);\n}\n\n.szenen-capability__state--no {\n color: #fecaca;\n background: var(--color-accent-red-dim);\n}\n\n.szenen-capability__state--unknown {\n color: #fef08a;\n background: rgba(234, 179, 8, 0.2);\n}\n\n.szenen-runs > ol > li {\n display: grid;\n gap: var(--space-sm);\n}\n\n/* B1 \u2014 die geschlossene Runde. Vorher stand die `run_id` als erstes und war\n die einzige Information, die niemand liest; jetzt beantwortet die Kopfzeile\n welche Runde, ob sie durchging, mit welchem Modell und was ungef\xE4hr\n herauskam. */\n.szenen-runs__hinweis {\n margin: var(--space-xs) 0 0;\n color: var(--color-text-secondary);\n font-size: 0.78rem;\n}\n\n.szenen-runs__kopf {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-sm);\n width: 100%;\n padding: var(--space-xs) 0;\n text-align: left;\n color: var(--color-text-secondary);\n background: transparent;\n border: none;\n cursor: pointer;\n}\n\n.szenen-runs__marke {\n font-weight: 700;\n color: var(--color-text-primary);\n}\n\n.szenen-runs__status {\n padding: 0.05rem 0.4rem;\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n border-radius: var(--radius-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n}\n\n.szenen-runs__status[data-status="succeeded"] {\n border-color: var(--color-success);\n}\n\n.szenen-runs__status[data-status="failed"] {\n border-color: var(--color-danger);\n}\n\n.szenen-runs__modell {\n font-size: 0.75rem;\n}\n\n/* Der Auszug ist die Inhaltsvorschau der Runde. Er bekommt eine eigene Zeile,\n damit er nicht mit Marke und Modell um dieselbe Zeile ringt. */\n.szenen-runs__auszug {\n flex: 1 1 100%;\n min-width: 0;\n color: var(--color-text-tertiary);\n font-size: 0.8125rem;\n}\n\n/* B2 \u2014 ein Fehler steht ausserhalb der aufklappbaren Fl\xE4che: Wer eine rote\n Runde sieht, soll nicht erst klicken m\xFCssen, um zu erfahren, woran sie\n gescheitert ist. */\n.szenen-runs__fehler {\n display: grid;\n gap: var(--space-xs);\n padding: var(--space-sm);\n border-radius: var(--radius-sm);\n}\n\n.szenen-runs__fehler p {\n margin: 0;\n}\n\n.szenen-runs__inhalt {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-runs__prompt > h5,\n.szenen-runs__sekundaer > h5 {\n margin: 0 0 var(--space-xs);\n}\n\n/* Im Kopf traegt die Zeile selbst den Abstand \u2014 sonst kaeme er doppelt. */\n.szenen-runs__promptkopf > h5 {\n margin: 0;\n}\n\n/* Ueberschrift und Kopierknopf in einer Zeile. Der Knopf gehoert an den Text,\n den er kopiert \u2014 nicht an den Rand der Runde, wo er neben dem falschen\n Abschnitt stuende. */\n.szenen-runs__promptkopf {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-sm);\n margin: 0 0 var(--space-xs);\n}\n\n/* Ein kompakter Knopf, kein zweiter Titel: Der Prompt ist die Hauptsache des\n Abschnitts, die Aktion daneben darf ihn nicht ueberstimmen. Rahmen und\n Hintergrund kommen aus `.szenen-view button` und bleiben \u2014 dieselbe Optik wie\n jeder andere Knopf der Ansicht; hier wird nur die Groesse zurueckgenommen.\n Zwei Klassen im Selektor, weil `.szenen-view button` sonst spezifischer ist. */\n.szenen-runs__promptkopf .szenen-runs__kopieren {\n min-height: 0;\n padding: 0.1rem 0.45rem;\n font-size: 0.72rem;\n}\n\n/* Regel 11: die Bestaetigung nennt die Zahl, nicht nur \u201EErfolgreich". */\n.szenen-runs__kopiert {\n color: var(--color-text-tertiary, var(--color-text-secondary));\n font-size: 0.72rem;\n}\n\n.szenen-runs__prompt > p {\n margin: 0;\n white-space: pre-wrap;\n}\n\n.szenen-runs__prompt--negativ > p,\n.szenen-runs__sekundaer > p {\n margin: 0;\n color: var(--color-text-secondary);\n white-space: pre-wrap;\n}\n\n.szenen-runs__mehr {\n justify-self: start;\n margin-top: var(--space-xs);\n padding: 0;\n color: var(--color-accent-teal, var(--color-text-secondary));\n background: transparent;\n border: none;\n font-size: 0.75rem;\n text-decoration: underline;\n cursor: pointer;\n}\n\n.szenen-runs > ol > li[data-status="succeeded"] {\n border-left: 3px solid var(--color-success);\n}\n\n.szenen-runs > ol > li[data-status="failed"] {\n border-left: 3px solid var(--color-danger);\n}\n\n.szenen-runs details pre {\n max-height: 20rem;\n overflow: auto;\n padding: var(--space-sm);\n white-space: pre-wrap;\n color: var(--color-text-secondary);\n background: var(--color-bg-app);\n border-radius: var(--radius-sm);\n}\n\n.szenen-media > section {\n display: grid;\n gap: var(--space-sm);\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-media__lookup,\n.szenen-media__attach {\n display: flex;\n flex-wrap: wrap;\n align-items: end;\n gap: var(--space-sm);\n}\n\n.szenen-media__lookup > label,\n.szenen-media__attach > label:first-child {\n flex: 1 1 18rem;\n}\n\n.szenen-media__list {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-media__list > li {\n display: grid;\n grid-template-columns: minmax(12rem, 1fr) auto auto auto;\n align-items: center;\n gap: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n@media (max-width: 760px) {\n .szenen-view {\n gap: var(--space-sm);\n }\n\n /* C1 \u2014 auf 390 px bleiben drei Kacheln je Reihe gross genug zum Erkennen\n und klein genug, dass vier Bilder eine Reihe sind und keine Seite. */\n .szenen-bildgalerie {\n grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));\n }\n\n /* Der Viewer bekommt den ganzen Bildschirm; die Bl\xE4tterkn\xF6pfe bleiben am\n Rand, wo der Daumen sie erreicht. */\n .szenen-bildviewer {\n padding: var(--space-xs);\n }\n\n .szenen-bildviewer__blaettern {\n width: 2.25rem;\n height: 4rem;\n }\n\n .szenen-view__nav {\n position: sticky;\n top: 0;\n z-index: 2;\n padding: var(--space-xs) 0;\n background: var(--color-bg-app);\n }\n\n\n .szenen-scene-editor {\n grid-template-columns: 1fr;\n }\n\n .szenen-capability > ul > li {\n grid-template-columns: 1fr;\n }\n\n .szenen-derive,\n .szenen-elements,\n .szenen-scene,\n .szenen-setup,\n .szenen-shot,\n .szenen-media,\n .szenen-runs {\n gap: var(--space-sm);\n }\n\n .szenen-elements__filter {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--space-sm);\n }\n\n .szenen-elements__filter > label {\n width: 100%;\n min-width: 0;\n flex: none;\n }\n\n .szenen-elements__filter > label:has(input[type="checkbox"]) {\n flex: none;\n grid-column: 1 / -1;\n }\n\n /* Schmal ist die Liste eine Spalte, und die Auswahl fuehrt weiter \u2014 der\n * Eintrag ist deshalb ein Ziel fuer den Finger, keine Kachel. */\n .szenen-elements__list {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .szenen-elements__list > li > button {\n min-height: 2.75rem;\n }\n\n .szenen-elements__back {\n justify-self: stretch;\n min-height: 2.5rem;\n }\n\n .szenen-detail__actions,\n .szenen-runs__start,\n .szenen-scene-editor__add,\n .szenen-scene-editor__add-relation {\n align-items: stretch;\n flex-direction: column;\n }\n\n .szenen-runs__start > *,\n .szenen-scene-editor__add > *,\n .szenen-scene-editor__add-relation > * {\n width: 100%;\n flex: none;\n }\n}\n\n/* \u2500\u2500 Kette `szenen-design`, P2: Szenen-\xDCbersicht als Bildgalerie \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Kacheln wie in der Library: quadratisch, Deckbild, Titel ueber einem\n * Verlauf, Bildzahl als Plakette. Eine Szene ohne Bild zeigt ihre\n * Node-Symbole; ein nicht ladbares Deckbild nennt den Grund. Die Schrift auf\n * dem Bild ist hell auf dunklem Verlauf \u2014 unabhaengig vom Hostthema, weil das\n * Bild es auch ist. */\n.szenen-galerie {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-galerie__kopf > .szenen-elements__heading {\n flex: 1 1 auto;\n margin: 0;\n}\n\n.szenen-galerie__anzahl,\n.szenen-galerie__sortierung {\n color: var(--color-text-secondary);\n font-weight: 400;\n}\n\n.szenen-galerie__sortierung {\n font-size: 0.8rem;\n}\n\n.szenen-galerie__raster {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr));\n gap: 0.625rem;\n min-width: 0;\n}\n\n/* Die Kacheln sind Zellen desselben Rasters wie die Neu-Kachel. */\n.szenen-view .szenen-galerie__liste {\n display: contents;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-galerie__kachel {\n min-width: 0;\n}\n\n.szenen-view .szenen-galerie__kachel > button,\n.szenen-view .szenen-galerie__neu,\n.szenen-view .szenen-galerie__zuletzt {\n position: relative;\n display: block;\n width: 100%;\n min-width: 0;\n padding: 0;\n overflow: hidden;\n color: var(--color-text-primary);\n text-align: left;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-view .szenen-galerie__kachel > button {\n aspect-ratio: 1 / 1;\n}\n\n.szenen-view .szenen-galerie__kachel > button[aria-current="true"],\n.szenen-view .szenen-galerie__zuletzt[aria-current="true"] {\n border-color: var(--color-accent-blue);\n box-shadow: 0 0 0 1px var(--color-accent-blue);\n}\n\n.szenen-galerie__bild {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.szenen-galerie__scrim {\n position: absolute;\n inset: 0;\n background: linear-gradient(to top, rgba(0, 0, 0, 0.88) 0%, rgba(0, 0, 0, 0.4) 40%, rgba(0, 0, 0, 0) 65%);\n}\n\n.szenen-galerie__ohnebild {\n position: absolute;\n inset: 0;\n padding: 0.75rem;\n background:\n radial-gradient(var(--color-border) 1px, transparent 1px) 0 0 / 14px 14px,\n var(--color-bg-surface);\n}\n\n.szenen-galerie__bildfehler {\n position: absolute;\n inset: 0;\n /* Oben Platz fuer Status-Punkte und Bildzahl, die darueber liegen. */\n padding: 2.25rem 0.75rem 0.75rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n font-size: 0.75rem;\n line-height: 1.3;\n}\n\n.szenen-galerie__text {\n position: absolute;\n right: 0.75rem;\n bottom: 0.7rem;\n left: 0.75rem;\n display: grid;\n gap: 0.25rem;\n}\n\n.szenen-galerie__kachel--mitbild .szenen-galerie__text,\n.szenen-galerie__zuletzt--mitbild .szenen-galerie__zuletzt-text {\n color: #fff;\n}\n\n.szenen-galerie__titel {\n display: -webkit-box;\n overflow: hidden;\n font-size: 0.875rem;\n font-weight: 650;\n line-height: 1.25;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 3;\n overflow-wrap: anywhere;\n}\n\n.szenen-galerie__meta {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-galerie__kachel--mitbild .szenen-galerie__meta,\n.szenen-galerie__zuletzt--mitbild .szenen-galerie__meta {\n color: rgba(255, 255, 255, 0.82);\n}\n\n.szenen-galerie__tags {\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n min-width: 0;\n}\n\n.szenen-galerie__tag {\n max-width: 100%;\n padding: 0.05rem 0.4rem;\n overflow: hidden;\n color: inherit;\n background: var(--color-bg-elevated);\n border-radius: var(--radius-full);\n font-size: 0.68rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-galerie__kachel--mitbild .szenen-galerie__tag {\n background: rgba(0, 0, 0, 0.5);\n}\n\n.szenen-galerie__status {\n position: absolute;\n top: 0.7rem;\n left: 0.7rem;\n display: flex;\n gap: 0.3rem;\n}\n\n.szenen-galerie__punkt {\n width: 0.625rem;\n height: 0.625rem;\n background: var(--color-text-secondary);\n border-radius: 50%;\n box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.55);\n}\n\n.szenen-galerie__punkt[data-ton="info"] { background: var(--color-accent-blue); }\n.szenen-galerie__punkt[data-ton="ok"] { background: var(--color-success); }\n.szenen-galerie__punkt[data-ton="fertig"] { background: var(--color-warning); }\n/* Unvollstaendig ist ein Ring: Die Form unterscheidet es von \u201Evollstaendig",\n * nicht nur der Farbton (P8). */\n.szenen-galerie__punkt[data-ton="warn"] {\n background: transparent;\n box-shadow: inset 0 0 0 2px var(--color-accent-orange), 0 0 0 2px rgba(0, 0, 0, 0.55);\n}\n\n/* Die Legende der Punkte \u2014 einmal je Ansicht. */\n.szenen-statuslegende {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem 0.85rem;\n margin: 0;\n padding: 0;\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n list-style: none;\n}\n\n.szenen-statuslegende__eintrag {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.szenen-statuslegende .szenen-galerie__punkt {\n display: inline-block;\n width: 0.5rem;\n height: 0.5rem;\n}\n\n.szenen-galerie__bildzahl {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.15rem 0.5rem;\n color: #fff;\n background: rgba(0, 0, 0, 0.65);\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.szenen-galerie__symbole {\n display: flex;\n flex-wrap: wrap;\n gap: 0.3rem;\n}\n\n.szenen-galerie__symbol {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 1.875rem;\n height: 1.875rem;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: 50%;\n}\n\n.szenen-galerie__symbol[data-node-type="light"] {\n color: var(--color-warning);\n}\n\n.szenen-galerie__symbol--rest {\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n}\n\n.szenen-view .szenen-galerie__neu {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.6rem;\n aspect-ratio: 1 / 1;\n text-align: center;\n background: var(--color-bg-app);\n border: 1.5px dashed var(--color-border-hover, var(--color-border));\n}\n\n.szenen-galerie__neu-plus {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 3.25rem;\n height: 3.25rem;\n color: var(--color-bg-app);\n background: var(--color-accent-teal, #2dd4bf);\n border-radius: 50%;\n}\n\n.szenen-galerie__neu-titel {\n font-size: 0.95rem;\n font-weight: 600;\n}\n\n.szenen-galerie__neu-text {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-galerie__zuletzt-bild {\n position: relative;\n display: block;\n aspect-ratio: 4 / 3;\n max-height: 17rem;\n width: 100%;\n}\n\n.szenen-galerie__chip {\n position: absolute;\n top: 0.75rem;\n left: 0.75rem;\n padding: 0.3rem 0.6rem;\n color: #fff;\n background: rgba(0, 0, 0, 0.6);\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n}\n\n.szenen-galerie__zuletzt .szenen-galerie__status {\n right: 0.75rem;\n left: auto;\n top: 1rem;\n}\n\n/* Die Symbole einer Szene ohne Bild stehen unter dem Chip, nicht darauf. */\n.szenen-galerie__zuletzt .szenen-galerie__ohnebild {\n padding-top: 3rem;\n}\n\n.szenen-galerie__zuletzt-text {\n position: absolute;\n right: 1rem;\n bottom: 0.9rem;\n left: 1rem;\n display: grid;\n gap: 0.35rem;\n}\n\n.szenen-galerie__zuletzt-text .szenen-galerie__titel {\n font-size: 1.3rem;\n font-weight: 700;\n line-height: 1.2;\n}\n\n.szenen-galerie__zuletzt-fuss {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n padding: 0.75rem 0.9rem;\n}\n\n.szenen-galerie__oeffnen {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 0.25rem;\n color: var(--color-accent-teal, #2dd4bf);\n font-size: 0.875rem;\n font-weight: 600;\n}\n\n/* \u2500\u2500 Stufe 6.5: Rekonstruktion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Der Bereich zeigt drei Dinge nebeneinander: den Vorschlag, das nicht\n * Ableitbare und die Widerspr\xFCche. Die Diagnosen sind deshalb bewusst nicht\n * kleiner gesetzt als der Vorschlag \u2014 wer sie \xFCbersieht, \xFCbernimmt Geratenes.\n */\n\n.szenen-derive {\n display: grid;\n gap: var(--space-md);\n}\n\n.szenen-form {\n display: grid;\n gap: var(--space-sm);\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-field {\n display: grid;\n gap: var(--space-xs);\n}\n\n.szenen-field > span {\n color: var(--color-text-secondary);\n font-size: 0.875rem;\n}\n\n.szenen-error {\n padding: var(--space-sm) var(--space-md);\n color: var(--color-danger);\n background: var(--color-accent-red-dim);\n border: 1px solid var(--color-accent-red);\n border-radius: var(--radius-sm);\n}\n\n.szenen-empty {\n padding: var(--space-md);\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-diagnose {\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-left: 3px solid var(--color-warning);\n border-radius: var(--radius-sm);\n}\n\n/* Ein Widerspruch ist der schwerste der drei Befunde: dort steht eine\n * Entscheidung aus, die das System bewusst nicht getroffen hat (D-74). */\n.szenen-diagnose--konflikt {\n border-left-color: var(--color-danger);\n}\n\n.szenen-diagnose > h4 {\n margin: 0 0 var(--space-sm);\n font-size: 0.9375rem;\n}\n\n.szenen-diagnose ul {\n display: grid;\n gap: var(--space-xs);\n margin: 0;\n padding-left: var(--space-md);\n}\n\n.szenen-proposal {\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-proposal > h4 {\n margin: 0 0 var(--space-sm);\n font-family: var(--font-mono);\n font-size: 0.9375rem;\n}\n\n.szenen-proposal__payload {\n max-height: 18rem;\n margin: 0 0 var(--space-sm);\n padding: var(--space-sm);\n overflow: auto;\n /* Ein erzeugter Prompt ist ein einziger langer Satz \u2014 ohne Umbruch\n verschwindet er nach rechts aus dem Bild. JSON-Payloads bringen ihre\n eigenen Zeilenumbrueche mit und leiden nicht darunter. */\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n font-family: var(--font-mono);\n font-size: 0.8125rem;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-proposal__done {\n margin: var(--space-sm) 0 0;\n color: var(--color-success);\n}\n\n/* Die Belege eines Laufs: Rohantwort und Systemprompt. Zum Lesen und Kopieren,\n nicht zum Bedienen \u2014 deshalb voll markierbar und in Monospace. */\n.szenen-beleg__text {\n width: 100%;\n margin: var(--space-sm) 0 0;\n padding: var(--space-sm);\n font-family: var(--font-mono);\n font-size: 0.8125rem;\n line-height: 1.5;\n white-space: pre;\n background: var(--color-bg-app);\n color: var(--color-text);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n resize: vertical;\n}\n\n/* Der Folgelauf (D-87): abgesetzt, damit er nicht wie Teil des Ergebnisses\n aussieht \u2014 er ist eine Frage, keine Auskunft. */\n.szenen-folgelauf {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md) var(--space-md);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-folgelauf > h4 {\n margin: var(--space-sm) 0 0;\n}\n\n.szenen-run__herkunft {\n margin: 0 0 var(--space-sm);\n font-size: 0.875rem;\n color: var(--color-text-muted, inherit);\n}\n\n/* Widerspricht das Modell, ist das das Wichtigste auf der Seite. */\n.szenen-diagnose--antwort {\n border-left: 3px solid var(--color-accent, var(--color-border));\n}\n\n/* Der Bildw\xE4hler (D-92) \u2014 Browser und Inspector, dem Labs-Tab nachgebildet,\n aber mit dem CSS dieser Ansicht: eine gemeinsame Komponente \xFCber zwei\n Dom\xE4nengrenzen w\xE4re eine Kopplung, die keiner gewollt hat.\n\n Der Review vom 2026-08-22 (R12.1/R12.2) hat den Ma\xDFstab gesetzt: Der Bestand\n ist ein **Browser**, kein Seiteninhalt. Vierzig Werke d\xFCrfen die Szenenseite\n nicht meterlang machen, und zw\xF6lf Varianten eines Werkes keine zw\xF6lf\n Bildschirmseiten. Deshalb steht hier alles unter zwei Regeln \u2014 begrenzte\n Fl\xE4che mit eigenem Scroll, und Kacheln statt Karten. */\n\n/* \u2500\u2500 Ebene 1: der Browser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-bildwahl {\n /* Dieselbe Begr\xFCndung wie beim Inspector: Als Grid-Element w\xFCrde der\n W\xE4hler sonst so breit wie sein breitester Inhalt. */\n min-width: 0;\n}\n\n.szenen-bildwahl__browser {\n /* Die eigene Scrollfl\xE4che ist der ganze Punkt: Der Bestand w\xE4chst nach\n innen, nicht nach unten. Dieselbe Gr\xF6\xDFenordnung wie `max-h-[300px]` im\n Labs-Browser. */\n max-height: 19rem;\n overflow-y: auto;\n overscroll-behavior: contain;\n margin-top: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-bildwahl__raster {\n display: grid;\n /* Vier Spalten auf schmalen Displays \u2014 der gemeldete Screenshot zeigte eine\n einzige Spalte gro\xDFer Karten. Breiter wird automatisch dichter. */\n grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bildwahl__karte {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n overflow: hidden;\n background: var(--color-bg-surface);\n text-align: left;\n cursor: pointer;\n}\n\n/* Das fokussierte Werk ist klar markiert \u2014 sonst wei\xDF niemand, wessen Galerie\n der Inspector unten zeigt. */\n.szenen-bildwahl__karte.is-fokus {\n border-color: var(--color-accent, var(--color-text-primary));\n box-shadow: 0 0 0 2px var(--color-accent, var(--color-text-primary));\n}\n\n/* \u2500\u2500 Die Kachel selbst \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Der Platz steht, bevor das Bild da ist \u2014 sonst springt das Raster, sobald\n die erste Vorschau eintrifft. */\n.szenen-bildkachel {\n display: block;\n width: 100%;\n aspect-ratio: 1;\n overflow: hidden;\n background: var(--color-bg-app);\n}\n\n.szenen-bildkachel img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n}\n\n.szenen-bildkachel__leer {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: linear-gradient(135deg, var(--color-bg-app), var(--color-bg-surface));\n}\n\n/* R12.3: Eine fehlende Vorschau bleibt kachelgro\xDF. Vorher fiel die Karte auf\n ihren Prompttext zur\xFCck \u2014 und ein Prompt hat im echten Bestand mehrere\n hundert Zeichen. */\n.szenen-bildkachel__zeichen {\n font-size: 0.875rem;\n font-weight: 700;\n color: var(--color-text-secondary);\n opacity: 0.6;\n}\n\n/* Wie viele Varianten das Werk hat \u2014 klein und \xFCberlagernd, nie als\n dominanter Text. */\n.szenen-bildwahl__anzahl {\n position: absolute;\n top: 0.15rem;\n right: 0.15rem;\n padding: 0.05rem 0.3rem;\n font-size: 0.625rem;\n font-weight: 700;\n line-height: 1.4;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n/* Eine Zeile, dann Schluss. Der Prompt eines Werkes ist oft mehrere hundert\n Zeichen lang und w\xE4re als Prim\xE4rdarstellung genau die Textw\xFCste, gegen die\n der Review antritt. */\n.szenen-bildwahl__kacheltitel {\n display: block;\n padding: 0.15rem 0.3rem;\n font-size: 0.625rem;\n line-height: 1.3;\n color: var(--color-text-secondary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 Ebene 2: der Inspector \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-bildwahl__inspector {\n /* Ohne `min-width: 0` gewinnt der Inhalt: Der W\xE4hler ist Element eines\n Grids (`.szenen-form`), und dort ist `min-width: auto` die Vorgabe. Der\n Streifen unten ist rund 1000 px breit \u2014 gemessen am 2026-08-22 im echten\n Browser zog er die Auswahl von 374 px auf 1088 px auf und schob die\n ganze Seite waagerecht heraus, statt selbst zu scrollen. */\n min-width: 0;\n margin-top: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n /* Sichtbar abgesetzt vom Browser: zwei Ebenen, nicht eine lange Liste. */\n border: 1px solid var(--color-border);\n border-left: 3px solid var(--color-accent, var(--color-border));\n border-radius: var(--radius-sm);\n}\n\n.szenen-bildwahl__inspektorkopf {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n margin-bottom: var(--space-sm);\n}\n\n.szenen-bildwahl__werktitel {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--color-text-primary);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-bildwahl__zurueck {\n flex: 0 0 auto;\n font-size: 0.6875rem;\n padding: 0.15rem 0.5rem;\n}\n\n/* Der Streifen: waagerecht scrollend, feste kleine Kacheln \u2014 zw\xF6lf Varianten\n bleiben ein \xDCberblick statt zw\xF6lf Bildschirmseiten. */\n.szenen-bildwahl__streifen {\n /* Die Breite kommt vom Elter, nie vom Inhalt \u2014 sonst scrollt hier nichts. */\n max-width: 100%;\n display: flex;\n gap: var(--space-sm);\n margin: 0;\n padding: 0 0 0.25rem;\n list-style: none;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n}\n\n.szenen-bildwahl__streifen > li {\n flex: 0 0 auto;\n width: 5rem;\n}\n\n.szenen-bildwahl__variante {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n overflow: hidden;\n background: var(--color-bg-app);\n cursor: pointer;\n}\n\n.szenen-bildwahl__variante.is-gewaehlt {\n border-color: var(--color-accent, var(--color-text-primary));\n box-shadow: 0 0 0 2px var(--color-accent, var(--color-text-primary));\n}\n\n.szenen-bildwahl__nummer {\n position: absolute;\n bottom: 0.15rem;\n left: 0.15rem;\n padding: 0.05rem 0.3rem;\n font-size: 0.625rem;\n line-height: 1.4;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border-radius: var(--radius-sm);\n}\n\n/* \u2500\u2500 Das Gew\xE4hlte \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-bildwahl__gewaehlt {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n margin: var(--space-sm) 0 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bildwahl__gewaehlt li {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.25rem 0.5rem;\n font-size: 0.8125rem;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n max-width: 100%;\n}\n\n/* Das gew\xE4hlte Bild wird best\xE4tigt, nicht nur benannt: eine kleine Vorschau\n neben dem Titel. */\n.szenen-bildwahl__gewaehlt .szenen-bildkachel {\n width: 2.25rem;\n flex: 0 0 auto;\n border-radius: var(--radius-sm);\n}\n\n.szenen-bildwahl__gewaehlt .szenen-bildwahl__kacheltitel {\n min-width: 0;\n max-width: 12rem;\n font-size: 0.75rem;\n}\n\n.szenen-beleg__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n margin-top: var(--space-sm);\n}\n\n.szenen-diagnose > details + details {\n margin-top: var(--space-sm);\n}\n\n.szenen-diagnose > details > summary {\n cursor: pointer;\n font-weight: 600;\n}\n\n/* \u2500\u2500 Die Fehlerrettung (Stufe 6.6, A5) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Sie steht im Fehlerblock und muss trotzdem als Werkzeug lesbar sein, nicht\n * als weitere Fehlermeldung. Deshalb abgesetzt wie der Folgelauf \u2014 und aus\n * demselben Grund: Beides sind Angebote, keine Ausk\xFCnfte.\n *\n * Der wichtigste optische Punkt ist die Trennung von Original und\n * Arbeitskopie. Das Original bekommt den ruhigen, \u201Efesten" Hintergrund der\n * Belege; die Kopie sieht aus wie ein normales Eingabefeld, weil sie eines\n * ist. */\n.szenen-rettung {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md) var(--space-md);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-rettung > h4 {\n margin: var(--space-sm) 0 0;\n}\n\n.szenen-rettung textarea[readonly] {\n background: var(--color-bg-surface);\n color: var(--color-text-secondary);\n font-family: var(--font-mono, monospace);\n font-size: 0.8125rem;\n}\n\n.szenen-rettung textarea:not([readonly]) {\n font-family: var(--font-mono, monospace);\n font-size: 0.8125rem;\n}\n\n.szenen-rettung__aktionen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n margin: var(--space-sm) 0;\n}\n\n/* Ein Befund tr\xE4gt Code, Bezug und Meldung. Der Code steht klein und\n * monospaced davor: Er ist die Kennung, nicht die Aussage. */\n.szenen-diagnose__liste {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding-left: var(--space-md);\n}\n\n.szenen-diagnose__liste code {\n font-size: 0.8125rem;\n}\n\n.szenen-diagnose__liste > li[data-severity=\'warning\'] {\n color: var(--color-text-secondary);\n}\n\n/* \u2500\u2500 Die Draft-Kette (Stufe 6.6, C4) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Der Hauptweg. Er steht nach den Einzel\xFCbernahmen und muss als das erkennbar\n * sein, was er ist: nicht eine weitere Option, sondern der k\xFCrzere Weg zum\n * selben Ziel. Deshalb durchgezogener Rahmen statt gestricheltem \u2014 er ist\n * Angebot **und** Empfehlung. */\n.szenen-kette {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md) var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-left: 3px solid var(--color-accent, var(--color-border));\n border-radius: var(--radius-sm);\n}\n\n.szenen-kette > h4 {\n margin: var(--space-sm) 0 0;\n}\n\n.szenen-kette ul {\n display: grid;\n gap: var(--space-xs);\n margin: 0 0 var(--space-sm);\n padding-left: var(--space-md);\n}\n\n.szenen-kette code {\n font-size: 0.8125rem;\n}\n\n/* Ein Hinweis, der eine Bedingung erklaert \u2014 nicht rot, weil er kein Fehler\n ist, aber abgesetzt, weil er eine Folge hat. */\n.szenen-detail__hint {\n margin: var(--space-sm) 0 0;\n padding: var(--space-sm);\n font-size: 0.875rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border-left: 3px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n/* \u2500\u2500 Stufe 6.7: Bilder am Prompt-Lauf (H0/H1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Der Bereich tr\xE4gt zwei Dinge, die man nie verwechseln darf: den **Eingang**\n * (woraus der Prompt entstand) und den **Ausgang** (was daraus wurde). Sie\n * bekommen deshalb verschiedene Akzentkanten statt nur verschiedener\n * \xDCberschriften \u2014 wer schnell liest, sieht die Trennung, bevor er sie liest.\n */\n.szenen-bilder {\n display: grid;\n gap: var(--space-md);\n margin-top: var(--space-sm);\n}\n\n.szenen-bilder__eingang,\n.szenen-bilder__ausgang {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-sm) var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__eingang {\n border-left: 3px solid var(--color-accent-purple, var(--color-border));\n}\n\n.szenen-bilder__ausgang {\n border-left: 3px solid var(--color-accent-teal, var(--color-border));\n}\n\n.szenen-bilder h5 {\n margin: 0;\n}\n\n.szenen-bilder__ids {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n margin: 0;\n align-items: baseline;\n color: var(--color-text-secondary);\n font-size: 0.875rem;\n}\n\n.szenen-bilder__eingangsliste,\n.szenen-bilder__batchliste,\n.szenen-bilder__auftraege {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bilder__eingangsliste > li,\n.szenen-bilder__batchliste > li,\n.szenen-bilder__auftraege > li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n font-size: 0.8125rem;\n}\n\n/* Ein unterbrochener Auftrag ist der Fall, f\xFCr den der Auftragssatz existiert.\n Er wird deshalb markiert \u2014 nicht rot, denn er ist kein Fehler, sondern eine\n offene Entscheidung. */\n.szenen-bilder__auftraege > li[data-status="started"] {\n border-left: 3px solid var(--color-warning);\n}\n\n.szenen-bilder__auftraege > li[data-status="succeeded"] {\n border-left: 3px solid var(--color-success);\n}\n\n.szenen-bilder__auftraege > li[data-status="partial"] {\n border-left: 3px solid var(--color-accent-blue, var(--color-border));\n}\n\n.szenen-bilder__auftraege > li[data-status="failed"] {\n border-left: 3px solid var(--color-danger);\n}\n\n/* Das Eingangsbild benutzt seit C3 dieselbe Kachel wie W\xE4hler und Galerie.\n Sie ist von Haus aus so breit wie ihr Platz \u2014 in dieser Zeile bekommt sie\n deshalb eine feste Gr\xF6sse, sonst sch\xF6be sie die Metadaten heraus. */\n.szenen-bilder__eingangsliste .szenen-bildkachel {\n flex: 0 0 auto;\n width: 4rem;\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__batch {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding: var(--space-sm);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__batchkopf {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-bilder__herkunft {\n color: var(--color-text-tertiary);\n font-size: 0.75rem;\n}\n\n/* Review-Befund \u2014 ein transienter Bildfehler ist wiederholbar, kein\n endg\xFCltiges \u201Efehlt". Dezent wie ein Angebot, nicht wie ein Fehlerzustand. */\n.szenen-bilder__retry {\n justify-self: start;\n padding: 0.15rem 0.5rem;\n font-size: 0.75rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n cursor: pointer;\n}\n\n/* C4 \u2014 die Provenienz vollst\xE4ndig, aber sekund\xE4r. */\n.szenen-bilder__technik > summary {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n cursor: pointer;\n}\n\n.szenen-bilder__meta {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n font-size: 0.75rem;\n color: var(--color-text-secondary);\n}\n\n/* C5 \u2014 der Verlauf verdichtet, seine Ausreisser nicht. */\n.szenen-bilder__verlauf > summary {\n color: var(--color-text-secondary);\n font-size: 0.8125rem;\n cursor: pointer;\n}\n\n.szenen-bilder__verlauf[open] > summary {\n margin-bottom: var(--space-sm);\n}\n\n.szenen-bilder__auffaellig {\n margin: 0;\n padding: var(--space-sm);\n border-radius: var(--radius-sm);\n font-size: 0.8125rem;\n}\n\n.szenen-bilder__auftragskennung {\n flex-basis: 100%;\n color: var(--color-text-tertiary);\n font-size: 0.6875rem;\n}\n\n/* \u2500\u2500 C1/C2 \u2014 Galerie und grosse Ansicht \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Das Raster w\xE4chst mit dem Platz: auf 390 px drei bis vier Kacheln je Reihe,\n auf dem Desktop entsprechend mehr. Vorher war jedes Bild eine Zeile aus\n Daumennagel plus vier Metadatenfeldern \u2014 vier Bilder ergaben vier Textzeilen\n und das Protokoll war die Hauptsache. */\n.szenen-bildgalerie {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr));\n gap: var(--space-sm);\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bildgalerie__kachel {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n cursor: pointer;\n}\n\n.szenen-bildgalerie__kachel:hover,\n.szenen-bildgalerie__kachel:focus-visible {\n border-color: var(--color-accent-teal, var(--color-text-primary));\n}\n\n.szenen-bildgalerie__nummer {\n position: absolute;\n bottom: 0.15rem;\n left: 0.15rem;\n padding: 0.05rem 0.3rem;\n font-size: 0.625rem;\n line-height: 1.4;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border-radius: var(--radius-sm);\n}\n\n/* Die grosse Ansicht liegt \xFCber allem und bringt ihren eigenen Grund mit \u2014\n `position: fixed` bezieht sich im Flow-Canvas auf dessen Rahmen, in React auf\n das Fenster; in beiden F\xE4llen genau das Gew\xFCnschte. */\n.szenen-bildviewer {\n position: fixed;\n inset: 0;\n z-index: 1000;\n display: grid;\n grid-template-rows: auto 1fr auto;\n gap: var(--space-sm);\n padding: var(--space-sm);\n /* Deckend, nicht get\xF6nt: Bei 0.92 schimmerte der Laufbereich durch und man\n las Prompttext quer \xFCber dem Bild \u2014 im Browser gemessen. */\n background: #000;\n}\n\n/* Titel, Z\xE4hlung, Schliessen \u2014 drei Spalten, damit ein langer Werktitel die\n Z\xE4hlung nicht in die n\xE4chste Zeile und \xFCber das Bild schiebt. */\n.szenen-bildviewer__kopf {\n display: grid;\n /* Titel nimmt den Rest; Zaehler, eine optionale Bildaktion (P6) und\n Schliessen stehen rechts \u2014 mit und ohne Aktion in einer Zeile. */\n grid-template-columns: minmax(0, 1fr);\n grid-auto-columns: auto;\n grid-auto-flow: column;\n align-items: center;\n gap: var(--space-sm);\n color: var(--color-text-primary);\n}\n\n.szenen-bildviewer__titel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 600;\n}\n\n.szenen-bildviewer__zaehler {\n color: var(--color-text-secondary);\n font-size: 0.8125rem;\n}\n\n.szenen-bildviewer__buehne {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--space-sm);\n min-height: 0;\n min-width: 0;\n}\n\n/* Der Rahmen nimmt den Platz, der zwischen den Bl\xE4tterkn\xF6pfen \xFCbrig ist \u2014\n `min-width: 0`, damit er auch wirklich schrumpft statt sie hinauszuschieben. */\n.szenen-bildviewer__rahmen {\n flex: 1 1 auto;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 0;\n min-height: 0;\n height: 100%;\n}\n\n.szenen-bildviewer__bild {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n}\n\n.szenen-bildviewer__leer {\n color: var(--color-text-secondary);\n text-align: center;\n}\n\n/* Die Bl\xE4tterkn\xF6pfe sind daumengross und liegen an den R\xE4ndern \u2014 auf einem\n Telefon ist der Rand erreichbar, die Bildmitte nicht. */\n.szenen-bildviewer__blaettern {\n flex: 0 0 auto;\n width: 2.75rem;\n height: 3.5rem;\n font-size: 1.75rem;\n line-height: 1;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n cursor: pointer;\n}\n\n.szenen-bildviewer__details {\n max-height: 8rem;\n overflow-y: auto;\n color: var(--color-text-secondary);\n}\n\n/* Die Aktionen stehen abgesetzt: Sie sind Angebote, keine Ausk\xFCnfte \u2014 dasselbe\n Muster wie beim Folgelauf und bei der Fehlerrettung. */\n/* D \u2014 die Aktionen stehen abgesetzt und standardm\xE4ssig kompakt: Sie sind\n Angebote, keine Ausk\xFCnfte. Vorher hielten beide Formulare dauerhaft offen und\n machten aus jedem Lauf zwei zus\xE4tzliche Bildschirmseiten. */\n.szenen-bilder__aktion {\n min-width: 0;\n padding: var(--space-sm) var(--space-md);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__aktion > summary {\n color: var(--color-text-primary);\n font-weight: 600;\n cursor: pointer;\n}\n\n.szenen-bilder__aktion[open] > summary {\n margin-bottom: var(--space-sm);\n}\n\n.szenen-bilder__aktion-inhalt {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding-bottom: var(--space-sm);\n}\n\n.szenen-bilder__aktion h5 {\n margin: var(--space-sm) 0 0;\n}\n\n.szenen-bilder__aktion ol {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding-left: var(--space-md);\n font-size: 0.8125rem;\n}\n\n/* Regelwerk-UX Schritt 16 \u2014 der ZIP-Sammelimport.\n *\n * \xA78: Der gemeldete Einsatz ist mobil. Deshalb **ein** Seedfeld statt einer\n * gestapelten Eingabe je Bild, und die Zuordnung Bild -> Seed als umbrechende\n * Zeile statt als Tabelle: Eine Tabelle waere auf 390 px abgeschnitten, und\n * abgeschnitten heisst hier, dass der Nutzer die Zuordnung nicht mehr pruefen\n * kann \u2014 genau die Pruefung, wegen der die Vorschau existiert. */\n.szenen-bilder__zip {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-bilder__zipkopf {\n margin: 0;\n overflow-wrap: anywhere;\n}\n\n.szenen-bilder__zipvorlagen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n margin: 0;\n}\n\n/* Eine laengere Liste bleibt scrollbar, statt die Sektion und damit den\n * Import-Knopf aus dem Blick zu schieben (\xA78, letzter Punkt). */\n.szenen-bilder__zipliste {\n max-height: 16rem;\n overflow-y: auto;\n}\n\n.szenen-bilder__zipliste > li {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-bilder__zipliste > li > span:first-child {\n overflow-wrap: anywhere;\n}\n\n.szenen-bilder__zipliste > li > span:last-child {\n color: var(--color-text-secondary);\n white-space: nowrap;\n}\n\n/* ==========================================================================\n STUFE 6.10 \u2014 ELEMENTEDITOR UND VERSIONSNAVIGATION\n ========================================================================== */\n\n/* \xA74.2 \u2014 vier Sachverhalte, vier Marken. Die Marken stehen in einer eigenen\n * Spalte, damit ANGEZEIGT + BEVORZUGT nebeneinander lesbar bleiben, statt sich\n * durch den Text zu schieben. */\n.szenen-detail__heads li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-version__titel {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n min-width: 0;\n margin-right: auto;\n}\n\n/* V17 \u2014 Kennungen bleiben vollst\xE4ndig sichtbar, aber optisch sekund\xE4r. */\n.szenen-version__id,\n.szenen-ref__id,\n.szenen-detail__field-key {\n color: var(--color-text-tertiary);\n font-size: 0.78rem;\n overflow-wrap: anywhere;\n}\n\n.szenen-version__marken {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n}\n\n.szenen-version__marken > span {\n padding: 0.1rem 0.5rem;\n color: var(--color-text-primary);\n background: rgba(45, 212, 191, 0.12);\n border: 1px solid rgba(45, 212, 191, 0.35);\n border-radius: var(--radius-full);\n font-size: 0.7rem;\n font-weight: 800;\n letter-spacing: 0.08em;\n}\n\n.szenen-version--angezeigt {\n border-color: var(--color-accent-teal, #2dd4bf) !important;\n}\n\n/* V9 \u2014 der Basiswechsel ist eine Entscheidung, keine Nebenwirkung. */\n.szenen-detail__confirm {\n display: grid;\n gap: var(--space-sm);\n margin: var(--space-md) 0;\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-accent-amber, #f59e0b);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__confirm p {\n margin: 0;\n}\n\n/* Untergruppen von Objektfeldern (`prompt_render_settings`, `overrides`,\n `blender_render_settings`) \u2014 seit A1/A2 auf- und zuklappbar. Eine optionale\n Gruppe startet zu: Blender und `overrides` f\xFCllten auf einem 390-px-Display\n sonst mehrere Bildschirmseiten, obwohl die meisten Shots sie nie anfassen. */\n.szenen-detail__group {\n min-width: 0;\n margin: var(--space-md) 0;\n padding: var(--space-sm) var(--space-md);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__group > summary {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n color: var(--color-text-secondary);\n font-weight: 600;\n cursor: pointer;\n}\n\n.szenen-detail__group[open] > summary {\n margin-bottom: var(--space-sm);\n}\n\n/* A2 \u2014 dass eine zugeklappte Gruppe schon Werte tr\xE4gt, muss man sehen, ohne\n sie zu \xF6ffnen. Sonst \xFCbersieht man eine gesetzte Blender-Ausgabe genau so\n lange, bis sie im Ergebnis auftaucht. */\n.szenen-detail__group-status {\n padding: 0.05rem 0.4rem;\n font-size: 0.6875rem;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n color: var(--color-text-tertiary);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__group[data-konfiguriert="ja"] > summary .szenen-detail__group-status {\n color: var(--color-text-primary);\n border-color: var(--color-accent-teal, var(--color-border));\n}\n\n.szenen-detail__group-inhalt {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding-bottom: var(--space-sm);\n}\n\n/* A3 \u2014 die Kernaussage steht am Feld, die Begr\xFCndung dahinter. Nicht als\n Tooltip: Auf einem Telefon gibt es kein Hover, und was dort unerreichbar ist,\n ist gestrichen \u2014 nur ohne dass es jemand entschieden h\xE4tte. */\n.szenen-detail__warum > summary {\n color: var(--color-text-tertiary);\n font-size: 0.75rem;\n cursor: pointer;\n}\n\n.szenen-detail__warum > small {\n display: block;\n padding-top: var(--space-xs);\n color: var(--color-text-tertiary);\n}\n\n.szenen-detail__fieldrow {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n margin-bottom: var(--space-md);\n}\n\n/* A4 \u2014 der technische Feldname bleibt lesbar, tritt aber hinter das fachliche\n Label zur\xFCck. */\n.szenen-detail__field-label {\n color: var(--color-text-primary);\n}\n\n.szenen-detail__field {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-detail__field > span {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n}\n\n/* Mehrfachauswahl und Listeneditoren. */\n.szenen-feld__mehrfach,\n.szenen-feld__liste,\n.szenen-feld__reflist,\n.szenen-feld__ref,\n.szenen-feld__zielmodell,\n.szenen-bilder__modellwahl,\n.szenen-feld__kamera {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n/* \u201ENeues Modell hinzufuegen" im Importdialog \u2014 dieselben Abstaende wie jedes\n andere Formular dieser Ansicht, damit es kein Fremdkoerper wird. */\n.szenen-feld__zielmodell-neu {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n padding: var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-feld__zielmodell-neu-aktionen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n}\n\n.szenen-feld__mehrfach > label,\n.szenen-feld__null {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n}\n\n.szenen-feld__liste-zeile {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n}\n\n.szenen-feld__reflist ol {\n display: grid;\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-feld__reflist li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n padding: var(--space-xs) var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n/* \xA76.1 \u2014 Titel und Typ zuerst, Kennungen daneben. */\n.szenen-ref__anzeige {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-ref__typ {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-ref__warn {\n padding: 0.1rem 0.5rem;\n color: #fecaca;\n background: var(--color-accent-red-dim);\n border-radius: var(--radius-full);\n font-size: 0.72rem;\n font-weight: 700;\n}\n\n/* \xA76.5 \u2014 abgeleitete Angaben, ausdr\xFCcklich nur Anzeige. */\n.szenen-detail__derived {\n margin-top: var(--space-md);\n padding: var(--space-sm) var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-detail__derived dl {\n display: grid;\n grid-template-columns: minmax(10rem, auto) 1fr;\n gap: var(--space-xs) var(--space-sm);\n margin: 0;\n}\n\n.szenen-detail__derived dt {\n color: var(--color-text-secondary);\n}\n\n.szenen-detail__derived dd {\n margin: 0;\n}\n\n.szenen-feld__abgeleitet {\n margin: 0;\n color: var(--color-text-tertiary);\n font-size: 0.78rem;\n}\n\n/* Bereich `Prompts` \u2014 die herkunftsuebergreifende Sicht (P1-A).\n *\n * Die Eintraege selbst rendert `RundenEintrag` und tragen damit die\n * `szenen-runs__*`-Regeln. Hier stehen nur Rahmen und Kennzeichen; eine zweite\n * Laufdarstellung gibt es nicht, also braucht sie auch kein zweites Aussehen. */\n.szenen-prompts__toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-prompts__heading {\n margin: 0;\n font-size: 1.05rem;\n margin-right: auto;\n}\n\n.szenen-view__fokus {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n margin-bottom: var(--space-sm);\n}\n\n.szenen-prompts__fokus {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n margin-bottom: var(--space-sm);\n padding: var(--space-xs) var(--space-sm);\n border: 1px solid var(--color-accent, #0d9488);\n border-radius: var(--radius-sm, 4px);\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-prompts__hinweis {\n font-style: italic;\n}\n\n.szenen-prompts__ausgeblendet {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n/* ==========================================================================\n Kette `szenen-design`, P8 \u2014 der Bereich `Prompts` als Bildraster\n ========================================================================== */\n\n/* Herkunfts-Chips: eine Zeile, die in sich scrollt \u2014 nie die Seite. */\n.szenen-prompts__chips {\n display: flex;\n flex-wrap: nowrap;\n gap: 0.375rem;\n min-width: 0;\n padding-bottom: 0.15rem;\n overflow-x: auto;\n scrollbar-width: thin;\n}\n\n.szenen-view .szenen-prompts__chip {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 0.35rem;\n min-height: 2.25rem;\n padding: 0 0.8rem;\n white-space: nowrap;\n border-radius: var(--radius-full);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-prompts__chip[aria-pressed="true"] {\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border-color: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-prompts__zeile {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.375rem;\n min-width: 0;\n}\n\n.szenen-prompts__anzahl {\n flex: 1 1 8rem;\n min-width: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-prompts__umschalter {\n min-height: 2rem;\n padding: 0 0.65rem;\n font-size: 0.75rem;\n}\n\n.szenen-prompts__raster-bereich {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n}\n\n/* Der neueste Lauf \u2014 gross, mit Promptzeile und Kopierknopf. */\n.szenen-prompts__neuester {\n min-width: 0;\n overflow: hidden;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-view .szenen-prompts__oeffnen {\n display: block;\n width: 100%;\n padding: 0;\n color: var(--color-text-primary);\n text-align: left;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-prompts__bild {\n position: relative;\n display: block;\n height: 17.5rem;\n overflow: hidden;\n}\n\n.szenen-prompts__neuester .szenen-galerie__status {\n top: 0.75rem;\n left: 0.75rem;\n padding: 0.35rem 0.5rem;\n background: rgba(0, 0, 0, 0.55);\n border-radius: var(--radius-full);\n}\n\n.szenen-prompts__neuester .szenen-galerie__bildzahl {\n top: 0.75rem;\n right: 0.75rem;\n}\n\n.szenen-prompts__promptzeile {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n padding: 0.6rem 0.5rem 0.6rem 0.9rem;\n}\n\n.szenen-prompts__prompt {\n flex: 1 1 auto;\n min-width: 0;\n margin: 0;\n overflow: hidden;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-view .szenen-kopieren--symbol {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n min-height: 2.75rem;\n padding: 0;\n color: var(--color-text-primary);\n border-radius: var(--radius-lg);\n}\n\n.szenen-prompts__promptzeile .szenen-lauf__kopieren {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 0.4rem;\n}\n\n/* Gruppe aufeinanderfolgender Laeufe derselben Szene. */\n.szenen-prompts__gruppe {\n display: grid;\n gap: 0.6rem;\n min-width: 0;\n}\n\n.szenen-prompts__gruppenkopf {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-prompts__gruppenkopf h4 {\n min-width: 0;\n margin: 0;\n font-size: 1rem;\n font-weight: 650;\n line-height: 1.3;\n overflow-wrap: anywhere;\n}\n\n.szenen-prompts__gruppenkopf span {\n flex: none;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n/* Zwei Spalten, Kacheln im Format 3:4. */\n.szenen-view .szenen-prompts__raster {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 0.625rem;\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n@media (min-width: 761px) {\n .szenen-view .szenen-prompts__raster {\n grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));\n }\n}\n\n.szenen-prompts__kachel {\n min-width: 0;\n}\n\n.szenen-view .szenen-prompts__kachel > button {\n position: relative;\n display: block;\n width: 100%;\n min-width: 0;\n aspect-ratio: 3 / 4;\n padding: 0;\n overflow: hidden;\n color: var(--color-text-primary);\n text-align: left;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-view .szenen-prompts__kachel.is-fokus > button,\n.szenen-view .szenen-prompts__neuester.is-fokus {\n border-color: var(--color-accent-blue);\n box-shadow: 0 0 0 1px var(--color-accent-blue);\n}\n\n.szenen-prompts__text {\n position: absolute;\n right: 0.75rem;\n bottom: 0.7rem;\n left: 0.75rem;\n display: grid;\n gap: 0.2rem;\n min-width: 0;\n}\n\n.szenen-prompts--mitbild .szenen-prompts__text {\n color: #fff;\n}\n\n.szenen-prompts__titel {\n display: -webkit-box;\n overflow: hidden;\n font-size: 1.25rem;\n font-weight: 700;\n line-height: 1.2;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow-wrap: anywhere;\n}\n\n.szenen-prompts__kachelrunde {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.95rem;\n font-weight: 700;\n}\n\n.szenen-prompts__meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.3rem;\n min-width: 0;\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-prompts--mitbild .szenen-prompts__meta {\n color: rgba(255, 255, 255, 0.82);\n}\n\n.szenen-prompts__statuspunkt {\n display: inline-block;\n flex: none;\n width: 0.5rem;\n height: 0.5rem;\n background: var(--color-success);\n border-radius: 50%;\n}\n\n.szenen-prompts__statuspunkt[data-status="failed"] {\n background: var(--color-danger);\n}\n\n/* Eine Kachel ohne Bild nennt ihren Grund \u2014 oben, damit der Text unten frei bleibt. */\n.szenen-prompts__grund {\n display: grid;\n align-content: start;\n gap: 0.3rem;\n padding-top: 2.25rem;\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n line-height: 1.3;\n}\n\n.szenen-prompts__fehlertext {\n display: -webkit-box;\n overflow: hidden;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 4;\n overflow-wrap: anywhere;\n}\n\n/* ==========================================================================\n ZIP-MODELLVORSCHLAG (modaler Best\xE4tigungsdialog)\n ========================================================================== */\n\n/* Wie die grosse Bildansicht: eigener Grund, `position: fixed`, damit der\n Dialog im Flow-Canvas und in React gleichermassen \xFCber allem liegt. */\n.szenen-zipmodell {\n position: fixed;\n inset: 0;\n z-index: 1100;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--space-md);\n background: rgba(0, 0, 0, 0.72);\n}\n\n.szenen-zipmodell__karte {\n display: grid;\n gap: var(--space-sm);\n width: min(34rem, 100%);\n max-height: 100%;\n overflow-y: auto;\n padding: var(--space-md);\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-zipmodell__titel {\n margin: 0;\n font-size: 1rem;\n}\n\n.szenen-zipmodell__quelle,\n.szenen-zipmodell__treffer,\n.szenen-zipmodell__vertrauen,\n.szenen-zipmodell__fallback {\n margin: 0;\n font-size: 0.85rem;\n}\n\n.szenen-zipmodell__quelle,\n.szenen-zipmodell__vertrauen {\n color: var(--color-text-secondary);\n}\n\n/* Ein schwacher oder mehrdeutiger Treffer muss sich vom sicheren unterscheiden,\n sonst ist die Warnung nur ein weiterer Satz. */\n.szenen-zipmodell__warnung {\n margin: 0;\n padding: var(--space-xs) var(--space-sm);\n color: var(--color-text-primary);\n background: rgba(234, 179, 8, 0.14);\n border-left: 3px solid #eab308;\n border-radius: var(--radius-sm);\n font-size: 0.85rem;\n}\n\n.szenen-zipmodell__alternativen {\n display: grid;\n gap: 0.2rem;\n margin: 0;\n padding: var(--space-xs) var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n font-size: 0.85rem;\n}\n\n.szenen-zipmodell__alternativen > label {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n}\n\n.szenen-zipmodell__aktionen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n}\n\n/* ==========================================================================\n MEHR LADEN \u2014 der gemeinsame Fuss jeder seitenweise geladenen Liste\n ========================================================================== */\n\n.szenen-mehr-laden {\n display: grid;\n gap: var(--space-xs);\n justify-items: start;\n padding: var(--space-xs) 0;\n}\n\n.szenen-mehr-laden__button {\n padding: var(--space-xs) var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n background: var(--color-bg-surface);\n color: var(--color-text-primary);\n font-size: 0.85rem;\n cursor: pointer;\n}\n\n.szenen-mehr-laden__button:disabled {\n cursor: progress;\n opacity: 0.6;\n}\n\n.szenen-mehr-laden__fehler {\n margin: 0;\n color: var(--color-danger, #f87171);\n font-size: 0.8rem;\n}\n\n/* ==========================================================================\n PROMPTKARTE \u2014 Tags, Vorschau und Bildzahl\n (Kette `szenen-prompt-anzeige-bilder-tags`)\n\n Der Zuschnitt ist der der Library-Karte (`.library-item` + der absolut\n gesetzte Bildstreifen in `LibraryTab`): Textteil links, Deckbild rechts am\n Rand ueber die ganze Kartenhoehe, Bildzahl als Plakette darauf. Dieselben\n Werte (7rem Streifenbreite, linke Trennlinie, Plakette unten rechts), nur\n hier statt in Tailwind-Klassen \u2014 die Szenen-Ansicht teilt dieses Stylesheet\n byteweise mit Flow, und Flow hat kein Tailwind.\n ========================================================================== */\n\n.szenen-promptkarte {\n position: relative;\n overflow: hidden;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: var(--space-sm);\n}\n\n/* Nur wo ein Bild liegt, wird Platz dafuer freigehalten. Ohne Bild nutzt der\n Textteil die ganze Breite \u2014 keine leere Spalte. */\n.szenen-promptkarte--mitbild .szenen-promptkarte__inhalt {\n padding-right: calc(7rem + var(--space-sm));\n}\n\n.szenen-promptkarte__bild {\n position: absolute;\n top: 0;\n right: 0;\n width: 7rem;\n height: 100%;\n /* Hoechstens so hoch wie breit \u2014 der Streifen bleibt eine Kachel.\n `height: 100%` allein band ihn an die **Kartenhoehe**, und die ist in der\n aufgeklappten Runde die Hoehe des ganzen Prompts: Das Deckbild sprang\n dann als mehrere hundert Pixel hoher, auf Streifenbreite beschnittener\n Balken an den rechten Rand. Geschlossen aendert die Grenze nichts \u2014 dort\n ist die Karte niedriger als 7rem. */\n max-height: 7rem;\n border-left: 1px solid var(--color-border);\n background: #000;\n}\n\n/* Die gemeinsame Kachel bringt `width: 100%` und `aspect-ratio: 1` mit \u2014 hier\n fuellt sie stattdessen den Streifen, genau wie das Library-Deckbild. */\n.szenen-promptkarte__bild .szenen-bildkachel {\n width: 100%;\n height: 100%;\n aspect-ratio: auto;\n}\n\n.szenen-promptkarte__bildzahl {\n position: absolute;\n right: 0.25rem;\n bottom: 0.25rem;\n padding: 0.1rem 0.35rem;\n border-radius: var(--radius-sm);\n background: rgba(0, 0, 0, 0.6);\n color: #fff;\n font-size: 0.62rem;\n font-weight: 700;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n/* Ein Kasten je Karte, nicht zwei.\n *\n * `.szenen-view button` (master.css) gibt **jedem** Knopf der Ansicht Rahmen\n * und Hintergrund und schlaegt dabei `.szenen-runs__kopf` (eine Klasse gegen\n * Klasse plus Element). In der Laufhistorie ist das richtig: Dort ist der Kopf\n * der Eintrag. In der Promptkarte ist die Karte der Eintrag \u2014 ein zweiter\n * Kasten darin waere die doppelte Umrandung, die die Library nicht hat.\n * Der Hover braucht eine eigene Zeile, weil die Regel dort spezifischer ist. */\n.szenen-promptkarte .szenen-runs__kopf,\n.szenen-promptkarte .szenen-runs__kopf:hover:not(:disabled) {\n min-height: 0;\n padding: var(--space-xs) 0;\n background: transparent;\n border: none;\n}\n\n/* Dieselbe Karte in der Elementliste.\n *\n * Dort ist der Auswahlknopf die Karte \u2014 er traegt Rahmen, Hintergrund und die\n * Auswahlmarkierung. Der Bildstreifen liegt deshalb **darueber** statt darin:\n * Ein `<button>` nimmt nur Phrasing Content auf, ein Streifen-`div` darin\n * waere ungueltiges Markup. Damit der rechte Kartenrand trotzdem auswaehlbar\n * bleibt, laesst der Streifen Klicks durch. */\n.szenen-elementkarte {\n position: relative;\n}\n\n.szenen-elementkarte--mitbild > button {\n padding-right: calc(7rem + var(--space-sm));\n}\n\n.szenen-elementkarte > .szenen-promptkarte__bild {\n border-radius: 0 var(--radius-sm) var(--radius-sm) 0;\n}\n\n.szenen-promptkarte__bild--durchklickbar {\n pointer-events: none;\n}\n\n/* Null Bilder: die Zahl, keine Flaeche. */\n/* Die Tagliste bricht um. Auf einem Telefon ist das der Unterschied zwischen\n einer kompakten Karte und einer Zeile, die seitlich herauslaeuft. */\n.szenen-tagliste {\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n align-items: center;\n margin: 0 0 var(--space-xs);\n padding: 0;\n list-style: none;\n}\n\n.szenen-tag {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.05rem 0.4rem;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n background: var(--color-bg-app);\n font-size: 0.72rem;\n line-height: 1.5;\n white-space: nowrap;\n}\n\n/* Herkunft sichtbar, aber ohne zweite Bedeutungsebene: Ein Prompt-Tag steht\n voll, ein reiner Library-Tag zurueckgenommen. Die Karte soll schnell lesbar\n sein, nicht zwei Farbcodes lehren. */\n.szenen-tag[data-herkunft="library"] {\n border-style: dashed;\n opacity: 0.85;\n}\n\n.szenen-tag--rest {\n border-style: none;\n opacity: 0.7;\n}\n\n.szenen-tag__weg {\n border: none;\n background: none;\n padding: 0;\n color: var(--color-text-secondary, inherit);\n font-size: 0.85rem;\n line-height: 1;\n cursor: pointer;\n}\n\n.szenen-tag__weg:disabled {\n cursor: progress;\n opacity: 0.5;\n}\n\n.szenen-taggeber {\n display: grid;\n gap: var(--space-xs);\n padding: var(--space-xs);\n margin-bottom: var(--space-xs);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-taggeber__zeile {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n margin: 0;\n}\n\n.szenen-taggeber__label {\n font-size: 0.72rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n opacity: 0.75;\n}\n\n.szenen-taggeber__leer,\n.szenen-taggeber__hinweis {\n font-size: 0.72rem;\n opacity: 0.75;\n}\n\n.szenen-taggeber input[type="text"] {\n flex: 1 1 8rem;\n min-width: 0;\n padding: var(--space-xs);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n background: var(--color-bg-surface);\n color: var(--color-text-primary);\n font-size: 0.8rem;\n}\n\n/* ==========================================================================\n BILDAUFTR\xC4GE \u2014 die bestandsweite Arbeitsqueue\n Kette `szenen-bildauftraege-arbeitsqueue`, Schritt 01.\n ========================================================================== */\n\n.szenen-bildauftraege {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-bildauftraege__steuerung,\n.szenen-bildauftraege__filter,\n.szenen-bildauftraege__aktionen,\n.szenen-bildauftraege__nachladen,\n.szenen-bildauftraege__blaettern {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n}\n\n/* Der manuelle Refresh \u2014 Schritt 03 \xA72. Er steht oben und sichtbar, weil er\n die einzige Stelle ist, an der dieser Bereich nachlaedt: Es gibt keinen\n Timer mehr, den er ersetzen koennte. */\n.szenen-bildauftraege__nachladen {\n justify-content: flex-start;\n}\n\n.szenen-bildauftraege__nachladen span {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n/* Die Blaetterleiste der Bildkontrolle \u2014 Schritt 03 \xA73.1. */\n.szenen-bildauftraege__blaettern {\n margin: 0;\n}\n\n/* \u201EWeitere Bilder" \u2014 seit Schritt 06 eine **Leiste in der Zeile**, kein\n aufklappbares Formular: Modell, Anzahl, Knopf nebeneinander. */\n.szenen-bildauftraege__weitere {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n margin: var(--space-xs) 0 0;\n font-size: 0.85rem;\n}\n\n.szenen-bildauftraege__weitere label {\n color: var(--color-text-secondary);\n}\n\n/* Der Lauf-Zaehler: sichtbar, aber nicht im Weg (Schritt 06). */\n.szenen-bildauftraege__laufzaehler {\n padding: 0.05rem var(--space-xs);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm, 4px);\n font-size: 0.8rem;\n font-variant-numeric: tabular-nums;\n}\n\n/* Die Vorschau steht oben und beh\xE4lt ihren Platz, auch solange noch kein Bild\n vorliegt \u2014 sie ist die Kontrollfl\xE4che des zweiten Browserfensters (\xA75). */\n.szenen-bildauftraege__letztes {\n display: grid;\n gap: var(--space-xs);\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-bildauftraege__letztes h3 {\n margin: 0;\n font-size: 0.95rem;\n}\n\n.szenen-bildauftraege__letztes .szenen-bildkachel {\n width: min(100%, 22rem);\n height: auto;\n}\n\n.szenen-bildauftraege__lauf {\n padding: var(--space-xs) var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-bildauftraege__lauf p {\n margin: 0.1rem 0;\n}\n\n.szenen-bildauftraege__liste {\n display: grid;\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bildauftraege__zeile {\n display: grid;\n gap: 0.25rem;\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-bildauftraege__kopf,\n.szenen-bildauftraege__prompt {\n margin: 0;\n}\n\n.szenen-bildauftraege__meta {\n display: flex;\n flex-wrap: wrap;\n gap: 0.15rem var(--space-sm);\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-bildauftraege__prompt {\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n}\n\n/* \u2500\u2500 Kette `szenen-design`, P4: Szene als Studio \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n *\n * Kopf mit Speichern, Hero mit Titelbild und Versions-Pill, die B\xFChne auf\n * einem Punktraster, das Element-Sheet von unten, der Prompt-Start als ein\n * Block, L\xE4ufe als Bildstreifen, Aufklapper unten. Kn\xF6pfe in der B\xFChne und im\n * Sheet setzen die Grundoptik von `.szenen-view button` gezielt zur\xFCck \u2014 daher\n * die zwei Klassen in diesen Selektoren. */\n.szenen-studio {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n}\n\n.szenen-studio__kopf {\n position: sticky;\n top: 0;\n z-index: 3;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n min-height: 2.75rem;\n padding: var(--space-xs) 0;\n background: var(--color-bg-app);\n}\n\n.szenen-studio__kopf > .szenen-detail__ids {\n flex: 1 1 auto;\n margin: 0;\n}\n\n.szenen-studio__ungespeichert {\n color: var(--color-warning);\n font-size: 0.8rem;\n font-weight: 600;\n}\n\n.szenen-view .szenen-studio__speichern {\n min-height: 2.25rem;\n padding: 0 1rem;\n color: var(--color-accent-teal, #2dd4bf);\n background: transparent;\n border-color: var(--color-accent-teal, #2dd4bf);\n border-radius: var(--radius-full);\n font-weight: 650;\n}\n\n.szenen-studio__hero {\n position: relative;\n min-height: 12rem;\n overflow: hidden;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-studio__hero--mitbild {\n min-height: 16rem;\n border-color: transparent;\n}\n\n.szenen-studio__titelbild {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.szenen-studio__scrim {\n position: absolute;\n inset: 0;\n background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.45) 42%, rgba(0, 0, 0, 0) 70%);\n}\n\n.szenen-studio__ohnebild {\n position: absolute;\n inset: 0;\n padding: var(--space-md);\n background:\n radial-gradient(var(--color-border) 1px, transparent 1px) 0 0 / 16px 16px,\n var(--color-bg-surface);\n}\n\n.szenen-studio__symbole {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-sm);\n color: var(--color-text-secondary);\n}\n\n.szenen-studio__bildfehler {\n margin: 0 0 var(--space-sm);\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-studio__herotext {\n position: absolute;\n right: var(--space-md);\n bottom: var(--space-md);\n left: var(--space-md);\n display: grid;\n gap: var(--space-sm);\n}\n\n.szenen-studio__herotext h3 {\n margin: 0;\n font-size: 1.5rem;\n line-height: 1.2;\n overflow-wrap: anywhere;\n}\n\n.szenen-studio__hero--mitbild .szenen-studio__herotext {\n color: #fff;\n}\n\n.szenen-studio__herometa {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-studio__pill {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n min-height: 2.25rem;\n padding: 0 0.75rem;\n color: inherit;\n background: rgba(0, 0, 0, 0.55);\n border: 1px solid rgba(255, 255, 255, 0.25);\n border-radius: var(--radius-full);\n}\n\n.szenen-studio__hero:not(.szenen-studio__hero--mitbild) .szenen-studio__pill {\n background: var(--color-bg-elevated);\n border-color: var(--color-border);\n}\n\n/* Kette `szenen-design`, P6 \u2014 Titelbild: \u22EF-Menue im Hero, Hinweis, Zeile\n unter \u201ETechnisch" und die Aktion im Bildviewer. */\n.szenen-studio__heromenu {\n position: relative;\n display: inline-flex;\n}\n\n.szenen-view .szenen-studio__menuknopf {\n justify-content: center;\n min-width: 2.25rem;\n padding: 0 0.5rem;\n}\n\n.szenen-studio__menu {\n position: absolute;\n top: calc(100% + 0.25rem);\n left: 0;\n z-index: 5;\n display: grid;\n min-width: 12rem;\n padding: var(--space-xs, 0.25rem);\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md, 0.5rem);\n}\n\n.szenen-studio__menu button {\n min-height: 2.25rem;\n padding: 0 0.75rem;\n text-align: left;\n color: inherit;\n background: transparent;\n border: 0;\n}\n\n.szenen-studio__menu button:disabled {\n color: var(--color-text-secondary);\n}\n\n.szenen-studio__titelbildhinweis {\n margin: 0;\n font-size: 0.8rem;\n color: var(--color-warning);\n}\n\n.szenen-studio__hero--mitbild .szenen-studio__titelbildhinweis {\n color: #fde68a;\n}\n\n.szenen-studio__titelbildzeile {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n padding: var(--space-sm) 0;\n font-size: 0.875rem;\n}\n\n.szenen-studio__titelbildref {\n display: block;\n overflow-wrap: anywhere;\n color: var(--color-text-secondary);\n}\n\n.szenen-view .szenen-bildviewer__aktion {\n min-height: 2.25rem;\n padding: 0 0.75rem;\n}\n\n.szenen-bildviewer__titelbild {\n color: var(--color-accent-teal, #2dd4bf);\n font-size: 0.8125rem;\n}\n\n.szenen-studio__komposition {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-studio__abschnittkopf {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-studio__abschnittkopf h4 {\n margin: 0;\n}\n\n.szenen-studio__umschalter {\n display: inline-flex;\n padding: 3px;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n}\n\n.szenen-view .szenen-studio__umschalter button {\n min-height: 2rem;\n padding: 0 0.75rem;\n background: transparent;\n border: none;\n border-radius: var(--radius-full);\n}\n\n.szenen-view .szenen-studio__umschalter button[aria-pressed="true"] {\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-studio__aufklapper {\n display: grid;\n min-width: 0;\n}\n\n.szenen-studio__aufklapper > details {\n min-width: 0;\n border-top: 1px solid var(--color-border);\n}\n\n.szenen-studio__aufklapper > details:last-child {\n border-bottom: 1px solid var(--color-border);\n}\n\n.szenen-studio__aufklapper > details > summary {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n min-height: 2.75rem;\n cursor: pointer;\n}\n\n.szenen-studio__zusammenfassung {\n margin-left: auto;\n overflow: hidden;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Die B\xFChne */\n.szenen-buehne {\n position: relative;\n width: 100%;\n aspect-ratio: 358 / 330;\n overflow: hidden;\n background:\n radial-gradient(var(--color-border) 1px, transparent 1px) 0 0 / 16px 16px,\n var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-buehne--leer {\n display: grid;\n place-items: center;\n aspect-ratio: auto;\n min-height: 8rem;\n color: var(--color-text-secondary);\n}\n\n.szenen-buehne__linien {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n}\n\n.szenen-buehne__linie {\n stroke: var(--color-text-tertiary);\n stroke-width: 1.5;\n}\n\n.szenen-buehne__linie--naehe {\n stroke-width: 1;\n stroke-dasharray: 3 4;\n}\n\n.szenen-buehne__linie--kontakt {\n stroke: var(--color-text-primary);\n stroke-width: 3;\n}\n\n.szenen-buehne__kegel-start {\n stop-color: var(--color-accent-amber, #f2c46d);\n stop-opacity: 0.35;\n}\n\n.szenen-buehne__kegel-ende {\n stop-color: var(--color-accent-amber, #f2c46d);\n stop-opacity: 0;\n}\n\n.szenen-view .szenen-buehne__node {\n position: absolute;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.3rem;\n min-height: 0;\n max-width: 6rem;\n padding: 0;\n color: var(--color-text-primary);\n background: transparent;\n border: none;\n transform: translate(-50%, -50%);\n}\n\n.szenen-view .szenen-buehne__node:hover:not(:disabled) {\n background: transparent;\n}\n\n.szenen-buehne__symbol {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: 50%;\n}\n\n.szenen-buehne__node--mitte .szenen-buehne__symbol {\n width: 4rem;\n height: 4rem;\n border: 2px solid var(--color-text-primary);\n}\n\n.szenen-buehne__node--light .szenen-buehne__symbol {\n color: var(--color-accent-amber, #f2c46d);\n}\n\n.szenen-buehne__node[aria-pressed="true"] .szenen-buehne__symbol {\n box-shadow: 0 0 0 2px var(--color-accent-blue);\n}\n\n.szenen-buehne__name {\n max-width: 100%;\n padding: 0 0.25rem;\n overflow: hidden;\n background: var(--color-bg-app);\n border-radius: var(--radius-sm);\n font-size: 0.75rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-buehne__node--mitte .szenen-buehne__name {\n font-weight: 650;\n}\n\n.szenen-buehne__legende {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs) var(--space-md);\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-buehne__legende > span {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.szenen-buehne__legende-hinweis {\n margin-left: auto;\n}\n\n.szenen-buehne__muster {\n display: inline-block;\n width: 1.1rem;\n border-top: 1px dashed var(--color-text-tertiary);\n}\n\n.szenen-buehne__muster--kontakt {\n border-top: 3px solid var(--color-text-primary);\n}\n\n/* Das Element-Sheet */\n.szenen-sheet {\n position: fixed;\n inset: 0;\n z-index: 50;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n}\n\n.szenen-view .szenen-sheet__hintergrund {\n position: absolute;\n inset: 0;\n padding: 0;\n background: rgba(0, 0, 0, 0.6);\n border: none;\n border-radius: 0;\n cursor: default;\n}\n\n.szenen-sheet__flaeche {\n position: relative;\n display: grid;\n gap: var(--space-md);\n width: 100%;\n max-width: 40rem;\n max-height: 85vh;\n padding: var(--space-sm) var(--space-md) var(--space-md);\n overflow-y: auto;\n box-sizing: border-box;\n background: var(--color-bg-surface);\n border-top: 1px solid var(--color-border);\n border-radius: 1.5rem 1.5rem 0 0;\n}\n\n.szenen-sheet__griff {\n justify-self: center;\n width: 2.5rem;\n height: 4px;\n background: var(--color-border);\n border-radius: 2px;\n}\n\n.szenen-sheet__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-sheet__symbol {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 3.5rem;\n height: 3.5rem;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: 50%;\n}\n\n.szenen-sheet__symbol--light {\n color: var(--color-accent-amber, #f2c46d);\n}\n\n.szenen-sheet__titel {\n display: grid;\n gap: 0.15rem;\n min-width: 0;\n}\n\n.szenen-sheet__titel strong {\n font-size: 1.25rem;\n}\n\n.szenen-sheet__titel code {\n overflow: hidden;\n color: var(--color-text-secondary);\n font-family: var(--font-mono);\n font-size: 0.75rem;\n text-overflow: ellipsis;\n}\n\n.szenen-view .szenen-sheet__schliessen {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2.75rem;\n height: 2.75rem;\n margin-left: auto;\n padding: 0;\n border-radius: 50%;\n}\n\n.szenen-sheet__abschnitt {\n display: grid;\n gap: var(--space-xs);\n}\n\n.szenen-sheet__abschnitt h5 {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n font-weight: 500;\n}\n\n.szenen-sheet__leer {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-sheet__beziehungen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-sheet__beziehungen li {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n min-height: 2.25rem;\n padding: 0 0.75rem;\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.85rem;\n}\n\n.szenen-sheet__beziehungsart {\n color: var(--color-text-secondary);\n}\n\n.szenen-sheet__bilder {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-sheet__bild {\n position: relative;\n aspect-ratio: 1 / 1;\n overflow: hidden;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-sheet__bild img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.szenen-sheet__bildtext {\n display: grid;\n gap: 0.2rem;\n padding: 0.35rem;\n color: var(--color-text-secondary);\n font-size: 0.65rem;\n line-height: 1.25;\n overflow-wrap: anywhere;\n}\n\n.szenen-sheet__bildtext code {\n font-family: var(--font-mono);\n}\n\n.szenen-view .szenen-sheet__fertig {\n min-height: 3rem;\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border: none;\n border-radius: var(--radius-md);\n font-weight: 700;\n}\n\n/* Der Prompt-Start als ein Block */\n.szenen-start {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-view .szenen-start__primaer {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n min-height: 3.25rem;\n color: var(--color-bg-app);\n background: var(--color-accent-teal, #2dd4bf);\n border: none;\n border-radius: var(--radius-md);\n font-size: 1.05rem;\n font-weight: 700;\n}\n\n.szenen-start__kosten {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n text-align: center;\n}\n\n.szenen-start__manuell {\n display: grid;\n gap: var(--space-sm);\n}\n\n.szenen-view .szenen-start__zweit {\n min-height: 2.75rem;\n background: transparent;\n}\n\n.szenen-start__erklaerung > summary {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n cursor: pointer;\n}\n\n.szenen-start__erklaerung[open] .szenen-start__chevron {\n transform: rotate(90deg);\n}\n\n/* L\xE4ufe als Bildstreifen */\n.szenen-streifen {\n display: grid;\n gap: 0.35rem;\n padding: 0 var(--space-sm) var(--space-sm);\n}\n\n.szenen-streifen__bilder {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 4px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-streifen__bild {\n position: relative;\n aspect-ratio: 3 / 4;\n overflow: hidden;\n background: var(--color-bg-elevated);\n border-radius: var(--radius-sm);\n}\n\n.szenen-streifen__bild img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.szenen-streifen__fehler {\n display: block;\n padding: 0.25rem;\n color: var(--color-text-secondary);\n font-size: 0.65rem;\n}\n\n.szenen-streifen__mehr {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #fff;\n background: rgba(0, 0, 0, 0.6);\n font-size: 0.95rem;\n font-weight: 700;\n}\n\n.szenen-streifen__anzahl {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n/* \xC4ltere Runden: kompakte Zeile mit \xFCberlappenden Miniaturen. */\n.szenen-streifen--zeile {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-streifen--zeile .szenen-streifen__bilder {\n display: flex;\n gap: 0;\n}\n\n.szenen-streifen--zeile .szenen-streifen__bild {\n width: 2.1rem;\n height: 2.75rem;\n aspect-ratio: auto;\n border: 2px solid var(--color-bg-surface);\n}\n\n.szenen-streifen--zeile .szenen-streifen__bild + .szenen-streifen__bild {\n margin-left: -0.75rem;\n}\n\n.szenen-runs__eintrag--karte {\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n/* Szenenst\xE4nde enthalten mehrere Runden derselben eingefrorenen Szene (#538). */\n.szenen-runs__stand > h5 {\n margin: 0;\n font-size: 1rem;\n}\n\n.szenen-runs__stand-laeufe {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-runs__stand-laeufe > li {\n display: grid;\n gap: var(--space-sm);\n padding: var(--space-sm);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n/* ==========================================================================\n Kette `szenen-design`, P5 \u2014 der Prompt-Lauf als Ergebnisgalerie\n ========================================================================== */\n\n/* \u2500\u2500 Chips \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-chip,\n.szenen-view .szenen-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n min-height: 1.75rem;\n padding: 0 0.65rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n line-height: 1.2;\n white-space: nowrap;\n}\n\n.szenen-view .szenen-chip--knopf {\n min-height: 2.25rem;\n color: var(--color-text-primary);\n cursor: pointer;\n}\n\n.szenen-chip--library,\n.szenen-view .szenen-chip--library {\n color: var(--color-accent-teal, #2dd4bf);\n border-color: var(--color-accent-teal, #2dd4bf);\n}\n\n/* \u2500\u2500 Navigation der Laufansicht \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-lauf__nav {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n min-width: 0;\n scroll-margin-top: var(--space-md);\n}\n\n.szenen-view .szenen-lauf__zurueck {\n display: inline-flex;\n align-items: center;\n gap: 0.15rem;\n min-height: 2.75rem;\n padding: 0 0.6rem 0 0.25rem;\n color: var(--color-text-primary);\n background: transparent;\n border: none;\n}\n\n.szenen-lauf__blaettern {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.2rem;\n color: var(--color-text-secondary);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-lauf__blaettern button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n min-height: 2.5rem;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: var(--radius-full);\n}\n\n/* \u2500\u2500 Kopf: Runde, Status, Chips \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-laufinhalt {\n gap: var(--space-md);\n}\n\n.szenen-lauf__kopf {\n display: grid;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-lauf__szene {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-lauf__titelzeile {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-lauf__runde {\n margin: 0;\n color: var(--color-text-primary);\n font-size: 1.6rem;\n font-weight: 700;\n line-height: 1.15;\n}\n\n.szenen-lauf__status {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n min-height: 1.6rem;\n padding: 0 0.6rem;\n border: 1px solid currentColor;\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.szenen-lauf__status::before {\n content: "";\n width: 0.4rem;\n height: 0.4rem;\n border-radius: 50%;\n background: currentColor;\n}\n\n.szenen-lauf__status[data-status="succeeded"] { color: var(--color-success); }\n.szenen-lauf__status[data-status="failed"] { color: var(--color-danger); }\n\n.szenen-lauf__chips {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n min-width: 0;\n}\n\n.szenen-lauf__hinweis {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n}\n\n/* \u2500\u2500 Galerie \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-lauf .szenen-bilder__ausgang {\n padding: 0;\n background: none;\n border: none;\n}\n\n.szenen-lauf {\n gap: var(--space-md);\n margin-top: 0;\n}\n\n.szenen-lauf .szenen-bilder__batch {\n padding: 0;\n background: none;\n border: none;\n}\n\n.szenen-bildgalerie--ergebnis {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 4px;\n overflow: hidden;\n border-radius: var(--radius-md);\n}\n\n.szenen-bildgalerie--einzeln {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.szenen-bildgalerie--ergebnis .szenen-bildgalerie__kachel {\n border: none;\n border-radius: 0;\n}\n\n.szenen-bildgalerie--einzeln .szenen-bildgalerie__kachel {\n border-radius: var(--radius-md);\n}\n\n.szenen-bildgalerie--ergebnis .szenen-bildkachel {\n aspect-ratio: 3 / 4;\n}\n\n/* Ein einzelnes Ergebnisbild im echten Format zeigen \u2014 wie das Gemini-Preview:\n zentriert, ganz sichtbar, nichts abgeschnitten (vorher 3:4 mit cover). */\n.szenen-bildgalerie--einzeln .szenen-bildkachel {\n aspect-ratio: auto;\n background: none;\n}\n\n.szenen-bildgalerie--einzeln .szenen-bildkachel:not(:has(img)) {\n aspect-ratio: 4 / 3;\n}\n\n.szenen-bildgalerie--einzeln .szenen-bildkachel img {\n width: auto;\n max-width: 100%;\n height: auto;\n max-height: 28rem;\n margin-inline: auto;\n object-fit: contain;\n border: 1px solid var(--color-border-hover);\n border-radius: var(--radius-md);\n}\n\n.szenen-bildgalerie__alle-text {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.1rem;\n color: #fff;\n background: rgba(0, 0, 0, 0.65);\n font-size: 0.75rem;\n}\n\n.szenen-bildgalerie__alle-text strong {\n font-size: 1.25rem;\n}\n\n/* P5-Akzeptanz: Eine leere Kachel nennt ihren Grund \u2014 lesbar, nicht nur im\n Tooltip. */\n.szenen-bildkachel__grund {\n display: -webkit-box;\n max-width: 90%;\n overflow: hidden;\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n line-height: 1.3;\n text-align: center;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n}\n\n/* \u2500\u2500 Karten: Prompt, Tags \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-lauf__karte {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding: var(--space-sm) var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-lauf__kartenkopf {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-lauf__label {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-lauf__legende {\n color: var(--color-text-tertiary, var(--color-text-secondary));\n font-size: 0.72rem;\n}\n\n.szenen-lauf__kopieren {\n display: inline-flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-lauf__prompttext {\n margin: 0;\n color: var(--color-text-primary);\n line-height: 1.5;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n/* Drei Zeilen Vorschau \u2014 der volle Text bleibt im Dokument (Kopieren,\n Markieren), gek\xFCrzt wird nur die Darstellung. */\n.szenen-lauf__prompttext--zu {\n display: -webkit-box;\n overflow: hidden;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n}\n\n.szenen-view .szenen-lauf__ganz {\n justify-self: start;\n min-height: 2.25rem;\n padding: 0;\n color: var(--color-accent-teal, var(--color-text-primary));\n background: transparent;\n border: none;\n}\n\n.szenen-lauf__negativ {\n display: grid;\n gap: var(--space-xs);\n}\n\n.szenen-lauf__negativ[hidden] {\n display: none;\n}\n\n.szenen-lauf__negativ p {\n margin: 0;\n color: var(--color-text-secondary);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.szenen-lauf__karte .szenen-taggeber {\n margin: 0;\n}\n\n.szenen-tagliste .szenen-tag__neu {\n min-height: 2rem;\n}\n\n/* \u2500\u2500 \u201ENeue Bilder" (Serverauftrag des Hosts) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-neuebilder {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg, var(--radius-md));\n}\n\n.szenen-neuebilder__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-neuebilder__kopf h4 {\n margin: 0;\n color: var(--color-text-primary);\n font-size: 1.05rem;\n}\n\n.szenen-neuebilder__symbol {\n color: var(--color-accent-teal, #2dd4bf);\n}\n\n.szenen-neuebilder__weg {\n margin-left: auto;\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-neuebilder__felder {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--space-sm);\n}\n\n.szenen-wahlfeld {\n display: grid;\n gap: 0.15rem;\n min-width: 0;\n padding: 0.4rem 0.6rem;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-wahlfeld__label {\n color: var(--color-text-secondary);\n font-size: 0.68rem;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n}\n\n.szenen-view .szenen-wahlfeld select {\n min-height: 1.75rem;\n padding: 0;\n color: var(--color-text-primary);\n background: transparent;\n border: none;\n font-weight: 600;\n}\n\n.szenen-umschalter {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n padding: 3px;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-view .szenen-umschalter button {\n min-height: 2.5rem;\n background: transparent;\n border: none;\n}\n\n.szenen-view .szenen-umschalter button[aria-pressed="true"] {\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n font-weight: 600;\n}\n\n.szenen-view .szenen-neuebilder__start {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--space-sm);\n min-height: 3.25rem;\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border: none;\n border-radius: var(--radius-md);\n font-size: 1rem;\n font-weight: 700;\n}\n\n.szenen-view .szenen-neuebilder__start:hover:not(:disabled) {\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n opacity: 0.9;\n}\n\n.szenen-neuebilder__laedt,\n.szenen-neuebilder__fehler {\n margin: 0;\n font-size: 0.85rem;\n}\n\n.szenen-neuebilder__laedt { color: var(--color-text-secondary); }\n\n/* Referenzbild eines Laufs (#569-Folge): eigener Bereich \xFCber den Ergebnissen. */\n.szenen-bilder__referenz {\n display: flex;\n gap: var(--space-md);\n align-items: center;\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-left: 3px solid var(--color-accent-blue);\n border-radius: var(--radius-md);\n}\n\n.szenen-bilder__referenzbild {\n flex: none;\n width: 9rem;\n}\n\n.szenen-bilder__referenzbild img {\n display: block;\n width: 100%;\n border-radius: var(--radius-sm);\n}\n\n.szenen-bilder__referenzleer {\n display: grid;\n place-items: center;\n aspect-ratio: 4 / 3;\n color: var(--color-text-secondary);\n background: var(--color-bg-elevated);\n border-radius: var(--radius-sm);\n font-size: 0.8rem;\n}\n\n.szenen-bilder__referenztext {\n display: grid;\n gap: 0.2rem;\n min-width: 0;\n color: var(--color-text-secondary);\n font-size: 0.82rem;\n}\n\n.szenen-bilder__referenztext strong {\n color: var(--color-text-primary);\n}\n\n/* Referenzbild und Prompt am einzelnen Bildauftrag. */\n.szenen-zeitleiste__referenz {\n display: flex;\n gap: var(--space-sm);\n align-items: center;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-zeitleiste__referenz img,\n.szenen-zeitleiste__referenz-leer {\n display: block;\n width: 4.5rem;\n aspect-ratio: 4 / 3;\n object-fit: cover;\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-sm);\n}\n\n.szenen-zeitleiste__prompt {\n white-space: pre-wrap;\n user-select: text;\n}\n\n/* Das mitgegebene Kamera-Preview (#569-Folge) \u2014 sichtbar, bevor bestellt wird. */\n.szenen-neuebilder__referenz {\n margin: 0;\n padding: 0.35rem 0.6rem;\n color: var(--color-text-primary);\n background: var(--color-accent-blue-dim);\n border-left: 2px solid var(--color-accent-blue);\n border-radius: var(--radius-sm);\n font-size: 0.82rem;\n}\n.szenen-neuebilder__fehler { color: var(--color-danger); }\n\n.szenen-neuebilder__warnung > summary {\n display: flex;\n align-items: flex-start;\n gap: var(--space-sm);\n color: var(--color-warning);\n font-size: 0.85rem;\n line-height: 1.45;\n cursor: pointer;\n list-style: none;\n}\n\n.szenen-neuebilder__warnung > summary::-webkit-details-marker { display: none; }\n\n.szenen-neuebilder__warnung > p,\n.szenen-neuebilder__zuordnung ul {\n margin: var(--space-xs) 0 0;\n color: var(--color-text-secondary);\n font-size: 0.78rem;\n line-height: 1.5;\n}\n\n.szenen-neuebilder__zuordnung > summary {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n cursor: pointer;\n}\n\n.szenen-neuebilder__zuordnung ul {\n padding-left: 1.1rem;\n}\n\n/* \u2500\u2500 Aufklapper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-aufklapper {\n display: grid;\n min-width: 0;\n border-bottom: 1px solid var(--color-border);\n}\n\n.szenen-aufklapper__eintrag,\n.szenen-aufklapper .szenen-bilder__aktion {\n min-width: 0;\n padding: 0;\n border: none;\n border-top: 1px solid var(--color-border);\n border-radius: 0;\n}\n\n.szenen-aufklapper__eintrag > summary,\n.szenen-aufklapper .szenen-bilder__aktion > summary {\n list-style: none;\n cursor: pointer;\n}\n\n.szenen-aufklapper__eintrag > summary::-webkit-details-marker { display: none; }\n\n.szenen-aufklapper .szenen-bilder__aktion[open] > summary {\n margin-bottom: 0;\n}\n\n.szenen-aufklapper__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n min-height: 2.75rem;\n padding: 0 var(--space-xs);\n color: var(--color-text-primary);\n font-weight: 400;\n}\n\n.szenen-aufklapper__pfeil {\n flex: none;\n transition: transform 0.15s ease;\n}\n\ndetails[open] > summary .szenen-aufklapper__pfeil {\n transform: rotate(90deg);\n}\n\n.szenen-aufklapper__titel {\n min-width: 0;\n}\n\n.szenen-aufklapper__meta {\n margin-left: auto;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-aufklapper__inhalt {\n display: grid;\n gap: var(--space-sm);\n min-width: 0;\n padding: 0 var(--space-xs) var(--space-md) 2rem;\n}\n\n@media (max-width: 760px) {\n .szenen-aufklapper__inhalt {\n padding-left: var(--space-xs);\n }\n}\n\n.szenen-aufklapper__inhalt > p {\n margin: 0;\n}\n\n/* \u2500\u2500 Zeitleiste der Bildauftr\xE4ge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-zeitleiste {\n display: grid;\n gap: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-zeitleiste__schritt {\n position: relative;\n display: flex;\n gap: var(--space-sm);\n min-width: 0;\n padding-bottom: var(--space-md);\n}\n\n/* Die Linie zur n\xE4chsten Zeile. */\n.szenen-zeitleiste__schritt:not(:last-child)::before {\n content: "";\n position: absolute;\n top: 2.1rem;\n bottom: 0;\n left: calc(1rem - 1px);\n width: 2px;\n background: var(--color-border);\n}\n\n.szenen-zeitleiste__symbol {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n border: 1px solid var(--color-border);\n border-radius: 50%;\n background: var(--color-bg-elevated);\n color: var(--color-text-secondary);\n font-weight: 700;\n}\n\n.szenen-zeitleiste__symbol[data-zustand="fertig"] {\n color: var(--color-success);\n border-color: var(--color-success);\n background: var(--color-accent-green-dim, var(--color-bg-elevated));\n}\n\n.szenen-zeitleiste__symbol[data-zustand="fehlgeschlagen"] {\n color: var(--color-danger);\n border-color: var(--color-danger);\n background: var(--color-accent-red-dim, var(--color-bg-elevated));\n}\n\n.szenen-zeitleiste__symbol[data-zustand="teilweise"] {\n color: var(--color-warning);\n border-color: var(--color-warning);\n}\n\n.szenen-zeitleiste__inhalt {\n display: grid;\n gap: 0.15rem;\n min-width: 0;\n padding-top: 0.3rem;\n}\n\n.szenen-zeitleiste__titel {\n color: var(--color-text-primary);\n font-size: 0.9rem;\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n\n.szenen-zeitleiste__ergebnis,\n.szenen-zeitleiste__zusatz {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n overflow-wrap: anywhere;\n}\n\n.szenen-zeitleiste__ergebnis[data-zustand="fehlgeschlagen"] { color: var(--color-danger); }\n.szenen-zeitleiste__ergebnis[data-zustand="teilweise"] { color: var(--color-warning); }\n\n.szenen-zeitleiste__aktionen {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n margin-top: var(--space-xs);\n}\n\n.szenen-zeitleiste__meldung > summary {\n min-height: 2rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n line-height: 2rem;\n cursor: pointer;\n}\n\n.szenen-zeitleiste__meldung p {\n margin: var(--space-xs) 0 0;\n color: var(--color-text-secondary);\n font-size: 0.78rem;\n overflow-wrap: anywhere;\n}\n\n.szenen-zeitleiste__meldung code {\n display: block;\n margin-top: var(--space-xs);\n color: var(--color-text-tertiary, var(--color-text-secondary));\n font-family: var(--font-mono);\n font-size: 0.72rem;\n overflow-wrap: anywhere;\n}\n\n/* \u2500\u2500 Annahmen \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.szenen-annahmen {\n display: grid;\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-annahmen__zeile {\n display: flex;\n gap: var(--space-sm);\n min-width: 0;\n}\n\n.szenen-annahmen__symbol {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n border-radius: 50%;\n}\n\n.szenen-annahmen__text {\n display: grid;\n gap: 0.1rem;\n min-width: 0;\n font-size: 0.85rem;\n line-height: 1.45;\n overflow-wrap: anywhere;\n}\n\n.szenen-annahmen__art {\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n}\n\n.szenen-annahmen__text details > summary,\n.szenen-lauf__erlaeuterung > summary {\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n cursor: pointer;\n}\n\n.szenen-annahmen__text details p,\n.szenen-lauf__erlaeuterung p {\n margin: var(--space-xs) 0 0;\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n line-height: 1.5;\n white-space: pre-wrap;\n}\n\n.szenen-lauf__handeingabe h5 {\n margin: 0 0 var(--space-xs);\n}\n\n.szenen-lauf__handeingabe p {\n margin: 0;\n font-size: 0.85rem;\n}\n\n/* Kette `szenen-design`, P7 (#533) \u2014 die Szene aus Bausteinen. Felder als\n Karten, Bausteine im Feld als Chips; die Leiste ist das vorhandene\n Bottom-Sheet mit Bildkacheln. Bedient wird durch Antippen, nicht Ziehen. */\n.szenen-bausteinfelder {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n}\n\n.szenen-bausteinfelder__liste {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));\n gap: var(--space-sm);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bausteinfeld {\n display: grid;\n align-content: start;\n gap: var(--space-xs);\n min-width: 0;\n padding: var(--space-sm);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-bausteinfeld__kopf {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n}\n\n.szenen-bausteinfeld__leer,\n.szenen-bausteinfeld__gesperrt {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-bausteinfeld__refs {\n display: grid;\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-bausteinchip {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-xs);\n min-width: 0;\n}\n\n.szenen-view .szenen-bausteinchip__name {\n min-height: 2.25rem;\n max-width: 100%;\n padding: 0 0.75rem;\n overflow: hidden;\n background: var(--color-bg-elevated);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-full);\n font-size: 0.85rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-bausteinchip__aktionen {\n display: inline-flex;\n gap: var(--space-xs);\n}\n\n.szenen-view .szenen-bausteinchip__aktionen button {\n min-width: 2.25rem;\n min-height: 2.25rem;\n padding: 0 0.6rem;\n border-radius: var(--radius-full);\n}\n\n.szenen-view .szenen-bausteinfeld__plus {\n display: inline-flex;\n align-items: center;\n justify-self: start;\n gap: 0.35rem;\n min-height: 2.25rem;\n padding: 0 0.75rem;\n background: transparent;\n border: 1px dashed var(--color-border);\n border-radius: var(--radius-full);\n}\n\n.szenen-bausteinfelder__weitere {\n display: grid;\n gap: var(--space-xs);\n}\n\n.szenen-bausteinfelder__weitere h5 {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n font-weight: 500;\n}\n\n.szenen-bausteinfelder__weitere ul {\n display: grid;\n gap: 0.25rem;\n margin: 0;\n padding: 0;\n list-style: none;\n font-size: 0.85rem;\n}\n\n.szenen-bausteinfelder__ort {\n color: var(--color-text-secondary);\n}\n\n.szenen-view .szenen-bausteinleiste__suche {\n min-height: 2.75rem;\n width: 100%;\n box-sizing: border-box;\n}\n\n.szenen-bausteinleiste {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: var(--space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.szenen-view .szenen-bausteinkachel {\n display: grid;\n gap: 0.25rem;\n width: 100%;\n padding: 0;\n overflow: hidden;\n text-align: left;\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-view .szenen-bausteinkachel[aria-pressed="true"] {\n border-color: var(--color-text-primary);\n}\n\n.szenen-view .szenen-bausteinkachel:disabled {\n cursor: default;\n opacity: 0.7;\n}\n\n.szenen-bausteinkachel__name {\n display: flex;\n align-items: center;\n gap: 0.3rem;\n padding: 0 0.4rem;\n overflow: hidden;\n font-size: 0.8rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-bausteinkachel__status,\n.szenen-bausteinkachel__grund {\n padding: 0 0.4rem 0.4rem;\n color: var(--color-text-secondary);\n font-size: 0.7rem;\n line-height: 1.25;\n overflow-wrap: anywhere;\n}\n\n@media (min-width: 761px) {\n .szenen-bausteinleiste {\n grid-template-columns: repeat(4, minmax(0, 1fr));\n }\n}\n/* MCP_STAGE_START: shared stage styles embedded in the gateway resource. */\n/* Issue #569: mobile stage controls and exact camera letterbox. */\n/* 3D-B\xFChne (#569): Ansicht zuerst, Werte als Karten darunter. */\n.szenen-3d {\n display: grid;\n gap: var(--space-md);\n min-width: 0;\n padding: var(--space-md);\n background: var(--color-bg-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n}\n\n.szenen-3d__kopf {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n}\n\n.szenen-3d__kopf h4 {\n margin: 0 auto 0 0;\n}\n\n/* Als Ansicht \u201E3D\u201C der Komposition: kein zweiter Rahmen im Abschnitt. */\n.szenen-3d--eingebettet {\n padding: 0;\n background: transparent;\n border: none;\n border-radius: 0;\n}\n\n.szenen-3d__kopf {\n flex-wrap: wrap;\n}\n\n.szenen-3d .szenen-3d__aufbau {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n min-width: 0;\n margin-right: auto;\n}\n\n.szenen-3d .szenen-3d__aufbau select {\n width: auto;\n min-width: 0;\n max-width: 100%;\n}\n\n.szenen-3d__stand {\n min-width: 0;\n margin-right: auto;\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.szenen-3d__sync {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-3d__sync::before {\n width: 0.5rem;\n height: 0.5rem;\n background: var(--color-success);\n border-radius: var(--radius-full);\n content: "";\n}\n\n.szenen-3d__sync[data-state="speichert"]::before {\n background: var(--color-warning);\n}\n\n.szenen-3d__sync[data-state="ansicht"]::before {\n background: var(--color-accent-blue);\n}\n\n.szenen-3d__meldung,\n.szenen-3d__fehler {\n margin: 0;\n padding: var(--space-sm) var(--space-md);\n background: var(--color-bg-elevated);\n border-left: 3px solid var(--color-accent-blue);\n border-radius: var(--radius-sm);\n}\n\n.szenen-3d__fehler {\n border-left-color: var(--color-danger);\n}\n\n.szenen-3d__oeffnen {\n display: grid;\n gap: var(--space-sm);\n}\n\n.szenen-3d label {\n display: grid;\n gap: 0.3rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-3d__leiste {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-sm);\n}\n\n.szenen-3d__katalog {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.35rem;\n}\n\n.szenen-3d__katalog > span {\n margin-right: 0.15rem;\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n}\n\n.szenen-view .szenen-3d__katalog button,\n.szenen-view .szenen-3d__elemente button {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n min-height: 2rem;\n padding: 0 0.7rem;\n border-radius: var(--radius-full);\n font-size: 0.85rem;\n}\n\n.szenen-3d__katalog i,\n.szenen-3d__elemente i {\n flex: none;\n width: 0.6rem;\n height: 0.6rem;\n border-radius: 2px;\n}\n\n.szenen-view .szenen-3d__elemente button[aria-pressed="true"] {\n color: var(--color-text-primary);\n background: var(--color-bg-surface-hover);\n border-color: var(--color-text-primary);\n}\n\n/* Viewport: feste H\xF6he f\xFCr Drauf- und Seitenansicht; die Kameraansicht wird\n * darin auf das gespeicherte Kameraformat eingepasst (Letterbox). */\n.szenen-3d__viewport {\n position: relative;\n display: grid;\n place-items: center;\n /* Dieselbe Gr\xF6\xDFe wie die 2D-B\xFChne (`.szenen-buehne`): Beim Wechsel springt nichts. */\n width: 100%;\n aspect-ratio: 358 / 330;\n overflow: hidden;\n background: #0d0f12;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n container-type: size;\n outline: none;\n}\n\n.szenen-3d__viewport--laden {\n background:\n linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px) 0 0 / 32px 32px,\n linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px) 0 0 / 32px 32px,\n #0d0f12;\n}\n\n.szenen-3d__geruest {\n display: contents;\n}\n\n.szenen-3d__geruest button {\n pointer-events: none;\n}\n\n.szenen-3d__viewport:focus-visible {\n border-color: var(--color-accent-blue);\n box-shadow: 0 0 0 1px var(--color-accent-blue);\n}\n\n.szenen-3d__surface {\n position: relative;\n width: 100%;\n height: 100%;\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n}\n\n.szenen-3d__viewport[data-view="camera"] {\n background: #050607;\n}\n\n.szenen-3d__viewport[data-view="camera"] .szenen-3d__surface {\n width: min(100cqw, calc(100cqh * var(--seitenverhaeltnis)));\n height: min(100cqh, calc(100cqw / var(--seitenverhaeltnis)));\n}\n\n.szenen-3d__hud {\n position: absolute;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #d4d4d4;\n font-size: 0.78rem;\n font-variant-numeric: tabular-nums;\n pointer-events: none;\n}\n\n.szenen-3d__hud--werkzeuge {\n top: 0.6rem;\n right: 0.6rem;\n gap: 0.25rem;\n pointer-events: auto;\n}\n\n.szenen-view .szenen-3d__hud--werkzeuge button {\n min-width: 2rem;\n min-height: 2rem;\n padding: 0 0.6rem;\n color: #e5e5e5;\n background: rgba(23, 23, 23, 0.85);\n border-color: rgba(255, 255, 255, 0.12);\n backdrop-filter: blur(4px);\n}\n\n.szenen-3d__hud--kamera {\n top: 0.6rem;\n left: 0.6rem;\n padding: 0.2rem 0.55rem;\n background: rgba(0, 0, 0, 0.65);\n border-radius: var(--radius-full);\n}\n\n.szenen-3d__hud--info {\n bottom: 0.6rem;\n left: 0.6rem;\n max-width: calc(100% - 7rem);\n padding: 0.25rem 0.6rem;\n background: rgba(0, 0, 0, 0.6);\n border-radius: var(--radius-full);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.szenen-3d__hud--info strong {\n color: #ffffff;\n font-weight: 600;\n}\n\n.szenen-3d__hud i {\n font-style: normal;\n font-weight: 700;\n}\n\n.szenen-3d__hud--achsen {\n right: 0.75rem;\n bottom: 0.7rem;\n gap: 0.6rem;\n font-weight: 700;\n}\n\n.szenen-3d__labels {\n position: absolute;\n inset: 0;\n overflow: hidden;\n pointer-events: none;\n}\n\n.szenen-3d__label {\n position: absolute;\n padding: 0.05rem 0.4rem;\n color: #f5f5f5;\n background: rgba(10, 10, 10, 0.72);\n border-left: 2px solid var(--farbe, #9bafbc);\n border-radius: 3px;\n font: 500 0.72rem/1.4 var(--font-sans);\n white-space: nowrap;\n transform: translate(-50%, 6px);\n}\n\n.szenen-3d__label--side {\n transform: translate(-50%, calc(-100% - 6px));\n}\n\n.szenen-3d__label--kamera {\n color: #bfdbfe;\n border-left-color: #60a5fa;\n transform: translate(14px, -50%);\n}\n\n.szenen-3d__label--kamera.is-links {\n transform: translate(calc(-100% - 14px), -50%);\n}\n\n.szenen-3d__label.is-selected {\n color: #000000;\n background: #ffffff;\n}\n\n.szenen-3d__inspektor {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));\n gap: var(--space-sm);\n}\n\n.szenen-3d__karte {\n display: grid;\n align-content: start;\n gap: var(--space-sm);\n min-width: 0;\n padding: var(--space-sm) var(--space-md) var(--space-md);\n background: var(--color-bg-app);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n\n.szenen-3d__karte h5 {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.72rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.szenen-3d__elemente {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem;\n}\n\n.szenen-3d__werte {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 0.4rem;\n margin: 0;\n padding: 0;\n border: none;\n}\n\n.szenen-3d__werte legend {\n margin-bottom: 0.4rem;\n padding: 0;\n color: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-3d__werte legend span {\n margin-left: 0.35rem;\n color: var(--color-text-secondary);\n font-size: 0.78rem;\n font-weight: 400;\n}\n\n.szenen-3d__zeilenkopf {\n grid-column: 1 / -1;\n margin-top: 0.2rem;\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-3d__werte > button {\n grid-column: 1 / -1;\n}\n\n/* Markerfarbe eines Proxys (#587): W\xE4hler, Hexfeld und R\xFCcksetzen in einer\n Zeile; auf schmalem Touch-Viewport bricht sie um, ohne Controls zu verdecken. */\n.szenen-3d__farbe {\n grid-column: 1 / -1;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.4rem;\n}\n\n.szenen-view .szenen-3d__farbe input[type="color"] {\n flex: 0 0 auto;\n width: 2.75rem;\n min-height: 2.75rem;\n padding: 0.15rem;\n cursor: pointer;\n}\n\n.szenen-view .szenen-3d__farbe input[type="text"] {\n flex: 1 1 6.5rem;\n min-width: 6.5rem;\n min-height: 2.75rem;\n font-family: var(--font-mono, monospace);\n text-transform: lowercase;\n}\n\n.szenen-view .szenen-3d__farbe button {\n flex: 0 0 auto;\n min-height: 2.75rem;\n}\n\n.szenen-3d__entfernen {\n grid-column: 1 / -1;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.4rem;\n}\n\n.szenen-3d__entfernen > span {\n flex: 1 1 100%;\n color: var(--color-text-primary);\n font-size: 0.85rem;\n}\n\n.szenen-view .szenen-3d__entfernen button {\n min-height: 2.75rem;\n}\n\n.szenen-view .szenen-3d__gefahr {\n color: #fff;\n background: var(--color-danger);\n border-color: var(--color-danger);\n}\n\n.szenen-3d__farbe-auto {\n color: var(--color-text-secondary);\n font-size: 0.75rem;\n}\n\n.szenen-3d__farbe-hinweis {\n grid-column: 1 / -1;\n margin: 0;\n color: var(--color-warning, #eab308);\n font-size: 0.78rem;\n}\n\n.szenen-3d .szenen-3d__feld {\n position: relative;\n display: block;\n}\n\n.szenen-3d__achse {\n position: absolute;\n top: 50%;\n left: 0.55rem;\n font-size: 0.72rem;\n font-weight: 700;\n transform: translateY(-50%);\n pointer-events: none;\n}\n\n.szenen-3d__achse--x { color: #f87171; }\n.szenen-3d__achse--y { color: #4ade80; }\n.szenen-3d__achse--z { color: #60a5fa; }\n\n.szenen-view .szenen-3d__feld input {\n padding-left: 1.6rem;\n font-variant-numeric: tabular-nums;\n}\n\n.szenen-3d__hinweis {\n margin: 0;\n color: var(--color-text-secondary);\n font-size: 0.82rem;\n}\n\n.szenen-3d__abschluss {\n display: grid;\n gap: var(--space-sm);\n}\n\n.szenen-view .szenen-3d__primaer {\n min-height: 2.75rem;\n color: var(--color-bg-app);\n background: var(--color-text-primary);\n border-color: var(--color-text-primary);\n font-weight: 600;\n}\n\n.szenen-view .szenen-3d__primaer:hover:not(:disabled) {\n color: var(--color-bg-app);\n background: var(--color-primary-hover);\n}\n\n.szenen-view .szenen-3d__nebenaktion {\n justify-self: start;\n min-height: 2rem;\n padding: 0;\n background: none;\n border: none;\n font-size: 0.82rem;\n text-decoration: underline;\n}\n\n/* Hinweise passend zum Eingabeger\xE4t; ohne Angabe gilt die Maus-Variante. */\n.szenen-3d__nur-touch {\n display: none;\n}\n\n@media (hover: none) and (pointer: coarse) {\n .szenen-3d__nur-maus {\n display: none;\n }\n\n .szenen-3d__nur-touch {\n display: inline;\n }\n\n /* Fingergerechte Ziele (44 px) f\xFCr Ansichtssteuerung, Katalog und Elemente. */\n .szenen-view .szenen-3d__hud--werkzeuge button,\n .szenen-view .szenen-3d__katalog button,\n .szenen-view .szenen-3d__elemente button,\n .szenen-view .szenen-3d .szenen-studio__umschalter button {\n min-width: 2.75rem;\n min-height: 2.75rem;\n }\n}\n\n@media (max-width: 760px) {\n .szenen-3d {\n gap: var(--space-sm);\n padding: var(--space-sm);\n }\n\n .szenen-3d__leiste {\n display: grid;\n }\n\n .szenen-3d .szenen-studio__umschalter {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n }\n\n /* Katalog als eine Zeile, die in sich scrollt, statt die Ansicht nach unten zu schieben. */\n .szenen-3d__katalog {\n flex-wrap: nowrap;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n }\n\n .szenen-3d__katalog > * {\n flex: none;\n }\n\n .szenen-3d__viewport {\n aspect-ratio: 358 / 330;\n margin: 0 calc(-1 * var(--space-sm));\n border-right: none;\n border-left: none;\n border-radius: 0;\n }\n\n .szenen-3d__hud--info {\n max-width: calc(100% - 1.2rem);\n bottom: 2.4rem;\n }\n\n .szenen-3d__hud--achsen {\n bottom: 0.8rem;\n left: 0.75rem;\n right: auto;\n }\n}\n\n/* One DOM canvas, no nested React renderer. */\n.szenen-3d__canvas { display: block; width: 100%; height: 100%; }\n\n/* Prompt choices before the 3D run; mobile buttons wrap within each category. */\n.szenen-3d__prompt details { margin-block: .65rem; }\n.szenen-3d__prompt summary { cursor: pointer; font-weight: 600; }\n.szenen-3d__prompt fieldset { border: 0; padding: .6rem 0; min-width: 0; }\n.szenen-3d__prompt legend { color: var(--color-text-secondary); font-size: .85rem; }\n.szenen-3d__prompt textarea { min-height: 6rem; width: 100%; box-sizing: border-box; }\n.szenen-3d__referenz { white-space: pre-wrap; overflow-wrap: anywhere; font-size: .9rem; }\n\n/* Das Preview in seinem echten Format (z. B. 4:3) \u2014 keine F\xFCllfl\xE4che in Hintergrundfarbe, die ein Querformat vort\xE4uscht. */\n.szenen-3d__gemini img { display: block; width: auto; max-width: 100%; height: auto; max-height: 28rem; margin-inline: auto; border: 1px solid var(--color-border-hover); border-radius: .4rem; }\n.szenen-3d__gemini pre { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 32rem; overflow: auto; font-size: .8rem; }\n.szenen-3d__gemini ul { list-style: none; padding: 0; }\n.szenen-3d__gemini li { margin-block: .6rem; overflow-wrap: anywhere; }\n.szenen-3d__gemini li i { display: inline-block; width: .9rem; height: .9rem; margin-right: .4rem; border-radius: .15rem; }\n\n/* Desktop: 2D- und 3D-B\xFChne auf 60 % der Breite, gleich gro\xDF und zentriert.\n Unter 761 px bleibt die volle Breite (Touch, schmale Spalte). Steht am\n Dateiende, damit es die Grundregeln beider B\xFChnen \xFCberschreibt. */\n@media (min-width: 761px) {\n .szenen-buehne,\n .szenen-3d__viewport {\n width: 60%;\n justify-self: center;\n margin-inline: auto;\n }\n}\n\n/* One mobile object sheet and a separate ring gesture on the selected object. */\n.szenen-3d__drehring { position:absolute; overflow:visible; pointer-events:none; z-index:12; }\n.szenen-3d__drehring circle { pointer-events:stroke; cursor:grab; touch-action:none; }\n.szenen-3d__drehring circle:focus-visible { stroke:#ffffff; outline:none; }\n.szenen-3d__blatt-schliessen { display:none; }\n.szenen-3d__objekt-aktionen, .szenen-3d__pose { display:flex; flex-wrap:wrap; gap:.4rem; grid-column:1/-1; }\n.szenen-3d__morph { display:flex; align-items:center; gap:.6rem; grid-column:1/-1; }\n.szenen-3d__morph input { flex:1; min-width:0; min-height:44px; }\n.szenen-3d__pose button[aria-pressed="true"] { border-color:var(--color-accent-blue); }\n@media (max-width:760px) {\n .szenen-3d__objektblatt { position:fixed; left:0; right:0; bottom:0; z-index:50; max-height:42dvh; overflow:auto; overscroll-behavior:contain; background:var(--color-bg-secondary,#15171b); border:1px solid var(--color-border); border-radius:18px 18px 0 0; padding:.7rem 1rem calc(.8rem + env(safe-area-inset-bottom)); box-shadow:0 -8px 30px #0008; }\n .szenen-3d__blatt-schliessen { display:block; margin-left:auto; min-height:44px; }\n .szenen-3d__objektblatt button, .szenen-3d__objektblatt input, .szenen-3d__objektblatt select { min-height:44px; }\n}\n\n.szenen-3d__werte { min-width:0; }\n.szenen-3d__objektblatt input, .szenen-3d__objektblatt select { min-width:0; max-width:100%; }\n\n@media (max-width:760px) { .szenen-3d__objektblatt { width:100vw; max-width:100vw; box-sizing:border-box; } }\n\n.szenen-3d__karte, .szenen-3d__abschluss { grid-template-columns:minmax(0,1fr); }\n\n\n.szenen-3d { overflow-x:clip; }\n\n/* Display options (walls, fullscreen) and the fullscreen stage (#582 follow-up).\n Fullscreen: the stage frame covers the screen; sheets lie over the 3D view. */\n.szenen-3d__ansichtsoptionen { display:flex; flex-wrap:wrap; gap:.4rem; }\n.szenen-view .szenen-3d__ansichtsoptionen button[aria-pressed="true"] { border-color:var(--color-accent-blue); }\n.szenen-3d__buehne { display:grid; gap:var(--space-sm); min-width:0; }\n.szenen-3d__buehne.is-vollbild { position:fixed; inset:0; z-index:1000; display:flex; flex-direction:column; gap:0; background:#0d0f12;\n padding:env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left); }\n/* Two rows, both always visible: the four views, then walls/camera/exit. */\n.szenen-3d__buehne.is-vollbild .szenen-3d__leiste { display:grid; flex:none; gap:.35rem; padding:.4rem; }\n.szenen-3d__buehne.is-vollbild .szenen-studio__umschalter { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); }\n.szenen-3d__buehne.is-vollbild .szenen-studio__umschalter button { min-width:0; padding-inline:.3rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n.szenen-3d__buehne.is-vollbild .szenen-3d__ansichtsoptionen { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr); }\n.szenen-3d__buehne.is-vollbild .szenen-3d__katalog { display:none; }\n.szenen-3d__buehne.is-vollbild .szenen-3d__viewport { flex:1; min-height:0; width:100%; aspect-ratio:auto; margin:0; border:0; border-radius:0; }\n.szenen-3d__buehne.is-vollbild .szenen-3d__objektblatt { position:absolute; left:0; right:0; bottom:0; z-index:20; width:auto; max-width:none; max-height:45%;\n overflow:auto; overscroll-behavior:contain; box-sizing:border-box; background:var(--color-bg-secondary,#15171b); border:1px solid var(--color-border);\n border-radius:18px 18px 0 0; padding:.7rem 1rem calc(.8rem + env(safe-area-inset-bottom)); box-shadow:0 -8px 30px #0008; }\n.szenen-3d__buehne.is-vollbild .szenen-3d__blatt-schliessen { display:block; margin-left:auto; min-height:44px; }\n.szenen-3d__buehne.is-vollbild .szenen-3d__objektblatt button,\n.szenen-3d__buehne.is-vollbild .szenen-3d__objektblatt input,\n.szenen-3d__buehne.is-vollbild .szenen-3d__objektblatt select { min-height:44px; }\n.szenen-3d__kamerablatt label { display:grid; gap:.25rem; grid-column:1/-1; }\n@media (min-width:761px) {\n .szenen-3d__buehne.is-vollbild .szenen-3d__objektblatt { left:auto; top:0; width:min(26rem,40%); max-height:none; border-radius:18px 0 0 18px; }\n}\n\n/* Visibility list and sheet switch (editor display only, never saved).\n "Objektblatt" only matters where the sheet covers the stage: fullscreen and phone width. */\n.szenen-3d__sichtbar { position:relative; min-width:0; }\n.szenen-3d__sichtbar > summary { display:flex; align-items:center; justify-content:center; box-sizing:border-box; height:100%; min-height:2.25rem;\n padding:.45rem .75rem; color:var(--color-text-secondary); background:var(--color-bg-elevated); border:1px solid var(--color-border);\n border-radius:var(--radius-sm); cursor:pointer; list-style:none; text-align:center; }\n.szenen-3d__sichtbar > summary::-webkit-details-marker { display:none; }\n.szenen-3d__sichtbar[open] > summary { border-color:var(--color-accent-blue); color:var(--color-text-primary); }\n.szenen-3d__sichtbar-liste { position:absolute; top:calc(100% + .3rem); left:0; z-index:40; display:grid; gap:.1rem; width:max-content; min-width:14rem;\n max-width:min(22rem,calc(100vw - 1rem)); max-height:60vh; overflow:auto; overscroll-behavior:contain; box-sizing:border-box; padding:.4rem;\n background:var(--color-bg-secondary,#15171b); border:1px solid var(--color-border); border-radius:var(--radius-md); box-shadow:0 8px 30px #0008; }\n.szenen-3d__sichtbar-liste label { display:flex; align-items:center; gap:.5rem; min-height:44px; padding:0 .4rem; cursor:pointer; }\n.szenen-3d__sichtbar-liste input { width:1.15rem; height:1.15rem; margin:0; flex:none; }\n.szenen-3d__sichtbar-liste i { flex:none; width:.6rem; height:.6rem; border-radius:2px; }\n.szenen-3d__sichtbar-liste button { margin-top:.3rem; min-height:44px; }\n.szenen-3d__blatt-schalter { display:none; }\n.szenen-3d__buehne.is-vollbild .szenen-3d__blatt-schalter { display:block; }\n@media (max-width:760px) {\n .szenen-3d__blatt-schalter { display:block; }\n .szenen-3d__objektblatt.is-zu { display:none; }\n}\n\n/* MCP_STAGE_END */\n';
65
65
 
66
66
  // src/lib/utils.ts
67
67
  var getFormattedTimestamp = () => {
@@ -2416,7 +2416,7 @@ function useHFState(token, namespace) {
2416
2416
  setForks(findForks(dag));
2417
2417
  setEventCount(afterConsolidation.length);
2418
2418
  if (afterConsolidation.length) setLastEventTs(Math.max(...afterConsolidation.map((e) => e.ts)));
2419
- return _chunkHFX6D53Wjs.applyEvents.call(void 0, snapshot, afterConsolidation);
2419
+ return _chunkVSHSZEGVjs.applyEvents.call(void 0, snapshot, afterConsolidation);
2420
2420
  }, []);
2421
2421
  const loadFull = _react.useCallback.call(void 0, async () => {
2422
2422
  if (!token || !namespace) return;
@@ -2424,14 +2424,14 @@ function useHFState(token, namespace) {
2424
2424
  setError(null);
2425
2425
  knownFilePaths.current = /* @__PURE__ */ new Set();
2426
2426
  try {
2427
- const snapshot = await _chunkHFX6D53Wjs.loadHFState.call(void 0, namespace, token);
2427
+ const snapshot = await _chunkVSHSZEGVjs.loadHFState.call(void 0, namespace, token);
2428
2428
  setHasStateZip(snapshot !== null);
2429
2429
  const base = _nullishCoalesce(snapshot, () => ( {
2430
2430
  metadata: [],
2431
2431
  tags: { by_category: {}, all: [] },
2432
2432
  meta: { consolidatedAt: 0, version: 1 }
2433
2433
  }));
2434
- const hfEvents = await _chunkHFX6D53Wjs.loadPendingEvents.call(void 0, namespace, token, base.meta.consolidatedAt, knownFilePaths.current);
2434
+ const hfEvents = await _chunkVSHSZEGVjs.loadPendingEvents.call(void 0, namespace, token, base.meta.consolidatedAt, knownFilePaths.current);
2435
2435
  const hfEventKeys = new Set(hfEvents.map((e) => `${e.ts}_${e.clientId}`));
2436
2436
  const localOnlyEvents = allEventsRef.current.filter(
2437
2437
  (e) => !hfEventKeys.has(`${e.ts}_${e.clientId}`)
@@ -2449,14 +2449,14 @@ function useHFState(token, namespace) {
2449
2449
  const failed = [];
2450
2450
  for (const evt of buffer) {
2451
2451
  try {
2452
- await _chunkHFX6D53Wjs.writeHFEvent.call(void 0, namespace, token, evt.type, evt.payload, evt.prevTs);
2452
+ await _chunkVSHSZEGVjs.writeHFEvent.call(void 0, namespace, token, evt.type, evt.payload, evt.prevTs);
2453
2453
  } catch (e5) {
2454
2454
  failed.push(evt);
2455
2455
  }
2456
2456
  }
2457
2457
  writeOfflineBuffer(failed);
2458
2458
  setPendingBufferCount(failed.length);
2459
- const freshEvents = await _chunkHFX6D53Wjs.loadPendingEvents.call(void 0, namespace, token, base.meta.consolidatedAt, knownFilePaths.current);
2459
+ const freshEvents = await _chunkVSHSZEGVjs.loadPendingEvents.call(void 0, namespace, token, base.meta.consolidatedAt, knownFilePaths.current);
2460
2460
  freshEvents.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
2461
2461
  setState((prev) => prev ? applyNewEvents(base, freshEvents) : prev);
2462
2462
  }
@@ -2469,7 +2469,7 @@ function useHFState(token, namespace) {
2469
2469
  const pollNew = _react.useCallback.call(void 0, async () => {
2470
2470
  if (!token || !namespace || !state) return;
2471
2471
  try {
2472
- const events = await _chunkHFX6D53Wjs.loadPendingEvents.call(void 0, namespace, token, state.meta.consolidatedAt, knownFilePaths.current);
2472
+ const events = await _chunkVSHSZEGVjs.loadPendingEvents.call(void 0, namespace, token, state.meta.consolidatedAt, knownFilePaths.current);
2473
2473
  const newEvents = events.filter((e) => !knownEventPaths.current.has(`${e.ts}_${e.clientId}`));
2474
2474
  if (!newEvents.length) return;
2475
2475
  newEvents.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
@@ -2494,7 +2494,7 @@ function useHFState(token, namespace) {
2494
2494
  await pollNew();
2495
2495
  try {
2496
2496
  console.log("[HF] writeHFEvent start, path will be:", `${namespace}events/...`);
2497
- const event = await _chunkHFX6D53Wjs.writeHFEvent.call(void 0, namespace, token, type, payload, prevTs);
2497
+ const event = await _chunkVSHSZEGVjs.writeHFEvent.call(void 0, namespace, token, type, payload, prevTs);
2498
2498
  console.log("[HF] writeHFEvent success:", event.ts);
2499
2499
  knownEventPaths.current.add(`${event.ts}_${event.clientId}`);
2500
2500
  const confirmedKey = `${event.ts}_${event.clientId}`;
@@ -2511,7 +2511,7 @@ function useHFState(token, namespace) {
2511
2511
  type,
2512
2512
  ts: Date.now(),
2513
2513
  prevTs,
2514
- clientId: _chunkHFX6D53Wjs.getSessionClientId.call(void 0, ),
2514
+ clientId: _chunkVSHSZEGVjs.getSessionClientId.call(void 0, ),
2515
2515
  payload
2516
2516
  };
2517
2517
  writeOfflineBuffer([...buffer, offline]);
@@ -2544,11 +2544,11 @@ function useHFState(token, namespace) {
2544
2544
  var _jszip = require('jszip'); var _jszip2 = _interopRequireDefault(_jszip);
2545
2545
  var CURRENT_TAG_EVENT_VERSION = { major: 1, minor: 0 };
2546
2546
  async function loadTagBase(namespace, token) {
2547
- const files = await _chunkHFX6D53Wjs.hfListDir.call(void 0, namespace, "", token);
2547
+ const files = await _chunkVSHSZEGVjs.hfListDir.call(void 0, namespace, "", token);
2548
2548
  const tagBaseFiles = files.filter((f) => f.type === "file" && /^tags-state-[\dT\-]+Z\.zip$/.test(f.path.split("/").pop() || "")).sort((a, b) => b.path.localeCompare(a.path));
2549
2549
  if (!tagBaseFiles.length) return null;
2550
2550
  const newestPath = tagBaseFiles[0].path;
2551
- const zipBytes = await _chunkHFX6D53Wjs.hfDownloadBinaryByPath.call(void 0, newestPath, token);
2551
+ const zipBytes = await _chunkVSHSZEGVjs.hfDownloadBinaryByPath.call(void 0, newestPath, token);
2552
2552
  const zip = await _jszip2.default.loadAsync(zipBytes);
2553
2553
  const [usersStr, contextsStr, tagsStr, metaStr] = await Promise.all([
2554
2554
  _optionalChain([zip, 'access', _50 => _50.file, 'call', _51 => _51("users.json"), 'optionalAccess', _52 => _52.async, 'call', _53 => _53("string")]),
@@ -2573,14 +2573,14 @@ async function writeTagEvent(namespace, token, event) {
2573
2573
  const uuid = crypto.randomUUID().slice(0, 8);
2574
2574
  const filename = `${tsToFilename(event.ts)}_${uuid}.json`;
2575
2575
  const repoPath = `${namespace}tag-events/${filename}`;
2576
- await _chunkHFX6D53Wjs.hfUploadSmallFile.call(void 0, repoPath, JSON.stringify(event, null, 2), token, `TagEvent: ${event.type}`);
2576
+ await _chunkVSHSZEGVjs.hfUploadSmallFile.call(void 0, repoPath, JSON.stringify(event, null, 2), token, `TagEvent: ${event.type}`);
2577
2577
  }
2578
2578
  function createTagCreatedEvent(baseVersion, userId, payload) {
2579
2579
  return {
2580
2580
  v: CURRENT_TAG_EVENT_VERSION,
2581
2581
  type: "tag_created",
2582
2582
  ts: Date.now(),
2583
- clientId: _chunkHFX6D53Wjs.getSessionClientId.call(void 0, ),
2583
+ clientId: _chunkVSHSZEGVjs.getSessionClientId.call(void 0, ),
2584
2584
  baseVersion,
2585
2585
  userId,
2586
2586
  payload
@@ -2591,7 +2591,7 @@ function createTagUpdatedEvent(baseVersion, userId, id, delta) {
2591
2591
  v: CURRENT_TAG_EVENT_VERSION,
2592
2592
  type: "tag_updated",
2593
2593
  ts: Date.now(),
2594
- clientId: _chunkHFX6D53Wjs.getSessionClientId.call(void 0, ),
2594
+ clientId: _chunkVSHSZEGVjs.getSessionClientId.call(void 0, ),
2595
2595
  baseVersion,
2596
2596
  userId,
2597
2597
  payload: { id, delta }
@@ -5465,7 +5465,7 @@ function ServerTab({ serverBaseUrl }) {
5465
5465
  function FlowWorkspacePicker({
5466
5466
  tagBase,
5467
5467
  selectedUserId,
5468
- message,
5468
+ message: message2,
5469
5469
  onSelectUser,
5470
5470
  onSelectContext
5471
5471
  }) {
@@ -5489,7 +5489,7 @@ function FlowWorkspacePicker({
5489
5489
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: "FineArt Flow" }),
5490
5490
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "small", { children: step === "user" ? "Benutzer w\xE4hlen" : `Kontext f\xFCr ${_nullishCoalesce(_optionalChain([selectedUser, 'optionalAccess', _153 => _153.username]), () => ( `User ${selectedUserId}`))}` })
5491
5491
  ] }),
5492
- message && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "flow-workspace-picker__warning", children: message }),
5492
+ message2 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "flow-workspace-picker__warning", children: message2 }),
5493
5493
  step === "user" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flow-workspace-picker__choices", "aria-label": "Benutzer w\xE4hlen", children: [
5494
5494
  tagBase.users.map((user) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { type: "button", onClick: () => chooseUser(user.id), children: [
5495
5495
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: user.username }),
@@ -5530,6 +5530,328 @@ function FlowWorkspacePicker({
5530
5530
  ] }) });
5531
5531
  }
5532
5532
 
5533
+ // src/components/FlowBridgePanel.tsx
5534
+
5535
+
5536
+ // src/lib/flowBridgeClient.ts
5537
+ var FLOW_BRIDGE_REQUEST_EVENT = "fine-art-flow-bridge:request:v1";
5538
+ var FLOW_BRIDGE_RESPONSE_EVENT = "fine-art-flow-bridge:response:v1";
5539
+ var FLOW_BRIDGE_HELLO_TIMEOUT_MS = 1500;
5540
+ var FLOW_BRIDGE_REQUEST_TIMEOUT_MS = 15e3;
5541
+ function isRecord(value) {
5542
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5543
+ }
5544
+ function readError(value) {
5545
+ if (isRecord(value) && typeof value.code === "string" && typeof value.message === "string") {
5546
+ return { code: value.code, message: value.message };
5547
+ }
5548
+ return { code: "invalid-message", message: "Antwort der Flow-Bridge ohne gueltige Fehlerangabe." };
5549
+ }
5550
+ function noBridge(timeoutMs) {
5551
+ return {
5552
+ code: "no-bridge",
5553
+ message: `Keine Antwort der Flow-Bridge innerhalb von ${timeoutMs} ms \u2014 Extension nicht installiert, deaktiviert oder fuer diesen Frame nicht freigegeben.`
5554
+ };
5555
+ }
5556
+ var nullableNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
5557
+ var nextId = 0;
5558
+ function createFlowBridgeClient({
5559
+ target = document,
5560
+ appVersion,
5561
+ helloTimeoutMs = FLOW_BRIDGE_HELLO_TIMEOUT_MS,
5562
+ requestTimeoutMs = FLOW_BRIDGE_REQUEST_TIMEOUT_MS,
5563
+ clock = () => performance.now()
5564
+ } = {}) {
5565
+ function exchange(payload, timeoutMs) {
5566
+ nextId += 1;
5567
+ const id = `fb-${Date.now().toString(36)}-${nextId}`;
5568
+ return new Promise((resolve) => {
5569
+ const onResponse = (event) => {
5570
+ const detail = event.detail;
5571
+ if (typeof detail !== "string") return;
5572
+ let parsed;
5573
+ try {
5574
+ parsed = JSON.parse(detail);
5575
+ } catch (e20) {
5576
+ return;
5577
+ }
5578
+ if (!isRecord(parsed) || parsed.id !== id) return;
5579
+ cleanup();
5580
+ resolve(parsed);
5581
+ };
5582
+ const timer = setTimeout(() => {
5583
+ cleanup();
5584
+ resolve(null);
5585
+ }, timeoutMs);
5586
+ const cleanup = () => {
5587
+ clearTimeout(timer);
5588
+ target.removeEventListener(FLOW_BRIDGE_RESPONSE_EVENT, onResponse);
5589
+ };
5590
+ target.addEventListener(FLOW_BRIDGE_RESPONSE_EVENT, onResponse);
5591
+ target.dispatchEvent(new CustomEvent(FLOW_BRIDGE_REQUEST_EVENT, { detail: JSON.stringify({ id, ...payload }) }));
5592
+ });
5593
+ }
5594
+ return {
5595
+ async status() {
5596
+ const started = clock();
5597
+ const reply = await exchange({ op: "hello", app: "flowfa", ...appVersion ? { appVersion } : {} }, helloTimeoutMs);
5598
+ const roundTripMs = Math.round(clock() - started);
5599
+ if (!reply) return { available: false, error: noBridge(helloTimeoutMs), roundTripMs };
5600
+ if (reply.ok !== true) return { available: false, error: readError(reply.error), roundTripMs };
5601
+ const bridge = reply.bridge;
5602
+ if (!isRecord(bridge) || typeof bridge.name !== "string" || typeof bridge.version !== "string" || typeof bridge.protocol !== "number") {
5603
+ return { available: false, error: { code: "invalid-message", message: "Handshake-Antwort ohne Bridge-Kennung." }, roundTripMs };
5604
+ }
5605
+ return { available: true, name: bridge.name, version: bridge.version, protocol: bridge.protocol, roundTripMs };
5606
+ },
5607
+ async request(request) {
5608
+ const started = clock();
5609
+ const tokenSuffix = "tokenSuffix" in request && request.tokenSuffix !== void 0 ? { tokenSuffix: request.tokenSuffix } : {};
5610
+ const reply = await exchange({ op: "request", target: request.target, method: request.method, path: request.path, ...tokenSuffix }, requestTimeoutMs);
5611
+ const roundTripMs = Math.round(clock() - started);
5612
+ if (!reply) {
5613
+ return { ok: false, transport: null, status: null, data: null, latencyMs: null, roundTripMs, error: noBridge(requestTimeoutMs) };
5614
+ }
5615
+ const ok = reply.ok === true;
5616
+ return {
5617
+ ok,
5618
+ transport: typeof reply.transport === "string" ? reply.transport : null,
5619
+ status: nullableNumber(reply.status),
5620
+ data: ok ? _nullishCoalesce(reply.data, () => ( null)) : null,
5621
+ latencyMs: nullableNumber(reply.latencyMs),
5622
+ roundTripMs,
5623
+ error: ok ? null : readError(reply.error)
5624
+ };
5625
+ }
5626
+ };
5627
+ }
5628
+
5629
+ // src/lib/flowProbeLoader.ts
5630
+ var FLOW_PROBE_REQUEST = { target: "devMcp", method: "GET", path: "/flow-app/probe-bundle" };
5631
+ var HF_TOKEN_SUFFIX_CHARS = 8;
5632
+ var FLOW_PROBE_MARKER = "__faFlowProbe";
5633
+ var FLOW_PROBE_METHOD = "script-blob";
5634
+ var FLOW_PROBE_LOAD_TIMEOUT_MS = 5e3;
5635
+ var CSP_SETTLE_MS = 100;
5636
+ function isRecord2(value) {
5637
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5638
+ }
5639
+ function hfTokenSuffix(token) {
5640
+ const trimmed = (_nullishCoalesce(token, () => ( ""))).trim();
5641
+ return trimmed.length >= HF_TOKEN_SUFFIX_CHARS ? trimmed.slice(-HF_TOKEN_SUFFIX_CHARS) : null;
5642
+ }
5643
+ function readFlowProbeBundle(data) {
5644
+ if (!isRecord2(data)) return null;
5645
+ const { version: version2, sha256, source } = data;
5646
+ if (typeof version2 !== "string" || !/^probe-\d{3}$/.test(version2)) return null;
5647
+ if (typeof sha256 !== "string" || !/^[0-9a-f]{64}$/.test(sha256)) return null;
5648
+ if (typeof source !== "string" || source.length === 0) return null;
5649
+ return { version: version2, sha256, source };
5650
+ }
5651
+ function readMarker(value) {
5652
+ if (!isRecord2(value) || value.executed !== true || typeof value.version !== "string") return null;
5653
+ return { executed: true, version: value.version, executedAt: typeof value.executedAt === "string" ? value.executedAt : null };
5654
+ }
5655
+ async function sha256Hex(text) {
5656
+ if (!_optionalChain([globalThis, 'access', _154 => _154.crypto, 'optionalAccess', _155 => _155.subtle])) throw new Error("crypto.subtle ist in diesem Kontext nicht verfuegbar.");
5657
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
5658
+ return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
5659
+ }
5660
+ var message = (error) => error instanceof Error ? error.message : String(error);
5661
+ var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5662
+ async function executeFlowProbeBundle(bundle, {
5663
+ win = window,
5664
+ doc = document,
5665
+ timeoutMs = FLOW_PROBE_LOAD_TIMEOUT_MS,
5666
+ digest = sha256Hex
5667
+ } = {}) {
5668
+ const markerHost = win;
5669
+ const result = {
5670
+ method: FLOW_PROBE_METHOD,
5671
+ pageOrigin: win.location.origin,
5672
+ hash: { expected: bundle.sha256, actual: null, matches: null, error: null },
5673
+ scriptEvent: "not-started",
5674
+ marker: null,
5675
+ executed: false,
5676
+ cspViolations: [],
5677
+ error: null
5678
+ };
5679
+ try {
5680
+ result.hash.actual = await digest(bundle.source);
5681
+ result.hash.matches = result.hash.actual === bundle.sha256;
5682
+ } catch (error) {
5683
+ result.hash.error = message(error);
5684
+ }
5685
+ if (result.hash.matches === false) {
5686
+ result.error = "SHA-256 des empfangenen Quelltexts weicht ab \u2014 Bundle nicht ausgefuehrt.";
5687
+ return result;
5688
+ }
5689
+ delete markerHost[FLOW_PROBE_MARKER];
5690
+ const onViolation = (event) => {
5691
+ const violation = event;
5692
+ result.cspViolations.push(`${violation.effectiveDirective || violation.violatedDirective}: ${violation.blockedURI || "unbekannt"}`);
5693
+ };
5694
+ doc.addEventListener("securitypolicyviolation", onViolation);
5695
+ let url = null;
5696
+ let script = null;
5697
+ try {
5698
+ url = URL.createObjectURL(new Blob([bundle.source], { type: "text/javascript" }));
5699
+ const element = doc.createElement("script");
5700
+ script = element;
5701
+ result.scriptEvent = await new Promise((resolve) => {
5702
+ const timer = setTimeout(() => resolve("timeout"), timeoutMs);
5703
+ element.addEventListener("load", () => {
5704
+ clearTimeout(timer);
5705
+ resolve("load");
5706
+ });
5707
+ element.addEventListener("error", () => {
5708
+ clearTimeout(timer);
5709
+ resolve("error");
5710
+ });
5711
+ element.src = url;
5712
+ (_nullishCoalesce(doc.head, () => ( doc.documentElement))).appendChild(element);
5713
+ });
5714
+ } catch (error) {
5715
+ result.error = `Skript nicht einfuegbar: ${message(error)}`;
5716
+ }
5717
+ result.marker = readMarker(markerHost[FLOW_PROBE_MARKER]);
5718
+ result.executed = result.marker !== null && result.marker.version === bundle.version;
5719
+ if (!result.executed) await wait(CSP_SETTLE_MS);
5720
+ doc.removeEventListener("securitypolicyviolation", onViolation);
5721
+ _optionalChain([script, 'optionalAccess', _156 => _156.remove, 'call', _157 => _157()]);
5722
+ if (url) URL.revokeObjectURL(url);
5723
+ if (!result.executed && !result.error) {
5724
+ if (result.marker) result.error = `Marker meldet Version ${result.marker.version}, erwartet ${bundle.version}.`;
5725
+ else if (result.scriptEvent === "load") result.error = "script.onload ohne Marker \u2014 Ausfuehrung nicht belegt.";
5726
+ else if (result.scriptEvent === "error") result.error = "script.onerror \u2014 Skript nicht geladen oder blockiert.";
5727
+ else result.error = `Kein Skript-Ereignis innerhalb von ${timeoutMs} ms.`;
5728
+ }
5729
+ return result;
5730
+ }
5731
+
5732
+ // src/components/FlowBridgePanel.tsx
5733
+
5734
+ var STATUS_REQUEST = { target: "dev", method: "GET", path: "/api/status" };
5735
+ function hashText(execution) {
5736
+ if (execution.hash.matches === true) return "Hash gepr\xFCft";
5737
+ if (execution.hash.matches === false) return `Hash ABWEICHEND (berechnet ${_optionalChain([execution, 'access', _158 => _158.hash, 'access', _159 => _159.actual, 'optionalAccess', _160 => _160.slice, 'call', _161 => _161(0, 12)])}\u2026)`;
5738
+ return `Hash nicht pr\xFCfbar (${execution.hash.error})`;
5739
+ }
5740
+ function probeVerdict(run) {
5741
+ if (_optionalChain([run, 'access', _162 => _162.execution, 'optionalAccess', _163 => _163.executed])) return { ok: true, text: `ERGEBNIS: ausgef\xFChrt (executed: true, ${_optionalChain([run, 'access', _164 => _164.execution, 'access', _165 => _165.marker, 'optionalAccess', _166 => _166.version])})` };
5742
+ if (!run.response.ok) {
5743
+ return { ok: false, text: `ERGEBNIS: nicht ausgef\xFChrt \u2014 ${_optionalChain([run, 'access', _167 => _167.response, 'access', _168 => _168.error, 'optionalAccess', _169 => _169.code]) === "no-hf-token" ? "kein HF-Token in FlowFA." : "Bundle nicht \xFCber die Bridge erhalten."}` };
5744
+ }
5745
+ if (!run.bundle) return { ok: false, text: "ERGEBNIS: nicht ausgef\xFChrt \u2014 Antwort ohne g\xFCltiges Bundle." };
5746
+ return { ok: false, text: `ERGEBNIS: nicht ausgef\xFChrt \u2014 ${_optionalChain([run, 'access', _170 => _170.execution, 'optionalAccess', _171 => _171.error])}` };
5747
+ }
5748
+ var FlowBridgePanel = ({ appVersion, client, hfToken }) => {
5749
+ const bridge = _react.useMemo.call(void 0, () => _nullishCoalesce(client, () => ( createFlowBridgeClient({ appVersion }))), [client, appVersion]);
5750
+ const [status, setStatus] = _react.useState.call(void 0, null);
5751
+ const [response, setResponse] = _react.useState.call(void 0, null);
5752
+ const [probe, setProbe] = _react.useState.call(void 0, null);
5753
+ const [busy, setBusy] = _react.useState.call(void 0, null);
5754
+ const checkStatus = async () => {
5755
+ setBusy("status");
5756
+ try {
5757
+ setStatus(await bridge.status());
5758
+ } finally {
5759
+ setBusy(null);
5760
+ }
5761
+ };
5762
+ _react.useEffect.call(void 0, () => {
5763
+ let active = true;
5764
+ void bridge.status().then((result) => {
5765
+ if (active) setStatus(result);
5766
+ });
5767
+ return () => {
5768
+ active = false;
5769
+ };
5770
+ }, [bridge]);
5771
+ const runRequest = async () => {
5772
+ setBusy("request");
5773
+ setResponse(null);
5774
+ try {
5775
+ setResponse(await bridge.request(STATUS_REQUEST));
5776
+ } finally {
5777
+ setBusy(null);
5778
+ }
5779
+ };
5780
+ const runProbe = async () => {
5781
+ setBusy("probe");
5782
+ setProbe(null);
5783
+ try {
5784
+ const tokenSuffix = hfTokenSuffix(hfToken);
5785
+ if (!tokenSuffix) {
5786
+ setProbe({
5787
+ response: {
5788
+ ok: false,
5789
+ transport: null,
5790
+ status: null,
5791
+ data: null,
5792
+ latencyMs: null,
5793
+ roundTripMs: 0,
5794
+ error: { code: "no-hf-token", message: "Kein HF-Token in FlowFA gesetzt \u2014 ohne ihn kein Zugang zum Dev-MCP-Host." }
5795
+ },
5796
+ bundle: null,
5797
+ execution: null
5798
+ });
5799
+ return;
5800
+ }
5801
+ const response2 = await bridge.request({ ...FLOW_PROBE_REQUEST, tokenSuffix });
5802
+ const bundle = response2.ok ? readFlowProbeBundle(response2.data) : null;
5803
+ const execution = bundle ? await executeFlowProbeBundle(bundle) : null;
5804
+ setProbe({ response: response2, bundle, execution });
5805
+ } finally {
5806
+ setBusy(null);
5807
+ }
5808
+ };
5809
+ const buttonStyle = {
5810
+ height: 36,
5811
+ border: "1px solid rgba(255,255,255,0.12)",
5812
+ color: "rgba(255,255,255,0.7)",
5813
+ background: "rgba(255,255,255,0.04)"
5814
+ };
5815
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "details", { className: "w-full max-w-[280px] rounded-xl px-3 py-2", style: { border: "1px solid rgba(255,255,255,0.08)" }, children: [
5816
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "summary", { className: "text-white/40 text-[10px] uppercase tracking-widest font-bold cursor-pointer", children: "Flow-Bridge (Firefox)" }),
5817
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2 mt-2 text-[10px] font-mono", children: [
5818
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-2", children: [
5819
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { type: "button", onClick: checkStatus, disabled: busy !== null, className: "rounded-lg text-[11px] font-bold disabled:opacity-40", style: buttonStyle, children: busy === "status" ? "Pr\xFCfe\u2026" : "Bridge pr\xFCfen" }),
5820
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { type: "button", onClick: runRequest, disabled: busy !== null, className: "rounded-lg text-[11px] font-bold disabled:opacity-40", style: buttonStyle, children: busy === "request" ? "L\xE4uft\u2026" : "Dev /api/status" })
5821
+ ] }),
5822
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { type: "button", onClick: runProbe, disabled: busy !== null, className: "rounded-lg text-[11px] font-bold disabled:opacity-40", style: buttonStyle, children: busy === "probe" ? "L\xE4uft\u2026" : "Mini-Bundle laden & ausf\xFChren" }),
5823
+ status && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { role: "status", "data-testid": "flow-bridge-status", style: { color: status.available ? "#4ade80" : "#f87171" }, children: status.available ? `Bridge: verbunden \xB7 ${status.name} v${status.version} \xB7 Protokoll ${status.protocol} \xB7 ${status.roundTripMs} ms` : `Bridge: nicht verbunden \xB7 ${status.error.code}: ${status.error.message}` }),
5824
+ response && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { "data-testid": "flow-bridge-response", className: "flex flex-col gap-1", children: [
5825
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: { color: response.ok ? "#4ade80" : "#f87171" }, children: [
5826
+ `${STATUS_REQUEST.method} ${STATUS_REQUEST.path} (${STATUS_REQUEST.target}) \u2192 `,
5827
+ response.status !== null ? `HTTP ${response.status}` : "kein HTTP-Status",
5828
+ response.ok ? "" : ` \xB7 ${_optionalChain([response, 'access', _172 => _172.error, 'optionalAccess', _173 => _173.code])}: ${_optionalChain([response, 'access', _174 => _174.error, 'optionalAccess', _175 => _175.message])}`
5829
+ ] }),
5830
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-white/40", children: `Transport: ${_nullishCoalesce(response.transport, () => ( "keiner"))} \xB7 Server ${_nullishCoalesce(response.latencyMs, () => ( "\u2014"))} ms \xB7 gesamt ${response.roundTripMs} ms` }),
5831
+ response.ok && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "pre", { className: "text-white/60 whitespace-pre-wrap break-all bg-black/30 rounded-lg p-2", children: JSON.stringify(response.data, null, 2) })
5832
+ ] }),
5833
+ probe && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { "data-testid": "flow-bridge-probe", className: "flex flex-col gap-1", children: [
5834
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: { color: probe.response.ok ? "#4ade80" : "#f87171" }, children: [
5835
+ `${FLOW_PROBE_REQUEST.method} ${FLOW_PROBE_REQUEST.path} (${FLOW_PROBE_REQUEST.target}) \u2192 `,
5836
+ probe.response.status !== null ? `HTTP ${probe.response.status}` : "kein HTTP-Status",
5837
+ probe.response.ok ? "" : ` \xB7 ${_optionalChain([probe, 'access', _176 => _176.response, 'access', _177 => _177.error, 'optionalAccess', _178 => _178.code])}: ${_optionalChain([probe, 'access', _179 => _179.response, 'access', _180 => _180.error, 'optionalAccess', _181 => _181.message])}`
5838
+ ] }),
5839
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-white/40", children: `Transport: ${_nullishCoalesce(probe.response.transport, () => ( "keiner"))} \xB7 Server ${_nullishCoalesce(probe.response.latencyMs, () => ( "\u2014"))} ms \xB7 gesamt ${probe.response.roundTripMs} ms` }),
5840
+ probe.bundle && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-white/60 break-all", children: [
5841
+ `Bundle ${probe.bundle.version} \xB7 ${probe.bundle.source.length} Zeichen \xB7 SHA-256 ${probe.bundle.sha256.slice(0, 12)}\u2026`,
5842
+ probe.execution ? ` \xB7 ${hashText(probe.execution)}` : ""
5843
+ ] }),
5844
+ probe.execution && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
5845
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-white/60 break-all", children: `Ausf\xFChrung: <script src=blob:> \xB7 Ereignis ${probe.execution.scriptEvent} \xB7 Seite ${probe.execution.pageOrigin}` }),
5846
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-white/60 break-all", children: `Marker window.${FLOW_PROBE_MARKER}: ${probe.execution.marker ? JSON.stringify(probe.execution.marker) : "fehlt"}` }),
5847
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "break-all", style: { color: probe.execution.cspViolations.length > 0 ? "#f87171" : "rgba(255,255,255,0.4)" }, children: probe.execution.cspViolations.length > 0 ? `CSP: ${probe.execution.cspViolations.join("; ")}` : "CSP: keine Verletzung gemeldet" })
5848
+ ] }),
5849
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { "data-testid": "flow-bridge-probe-verdict", className: "font-bold", style: { color: probeVerdict(probe).ok ? "#4ade80" : "#f87171" }, children: probeVerdict(probe).text })
5850
+ ] })
5851
+ ] })
5852
+ ] });
5853
+ };
5854
+
5533
5855
  // src/lib/flowBootstrapTarget.ts
5534
5856
  var PROD_NAMESPACE = "app.art-by-rolands.de/";
5535
5857
  var DEV_NAMESPACE = "dev-app.art-by-rolands.de/";
@@ -5597,7 +5919,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5597
5919
  const [layoutChoice, setLayoutChoice] = _react.useState.call(void 0, () => {
5598
5920
  try {
5599
5921
  return localStorage.getItem("aa-layout") || null;
5600
- } catch (e20) {
5922
+ } catch (e21) {
5601
5923
  return null;
5602
5924
  }
5603
5925
  });
@@ -5606,7 +5928,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5606
5928
  const [hfNamespaceLocal, setHfNamespaceLocal] = _react.useState.call(void 0, () => {
5607
5929
  try {
5608
5930
  return normalizeSelectableNamespace(localStorage.getItem("aa-hf-namespace"));
5609
- } catch (e21) {
5931
+ } catch (e22) {
5610
5932
  return DEFAULT_NAMESPACE;
5611
5933
  }
5612
5934
  });
@@ -5631,7 +5953,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5631
5953
  });
5632
5954
  const effectiveNamespace = _nullishCoalesce(bootstrapTarget.namespace, () => ( ""));
5633
5955
  const kontextRef = _react.useRef.call(void 0, null);
5634
- const szenenPort = _react.useMemo.call(void 0, () => hfToken && effectiveNamespace ? _chunkHFX6D53Wjs.createFlowSzenenViewPort.call(void 0, {
5956
+ const szenenPort = _react.useMemo.call(void 0, () => hfToken && effectiveNamespace ? _chunkVSHSZEGVjs.createFlowSzenenViewPort.call(void 0, {
5635
5957
  generateText: onGeneratePrompt,
5636
5958
  token: hfToken,
5637
5959
  namespace: effectiveNamespace,
@@ -5690,7 +6012,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5690
6012
  setIsBootstrapping(true);
5691
6013
  setBootstrapLog([]);
5692
6014
  try {
5693
- await _chunkHFX6D53Wjs.hfBootstrapFromLegacy.call(void 0, effectiveNamespace, hfToken, (msg) => setBootstrapLog((prev) => [...prev, msg]));
6015
+ await _chunkVSHSZEGVjs.hfBootstrapFromLegacy.call(void 0, effectiveNamespace, hfToken, (msg) => setBootstrapLog((prev) => [...prev, msg]));
5694
6016
  setBootstrapLog((prev) => [...prev, "\u2713 Fertig"]);
5695
6017
  setTimeout(() => refreshHF(), 1500);
5696
6018
  } catch (e) {
@@ -5709,7 +6031,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5709
6031
  const startApp = (choice) => {
5710
6032
  try {
5711
6033
  localStorage.setItem("aa-layout", choice);
5712
- } catch (e22) {
6034
+ } catch (e23) {
5713
6035
  }
5714
6036
  setLayoutChoice(choice);
5715
6037
  setTargetConfirmed(true);
@@ -5730,9 +6052,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5730
6052
  const loadThumbnailsForEntries = _react.useCallback.call(void 0, async (entries) => {
5731
6053
  await loadThumbnailsSequentially(entries, {
5732
6054
  inFlight: hfInFlightRef.current,
5733
- isAlreadyLoaded: (entry) => !!_optionalChain([galleryItemsRef, 'access', _154 => _154.current, 'access', _155 => _155.find, 'call', _156 => _156((g) => g.id === entry.id), 'optionalAccess', _157 => _157.base64]),
6055
+ isAlreadyLoaded: (entry) => !!_optionalChain([galleryItemsRef, 'access', _182 => _182.current, 'access', _183 => _183.find, 'call', _184 => _184((g) => g.id === entry.id), 'optionalAccess', _185 => _185.base64]),
5734
6056
  isKnownMissing: (entry) => hfImageNotFoundRef.current.has(entry.id),
5735
- loadImage: (entry) => _chunkHFX6D53Wjs.hfLoadImageAsBase64.call(void 0, entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb),
6057
+ loadImage: (entry) => _chunkVSHSZEGVjs.hfLoadImageAsBase64.call(void 0, entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb),
5736
6058
  onLoaded: (entry, b64) => {
5737
6059
  const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
5738
6060
  setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
@@ -5749,7 +6071,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5749
6071
  }, [hfToken, effectiveNamespace]);
5750
6072
  _react.useEffect.call(void 0, () => {
5751
6073
  if (!hfState) return;
5752
- if (_optionalChain([hfState, 'access', _158 => _158.tags, 'optionalAccess', _159 => _159.by_category])) setWorkspaceTags(hfState.tags);
6074
+ if (_optionalChain([hfState, 'access', _186 => _186.tags, 'optionalAccess', _187 => _187.by_category])) setWorkspaceTags(hfState.tags);
5753
6075
  const hfIds = new Set(hfState.metadata.map((m) => m.id));
5754
6076
  const skeletons = hfState.metadata.map((m) => ({
5755
6077
  id: m.id,
@@ -5795,7 +6117,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5795
6117
  try {
5796
6118
  const v = parseInt(localStorage.getItem("aa-image-count") || "", 10);
5797
6119
  return v >= 1 && v <= 8 ? v : 4;
5798
- } catch (e23) {
6120
+ } catch (e24) {
5799
6121
  return 4;
5800
6122
  }
5801
6123
  });
@@ -5804,7 +6126,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5804
6126
  setImageCount(n);
5805
6127
  try {
5806
6128
  localStorage.setItem("aa-image-count", String(n));
5807
- } catch (e24) {
6129
+ } catch (e25) {
5808
6130
  }
5809
6131
  };
5810
6132
  const imageCountOptions = [
@@ -5818,14 +6140,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5818
6140
  const [leftPanelWidth, setLeftPanelWidth] = _react.useState.call(void 0, () => {
5819
6141
  try {
5820
6142
  return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
5821
- } catch (e25) {
6143
+ } catch (e26) {
5822
6144
  return 260;
5823
6145
  }
5824
6146
  });
5825
6147
  const [rightPanelWidth, setRightPanelWidth] = _react.useState.call(void 0, () => {
5826
6148
  try {
5827
6149
  return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
5828
- } catch (e26) {
6150
+ } catch (e27) {
5829
6151
  return 320;
5830
6152
  }
5831
6153
  });
@@ -5834,7 +6156,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5834
6156
  const [highContrast, setHighContrast] = _react.useState.call(void 0, () => {
5835
6157
  try {
5836
6158
  return localStorage.getItem("aa-contrast") === "high";
5837
- } catch (e27) {
6159
+ } catch (e28) {
5838
6160
  return false;
5839
6161
  }
5840
6162
  });
@@ -5847,14 +6169,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5847
6169
  const [zoomOffset, setZoomOffset] = _react.useState.call(void 0, { x: 0, y: 0 });
5848
6170
  const { historyVisible, galleryVisible } = computePrefetchVisibility({
5849
6171
  layoutChoice,
5850
- appShellVisible: !showStart && !requireWorkspaceSelection && !(isFullscreen && !!_optionalChain([currentResult, 'optionalAccess', _160 => _160.base64])),
6172
+ appShellVisible: !showStart && !requireWorkspaceSelection && !(isFullscreen && !!_optionalChain([currentResult, 'optionalAccess', _188 => _188.base64])),
5851
6173
  mobileTab,
5852
6174
  middlePanel,
5853
6175
  activeTab,
5854
6176
  isRightCollapsed
5855
6177
  });
5856
6178
  useThumbnailPrefetch({
5857
- metadata: _optionalChain([hfState, 'optionalAccess', _161 => _161.metadata]),
6179
+ metadata: _optionalChain([hfState, 'optionalAccess', _189 => _189.metadata]),
5858
6180
  historyVisible,
5859
6181
  galleryVisible,
5860
6182
  historyVisibleCount,
@@ -5910,12 +6232,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5910
6232
  setHighContrast(next);
5911
6233
  try {
5912
6234
  localStorage.setItem("aa-contrast", next ? "high" : "low");
5913
- } catch (e28) {
6235
+ } catch (e29) {
5914
6236
  }
5915
6237
  };
5916
6238
  const handleSelectReference = async () => {
5917
6239
  const media = await onSelectMedia();
5918
- if (!_optionalChain([media, 'optionalAccess', _162 => _162.length])) return;
6240
+ if (!_optionalChain([media, 'optionalAccess', _190 => _190.length])) return;
5919
6241
  const first = media[0];
5920
6242
  if (first.mediaId) {
5921
6243
  setActiveReferenceId(first.mediaId);
@@ -5938,7 +6260,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5938
6260
  generateImage: onGenerateImage,
5939
6261
  saveResult: async (item) => {
5940
6262
  const frame = item.frames[0];
5941
- if (_optionalChain([frame, 'optionalAccess', _163 => _163.base64])) {
6263
+ if (_optionalChain([frame, 'optionalAccess', _191 => _191.base64])) {
5942
6264
  const gen = frameToGeneration(frame, item);
5943
6265
  setGalleryItems((prev) => [gen, ...prev]);
5944
6266
  setHistory((prev) => [gen, ...prev]);
@@ -5956,7 +6278,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5956
6278
  setLeftPanelWidth(w);
5957
6279
  try {
5958
6280
  localStorage.setItem("aa-left-width", String(w));
5959
- } catch (e29) {
6281
+ } catch (e30) {
5960
6282
  }
5961
6283
  };
5962
6284
  const onUp = () => {
@@ -5975,7 +6297,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5975
6297
  setRightPanelWidth(w);
5976
6298
  try {
5977
6299
  localStorage.setItem("aa-right-width", String(w));
5978
- } catch (e30) {
6300
+ } catch (e31) {
5979
6301
  }
5980
6302
  };
5981
6303
  const onUp = () => {
@@ -6006,7 +6328,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6006
6328
  setIsScanningImage(false);
6007
6329
  }
6008
6330
  };
6009
- const currentIndex = _react.useMemo.call(void 0, () => history.findIndex((h) => h.id === _optionalChain([currentResult, 'optionalAccess', _164 => _164.id])), [history, currentResult]);
6331
+ const currentIndex = _react.useMemo.call(void 0, () => history.findIndex((h) => h.id === _optionalChain([currentResult, 'optionalAccess', _192 => _192.id])), [history, currentResult]);
6010
6332
  const goToPrev = _react.useCallback.call(void 0, () => {
6011
6333
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
6012
6334
  }, [currentIndex, history]);
@@ -6017,10 +6339,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6017
6339
  setCurrentResult(g);
6018
6340
  setMobileTab("stage");
6019
6341
  if (g.hasThumb && g.filename && hfToken && !g.fullBase64) {
6020
- _chunkHFX6D53Wjs.hfLoadImageAsBase64.call(void 0, g.id, hfToken, effectiveNamespace, g.filename, void 0, g.mimeType, false).then((b64) => {
6342
+ _chunkVSHSZEGVjs.hfLoadImageAsBase64.call(void 0, g.id, hfToken, effectiveNamespace, g.filename, void 0, g.mimeType, false).then((b64) => {
6021
6343
  if (!b64) return;
6022
6344
  const full = `data:${g.mimeType || "image/jpeg"};base64,${b64}`;
6023
- setCurrentResult((prev) => _optionalChain([prev, 'optionalAccess', _165 => _165.id]) === g.id ? { ...prev, fullBase64: full } : prev);
6345
+ setCurrentResult((prev) => _optionalChain([prev, 'optionalAccess', _193 => _193.id]) === g.id ? { ...prev, fullBase64: full } : prev);
6024
6346
  setGalleryItems((prev) => prev.map((item) => item.id === g.id ? { ...item, fullBase64: full } : item));
6025
6347
  }).catch(() => {
6026
6348
  });
@@ -6036,13 +6358,13 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6036
6358
  }
6037
6359
  }, [hfToken, effectiveNamespace, hfWriteEvent]);
6038
6360
  const currentGroup = _react.useMemo.call(void 0, () => {
6039
- if (!_optionalChain([currentResult, 'optionalAccess', _166 => _166.prompt])) return [];
6361
+ if (!_optionalChain([currentResult, 'optionalAccess', _194 => _194.prompt])) return [];
6040
6362
  const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
6041
6363
  const group = groups.find((gr) => gr.prompt === currentResult.prompt);
6042
6364
  return group ? group.items : [];
6043
- }, [galleryItems, _optionalChain([currentResult, 'optionalAccess', _167 => _167.prompt])]);
6365
+ }, [galleryItems, _optionalChain([currentResult, 'optionalAccess', _195 => _195.prompt])]);
6044
6366
  _react.useEffect.call(void 0, () => {
6045
- if (!_optionalChain([currentResult, 'optionalAccess', _168 => _168.prompt]) || !hfToken || !effectiveNamespace || !hfState) return;
6367
+ if (!_optionalChain([currentResult, 'optionalAccess', _196 => _196.prompt]) || !hfToken || !effectiveNamespace || !hfState) return;
6046
6368
  const siblings = galleryItemsRef.current.filter(
6047
6369
  (g) => g.prompt === currentResult.prompt && !g.base64 && !hfImageNotFoundRef.current.has(g.id)
6048
6370
  );
@@ -6052,7 +6374,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6052
6374
  const meta = hfState.metadata.find((m) => m.id === sib.id);
6053
6375
  if (!meta) continue;
6054
6376
  try {
6055
- const b64 = await _chunkHFX6D53Wjs.hfLoadImageAsBase64.call(void 0, sib.id, hfToken, effectiveNamespace, meta.filename, void 0, meta.mimeType, meta.hasThumb);
6377
+ const b64 = await _chunkVSHSZEGVjs.hfLoadImageAsBase64.call(void 0, sib.id, hfToken, effectiveNamespace, meta.filename, void 0, meta.mimeType, meta.hasThumb);
6056
6378
  if (!b64) {
6057
6379
  hfImageNotFoundRef.current.set(sib.id, Date.now());
6058
6380
  continue;
@@ -6060,12 +6382,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6060
6382
  const prefix = `data:${meta.mimeType || "image/jpeg"};base64,`;
6061
6383
  setGalleryItems((prev) => prev.map((g) => g.id === sib.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
6062
6384
  setHistory((prev) => prev.map((g) => g.id === sib.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
6063
- } catch (e31) {
6385
+ } catch (e32) {
6064
6386
  hfImageNotFoundRef.current.set(sib.id, Date.now());
6065
6387
  }
6066
6388
  }
6067
6389
  })();
6068
- }, [_optionalChain([currentResult, 'optionalAccess', _169 => _169.id]), _optionalChain([currentResult, 'optionalAccess', _170 => _170.prompt])]);
6390
+ }, [_optionalChain([currentResult, 'optionalAccess', _197 => _197.id]), _optionalChain([currentResult, 'optionalAccess', _198 => _198.prompt])]);
6069
6391
  const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
6070
6392
  const runningBadge = activeGenerationsCount > 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6071
6393
  "div",
@@ -6124,7 +6446,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6124
6446
  console.log("[HF] handleGenerateImage \u2014 condition check:", { hfToken: !!hfToken, base64: !!base64, effectiveNamespace });
6125
6447
  if (hfToken && base64 && effectiveNamespace) {
6126
6448
  setImageUploadStatus((m) => new Map(m).set(genId, "uploading"));
6127
- _chunkHFX6D53Wjs.hfUploadImage.call(void 0, base64, genId, hfToken).then(() => setImageUploadStatus((m) => new Map(m).set(genId, "done"))).catch((e) => {
6449
+ _chunkVSHSZEGVjs.hfUploadImage.call(void 0, base64, genId, hfToken).then(() => setImageUploadStatus((m) => new Map(m).set(genId, "done"))).catch((e) => {
6128
6450
  console.error("[HF] hfUploadImage failed:", e);
6129
6451
  setImageUploadStatus((m) => new Map(m).set(genId, "failed"));
6130
6452
  });
@@ -6146,7 +6468,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6146
6468
  const errorGen = { ...newGen, status: "error", error: { message: err.message || "Unbekannter Fehler", details: err.toString() } };
6147
6469
  setHistory((prev) => prev.map((g) => g.id === genId ? errorGen : g));
6148
6470
  setGalleryItems((prev) => prev.filter((g) => g.id !== genId));
6149
- if (!options.silent || _optionalChain([currentResult, 'optionalAccess', _171 => _171.id]) === genId) setCurrentResult(errorGen);
6471
+ if (!options.silent || _optionalChain([currentResult, 'optionalAccess', _199 => _199.id]) === genId) setCurrentResult(errorGen);
6150
6472
  } finally {
6151
6473
  setActiveGenerationsCount((prev) => Math.max(0, prev - 1));
6152
6474
  }
@@ -6181,7 +6503,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6181
6503
  timestamp: Date.now(),
6182
6504
  mimeType: "image/jpeg"
6183
6505
  };
6184
- await _chunkHFX6D53Wjs.hfUploadImage.call(void 0, base64, genId, hfToken);
6506
+ await _chunkVSHSZEGVjs.hfUploadImage.call(void 0, base64, genId, hfToken);
6185
6507
  await hfWriteEvent("image_added", entry);
6186
6508
  return [genId];
6187
6509
  } catch (e) {
@@ -6202,7 +6524,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6202
6524
  setActivePrompt(prompt);
6203
6525
  setFocusedNodeId(nodeId);
6204
6526
  if (autoGenerate) handleGenerateImage(prompt, void 0, nodeId);
6205
- } catch (e32) {
6527
+ } catch (e33) {
6206
6528
  setActivePrompt("Synthese-Fehler");
6207
6529
  } finally {
6208
6530
  setIsSynthesizing(false);
@@ -6275,14 +6597,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6275
6597
  const { prompt, feedback } = parsePromptResponse(raw);
6276
6598
  setActivePrompt(prompt);
6277
6599
  setPromptFeedback(feedback);
6278
- } catch (e33) {
6600
+ } catch (e34) {
6279
6601
  setActivePrompt("Synthese-Fehler");
6280
6602
  } finally {
6281
6603
  setIsPromptTabGenerating(false);
6282
6604
  }
6283
6605
  };
6284
6606
  const handleDownloadSingle = async () => {
6285
- if (!_optionalChain([currentResult, 'optionalAccess', _172 => _172.base64])) return;
6607
+ if (!_optionalChain([currentResult, 'optionalAccess', _200 => _200.base64])) return;
6286
6608
  try {
6287
6609
  const downloadSrc = currentResult.fullBase64 || currentResult.base64;
6288
6610
  const base64Data = downloadSrc.split(",")[1];
@@ -6298,9 +6620,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6298
6620
  const reader = new FileReader();
6299
6621
  reader.onload = (ev) => {
6300
6622
  try {
6301
- const root = JSON.parse(_optionalChain([ev, 'access', _173 => _173.target, 'optionalAccess', _174 => _174.result]));
6623
+ const root = JSON.parse(_optionalChain([ev, 'access', _201 => _201.target, 'optionalAccess', _202 => _202.result]));
6302
6624
  const rawTags = root.tags || root;
6303
- if (!_optionalChain([rawTags, 'optionalAccess', _175 => _175.by_category])) return;
6625
+ if (!_optionalChain([rawTags, 'optionalAccess', _203 => _203.by_category])) return;
6304
6626
  const filtered = {};
6305
6627
  const EXCLUDED2 = ["pdf-export", "book.micro-edit-rules"];
6306
6628
  Object.entries(rawTags.by_category).forEach(([cat, items]) => {
@@ -6317,7 +6639,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6317
6639
  };
6318
6640
  const handleHfInitialSync = async (onProgress) => {
6319
6641
  if (!hfToken || !effectiveNamespace) return;
6320
- const existingIds = new Set((_optionalChain([hfState, 'optionalAccess', _176 => _176.metadata]) || []).map((m) => m.id));
6642
+ const existingIds = new Set((_optionalChain([hfState, 'optionalAccess', _204 => _204.metadata]) || []).map((m) => m.id));
6321
6643
  const gens = galleryItems.filter((g) => g.base64 && g.status === "done" && !existingIds.has(g.id));
6322
6644
  const total = gens.length;
6323
6645
  onProgress(0, total);
@@ -6325,7 +6647,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6325
6647
  for (const gen of gens) {
6326
6648
  const raw = gen.base64.includes(",") ? gen.base64.split(",")[1] : gen.base64;
6327
6649
  const mimeType = gen.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg";
6328
- await _chunkHFX6D53Wjs.hfUploadImage.call(void 0, raw, gen.id, hfToken, mimeType).catch(() => {
6650
+ await _chunkVSHSZEGVjs.hfUploadImage.call(void 0, raw, gen.id, hfToken, mimeType).catch(() => {
6329
6651
  });
6330
6652
  const entry = {
6331
6653
  id: gen.id,
@@ -6343,7 +6665,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6343
6665
  }
6344
6666
  };
6345
6667
  const mergeWorkspaceTags = (local, remote) => {
6346
- if (!_optionalChain([remote, 'optionalAccess', _177 => _177.by_category])) return local;
6668
+ if (!_optionalChain([remote, 'optionalAccess', _205 => _205.by_category])) return local;
6347
6669
  const merged = {};
6348
6670
  const allCategories = /* @__PURE__ */ new Set([...Object.keys(local.by_category), ...Object.keys(remote.by_category)]);
6349
6671
  for (const cat of allCategories) {
@@ -6353,7 +6675,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6353
6675
  const localValues = new Set(localTags.map((t) => t.value));
6354
6676
  const mergedLocal = localTags.map((t) => {
6355
6677
  const remote2 = remoteMap.get(t.value);
6356
- return _optionalChain([remote2, 'optionalAccess', _178 => _178.is_deleted]) ? { ...t, is_deleted: true } : t;
6678
+ return _optionalChain([remote2, 'optionalAccess', _206 => _206.is_deleted]) ? { ...t, is_deleted: true } : t;
6357
6679
  });
6358
6680
  const onlyInRemote = remoteTags.filter((t) => !localValues.has(t.value));
6359
6681
  merged[cat] = [...mergedLocal, ...onlyInRemote];
@@ -6361,7 +6683,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6361
6683
  const all = Object.entries(merged).flatMap(([cat, tags]) => tags.map((t) => ({ ...t, category: cat })));
6362
6684
  return { by_category: merged, all };
6363
6685
  };
6364
- if (isFullscreen && _optionalChain([currentResult, 'optionalAccess', _179 => _179.base64])) {
6686
+ if (isFullscreen && _optionalChain([currentResult, 'optionalAccess', _207 => _207.base64])) {
6365
6687
  const fsRaw = currentResult.fullBase64 || currentResult.base64;
6366
6688
  const fsBase64 = fsRaw.startsWith("data:") ? fsRaw : `data:image/png;base64,${fsRaw}`;
6367
6689
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
@@ -6475,7 +6797,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6475
6797
  setHfNamespaceLocal(ns);
6476
6798
  try {
6477
6799
  localStorage.setItem("aa-hf-namespace", ns);
6478
- } catch (e34) {
6800
+ } catch (e35) {
6479
6801
  }
6480
6802
  },
6481
6803
  className: "px-3 py-1 rounded-lg text-[11px] font-bold transition-colors",
@@ -6511,7 +6833,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6511
6833
  )) }),
6512
6834
  layoutChoice === "mobile-desktop" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
6513
6835
  layoutChoice === "tablet-landscape" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
6514
- ] })
6836
+ ] }),
6837
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FlowBridgePanel, { appVersion: version, hfToken })
6515
6838
  ] });
6516
6839
  }
6517
6840
  if (requireWorkspaceSelection) {
@@ -6556,7 +6879,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6556
6879
  );
6557
6880
  }
6558
6881
  }
6559
- const szenenPane = szenenPort ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flow-szenen-pane", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkHFX6D53Wjs.SzenenView, { port: szenenPort, contextId: szenenKontextId }) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flow-szenen-pane flow-szenen-pane--empty", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { children: [
6882
+ const szenenPane = szenenPort ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flow-szenen-pane", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVSHSZEGVjs.SzenenView, { port: szenenPort, contextId: szenenKontextId }) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flow-szenen-pane flow-szenen-pane--empty", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { children: [
6560
6883
  "Szenen brauchen einen HF-Token f\xFCr Namespace ",
6561
6884
  effectiveNamespace || "(noch nicht bestimmt)",
6562
6885
  " \u2014 auf der Flow-Startseite setzen."
@@ -6575,7 +6898,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6575
6898
  }, children: [
6576
6899
  mobileTab === "labs" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LabsTab, { services: labServices, onResult: (item) => {
6577
6900
  const frame = item.frames[0];
6578
- if (_optionalChain([frame, 'optionalAccess', _180 => _180.base64])) {
6901
+ if (_optionalChain([frame, 'optionalAccess', _208 => _208.base64])) {
6579
6902
  setCurrentResult(frameToGeneration(frame, item));
6580
6903
  setMobileTab("stage");
6581
6904
  }
@@ -6599,7 +6922,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6599
6922
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
6600
6923
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6601
6924
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1" }),
6602
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _181 => _181.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
6925
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _209 => _209.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
6603
6926
  runningBadge,
6604
6927
  activeReferenceThumbnail ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
6605
6928
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
@@ -6650,21 +6973,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6650
6973
  setTouchStartX(null);
6651
6974
  },
6652
6975
  children: [
6653
- _optionalChain([currentResult, 'optionalAccess', _182 => _182.status]) === "processing" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
6976
+ _optionalChain([currentResult, 'optionalAccess', _210 => _210.status]) === "processing" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
6654
6977
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
6655
6978
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[11px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6656
6979
  ] }),
6657
- _optionalChain([currentResult, 'optionalAccess', _183 => _183.status]) === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
6980
+ _optionalChain([currentResult, 'optionalAccess', _211 => _211.status]) === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
6658
6981
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
6659
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-white/50 text-[13px]", children: _optionalChain([currentResult, 'access', _184 => _184.error, 'optionalAccess', _185 => _185.message]) }),
6982
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-white/50 text-[13px]", children: _optionalChain([currentResult, 'access', _212 => _212.error, 'optionalAccess', _213 => _213.message]) }),
6660
6983
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: () => handleGenerateImage(currentResult.prompt), className: "px-4 py-2 rounded-lg border border-white/20 text-[13px] text-white/70 active:bg-white/10", children: "Erneut versuchen" })
6661
6984
  ] }),
6662
- _optionalChain([currentResult, 'optionalAccess', _186 => _186.status]) === "done" && currentResult.base64 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
6985
+ _optionalChain([currentResult, 'optionalAccess', _214 => _214.status]) === "done" && currentResult.base64 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
6663
6986
  !currentResult && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6664
6987
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
6665
6988
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6666
6989
  ] }),
6667
- _optionalChain([currentResult, 'optionalAccess', _187 => _187.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: openFullscreen, className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center rounded-full bg-black/60 border border-white/10 z-10", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
6990
+ _optionalChain([currentResult, 'optionalAccess', _215 => _215.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: openFullscreen, className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center rounded-full bg-black/60 border border-white/10 z-10", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
6668
6991
  history.length > 1 && currentResult && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
6669
6992
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: goToPrev, disabled: currentIndex <= 0, className: "absolute left-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
6670
6993
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, className: "absolute right-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
@@ -6677,7 +7000,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6677
7000
  ]
6678
7001
  }
6679
7002
  ),
6680
- _optionalChain([currentResult, 'optionalAccess', _188 => _188.status]) === "done" && currentGroup.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { position: "relative", flexShrink: 0 }, children: [
7003
+ _optionalChain([currentResult, 'optionalAccess', _216 => _216.status]) === "done" && currentGroup.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { position: "relative", flexShrink: 0 }, children: [
6681
7004
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6682
7005
  "div",
6683
7006
  {
@@ -6720,7 +7043,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6720
7043
  }
6721
7044
  )
6722
7045
  ] }, item.id)) }),
6723
- _optionalChain([currentResult, 'optionalAccess', _189 => _189.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2 mt-3", children: [
7046
+ _optionalChain([currentResult, 'optionalAccess', _217 => _217.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2 mt-3", children: [
6724
7047
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { onClick: () => setActivePrompt(currentResult.prompt || ""), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl border border-white/10 bg-white/5 active:bg-white/10 transition-colors", style: { height: 44 }, children: [
6725
7048
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
6726
7049
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[12px] text-white/60", children: "Prompt" })
@@ -6742,14 +7065,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6742
7065
  hfToken && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-12 flex items-center justify-center text-white/20 active:text-white transition-colors disabled:opacity-30", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
6743
7066
  ] }),
6744
7067
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 overflow-hidden relative", children: [
6745
- activeTab === "history" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _190 => _190.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
7068
+ activeTab === "history" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _218 => _218.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
6746
7069
  activeTab === "gallery" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6747
7070
  MediaLibrary,
6748
7071
  {
6749
7072
  items: galleryItems,
6750
7073
  onImport: async () => {
6751
7074
  const media = await onSelectMedia();
6752
- if (!_optionalChain([media, 'optionalAccess', _191 => _191.length])) return;
7075
+ if (!_optionalChain([media, 'optionalAccess', _219 => _219.length])) return;
6753
7076
  setGalleryItems((prev) => [...media.map((m) => ({ id: crypto.randomUUID(), nodeId: "1", base64: `data:${m.mimeType};base64,${m.base64}`, mediaId: m.mediaId, prompt: m.name || "Importiert", timestamp: Date.now(), status: "done", tags: [], type: "import" })), ...prev]);
6754
7077
  },
6755
7078
  onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
@@ -6897,7 +7220,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6897
7220
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
6898
7221
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6899
7222
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { flex: 1 } }),
6900
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _192 => _192.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7223
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _220 => _220.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
6901
7224
  runningBadge,
6902
7225
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: toggleContrast, style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
6903
7226
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: () => setShowStart(true), style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
@@ -6926,7 +7249,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6926
7249
  ]
6927
7250
  }
6928
7251
  ) }),
6929
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _193 => _193.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }) })
7252
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _221 => _221.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }) })
6930
7253
  ] }),
6931
7254
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
6932
7255
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -6942,21 +7265,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6942
7265
  setTouchStartX(null);
6943
7266
  },
6944
7267
  children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { height: "100%", width: "100%", borderRadius: 20, border: "1px solid rgba(255,255,255,0.05)", background: "rgba(0,0,0,0.4)", position: "relative", overflow: "hidden", display: "flex", alignItems: "center", justifyContent: "center" }, children: [
6945
- _optionalChain([currentResult, 'optionalAccess', _194 => _194.status]) === "processing" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
7268
+ _optionalChain([currentResult, 'optionalAccess', _222 => _222.status]) === "processing" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
6946
7269
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 36 }, children: "hourglass_top" }),
6947
7270
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 10, color: "rgba(255,255,255,0.6)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
6948
7271
  ] }),
6949
- _optionalChain([currentResult, 'optionalAccess', _195 => _195.status]) === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
7272
+ _optionalChain([currentResult, 'optionalAccess', _223 => _223.status]) === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
6950
7273
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
6951
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: _optionalChain([currentResult, 'access', _196 => _196.error, 'optionalAccess', _197 => _197.message]) }),
7274
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: _optionalChain([currentResult, 'access', _224 => _224.error, 'optionalAccess', _225 => _225.message]) }),
6952
7275
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: () => handleGenerateImage(currentResult.prompt), style: { padding: "8px 16px", borderRadius: 8, border: "1px solid rgba(255,255,255,0.2)", fontSize: 11, color: "rgba(255,255,255,0.7)", background: "none", cursor: "pointer", fontFamily: "inherit" }, children: "Erneut versuchen" })
6953
7276
  ] }),
6954
- _optionalChain([currentResult, 'optionalAccess', _198 => _198.status]) === "done" && currentResult.base64 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
7277
+ _optionalChain([currentResult, 'optionalAccess', _226 => _226.status]) === "done" && currentResult.base64 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
6955
7278
  !currentResult && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
6956
7279
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
6957
7280
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
6958
7281
  ] }),
6959
- _optionalChain([currentResult, 'optionalAccess', _199 => _199.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: openFullscreen, style: { position: "absolute", top: 8, right: 8, width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
7282
+ _optionalChain([currentResult, 'optionalAccess', _227 => _227.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: openFullscreen, style: { position: "absolute", top: 8, right: 8, width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
6960
7283
  history.length > 1 && currentResult && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
6961
7284
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: goToPrev, disabled: currentIndex <= 0, style: { position: "absolute", left: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex <= 0 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
6962
7285
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, style: { position: "absolute", right: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex >= history.length - 1 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
@@ -6969,7 +7292,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6969
7292
  ] })
6970
7293
  }
6971
7294
  ),
6972
- _optionalChain([currentResult, 'optionalAccess', _200 => _200.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
7295
+ _optionalChain([currentResult, 'optionalAccess', _228 => _228.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
6973
7296
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { onClick: () => setActivePrompt(currentResult.prompt || ""), style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "1px solid rgba(255,255,255,0.1)", background: "rgba(255,255,255,0.05)", color: "rgba(255,255,255,0.6)", fontSize: 11, cursor: "pointer", fontFamily: "inherit" }, children: [
6974
7297
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
6975
7298
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Prompt" })
@@ -7091,7 +7414,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7091
7414
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Ref" })
7092
7415
  ] }),
7093
7416
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
7094
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _201 => _201.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7417
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _229 => _229.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7095
7418
  runningBadge,
7096
7419
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PillButton, { variant: "solid", icon: "bolt", disabled: !activePrompt.trim(), onClick: () => handleGenerateBatch(), children: "Generieren" })
7097
7420
  ] })
@@ -7103,7 +7426,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7103
7426
  ] }) }),
7104
7427
  middlePanel === "szenen" ? szenenPane : middlePanel === "labs" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LabsTab, { services: labServices, onResult: (item) => {
7105
7428
  const frame = item.frames[0];
7106
- if (_optionalChain([frame, 'optionalAccess', _202 => _202.base64])) setCurrentResult(frameToGeneration(frame, item));
7429
+ if (_optionalChain([frame, 'optionalAccess', _230 => _230.base64])) setCurrentResult(frameToGeneration(frame, item));
7107
7430
  } }) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 overflow-hidden flex flex-col", children: [
7108
7431
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full w-full max-w-4xl aspect-square rounded-3xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center group shadow-2xl", children: currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-4 opacity-40", children: [
7109
7432
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
@@ -7112,7 +7435,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7112
7435
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
7113
7436
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
7114
7437
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
7115
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-white/60 text-[12px] leading-relaxed", children: _optionalChain([currentResult, 'access', _203 => _203.error, 'optionalAccess', _204 => _204.message]) })
7438
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-white/60 text-[12px] leading-relaxed", children: _optionalChain([currentResult, 'access', _231 => _231.error, 'optionalAccess', _232 => _232.message]) })
7116
7439
  ] }),
7117
7440
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
7118
7441
  ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "h-full w-full relative flex items-center justify-center", children: [
@@ -7126,7 +7449,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7126
7449
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
7127
7450
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
7128
7451
  ] }) }) }),
7129
- _optionalChain([currentResult, 'optionalAccess', _205 => _205.status]) === "done" && currentGroup.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { position: "relative", flexShrink: 0 }, children: [
7452
+ _optionalChain([currentResult, 'optionalAccess', _233 => _233.status]) === "done" && currentGroup.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { position: "relative", flexShrink: 0 }, children: [
7130
7453
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7131
7454
  "div",
7132
7455
  {
@@ -7207,14 +7530,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7207
7530
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
7208
7531
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
7209
7532
  ] }) }),
7210
- activeTab === "history" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _206 => _206.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
7533
+ activeTab === "history" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _234 => _234.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
7211
7534
  activeTab === "gallery" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7212
7535
  MediaLibrary,
7213
7536
  {
7214
7537
  items: galleryItems,
7215
7538
  onImport: async () => {
7216
7539
  const media = await onSelectMedia();
7217
- if (!_optionalChain([media, 'optionalAccess', _207 => _207.length])) return;
7540
+ if (!_optionalChain([media, 'optionalAccess', _235 => _235.length])) return;
7218
7541
  setGalleryItems((prev) => [...media.map((m) => ({ id: crypto.randomUUID(), nodeId: "1", base64: `data:${m.mimeType};base64,${m.base64}`, mediaId: m.mediaId, prompt: m.name || "Importiert", timestamp: Date.now(), status: "done", tags: [], type: "import" })), ...prev]);
7219
7542
  },
7220
7543
  onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
@@ -7265,7 +7588,7 @@ function FaApp({
7265
7588
  });
7266
7589
  }, [serverBaseUrl]);
7267
7590
  const wrappedPrompt = _react.useMemo.call(void 0,
7268
- () => _chunkHFX6D53Wjs.alsFlowTextZugang.call(void 0, onGeneratePrompt),
7591
+ () => _chunkVSHSZEGVjs.alsFlowTextZugang.call(void 0, onGeneratePrompt),
7269
7592
  [onGeneratePrompt]
7270
7593
  );
7271
7594
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -7370,7 +7693,7 @@ function createFaStore({ contracts, descriptors, persistence, workspaceId }) {
7370
7693
  };
7371
7694
  };
7372
7695
  const applyWriteResult = (sliceId, result, savedData, signal) => {
7373
- if (_optionalChain([signal, 'optionalAccess', _208 => _208.aborted])) {
7696
+ if (_optionalChain([signal, 'optionalAccess', _236 => _236.aborted])) {
7374
7697
  patchMeta(sliceId, { saveState: "idle" });
7375
7698
  return result;
7376
7699
  }
@@ -7398,8 +7721,8 @@ function createFaStore({ contracts, descriptors, persistence, workspaceId }) {
7398
7721
  const requestId = _nullishCoalesce(externalRequestId, () => ( nextRequestId()));
7399
7722
  patchMeta(sliceId, { loadRequestId: requestId, saveState: "restoring" });
7400
7723
  const result = await persistence.load(workspaceId, descriptor, _nullishCoalesce(signal, () => ( new AbortController().signal)));
7401
- if (_optionalChain([signal, 'optionalAccess', _209 => _209.aborted]) || _optionalChain([get, 'call', _210 => _210(), 'access', _211 => _211.meta, 'access', _212 => _212[sliceId], 'optionalAccess', _213 => _213.loadRequestId]) !== requestId) {
7402
- if (_optionalChain([signal, 'optionalAccess', _214 => _214.aborted]) && _optionalChain([get, 'call', _215 => _215(), 'access', _216 => _216.meta, 'access', _217 => _217[sliceId], 'optionalAccess', _218 => _218.loadRequestId]) === requestId) {
7724
+ if (_optionalChain([signal, 'optionalAccess', _237 => _237.aborted]) || _optionalChain([get, 'call', _238 => _238(), 'access', _239 => _239.meta, 'access', _240 => _240[sliceId], 'optionalAccess', _241 => _241.loadRequestId]) !== requestId) {
7725
+ if (_optionalChain([signal, 'optionalAccess', _242 => _242.aborted]) && _optionalChain([get, 'call', _243 => _243(), 'access', _244 => _244.meta, 'access', _245 => _245[sliceId], 'optionalAccess', _246 => _246.loadRequestId]) === requestId) {
7403
7726
  patchMeta(sliceId, { saveState: "idle", loadRequestId: null });
7404
7727
  }
7405
7728
  return result;
@@ -7434,7 +7757,7 @@ function createFaStore({ contracts, descriptors, persistence, workspaceId }) {
7434
7757
  },
7435
7758
  async resetSlice(sliceId, signal, options) {
7436
7759
  const contract = requireContract(sliceId);
7437
- if (get().meta[sliceId].dirty && !_optionalChain([options, 'optionalAccess', _219 => _219.confirmed])) {
7760
+ if (get().meta[sliceId].dirty && !_optionalChain([options, 'optionalAccess', _247 => _247.confirmed])) {
7438
7761
  throw new Error(`Reset for slice ${sliceId} requires confirmation while unsaved changes exist`);
7439
7762
  }
7440
7763
  const defaultData = contract.createDefault();
@@ -7487,7 +7810,7 @@ function createInMemoryWorkspacePersistence(now = () => Date.now()) {
7487
7810
  }
7488
7811
  const saved = {
7489
7812
  ...clone(slice),
7490
- revision: (_nullishCoalesce(_optionalChain([current, 'optionalAccess', _220 => _220.revision]), () => ( 0))) + 1,
7813
+ revision: (_nullishCoalesce(_optionalChain([current, 'optionalAccess', _248 => _248.revision]), () => ( 0))) + 1,
7491
7814
  updatedAt: now(),
7492
7815
  ...resetAt !== void 0 ? { resetAt } : {}
7493
7816
  };
@@ -7568,7 +7891,7 @@ function createPersistenceCoordinator({
7568
7891
  if (disposed) return;
7569
7892
  const runtime = runtimeOf(sliceId);
7570
7893
  const meta = store.getState().meta[sliceId];
7571
- if (!_optionalChain([meta, 'optionalAccess', _221 => _221.dirty])) return;
7894
+ if (!_optionalChain([meta, 'optionalAccess', _249 => _249.dirty])) return;
7572
7895
  if (meta.saveState === "restoring" || meta.saveState === "saving") {
7573
7896
  runtime.pendingSave = true;
7574
7897
  return;
@@ -7596,7 +7919,7 @@ function createPersistenceCoordinator({
7596
7919
  return {
7597
7920
  async load(sliceId) {
7598
7921
  const runtime = runtimeOf(sliceId);
7599
- _optionalChain([runtime, 'access', _222 => _222.loadController, 'optionalAccess', _223 => _223.abort, 'call', _224 => _224()]);
7922
+ _optionalChain([runtime, 'access', _250 => _250.loadController, 'optionalAccess', _251 => _251.abort, 'call', _252 => _252()]);
7600
7923
  runtime.loadController = new AbortController();
7601
7924
  const controller = runtime.loadController;
7602
7925
  try {
@@ -7624,8 +7947,8 @@ function createPersistenceCoordinator({
7624
7947
  disposed = true;
7625
7948
  for (const runtime of runtimes.values()) {
7626
7949
  clearTimer(runtime);
7627
- _optionalChain([runtime, 'access', _225 => _225.loadController, 'optionalAccess', _226 => _226.abort, 'call', _227 => _227()]);
7628
- _optionalChain([runtime, 'access', _228 => _228.saveController, 'optionalAccess', _229 => _229.abort, 'call', _230 => _230()]);
7950
+ _optionalChain([runtime, 'access', _253 => _253.loadController, 'optionalAccess', _254 => _254.abort, 'call', _255 => _255()]);
7951
+ _optionalChain([runtime, 'access', _256 => _256.saveController, 'optionalAccess', _257 => _257.abort, 'call', _258 => _258()]);
7629
7952
  runtime.pendingSave = false;
7630
7953
  }
7631
7954
  runtimes.clear();
@@ -7729,7 +8052,7 @@ function parseLegacyLibraryFilters(source, knownTagIds) {
7729
8052
  return null;
7730
8053
  }).filter((id) => id !== null && knownTagIds.has(id));
7731
8054
  }
7732
- } catch (e35) {
8055
+ } catch (e36) {
7733
8056
  tagIds = [];
7734
8057
  }
7735
8058
  }
@@ -7740,7 +8063,7 @@ function parseLegacyLibraryFilters(source, knownTagIds) {
7740
8063
  if (Array.isArray(parsed)) {
7741
8064
  recentFilterTagIds = parsed.filter((entry) => typeof entry === "string" || typeof entry === "number").map((entry) => String(entry)).filter((id) => knownTagIds.has(id)).slice(0, 5);
7742
8065
  }
7743
- } catch (e36) {
8066
+ } catch (e37) {
7744
8067
  recentFilterTagIds = [];
7745
8068
  }
7746
8069
  }
@@ -7779,9 +8102,9 @@ function hatNavigationsziele(zugehoerigkeit) {
7779
8102
  var kennung = (wert) => typeof wert === "string" && wert.trim().length > 0;
7780
8103
  var kurz = (id) => id.slice(0, 8);
7781
8104
  function zugehoerigkeitOf(item) {
7782
- const runId = _optionalChain([item, 'optionalAccess', _231 => _231.szenen, 'optionalAccess', _232 => _232.prompt_run_id]);
8105
+ const runId = _optionalChain([item, 'optionalAccess', _259 => _259.szenen, 'optionalAccess', _260 => _260.prompt_run_id]);
7783
8106
  if (!kennung(runId)) return null;
7784
- const links = _nullishCoalesce(_optionalChain([item, 'optionalAccess', _233 => _233.szenen_links]), () => ( null));
8107
+ const links = _nullishCoalesce(_optionalChain([item, 'optionalAccess', _261 => _261.szenen_links]), () => ( null));
7785
8108
  if (!links || links.prompt_run_id !== runId) {
7786
8109
  return {
7787
8110
  run: null,
@@ -7812,15 +8135,15 @@ function zugehoerigkeitOf(item) {
7812
8135
  return { run, scene, hinweis: null };
7813
8136
  }
7814
8137
  function zugehoerigkeitenOf(item) {
7815
- const szenen = _optionalChain([item, 'optionalAccess', _234 => _234.szenen]);
8138
+ const szenen = _optionalChain([item, 'optionalAccess', _262 => _262.szenen]);
7816
8139
  if (!szenen) return [];
7817
8140
  const laeufe = [];
7818
8141
  const merken = (id) => {
7819
8142
  if (kennung(id) && !laeufe.includes(id)) laeufe.push(id);
7820
8143
  };
7821
8144
  merken(szenen.prompt_run_id);
7822
- for (const run of _nullishCoalesce(szenen.runs, () => ( []))) merken(_optionalChain([run, 'optionalAccess', _235 => _235.prompt_run_id]));
7823
- const linkFuer = (runId) => _nullishCoalesce((_nullishCoalesce(_optionalChain([item, 'optionalAccess', _236 => _236.szenen_run_links]), () => ( []))).find((l) => l.prompt_run_id === runId), () => ( (_optionalChain([item, 'optionalAccess', _237 => _237.szenen_links]) && item.szenen_links.prompt_run_id === runId ? item.szenen_links : null)));
8145
+ for (const run of _nullishCoalesce(szenen.runs, () => ( []))) merken(_optionalChain([run, 'optionalAccess', _263 => _263.prompt_run_id]));
8146
+ const linkFuer = (runId) => _nullishCoalesce((_nullishCoalesce(_optionalChain([item, 'optionalAccess', _264 => _264.szenen_run_links]), () => ( []))).find((l) => l.prompt_run_id === runId), () => ( (_optionalChain([item, 'optionalAccess', _265 => _265.szenen_links]) && item.szenen_links.prompt_run_id === runId ? item.szenen_links : null)));
7824
8147
  const ergebnis = [];
7825
8148
  for (const runId of laeufe) {
7826
8149
  const z = zugehoerigkeitOf({ szenen: { prompt_run_id: runId }, szenen_links: linkFuer(runId) });
@@ -7966,7 +8289,7 @@ function parseLegacyRecentTags(raw) {
7966
8289
  }
7967
8290
  return null;
7968
8291
  }).filter((entry) => entry !== null).slice(0, 10);
7969
- } catch (e37) {
8292
+ } catch (e38) {
7970
8293
  return [];
7971
8294
  }
7972
8295
  }
@@ -8093,4 +8416,10 @@ async function runTagsLegacyImport(options) {
8093
8416
 
8094
8417
 
8095
8418
 
8096
- exports.AvatarArchitectApp = AvatarArchitectApp; exports.CURRENT_TAG_EVENT_VERSION = CURRENT_TAG_EVENT_VERSION; exports.CollapsibleCard = CollapsibleCard; exports.CompactDropdown = CompactDropdown; exports.FaApp = FaApp; exports.FaToolsBadge = FaToolsBadge; exports.FlowWorkspacePicker = FlowWorkspacePicker; exports.GLOBAL_STYLES = GLOBAL_STYLES; exports.HfMediaSyncTab = HfMediaSyncTab; exports.HistoryPanel = HistoryPanel; exports.InspectPanel = InspectPanel; exports.LIBRARY_CUTOVER_MARKER = LIBRARY_CUTOVER_MARKER; exports.LIBRARY_SLICE_SCHEMA_VERSION = LIBRARY_SLICE_SCHEMA_VERSION; exports.LIB_VERSION = version; exports.LabBlend = LabBlend; exports.LabCompare = LabCompare; exports.LabFrameExtractor = LabFrameExtractor; exports.LabImagePicker = LabImagePicker; exports.LabLoop = LabLoop; exports.LabRemix = LabRemix; exports.LabsTab = LabsTab; exports.LibraryView = LibraryView; exports.ListView = ListView; exports.MediaLibrary = MediaLibrary; exports.PillButton = PillButton; exports.PromptTab = PromptTab; exports.SCOPE_MAP = SCOPE_MAP; exports.SectionLabel = SectionLabel; exports.ServerTab = ServerTab; exports.SetupPanel = SetupPanel; exports.TAGS_CUTOVER_MARKER = TAGS_CUTOVER_MARKER; exports.TAGS_SLICE_SCHEMA_VERSION = TAGS_SLICE_SCHEMA_VERSION; exports.TagBaseSection = TagBaseSection; exports.TagManager = TagManager; exports.TagManagerPanel = TagManagerPanel; exports.ZugehoerigkeitLinks = ZugehoerigkeitLinks; exports.autoLabel = autoLabel; exports.buildBlendInstruction = buildBlendInstruction; exports.buildCompareInstruction = buildCompareInstruction; exports.buildFallbackPrompt = buildFallbackPrompt; exports.buildGenerationPrompt = buildGenerationPrompt; exports.buildImageGenerationOptions = buildImageGenerationOptions; exports.buildLoopInstruction = buildLoopInstruction; exports.buildPromptTabPayload = buildPromptTabPayload; exports.buildReferenceImageMediaIds = buildReferenceImageMediaIds; exports.buildRemixInstruction = buildRemixInstruction; exports.buildScanInstruction = buildScanInstruction; exports.cleanAiResponse = cleanAiResponse; exports.createFaStore = createFaStore; exports.createFlowServices = createFlowServices; exports.createInMemoryLibraryDataSource = createInMemoryLibraryDataSource; exports.createInMemoryWorkspacePersistence = createInMemoryWorkspacePersistence; exports.createLibraryDefault = createLibraryDefault; exports.createPersistenceCoordinator = createPersistenceCoordinator; exports.createTagCreatedEvent = createTagCreatedEvent; exports.createTagUpdatedEvent = createTagUpdatedEvent; exports.createTagsDefault = createTagsDefault; exports.deriveTagBaseWorkspaceTags = deriveTagBaseWorkspaceTags; exports.deriveTagViewModel = deriveTagViewModel; exports.formatTreeToMarkdown = formatTreeToMarkdown; exports.frameToGeneration = frameToGeneration; exports.getFormattedTimestamp = getFormattedTimestamp; exports.getHFToken = _chunkHFX6D53Wjs.getHFToken; exports.getSessionClientId = _chunkHFX6D53Wjs.getSessionClientId; exports.groupGenerationsToLabItems = groupGenerationsToLabItems; exports.hatNavigationsziele = hatNavigationsziele; exports.hfBatchArchive = _chunkHFX6D53Wjs.hfBatchArchive; exports.hfBootstrapFromLegacy = _chunkHFX6D53Wjs.hfBootstrapFromLegacy; exports.hfListDir = _chunkHFX6D53Wjs.hfListDir; exports.hfLoadImageAsBase64 = _chunkHFX6D53Wjs.hfLoadImageAsBase64; exports.hfUploadImage = _chunkHFX6D53Wjs.hfUploadImage; exports.hfUploadSmallFile = _chunkHFX6D53Wjs.hfUploadSmallFile; exports.injectXMPMetadata = injectXMPMetadata; exports.interpretSdkError = interpretSdkError; exports.libraryContract = libraryContract; exports.libraryReactDescriptor = libraryReactDescriptor; exports.listCategories = listCategories; exports.loadHFState = _chunkHFX6D53Wjs.loadHFState; exports.loadPendingEvents = _chunkHFX6D53Wjs.loadPendingEvents; exports.loadTagBase = loadTagBase; exports.parseLegacyLibraryFilters = parseLegacyLibraryFilters; exports.parseLegacyRecentTags = parseLegacyRecentTags; exports.parsePromptFile = parsePromptFile; exports.parsePromptResponse = parsePromptResponse; exports.runLegacyMigration = runLegacyMigration; exports.runLibraryLegacyImport = runLibraryLegacyImport; exports.runTagsLegacyImport = runTagsLegacyImport; exports.setHFToken = _chunkHFX6D53Wjs.setHFToken; exports.tagsContract = tagsContract; exports.tagsReactDescriptor = tagsReactDescriptor; exports.tsFromEventPath = _chunkHFX6D53Wjs.tsFromEventPath; exports.useFaSlice = useFaSlice; exports.useFaSliceMeta = useFaSliceMeta; exports.useHFState = useHFState; exports.useKeyboardNavigation = useKeyboardNavigation; exports.useOnClickOutside = useOnClickOutside; exports.useTagBase = useTagBase; exports.validateTagBaseSelection = validateTagBaseSelection; exports.writeHFEvent = _chunkHFX6D53Wjs.writeHFEvent; exports.writeTagEvent = writeTagEvent; exports.zugehoerigkeitOf = zugehoerigkeitOf; exports.zugehoerigkeitenOf = zugehoerigkeitenOf;
8419
+
8420
+
8421
+
8422
+
8423
+
8424
+
8425
+ exports.AvatarArchitectApp = AvatarArchitectApp; exports.CURRENT_TAG_EVENT_VERSION = CURRENT_TAG_EVENT_VERSION; exports.CollapsibleCard = CollapsibleCard; exports.CompactDropdown = CompactDropdown; exports.FLOW_PROBE_MARKER = FLOW_PROBE_MARKER; exports.FLOW_PROBE_REQUEST = FLOW_PROBE_REQUEST; exports.FaApp = FaApp; exports.FaToolsBadge = FaToolsBadge; exports.FlowBridgePanel = FlowBridgePanel; exports.FlowWorkspacePicker = FlowWorkspacePicker; exports.GLOBAL_STYLES = GLOBAL_STYLES; exports.HfMediaSyncTab = HfMediaSyncTab; exports.HistoryPanel = HistoryPanel; exports.InspectPanel = InspectPanel; exports.LIBRARY_CUTOVER_MARKER = LIBRARY_CUTOVER_MARKER; exports.LIBRARY_SLICE_SCHEMA_VERSION = LIBRARY_SLICE_SCHEMA_VERSION; exports.LIB_VERSION = version; exports.LabBlend = LabBlend; exports.LabCompare = LabCompare; exports.LabFrameExtractor = LabFrameExtractor; exports.LabImagePicker = LabImagePicker; exports.LabLoop = LabLoop; exports.LabRemix = LabRemix; exports.LabsTab = LabsTab; exports.LibraryView = LibraryView; exports.ListView = ListView; exports.MediaLibrary = MediaLibrary; exports.PillButton = PillButton; exports.PromptTab = PromptTab; exports.SCOPE_MAP = SCOPE_MAP; exports.SectionLabel = SectionLabel; exports.ServerTab = ServerTab; exports.SetupPanel = SetupPanel; exports.TAGS_CUTOVER_MARKER = TAGS_CUTOVER_MARKER; exports.TAGS_SLICE_SCHEMA_VERSION = TAGS_SLICE_SCHEMA_VERSION; exports.TagBaseSection = TagBaseSection; exports.TagManager = TagManager; exports.TagManagerPanel = TagManagerPanel; exports.ZugehoerigkeitLinks = ZugehoerigkeitLinks; exports.autoLabel = autoLabel; exports.buildBlendInstruction = buildBlendInstruction; exports.buildCompareInstruction = buildCompareInstruction; exports.buildFallbackPrompt = buildFallbackPrompt; exports.buildGenerationPrompt = buildGenerationPrompt; exports.buildImageGenerationOptions = buildImageGenerationOptions; exports.buildLoopInstruction = buildLoopInstruction; exports.buildPromptTabPayload = buildPromptTabPayload; exports.buildReferenceImageMediaIds = buildReferenceImageMediaIds; exports.buildRemixInstruction = buildRemixInstruction; exports.buildScanInstruction = buildScanInstruction; exports.cleanAiResponse = cleanAiResponse; exports.createFaStore = createFaStore; exports.createFlowBridgeClient = createFlowBridgeClient; exports.createFlowServices = createFlowServices; exports.createInMemoryLibraryDataSource = createInMemoryLibraryDataSource; exports.createInMemoryWorkspacePersistence = createInMemoryWorkspacePersistence; exports.createLibraryDefault = createLibraryDefault; exports.createPersistenceCoordinator = createPersistenceCoordinator; exports.createTagCreatedEvent = createTagCreatedEvent; exports.createTagUpdatedEvent = createTagUpdatedEvent; exports.createTagsDefault = createTagsDefault; exports.deriveTagBaseWorkspaceTags = deriveTagBaseWorkspaceTags; exports.deriveTagViewModel = deriveTagViewModel; exports.executeFlowProbeBundle = executeFlowProbeBundle; exports.formatTreeToMarkdown = formatTreeToMarkdown; exports.frameToGeneration = frameToGeneration; exports.getFormattedTimestamp = getFormattedTimestamp; exports.getHFToken = _chunkVSHSZEGVjs.getHFToken; exports.getSessionClientId = _chunkVSHSZEGVjs.getSessionClientId; exports.groupGenerationsToLabItems = groupGenerationsToLabItems; exports.hatNavigationsziele = hatNavigationsziele; exports.hfBatchArchive = _chunkVSHSZEGVjs.hfBatchArchive; exports.hfBootstrapFromLegacy = _chunkVSHSZEGVjs.hfBootstrapFromLegacy; exports.hfListDir = _chunkVSHSZEGVjs.hfListDir; exports.hfLoadImageAsBase64 = _chunkVSHSZEGVjs.hfLoadImageAsBase64; exports.hfUploadImage = _chunkVSHSZEGVjs.hfUploadImage; exports.hfUploadSmallFile = _chunkVSHSZEGVjs.hfUploadSmallFile; exports.injectXMPMetadata = injectXMPMetadata; exports.interpretSdkError = interpretSdkError; exports.libraryContract = libraryContract; exports.libraryReactDescriptor = libraryReactDescriptor; exports.listCategories = listCategories; exports.loadHFState = _chunkVSHSZEGVjs.loadHFState; exports.loadPendingEvents = _chunkVSHSZEGVjs.loadPendingEvents; exports.loadTagBase = loadTagBase; exports.parseLegacyLibraryFilters = parseLegacyLibraryFilters; exports.parseLegacyRecentTags = parseLegacyRecentTags; exports.parsePromptFile = parsePromptFile; exports.parsePromptResponse = parsePromptResponse; exports.readFlowProbeBundle = readFlowProbeBundle; exports.runLegacyMigration = runLegacyMigration; exports.runLibraryLegacyImport = runLibraryLegacyImport; exports.runTagsLegacyImport = runTagsLegacyImport; exports.setHFToken = _chunkVSHSZEGVjs.setHFToken; exports.tagsContract = tagsContract; exports.tagsReactDescriptor = tagsReactDescriptor; exports.tsFromEventPath = _chunkVSHSZEGVjs.tsFromEventPath; exports.useFaSlice = useFaSlice; exports.useFaSliceMeta = useFaSliceMeta; exports.useHFState = useHFState; exports.useKeyboardNavigation = useKeyboardNavigation; exports.useOnClickOutside = useOnClickOutside; exports.useTagBase = useTagBase; exports.validateTagBaseSelection = validateTagBaseSelection; exports.writeHFEvent = _chunkVSHSZEGVjs.writeHFEvent; exports.writeTagEvent = writeTagEvent; exports.zugehoerigkeitOf = zugehoerigkeitOf; exports.zugehoerigkeitenOf = zugehoerigkeitenOf;