/* Gemeinsame Positionsverwaltung — Stile der KINDKOMPONENTEN des FnPositionsPanel.
   ------------------------------------------------------------------------------------------------
   WARUM GLOBAL UND NICHT SCOPED:
   Blazor-CSS-Isolation endet an der Komponentengrenze. Nach der S0-Zerlegung liegt das Markup fuer
   Tabelle, Reiter, Takt-Zeile, Erklaerband und Dialoge in eigenen Komponenten — die Regeln standen
   aber weiter in FnPositionsPanel.razor.css und griffen dort auf nichts mehr. Ergebnis im Browser:
   Frische-Ampel, Schutz-Lebenszyklus, Mono-Zahlen, Gefahrenzone und alle Dialoginhalte ungestylt.
   Dieselbe Loesung wie bei fn-chart.css / fn-list.css: eine geteilte, globale Datei.

   WARUM ALLES AN .fps HAENGT:
   Klassen wie .stk, .fresh, .due, .up, .down, .dir, .lc, .venue oder .stamp sind generisch. Global
   und ungebunden wuerden sie in JEDES Modul hineinwirken — genau die Praefixkollision, die den
   Umbau am 29.07.2026 schon einmal gekostet hat. Alle Kindkomponenten rendern innerhalb des
   Wurzelcontainers .fps, deshalb ist .fps der Anker. Ausnahme: .fps-dlg* und .fps-danger (Dialoge
   haengen in der FnFloatingWindow-Huelle ausserhalb von .fps) — die tragen bereits das eindeutige
   fps-Praefix.

   TOKEN-ONLY: ausschliesslich var(--fn-*), kein Hex, kein rgb (design.md / FinNavigator-DesignTokens).
   ------------------------------------------------------------------------------------------------ */

/* --- Tabelle (fn-list-Optik; positions-spezifische Zellen) ------------------------------------- */
/* Die Tabelle scrollt IN ihrer Huelle, statt die Seite aufzudruecken (AI-Trading-Muster). */
.fps .tblwrap { overflow-x: auto; max-width: 100%; min-width: 0; }

.fps .fps-instr { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fps .dir { font-size: 11px; font-weight: 700; letter-spacing: .3px; }
.fps .dir.long { color: var(--fn-success); }
.fps .dir.short { color: var(--fn-danger); }

.fps .stk { display: flex; flex-direction: column; gap: 1px; }
.fps .stk small { color: var(--fn-text-secondary); font-size: 11px; font-family: var(--fn-font-mono); }
.fps .stk b { color: var(--fn-text); font-family: var(--fn-font-mono); }
.fps td.num .stk { align-items: flex-end; }

/* Frische-Ampel: gruen bis zum Takt, gelb bis zum doppelten Takt, danach rot. */
.fps .fresh { width: 8px; height: 8px; border-radius: var(--fn-radius-round); display: inline-block; margin-right: 5px; vertical-align: middle; }
.fps .fresh.g { background: var(--fn-success); box-shadow: 0 0 6px var(--fn-success); }
.fps .fresh.y { background: var(--fn-warning); }
.fps .fresh.r { background: var(--fn-danger); }
/* Gespeicherter Tagesschluss: ruhiger, neutraler Punkt. Am Samstag ist ein Freitagskurs kein Fehler
   und keine Warnung — er ist das, was es gibt. Vorher war dort JEDE Zeile rot und blinkte, die Liste
   sah aus „wie ein Tannenbaum" (Niko 01.08.2026). Das Datum steht daneben, das genügt. */
.fps .fresh.hist { background: var(--fn-text-tertiary); }
/* ZU ALT: der Punkt blinkt — aber SCHWACH (Niko 01.08.2026). Er blinkt nur, wenn ein LIVE-Kurs älter
   ist als der doppelte Takt: genau dann steht in der Zeile eine Zahl, die aussieht wie aktuell und es
   nicht mehr ist. Kein Blinken bei fehlendem Kurs (dort täuscht nichts) und keines beim gespeicherten
   Tagesschluss (der ist mit Datum ausgewiesen). */
.fps .fresh.r.stale { animation: fps-blink 1.8s ease-in-out infinite; }

@keyframes fps-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: .4; }
}

/* Wer Bewegung im Betriebssystem abgeschaltet hat, bekommt sie auch hier nicht — die Aussage traegt
   dann die Farbe allein (Barrierefreiheit, design.md). */
@media (prefers-reduced-motion: reduce) {
  .fps .fresh.r.stale { animation: none; }
}
/* Puls waehrend des Abrufs (Zielbild, Nikos Entscheidung): der Punkt zeigt, dass gerade geholt wird. */
.fps .fresh.pulse { background: var(--fn-primary); animation: fps-pulse 1.1s ease-out infinite; }
.fps .due.busy { color: var(--fn-primary); font-weight: 700; }

@keyframes fps-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--fn-primary) 60%, transparent); }
  70%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--fn-primary) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--fn-primary) 0%, transparent); }
}

/* Kleinzeile ohne Kurs: sie traegt den Warnton, weil dort der Fehltext steht. Eine Variante .teal gab
   es einmal fuer die weggefallene zweite Kleinzeile — sie ist mit ihr entfallen. */
.fps .stamp { font-size: 10.5px; }
.fps .stamp.warn { color: var(--fn-warning); }
/* Countdown: schlichter Text wie im Zielbild (.cd), keine umrandete Pille — die zog in der
   Kurszelle mehr Aufmerksamkeit auf sich als der Kurs selbst. */
.fps .due { font-size: 10px; color: var(--fn-text-tertiary); font-family: var(--fn-font-mono); }
.fps .due.now { color: var(--fn-warning); }

.fps .up { color: var(--fn-success); }
.fps .down { color: var(--fn-danger); }

/* Kontomodus als Kasten (Zielbild .modetag) — dieselbe Optik in der Positionsliste und im Reiter
   „Geschlossene". Die Klasse wurde dort gerendert, stand aber in keinem Stylesheet: ungestylter Text
   an einer Stelle, gestylter an der anderen. */
.fps .modetag { display: inline-block; font-size: 10px; border: 1px solid var(--fn-border-strong);
  border-radius: var(--fn-radius-sm); padding: 1px 5px; color: var(--fn-text-secondary);
  font-family: var(--fn-font-mono); letter-spacing: .3px; }

/* --- Schutz-Lebenszyklus (Venue-Punkt · 4 Stufen · Stop) --------------------------------------- */
.fps .venue { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--fn-text-secondary); }
.fps .venue .d { width: 7px; height: 7px; border-radius: var(--fn-radius-round); background: var(--fn-cat-teal); }
/* „ungeschuetzt“ ist eine LUECKE, kein Fehlschlag — Warnton wie im Zielbild, nicht Gefahrenrot. */
.fps .venue.miss .d { background: var(--fn-warning); }
.fps .venue.miss { color: var(--fn-warning); }
.fps .venue.fin .d { background: var(--fn-warning); }
.fps .lifecycle { display: flex; gap: 3px; margin: 3px 0; }
.fps .lc { width: 16px; height: 4px; border-radius: 2px; background: var(--fn-border-strong); display: inline-block; }
.fps .lc.done { background: var(--fn-cat-teal); }
.fps .lc.now { background: var(--fn-primary); }

/* --- Status-Blase (1:1 AI-Master) -------------------------------------------------------------- */
.fps .pos-state { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--fn-text-secondary); }
.fps .pos-state::before { content: ""; width: 7px; height: 7px; border-radius: var(--fn-radius-round); background: var(--fn-success); }
.fps .pos-state.paused::before { background: var(--fn-warning); }
.fps .pos-state.stop::before { background: var(--fn-danger); }
/* Ohne Kurs wird die Zeile von nichts verfolgt — Warnton, nicht das Gruen von „laeuft". */
.fps .pos-state.noquote { color: var(--fn-warning); }
.fps .pos-state.noquote::before { background: var(--fn-warning); }

/* --- Zeilen-Aktionen: geteilter Standard fn-btn + fn-btn-icon + fn-btn-sm, Lucide-Icons.
       Kein rohes SVG, kein Text-Kreuz. Icongroesse kommt global aus .fn-btn .lucide. ------------- */
/* ===== Abgleich-Balken =====
   Aufbau, Maße und Formel 1:1 aus der abgenommenen Marktdaten-Abgleich-Anzeige
   (`Components/MarketData/MarketSyncBar.razor(.css)`, Variante C, Abnahme 09.06.2026):

     Zeile 1   ● Live · alle 15 s · zuletzt vor 9 s · nächste in 6 s      [Aktionen]
     Balken    ▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░   (4 px, volle Breite, Farbverlauf)
     Zeile 2   nächster Abgleich in 6 s                             [15 s] Takt

   Vorher stand hier ein 96 px breiter Stummel INNERHALB der Statuszeile — gleiche Idee, aber nicht
   die Form, die abgenommen ist (Niko 01.08.2026). Es wird bewusst NICHT die fremde Komponente
   eingebunden: sie hängt an MarketQuoteCache/MarketDataRefresher und kennt den Takt dieses Moduls
   nicht. Geteilt ist die FORM, nicht der Zustand. */
.fps .fps-sync { display: flex; flex-direction: column; gap: 7px; }

/* Rinne in --fn-bg-muted, nicht in --fn-surface: das Vorbild nutzt dort zwar --fn-surface, aber das
   Token ist schwebenden Flächen vorbehalten (Gate FINLIST004) — und dieselbe Rinne der Status-Leiste
   in diesem Modul steht längst auf --fn-bg-muted. Gleiche Höhe, gleicher Radius, gleiche Wirkung. */
.fps .fps-sync-prog {
  height: 4px; background: var(--fn-bg-muted); border-radius: 3px; overflow: hidden;
}
.fps .fps-sync-prog > i {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--fn-primary), var(--fn-success));
  transition: width .6s ease;
}
/* Während des Abrufs ist keine Restzeit gemeint: der Balken atmet, statt eine Zahl zu behaupten. */
.fps .fps-sync-prog.busy > i { transition: none; animation: fps-sync-run 1.1s ease-in-out infinite; }

/* Ruhend (Börse geschlossen). Der Balken bleibt als Form stehen, damit die Zeile nicht wegspringt und
   niemand einen Defekt vermutet — aber ohne Farbverlauf und ohne Bewegung: hier läuft nichts, und das
   soll man sehen, nicht lesen müssen. Der Grund steht in der Unterzeile und im Tooltip. */
.fps .fps-sync-prog.resting > i { background: var(--fn-text-tertiary); transition: none; animation: none; }

/* Gestört (letzter Abruf fehlgeschlagen). Warnton statt Grün — ein voller grüner Balken über einem
   misslungenen Abruf wäre genau die Frische-Behauptung, die die Daten nicht tragen. */
.fps .fps-sync-prog.failed > i { background: var(--fn-warning); transition: none; animation: none; }
@keyframes fps-sync-run {
  0%, 100% { opacity: .35; }
  50%      { opacity: 1; }
}

.fps .fps-sync-sub { font-size: 11px; color: var(--fn-text-tertiary); }
.fps .fps-sync-src { display: inline-flex; align-items: center; gap: 6px; }
.fps .fps-sync-badge {
  display: inline-block; min-width: 20px; text-align: center;
  border: var(--fn-border-width) solid var(--fn-border); border-radius: 5px; padding: 1px 6px;
  font-family: var(--fn-font-mono); font-weight: var(--fn-font-weight-bold); font-size: 11px;
  color: var(--fn-text-secondary);
}
.fps .fps-sync-badge.busy { color: var(--fn-primary); border-color: var(--fn-primary); background: var(--fn-accent-soft); }

@media (prefers-reduced-motion: reduce) {
  .fps .fps-sync-prog > i { transition: none; }
  .fps .fps-sync-prog.busy > i { animation: none; }
}

/* ===== Spaltenraster: feste Breiten, ziehbar, gespeichert (Niko 01.08.2026) =====
   Vorher richtete sich die Tabelle nach ihrem Inhalt: ein langer Name („Goldman Sachs …") zog die
   erste Spalte ins Unendliche und quetschte alle Geldspalten zusammen. Jetzt gilt die eingestellte
   Breite — der Inhalt wird abgeschnitten, nicht die Spalte gesprengt. */
.fps table.fps-sizable { table-layout: fixed; width: 100%; }
.fps table.fps-sizable th, .fps table.fps-sizable td { overflow: hidden; }

/* Abschneiden mit Auslassungszeichen. Der volle Text bleibt über den Titel des Elements erreichbar,
   und die Kennzeile darunter (ISIN · WKN · Art) bleibt vollständig lesbar. */
.fps table.fps-sizable td .fn-name,
.fps table.fps-sizable td .sec-ids,
.fps table.fps-sizable .stk b,
.fps table.fps-sizable .stk small {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; max-width: 100%;
}
/* Die Kennzeile darf umbrechen statt abzuschneiden — sie ist Pflichtinhalt, kein Beiwerk. */
.fps table.fps-sizable .fps-instr { flex-wrap: nowrap; min-width: 0; }
.fps table.fps-sizable .fps-instr > *:first-child { min-width: 0; flex: 1 1 auto; }

/* Zieh-Griff am rechten Rand jeder Kopfzelle — identisch zur Watchliste (.wl-col-rz). */
.fps table.fps-sizable th.rzh { position: relative; }
.fps .fps-col-rz {
  position: absolute; top: 0; right: -3px; width: 7px; height: 100%;
  cursor: col-resize; z-index: 3; touch-action: none;
}
.fps .fps-col-rz::after {
  content: ""; position: absolute; top: 6px; bottom: 6px; left: 3px; width: 2px;
  border-radius: 2px; background: var(--fn-border-strong); opacity: .55;
  transition: background .12s ease, opacity .12s ease;
}
.fps .fps-col-rz:hover::after, .fps .fps-col-rz:focus-visible::after { background: var(--fn-primary); opacity: 1; }
.fps .fps-col-rz:focus-visible { outline: none; }

/* Die Überschrift „Aktionen" steht ZENTRIERT über ihren Icons (Niko 01.08.2026) — sie war
   linksbündig, während die Icons darunter mittig standen. */
.fps th.fps-actions-head { text-align: center; }
/* Aktions-Icons auf EINER Linie (Niko 01.08.2026). Der Aufklapp-Knopf enthaelt ein Textzeichen
   (▸ / ▾), die uebrigen ein SVG. Ein Inline-Element mit Text richtet sich an der Schriftgrundlinie
   aus, eines mit SVG nicht — der Chevron sass dadurch tiefer als seine Nachbarn. Eine Flex-Reihe
   richtet alle an derselben Mittelachse aus, unabhaengig vom Inhalt. */
.fps .fps-rowactions { white-space: nowrap; }
.fps .fps-rowactions { display: flex; align-items: center; justify-content: center; gap: 3px; }
/* Huelle um gesperrte Aktionen: sie traegt den Grund als Hinweistext, weil der Browser an einem
   disabled-Element keine Zeiger-Ereignisse zustellt und der Text dort nie erschiene. */
.fps .fps-gate { display: inline-flex; }

/* --- Aufklappbare Zeile (Zielbild) --------------------------------------------------------------
   Muster uebernommen aus dem Handels-Journal (tj-detail-row + Chevron): der Kern bleibt sichtbar,
   alles Uebrige steht in drei Bloecken darunter. Kein eigener Aufklapper-Mechanismus. */
.fps .fps-chev { font-size: 11px; line-height: 1; }
.fps .fps-chev.open { color: var(--fn-primary); border-color: var(--fn-primary); }
.fps .fps-detailrow > td { background: var(--fn-bg-alt); border-bottom: 1px solid var(--fn-border-strong); }
.fps .fps-detailgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px 22px; padding: 10px 4px; }
.fps .fps-detailgrid .dgroup { font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--fn-primary); padding-bottom: 2px; border-bottom: 1px solid var(--fn-border-strong); margin-bottom: 4px; }
.fps .fps-detailgrid .dt { display: flex; justify-content: space-between; gap: 10px; padding: 3px 0;
  border-bottom: 1px dashed var(--fn-border); font-size: 11.5px; }
.fps .fps-detailgrid .dt .l { color: var(--fn-text-tertiary); }
.fps .fps-detailgrid .dt .v { color: var(--fn-text); font-family: var(--fn-font-mono); font-size: 11px; text-align: right; }
.fps .fps-detailgrid .dt .v.warn { color: var(--fn-warning); }

@media (max-width: 900px) {
  .fps .fps-detailgrid { grid-template-columns: 1fr 1fr; }
}

/* Fehlender Stop: der Strich steht im Warnton — er ist die wichtigste Luecke der Zeile (Zielbild). */
.fps .stopmiss { color: var(--fn-warning); font-weight: 700; }

/* Begruendung unter gesperrten Zeilen-Aktionen („gesperrt bis zu deiner Abnahme"). */
.fps .fps-tipbox { margin-top: 6px; font-size: 11px; color: var(--fn-warning); white-space: normal; }

/* --- Broker-Order-Nummer ----------------------------------------------------------------------- */
.fps .fps-brokerid { font-family: var(--fn-font-mono); font-size: 11px; color: var(--fn-text-secondary); }

/* --- Takt-Zeile mit abgesetzter Gefahrenzone (UX-Auflage A5: Rot erst im Hover) ----------------- */
.fps .fps-refnote { display: flex; align-items: center; gap: 8px; justify-content: flex-start; flex-wrap: wrap;
  font-size: 12.5px; color: var(--fn-text-secondary); }
.fps .fps-refnote b { color: var(--fn-text); }
.fps .fps-refnote .live-dot { width: 9px; height: 9px; border-radius: var(--fn-radius-round); background: var(--fn-success);
  box-shadow: 0 0 8px var(--fn-success); }
.fps .fps-refnote .live-dot.stale { background: var(--fn-warning); box-shadow: none; }
.fps .fps-refnote .live-dot.failed { background: var(--fn-danger); box-shadow: none; }
.fps .fps-refnote .fps-failed { color: var(--fn-danger); }
/* Waehrend des Abrufs pulst auch der globale Punkt — das Zielbild zeigt ihn so. Ohne diese Regel
   waere .live-dot.pulse eine Klasse ohne Wirkung, also derselbe Mangel wie eine Attrappe. */
.fps .fps-refnote .live-dot.pulse { background: var(--fn-primary); box-shadow: none;
  animation: fps-pulse 1.1s ease-out infinite; }
.fps .fps-refnote .fps-spacer { flex: 1 1 auto; }
.fps .fps-dz-sep { width: 1px; height: 18px; background: var(--fn-border-strong); margin: 0 4px; }
.fps .fps-dz-label { font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--fn-danger); opacity: .75; }
/* Steht statt „Trennen & alle schliessen", solange es keine Broker-Verbindung gibt: der Grund im
   Klartext, kein dauerhaft toter Gefahren-Button. */
.fps .fps-dz-note { font-size: 11.5px; color: var(--fn-text-tertiary); }
/* OHNE .fps-Anker: der Storno-Button des Order-Dialogs traegt dieselbe Klasse, haengt aber in der
   FnFloatingWindow-Huelle ausserhalb von .fps — mit Anker blieb er als einziger ungestylt. Das
   fps-Praefix ist eindeutig genug (dieselbe Ausnahme wie fuer .fps-dlg*). */
.fps-danger { border-color: var(--fn-border-strong); color: var(--fn-danger); background: transparent; }
.fps-danger:hover:not(:disabled) { background: var(--fn-danger-soft); border-color: var(--fn-danger); }

/* --- Schutz-Erklaerband: einklappbar (Niko 29.07.2026) ----------------------------------------- */
.fps .fps-explainer { margin: 12px 16px 0; }
.fps .fps-exp-head { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 8px 12px; border: 1px solid var(--fn-border); border-radius: var(--fn-radius-sm);
  background: var(--fn-bg-alt); color: var(--fn-text-secondary); font-size: 12.5px;
  font-family: inherit; cursor: pointer; }
.fps .fps-exp-head .chev { color: var(--fn-primary); font-size: 11px; }
.fps .fps-exp-head b { color: var(--fn-text); }
.fps .fps-exp-head .hint { color: var(--fn-text-tertiary); font-size: 11.5px; }
.fps .fps-exp-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 8px; }
.fps .fps-exp-steps .step { background: var(--fn-bg-alt); border: 1px solid var(--fn-border);
  border-radius: var(--fn-radius-sm); padding: 9px 11px; font-size: 11px; color: var(--fn-text-secondary); }
.fps .fps-exp-steps .step .n { display: inline-flex; width: 16px; height: 16px; border-radius: var(--fn-radius-round);
  background: var(--fn-primary); color: var(--fn-on-primary); font-weight: 700;
  align-items: center; justify-content: center; font-size: 10px; margin-right: 6px; }
.fps .fps-exp-steps .step b { color: var(--fn-text); }

@media (max-width: 900px) {
  .fps .fps-exp-steps { grid-template-columns: 1fr 1fr; }
}

/* --- Reiter "Nicht gehandelt" ------------------------------------------------------------------ */
.fps .fps-skip-note { margin: 12px 16px 0; padding: 10px 12px; font-size: 12px;
  border: 1px solid var(--fn-border); border-left: 3px solid var(--fn-cat-purple);
  border-radius: var(--fn-radius-sm); background: var(--fn-bg-alt); color: var(--fn-text-secondary); }
.fps .fps-skip-note b { color: var(--fn-text); margin-right: 4px; }
.fps .fps-skip-list { margin: 10px 16px 0; font-size: 12px; color: var(--fn-text-secondary); }
.fps .fps-skip-row { display: flex; gap: 12px; padding: 7px 0; border-bottom: 1px solid var(--fn-border); }
.fps .fps-skip-row .kind { color: var(--fn-cat-purple); min-width: 140px;
  font-family: var(--fn-font-mono); font-size: 11px; }
.fps .fps-skip-row .why { flex: 1; }
.fps .fps-skip-row .when { color: var(--fn-text-tertiary); font-family: var(--fn-font-mono); font-size: 11px; }

/* --- Leerzustand: sowohl im Panel als auch in den drei Neben-Reitern -------------------------- */
.fps .fps-empty { padding: 24px 16px; text-align: center; color: var(--fn-text-tertiary); font-size: 13px; }

/* --- Dialoginhalte -----------------------------------------------------------------------------
   Die Huelle kommt aus FnFloatingWindow und haengt AUSSERHALB von .fps — deshalb hier ohne .fps-Anker.
   Das fps-Praefix ist eindeutig genug; generische Namen stehen in diesem Block bewusst nicht. */
/* Der Dialog FUELLT die Fensterhoehe: sein Inhalt scrollt, die Fussleiste klebt unten (Niko
   01.08.2026 — "wenn ich den Dialog vergroessere, werden die Inhalte nicht verändert; die Buttons
   müssen unten angedockt werden und bleiben dann kleben"). Vorher wuchs nur das Fenster, der Inhalt
   blieb oben stehen und die Knoepfe wanderten mit ihm nach oben weg. */
.fps-dlg { display: flex; flex-direction: column; gap: 12px; padding: 4px 2px;
  height: 100%; min-height: 0; }
/* Alles ausser der Fussleiste teilt sich den Rest und scrollt darin. */
.fps-dlg > *:not(.fps-dlg-foot) { flex: 0 0 auto; }
.fps-dlg-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex;
  flex-direction: column; gap: 12px; }
.fps-dlg-note { border: 1px solid var(--fn-border); border-left: 3px solid var(--fn-cat-teal);
  border-radius: var(--fn-radius-sm); background: var(--fn-bg-alt); padding: 10px 12px;
  font-size: 12.5px; color: var(--fn-text-secondary); }
.fps-dlg-note b { color: var(--fn-text); display: block; margin-bottom: 3px; }
.fps-dlg-grid { display: grid; grid-template-columns: auto 1fr; gap: 6px 18px; font-size: 12.5px; }
.fps-dlg-grid .l { color: var(--fn-text-tertiary); }
.fps-dlg-grid .v { color: var(--fn-text); font-family: var(--fn-font-mono); font-size: 12px; }
.fps-dlg-grid .v.ok { color: var(--fn-success); }
.fps-dlg-grid .v.warn { color: var(--fn-warning); }
.fps-dlg-warn { border: 1px solid var(--fn-warning); border-radius: var(--fn-radius-sm);
  background: var(--fn-warning-soft); padding: 10px 12px; font-size: 12.5px; color: var(--fn-text); }
.fps-dlg-warn .reason { margin-top: 4px; color: var(--fn-text-secondary); font-size: 11.5px; }
.fps-dlg-empty { padding: 18px 12px; text-align: center; color: var(--fn-text-tertiary); font-size: 12.5px; }

/* Eingabe im Dialog: NUR die Anordnung von Beschriftung, Feld und Hinweis. Das Feld selbst ist die
   geteilte Primitive .fn-field aus fn-forms.css — hier wird keine Primitive nachgebaut (FINCOMP001). */
.fps-dlg-entry { display: flex; flex-direction: column; gap: 4px; }
.fps-dlg-entry label { font-size: 11px; text-transform: uppercase; letter-spacing: .4px; color: var(--fn-text-tertiary); }
.fps-dlg-entry small { font-size: 11px; color: var(--fn-text-tertiary); }

/* Fusszeile der Dialoge: Aktionen rechts, Hausmuster wie wl-dlg-foot (42 px, Sekundaer vor Primaer).
   Gezielt auf das Element, nicht auf die Primitive-Klasse. */
.fps-dlg-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: auto; padding-top: 12px;
  border-top: 1px solid var(--fn-border); flex: 0 0 auto;
  /* Klebt am unteren Rand, auch wenn der Inhalt darueber scrollt. */
  position: sticky; bottom: 0; background: var(--fn-bg-alt); }
.fps-dlg-foot > button { display: inline-flex; align-items: center; gap: 7px; }
.fps-dlg-foot > button { height: 42px; padding: 0 18px; font-size: 14px; }

/* --- Trefferliste der Wertpapier-Suche im Eroeffnungs-Dialog ------------------------------------ */
.fps-open-hits { display: flex; flex-direction: column; max-height: 220px; overflow-y: auto;
  border: 1px solid var(--fn-border); border-radius: var(--fn-radius-sm); }
.fps-open-hit { display: flex; align-items: baseline; gap: 8px; text-align: left; width: 100%;
  padding: 7px 10px; background: transparent; border: 0; border-bottom: 1px solid var(--fn-border);
  color: var(--fn-text-secondary); font-family: inherit; font-size: 12.5px; cursor: pointer; }
.fps-open-hit:last-child { border-bottom: 0; }
.fps-open-hit:hover { background: var(--fn-bg-muted); }
.fps-open-hit .sym { color: var(--fn-cat-blue); font-family: var(--fn-font-mono); font-weight: 700; font-size: 12.5px; }
.fps-open-hit .nm { color: var(--fn-text); }
.fps-open-hit small { margin-left: auto; color: var(--fn-text-tertiary); font-family: var(--fn-font-mono); font-size: 11px; }

/* --- Status-Lagebild ---------------------------------------------------------------------------- */
.fps-brief-verdict { border: 1px solid var(--fn-border); border-left: 3px solid var(--fn-primary);
  border-radius: var(--fn-radius-sm); background: var(--fn-bg-alt); padding: 10px 12px; font-size: 12.5px;
  color: var(--fn-text-secondary); }
.fps-brief-verdict b { color: var(--fn-text); display: block; margin-bottom: 3px; }
.fps-brief-verdict.pos { border-left-color: var(--fn-success); }
.fps-brief-verdict.neg { border-left-color: var(--fn-danger); }
.fps-brief-verdict.warn { border-left-color: var(--fn-warning); }
.fps-brief-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.fps-brief-chip { font-size: 11px; padding: 2px 8px; border-radius: var(--fn-radius-pill);
  border: 1px solid var(--fn-border-strong); color: var(--fn-text-secondary); }
.fps-brief-chip.pos { color: var(--fn-success); border-color: var(--fn-success); }
.fps-brief-chip.neg { color: var(--fn-danger); border-color: var(--fn-danger); }
.fps-brief-chip.warn { color: var(--fn-warning); border-color: var(--fn-warning); }
.fps-brief-cat .dgroup { font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--fn-primary); padding-bottom: 2px; border-bottom: 1px solid var(--fn-border-strong); margin-bottom: 4px; }
.fps-brief-item { display: flex; flex-direction: column; gap: 1px; padding: 5px 0;
  border-bottom: 1px dashed var(--fn-border); font-size: 12px; color: var(--fn-text); }
.fps-brief-item small { color: var(--fn-text-tertiary); font-size: 10.5px; font-family: var(--fn-font-mono); }
.fps-brief-item.pos { border-left: 2px solid var(--fn-success); padding-left: 7px; }
.fps-brief-item.neg { border-left: 2px solid var(--fn-danger); padding-left: 7px; }
.fps-brief-item.warn { border-left: 2px solid var(--fn-warning); padding-left: 7px; }
.fps-brief-empty { font-size: 11.5px; color: var(--fn-text-tertiary); padding: 4px 0; }
.fps-brief-foot { font-size: 11px; color: var(--fn-text-tertiary); border-top: 1px solid var(--fn-border);
  padding-top: 8px; }
.fps-brief-loading { display: flex; flex-direction: column; gap: 4px; }
.fps-brief-loading small { color: var(--fn-text-tertiary); font-size: 11px; }
.fps-brief-progress { height: 3px; background: var(--fn-bg-muted); border-radius: 2px; overflow: hidden; }
.fps-brief-progress > span { display: block; height: 100%; width: 40%; background: var(--fn-primary);
  animation: fps-brief-slide 1.1s ease-in-out infinite; }

@keyframes fps-brief-slide {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

/* Euro-Sicht: die umgerechnete Zweitzeile steht gedaempft unter dem Original — sie ist eine
   Lesehilfe, nicht die Wahrheit der Position (die notiert in ihrer eigenen Waehrung). */
.fps .stk small.tenant { color: var(--fn-text-tertiary); font-size: 10.5px; }

/* Aktiv-Schalter im Sperr-Hinweis (Niko 02.08.2026): ein Klick holt das Papier zurueck. */
.fps-reenable { margin-top: 8px; display: flex; align-items: center; gap: 9px; font-size: 12.5px;
                color: var(--fn-text); }
