
  /* ── Positions-Detail: Slide-in-Panel statt floatendem Modal (Phil #25,
     22.08.2026: «genau wie Sidecar von rechts reinfahren, volle Breite bis
     zum Mainmenu links»). Die pos-modal-*-Namen und IDs bleiben absichtlich
     stehen, damit die Deep-Link-/History-/Interceptor-Logik weiter unten
     unangetastet weiterlaeuft — nur die Praesentation ist neu. Die linke
     Kante folgt --pm-sidebar-w und damit auch dem schmalen Menuemodus. */
  .pos-modal-overlay {
    position: fixed; inset: 0; z-index: 20200;
    background: rgba(3, 6, 12, .55);
    backdrop-filter: blur(6px);
    opacity: 0; transition: opacity .22s ease;
  }
  .pos-modal-overlay.is-open { opacity: 1; }
  .pos-modal-shell {
    position: absolute; top: var(--pm-navbar-h, 0px); right: 0; bottom: 0;
    left: var(--pm-sidebar-w, 232px);
    background: var(--pm-bg, #0a0e1a);
    border-left: 1px solid var(--pm-border, #1f2937);
    box-shadow: -24px 0 80px rgba(0, 0, 0, .55);
    overflow: hidden;
    /* Einfahren von rechts wie der Sidecar: Startlage komplett draussen,
       .is-open am Overlay schiebt rein (Transition am transform, nicht an
       left/width — nur transform laeuft am Compositor ruckelfrei). */
    transform: translateX(100%);
    transition: transform .28s cubic-bezier(.22, .61, .36, 1);
  }
  .pos-modal-overlay.is-open .pos-modal-shell { transform: translateX(0); }
  .pos-modal-frame {
    width: 100%; height: 100%; border: 0; display: block;
    background: var(--pm-bg, #0a0e1a);
    opacity: 0; transition: opacity .18s ease;
  }
  .pos-modal-frame.is-loaded { opacity: 1; }
  .pos-modal-close {
    position: absolute; top: 10px; right: 10px; z-index: 2;
    width: 34px; height: 34px; border-radius: 50%;
    background: rgba(17, 24, 39, .88); border: 1px solid var(--pm-border, #1f2937);
    color: var(--pm-text, #e5e7eb); font-size: .95rem;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer; transition: background .15s, border-color .15s, transform .15s;
  }
  .pos-modal-close:hover { background: rgba(239, 68, 68, .22); border-color: #ef4444; transform: scale(1.06); }
  .pos-modal-spinner {
    position: absolute; inset: 0; z-index: 1;
    display: flex; align-items: center; justify-content: center;
    background: var(--pm-bg, #0a0e1a);
    transition: opacity .15s ease;
  }
  .pos-modal-spinner.is-hidden { opacity: 0; pointer-events: none; }
  .pos-modal-load-error:not([hidden]) {
    position: absolute; inset: 0; z-index: 1; padding: 3rem 1.5rem;
    display: flex; flex-wrap: wrap; align-content: center; justify-content: center;
    gap: .75rem; background: var(--pm-bg); color: var(--pm-text); text-align: center;
  }
  .pos-modal-load-error p { flex-basis: 100%; }
  .pos-modal-spin {
    width: 40px; height: 40px; border-radius: 50%;
    border: 3px solid var(--pm-border, #1f2937);
    border-top-color: var(--pm-accent, #3b82f6);
    animation: posModalSpin .7s linear infinite;
  }
  @keyframes posModalSpin { to { transform: rotate(360deg); } }
  /* Kein Body-Scroll waehrend das Modal offen ist (Scroll-Lock, siehe JS). */
  body.pos-modal-open { overflow: hidden; }
  /* Unter 992px ist das Hauptmenue eine Schublade (kein fester Streifen
     links) — dann gehoert dem Panel die volle Breite. */
  @media (max-width: 991.98px) {
    .pos-modal-shell { left: 0; }
  }
  /* Live-Demo-Banner (Phils Entscheid 22.08.2026) — dezent, permanent, normaler
     Flow-Block (siehe base.html-Kommentar direkt vor <main>). Bewusst KEIN
     Alarm-Rot wie #offlineBanner: das hier ist kein Fehlerzustand. */
  .pm-demo-banner {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 7px 16px; font-size: .82rem;
    background: rgba(59, 130, 246, .12); border-bottom: 1px solid rgba(59, 130, 246, .28);
    color: var(--pm-text, #e5e7eb);
  }
  .pm-demo-banner i { color: #3b82f6; }
  .pm-demo-banner a {
    color: #60a5fa; text-decoration: underline; font-weight: 600; margin-left: 2px;
  }
  .pm-demo-banner a:hover { color: #93c5fd; }
