
  html, body { margin: 0; height: 100%; background: #1c1c1c; font-family: system-ui, sans-serif; }
  #viewport { position: fixed; inset: 0; overflow: hidden; cursor: grab; touch-action: none; }
  #mapWrap { position: absolute; top: 0; left: 0; transform-origin: 0 0; }
  #mapWrap img { display: block; }
  .marker {
    position: absolute;
    width: 44px; height: 44px;
    margin-left: -22px; margin-top: -22px;
    border-radius: 50%;
    cursor: pointer;
  }
  .marker:hover { background: rgba(255,255,255,0.35); outline: 2px solid #fff; }
  .marker--disabled { cursor: not-allowed; }
  .marker--disabled:hover { background: none; outline: none; }
  /* IMU-Relativregistrierungs-Genauigkeit (siehe _build_left_markers_html/project_map.
     imu_relative_accuracy) - kleiner Kreis, nur sichtbar wenn der umgebende Marker gerade
     als .marker--current (aktive Scanposition, gross) angezeigt wird, siehe _SPLIT_CSS. */
  .marker-imu-dot {
    display: none; position: absolute; top: 50%; left: 50%;
    width: 40px; height: 40px; margin: -20px 0 0 -20px; border-radius: 50%;
    border: 2px solid #fff;
  }
  .zoom-controls {
    position: fixed; right: 16px; bottom: 16px; z-index: 10;
    display: flex; flex-direction: column; gap: 6px;
  }
  .zoom-controls button {
    width: 46px; height: 40px; border-radius: 8px; border: none;
    background: rgba(255,255,255,0.9); color: #1c1c1c; font-size: 20px;
    cursor: pointer; box-shadow: 0 1px 4px rgba(0,0,0,0.4);
  }
  /* Mehrbuchstabige Text-Buttons (3D/KML) statt der Icon-Buttons: gleiche Breite wie oben (alle
     Buttons von 3D bis KML sollen gleich breit sein), aber kleinere Schrift als die einzelnen
     Icon-Buttons, da 20px bei 3 Buchstaben nicht mehr in 46px passen wuerde. */
  .zoom-controls button.text-btn {
    font-size: 15px; font-weight: 700; letter-spacing: 0.02em;
  }
  /* "Ebenen"-Icon (Kartenhintergrund umschalten: OpenStreetMap/Satellit/weiss) statt Text -
     dasselbe Symbol, mit dem Kartenanwendungen ueblicherweise den Basiskartentyp umschalten. */
  .zoom-controls button.sat-toggle {
    display: flex; align-items: center; justify-content: center; padding: 0;
  }
  .zoom-controls button.sat-toggle svg { width: 22px; height: 22px; display: block; }
  .zoom-controls button:hover { background: #fff; }
  .zoom-controls button:disabled { opacity: 0.35; cursor: not-allowed; }
  .zoom-controls button:disabled:hover { background: rgba(255,255,255,0.9); }
  /* 3D-Button jetzt eigenstaendig oben links (gleiche Randabstaende wie #mapHeader), NICHT
     mehr Teil der .zoom-controls-Saeule - damit er exakt an derselben Bildschirmstelle sitzt
     wie der "2D"-Button auf der 3D-Seite (siehe proj.py reposition_compass_js), fuer schnelles
     Hin- und Herschalten per Mausklick. */
  .goto-3d-btn {
    position: absolute; top: 10px; left: 8px; z-index: 10;
    width: 46px; height: 44px; border-radius: 8px; border: none;
    background: rgba(255,255,255,0.9); color: #1c1c1c;
    font-family: system-ui, sans-serif; font-size: 18px; font-weight: 700;
    letter-spacing: 0.02em; cursor: pointer; box-shadow: 0 1px 4px rgba(0,0,0,0.4);
  }
  .goto-3d-btn:hover { background: #fff; }
  /* Duenner oranger Rahmen (RIEGL-Orange) mit abgerundeten Ecken auf ALLEN Buttons dieser
     Seite (nicht der Scanpositions-Marker, die sind <a>-Elemente, keine <button>s) - bewusst
     mit !important, um bestehende, spezifischere Button-Stile (z.B. "border: none" bei
     .zoom-controls button) nicht einzeln aufsuchen/anpassen zu muessen. */
  button {
    border: 1px solid #f39314 !important;
    border-radius: 6px !important;
  }


  #splitContainer { position: fixed; inset: 0; }
  .pane { position: absolute; top: 0; bottom: 0; overflow: hidden; cursor: grab; touch-action: none; background: #1c1c1c; }
  .pane .wrap { position: absolute; top: 0; left: 0; transform-origin: 0 0; }
  .pane .wrap img { display: block; }
  .pane .zoom-controls { position: absolute; right: 16px; bottom: 16px; }
  /* mapReflectorMarkers spannt (wie mapMarkers) die gesamte Projectmap auf, damit die
     wenigen Reflektor-Kreise absolut darin positioniert werden koennen - ohne
     pointer-events:none wuerde dieser leere Container aber JEDEN Klick auf die Projectmap
     abfangen (er liegt im DOM nach mapMarkers, also optisch darueber) und so die
     Scanpositions-Marker darunter unklickbar machen. */
  #mapReflectorMarkers { pointer-events: none; }
  #mapReflectorMarkers .marker--reflector { pointer-events: auto; }
  /* Fein gescannter Reflektor (siehe proj.collect_tiepoint_images): kleiner oranger Kreis an
     der tatsaechlichen Reflektorposition, sowohl im Panorama (#panoMarkers) als auch in der
     Projectmap (#mapReflectorMarkers) - deutlich kleiner als die normalen 44px-Marker und
     nicht anklickbar (nur Hinweis, keine Navigation). */
  .marker--reflector {
    width: 16px; height: 16px; margin-left: -8px; margin-top: -8px;
    background: #ff9500; border: 2px solid #fff; cursor: default; z-index: 7;
  }
  .marker--reflector:hover { background: #ff9500; outline: none; }
  /* Beim Anklicken einer Reflektor-Feinscan-Thumbnail (#panoTiePointImages) wird der
     zugehoerige Marker hier UND in der Projectmap rot hervorgehoben (siehe Klick-Handler bei
     panoTiePointImages) - .active nach .marker--reflector im Quelltext (gleiche Spezifitaet
     wie :hover, gewinnt bei Gleichstand durch spaetere Regel). */
  .marker--reflector.active { background: #e60000; }
  .pv-reflector-selected { outline: 2px solid #e60000; outline-offset: -1px; }
  /* Scanpositions-Ueberschrift oben, Panorama-Infoleisten unten: schieben das Panorama
     selbst in den Bereich dazwischen. Direkt unter dem Panorama: Exposure/ISO (links)
     und ein Helligkeits-Histogramm (rechts); darunter: Datum/Uhrzeit/Wetter. */
  #panoScanLabel {
    position: absolute; top: 0; left: 0; right: 0; height: 64px;
    background: #111; border-bottom: 1px solid #333; color: #fff;
    display: flex; align-items: center; justify-content: space-between; padding: 0 12px;
    font-family: system-ui, sans-serif; font-size: 26px; font-weight: 600;
  }
  #panoHeaderLeft { display: flex; align-items: center; gap: 8px; flex: 0 1 auto; min-width: 0; }
  /* Zeile zwischen Ueberschrift und Panorama: links die Scanner-Schnellvorschau
     (proj.collect_scan_previews, praktisch immer vorhanden), rechts - falls fuer die aktuelle
     Scanposition vorhanden - die fein gescannten Reflektoren (ScanPosXXX.SCNPOS/
     tiepointscans/*_TP##.png), von rechts nach links aneinandergereiht (row-reverse). Beide
     Kindelemente sind gleich hoch. rightViewport.style.top wird per JS umgeschaltet (siehe
     renderPanoTiePoints) - display:none macht diese Zeile hier unsichtbar UND nimmt keinen
     Platz weg, wenn weder Vorschau noch Reflektorbilder vorhanden sind. */
  #panoTiePoints {
    position: absolute; top: 64px; left: 0; right: 0; height: 112px;
    z-index: 5; display: none; align-items: center; justify-content: space-between; gap: 12px;
    padding: 0 12px; background: #111; border-bottom: 1px solid #333; box-sizing: border-box;
  }
  #panoTiePoints.has-images { display: flex; }
  #panoScanPreview {
    flex: 0 0 auto; height: calc(112px - 16px); display: none;
    /* siehe #rightViewport - dieselbe blaue Markierung trat auch beim Scan-Vorschaubild auf. */
    -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
  }
  #panoScanPreview.visible { display: block; cursor: pointer; }
  /* Per ID statt ueber "#panoScanPreview img" (traefe sonst auch die beiden unten definierten
     Wrap-Around-Kopien, die ausserhalb der grossen getauschten Ansicht immer verstect bleiben
     sollen). */
  #panoScanPreviewImg { display: block; height: 100%; width: auto; border-radius: 4px; border: 1px solid #f39314; }
  /* Die beiden Wrap-Around-Kopien (siehe previewApply/setPanoSwapped) sind ausserhalb der
     Miniatur-Ansicht immer versteckt - erst waehrend des Tauschs (grosse, pannbare Ansicht)
     per JS eingeblendet, dort dann OHNE eigenen Rahmen (keine Naht mitten in der Drehung) und
     ohne Mausinteraktion (die haengt weiterhin komplett an #panoScanPreview). */
  #panoScanPreviewImgL, #panoScanPreviewImgR { display: none; pointer-events: none; border: none; }
  #panoTiePointImages {
    flex: 1 1 auto; min-width: 0; height: 100%; display: flex; flex-direction: row-reverse;
    align-items: center; gap: 8px; overflow-x: auto;
  }
  #panoTiePointImages img {
    height: calc(112px - 16px); width: calc(112px - 16px);
    object-fit: cover; border-radius: 4px; border: 1px solid #f39314; flex: 0 0 auto;
  }
  #rightViewport {
    position: absolute; top: 64px; left: 0; right: 0; bottom: 206px;
    overflow: hidden; cursor: grab; touch-action: none;
    /* Anwenderwunsch: das Bild faerbt sich sonst gelegentlich blau (Browser-eigene Text-/
       Bild-Markierung, ausgeloest durch Doppelklick oder durch Ziehen mit gedrueckter linker
       Maustaste - beides normale Browser-Gesten, die hier aber zum Verschieben/Zoomen
       gebraucht werden, nicht zum Markieren). user-select:none unterbindet das. */
    -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
  }
  /* Panoramabild (nicht die Kachel-Bilder der Project Map, die ebenfalls ".wrap img" matchen
     wuerden) - oben dicker, unten duenner oranger Rahmen (Anwenderwunsch); links/rechts
     bewusst KEIN Rahmen mehr, seit das Bild fuer endloses Herumdrehen (siehe rightImgL/-R
     unten) nahtlos an sich selbst anschliesst - ein Rahmen dort waere eine stoerende Naht
     mitten in der eigentlich durchgehenden 360-Grad-Drehung. Dieselbe Regel gilt fuer die
     beiden Wrap-Around-Kopien, damit der obere/untere Streifen ueber die ganze Drehung hinweg
     durchgehend aussieht, unabhaengig davon, welche der drei Bildkopien gerade sichtbar ist. */
  /* Dicke wie #panoFrame's oberer Rahmen (16px) - dort ist es die eigentliche, per Ziehen
     verschiebbare Histogramm-Ausschluss-Grenze; hier ist es (an allen drei Bildkopien
     gleichermassen) der optische Bild-"Rahmen". Beide zusammen ergeben bei cropTopFrac==0
     (Normalfall) exakt eine einzige, ueberall gleich dicke Linie - sonst waere sie nur ueber
     der jeweils "kanonischen" Kopie (dort sitzt #panoFrame, siehe unten) dicker als ueber den
     beiden Wrap-Around-Nachbarn (vom Anwender gemeldet: "links dick, rechts nicht"). */
  #rightImg, #rightImgL, #rightImgR {
    border-top: 16px solid #f39314; border-bottom: 1px solid #f39314;
    border-left: none; border-right: none; box-sizing: border-box;
  }
  /* Zusaetzlich zu draggable="false" (siehe Markup) - verhindert in WebKit/Blink auch das
     "Geister-Bild", das beim Ziehen sonst gelegentlich statt des erwarteten Verschiebens
     erscheint (Teil desselben "wird blau/reagiert falsch beim Ziehen"-Problems). */
  #rightImg, #rightImgL, #rightImgR, #panoScanPreviewImg, #panoScanPreviewImgL, #panoScanPreviewImgR {
    -webkit-user-drag: none; user-drag: none;
  }
  /* Zwei zusaetzliche Kopien desselben Panoramas fuer nahtloses, endloses Herumdrehen (siehe
     panoApply/switchTo in der JS unten) - links/rechts der Hauptkopie positioniert,
     pointer-events:none (Maus-/Touch-Bedienung bleibt ausschliesslich am #rightViewport-
     Container haengen, unabhaengig davon, welche der drei Bildkopien gerade darunter sichtbar
     ist). */
  #rightImgL, #rightImgR { position: absolute; top: 0; pointer-events: none; }
  #panoInfo {
    position: absolute; left: 0; right: 0; bottom: 56px; height: 150px;
    background: #111; border-top: 1px solid #333; color: #fff;
    display: flex; font-family: system-ui, sans-serif;
  }
  #panoInfoExif {
    flex: 1; padding: 16px 24px; font-size: 22px; line-height: 1.8; white-space: nowrap;
  }
  #panoInfoHist { flex: 1; padding: 12px 20px; }
  #panoInfoHist canvas { width: 100%; height: 100%; display: block; background: #000; }
  /* QR-Code der AKTUELL im Browser geoeffneten Seite (window.location.href, clientseitig per
     qrcode.js gerendert - siehe unten) - rechts neben dem Histogramm, damit jemand anderes per
     Scan exakt dieselbe Seite oeffnen kann, egal wo/wie sie gerade gehostet ist. Feste Hoehe
     wie das Histogramm, quadratisch (Canvas-Breite=Hoehe wird per JS gesetzt). */
  #panoInfoQr { flex: 0 0 auto; display: flex; align-items: center; padding: 12px 24px 12px 0; }
  #panoInfoQr canvas { height: 100%; width: auto; display: block; border-radius: 4px; background: #fff; }
  /* Nav-/Zoom-Buttons: unten linksbuendig in derselben Zeile wie Exposure/ISO und
     Histogramm - links buendig mit dem Exposure/ISO-Text (gleicher 24px-Abstand wie
     #panoInfoExif), unten buendig mit der Unterkante des Histogramms (gleicher 12px-Abstand
     wie #panoInfoHist) - invertiert (weiss auf dunklem Grund, passt zum dunklen
     panoInfo-Hintergrund) und in derselben Groesse wie die Projectmap-Buttons (40x40px,
     siehe .zoom-controls button). Eigene Klasse statt der gemeinsamen .zoom-controls, damit
     die Projectmap-Buttons links (die weiterhin schwebend/hell bleiben) unberuehrt bleiben. */
  #panoButtonsRow {
    position: absolute; left: 24px; bottom: 12px; display: flex; align-items: center; gap: 10px;
  }
  #panoButtonsRow button {
    width: 40px; height: 40px; border-radius: 8px; border: none;
    background: rgba(255,255,255,0.12); color: #fff; font-size: 20px;
    cursor: pointer;
  }
  #panoButtonsRow button:hover { background: rgba(255,255,255,0.25); }
  #panoButtonsRow button:disabled { opacity: 0.35; cursor: not-allowed; }
  #panoButtonsRow button:disabled:hover { background: rgba(255,255,255,0.12); }
  #panoInfo2 {
    position: absolute; left: 0; right: 0; bottom: 0; height: 56px;
    background: #0a0a0a; border-top: 1px solid #333; color: #fff;
    display: flex; align-items: center; font-family: system-ui, sans-serif; font-size: 18px;
  }
  #panoInfo2 > div { flex: 1; padding: 0 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* Duenner oranger Rahmen um das Panorama; die obere Linie ist per Ziehen verschiebbar -
     das Histogramm bezieht sich dann nur auf den Bildteil, der noch eingerahmt ist.
     panoFrameMask (abgedunkelter, ausgeschlossener oberer Teil) ist ein Geschwister von
     panoFrame - beide liegen im selben Koordinatensystem wie das Bild (#rightWrap). */
  /* Weiss->Schwarz-Blinken reinweisser Pixel (siehe toggleWhiteBlink): invert(1) dreht die
     immer reinweiss gespeicherte Maske zu Schwarz, ohne den Alphakanal zu veraendern. Je eine
     Kopie links/rechts der Bildkopien-Kanone (siehe rightImgL/-R) - Position/Breite wird wie
     dort in panoApply() per JS gesetzt, damit das Blinken unabhaengig davon sichtbar ist,
     welche der drei Kopien man gerade sieht (vom Anwender gemeldet: ging nur bei einer). */
  #panoWhiteBlink.inverted, #panoWhiteBlinkL.inverted, #panoWhiteBlinkR.inverted { filter: invert(1); }
  /* left/width werden wie bei rightImgL/-R per JS gesetzt (siehe panoApply) - dieselben drei
     Kopien fuer den Histogramm-Ausschluss-Rahmen (Frame+Maske+Handle), damit sich die per
     Ziehen verschiebbare Grenze unabhaengig davon bedienen laesst/sichtbar bleibt, welche der
     drei Bildkopien gerade im Viewport ist (vom Anwender gemeldet: Ziehen wirkte sich nur auf
     eine der beiden sichtbaren Kopien aus). */
  #panoFrameMask, #panoFrameMaskL, #panoFrameMaskR {
    position: absolute; top: 0; height: 0;
    background: rgba(0,0,0,0.4); pointer-events: none;
  }
  #panoFrame, #panoFrameL, #panoFrameR {
    position: absolute; bottom: 0; top: 0;
    /* Nur noch oben ein Rahmen (die eigentliche, ziehbare Grenze) - links/rechts/unten
       entfernt: der optische Bild-Rahmen kommt ausschliesslich von #rightImg/-L/-R (siehe
       oben), dieser hier ist nur noch die Ziehlinie selbst. */
    border: none; border-top: 16px solid #ff9500;
    box-sizing: border-box; pointer-events: none;
  }
  /* Doppelt so dick wie zuvor (8px -> 16px) - auf einem iPad/Touchscreen ohne praezisen
     Mauszeiger liess sich der duenne obere Rahmen kaum treffen/ziehen. Der Handle bleibt um
     denselben (jetzt ebenfalls verdoppelten) Betrag zentriert um die Rahmenkante herum. */
  #panoFrameHandle, #panoFrameHandleL, #panoFrameHandleR {
    position: absolute; left: 0; right: 0; top: -14px; height: 28px;
    cursor: row-resize; pointer-events: auto;
  }
  #panoFrameIcon {
    position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
    color: #ff9500; background: rgba(0,0,0,0.7); border-radius: 4px;
    padding: 0 6px; font-size: 42px; line-height: 1.6; pointer-events: none;
    font-family: system-ui, sans-serif;
  }
  #divider {
    position: absolute; top: 0; bottom: 0; width: 16px; margin-left: -8px;
    background: #444; cursor: col-resize; z-index: 15; touch-action: none;
  }
  #divider:hover { background: #666; }
  /* Ueberschrift + RIEGL-Logo links oben in der Projectmap. */
  #mapHeader {
    position: absolute; top: 10px; right: 16px; z-index: 10; height: 44px; box-sizing: border-box;
    display: flex; align-items: center; gap: 10px;
    background: rgba(255,255,255,0.9); padding: 0 14px; border-radius: 6px;
    border: 1px solid #f39314; box-shadow: 0 1px 4px rgba(0,0,0,0.4);
    font-family: system-ui, sans-serif; font-size: 20px; font-weight: 600; color: #1c1c1c;
  }
  #mapHeader img { height: 28px; width: auto; display: block; }
  #helpBtn {
    width: 28px; height: 28px; flex: 0 0 auto; border-radius: 6px;
    border: none; background: rgba(0,0,0,0.08); color: #1c1c1c; font-size: 15px;
    font-weight: 700; cursor: pointer;
    font-style: normal; font-family: system-ui, sans-serif;
  }
  #helpBtn:hover { background: rgba(0,0,0,0.18); }
  /* Textfenster mit GNSS-/IMU-Genauigkeit der aktuell angezeigten (rechts als Panorama
     offenen, links als grosser Kreis markierten) Scanposition - siehe updateMapScanInfo,
     aufgerufen von switchTo(). Unten links, oberhalb der (kleineren) OSM-Attribution -
     display:none, solange kein Inhalt gesetzt ist (Projekte ganz ohne GNSS/IMU-Daten haetten
     sonst eine leere Box stehen) bzw. solange nicht ueber der aktiven Scanposition gehovert
     wird (siehe mouseover/mouseout auf #mapMarkers). */
  #mapScanInfo {
    position: absolute; bottom: 34px; left: 8px; z-index: 10; display: none;
    background: rgba(255,255,255,0.9); padding: 8px 14px; border-radius: 6px;
    border: 1px solid #f39314; box-shadow: 0 1px 4px rgba(0,0,0,0.4);
    font-family: system-ui, sans-serif; font-size: 15px; line-height: 1.5; color: #1c1c1c;
    white-space: nowrap;
  }
  #mapScanInfo b { font-size: 17px; }
  /* Breiteres, scrollbares Modal-Panel fuer den Hilfetext (mehr Inhalt als Passwort-/
     Start-Hinweis-Dialog). */
  #appModalPanel.wide { max-width: 820px; max-height: 80vh; overflow-y: auto; }
  /* Start-Hinweis (frueher nur ueber den separaten "i"-Button neben "Project Map" abrufbar,
     der auf Anwenderwunsch entfernt wurde) - steht jetzt hier fest im Hilfe-Fenster, sprach-
     unabhaengig (der Text selbst existiert nur auf Englisch), oberhalb der Sprachauswahl. */
  .help-intro {
    margin-bottom: 16px; padding-bottom: 16px; border-bottom: 1px solid rgba(255,255,255,0.2);
  }
  .help-intro p { margin: 0 0 8px 0; font-size: 14px; line-height: 1.4; color: #ddd; }
  .help-intro p:last-child { margin-bottom: 0; }
  .help-lang-bar {
    display: flex; align-items: center; justify-content: flex-end; gap: 8px;
    font-size: 13px; color: #ddd; margin-bottom: 4px;
  }
  .help-lang-bar select {
    background: rgba(255,255,255,0.12); color: #fff; border: 1px solid #f39314 !important;
    border-radius: 6px; padding: 3px 6px; font-size: 13px; font-family: system-ui, sans-serif;
  }
  .help-lang-bar select option { color: #000; background: #fff; }
  .help-section { margin-bottom: 20px; }
  .help-section:last-child { margin-bottom: 0; }
  .help-section h4 {
    margin: 0 0 10px 0; font-size: 13px; color: #ff9500; text-transform: uppercase;
    letter-spacing: 0.05em;
  }
  .help-row { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 10px; }
  .help-row:last-child { margin-bottom: 0; }
  .help-row p { margin: 0; font-size: 14px; line-height: 1.4; color: #ddd; }
  .help-row b { color: #fff; }
  .helpIcon {
    display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
    width: 26px; height: 26px; border-radius: 6px; background: rgba(255,255,255,0.12);
    color: #ff9500; font-size: 13px; font-weight: 700; line-height: 1; margin-top: 1px;
  }
  /* i-Button, Projektname und ScanPos-Ueberschrift sollen alle gleich hoch wirken - 44px,
     dieselbe Groesse wie im 3D-Fenster (Kompass/Open/Record/2D-Button/Ueberschrift, siehe
     proj.py reposition_compass_js), auf Anwenderwunsch (vorher 40px, dadurch leicht
     unterschiedlich zur 3D-Seite). */
  #projectTitle {
    color: #fff; background: rgba(255,255,255,0.12); padding: 0 12px; border-radius: 6px;
    height: 44px; box-sizing: border-box;
    font-size: 18px; font-weight: 400; white-space: nowrap; max-width: 40vw;
    text-overflow: ellipsis; overflow: hidden;
    border: none; cursor: pointer; font-family: system-ui, sans-serif;
  }
  #projectTitle option { color: #000; background: #fff; font-size: 16px; }
  #projectInfoBtn {
    width: 46px; height: 44px; box-sizing: border-box; flex: 0 0 auto; border-radius: 8px;
    border: none; background: rgba(255,255,255,0.12); color: #ff9500; font-size: 17px;
    font-weight: 700; font-style: italic; font-family: Georgia, 'Times New Roman', serif;
    cursor: pointer;
  }
  #projectInfoBtn:hover { background: rgba(255,255,255,0.25); }
  #panoScanLabelText { line-height: 44px; }
  /* Notification-Tool (siehe startNotifRecording/stopNotifRecording/openNotifPlayFile/
     showNextNotifEntry): 3 gleich grosse Icon-Buttons rechts neben dem Projektnamen - Open
     (Ordner-Symbol) laedt per "Datei oeffnen"-Dialog (showOpenFilePicker) eine bestehende
     Notification-Datei fuer Play; Record (Quadrat) schreibt (showSaveFilePicker) eine EIGENE,
     unabhaengige Datei und faerbt sich waehrend einer aktiven Aufzeichnung rot (.active);
     Play (Dreieck) bleibt deaktiviert, bis Open (oder Drag&Drop einer .txt-Datei) etwas
     geladen hat, und faerbt sich gruen (.active), waehrend man sich per Klick eine Notiz nach
     der anderen ansieht. */
  /* 44x44 (statt vormals 36x36) - dieselbe Groesse wie die Annotation-Recorder-Buttons der
     3D-Seite (siehe proj.py btnCss), auf Anwenderwunsch fuer ein einheitliches Erscheinungsbild
     der Recorder-Buttons auf beiden Seiten. */
  .notif-icon-btn {
    height: 44px; width: 44px; box-sizing: border-box; border-radius: 8px;
    background: rgba(255,255,255,0.12); color: #fff; font-size: 18px;
    display: flex; align-items: center; justify-content: center; padding: 0;
    cursor: pointer; line-height: 1;
  }
  .notif-icon-btn:hover { background: rgba(255,255,255,0.25); }
  .notif-icon-btn:disabled { opacity: 0.35; cursor: not-allowed; }
  .notif-icon-btn:disabled:hover { background: rgba(255,255,255,0.12); }
  .notif-icon-btn svg { width: 20px; height: 20px; }
  /* Als eigenes, exakt zentriertes Element (statt eines Unicode-Quadrat-Zeichens, dessen
     Position je nach Schriftart/Browser leicht verschoben wirken kann) - Hintergrundfarbe
     statt Textfarbe, damit sich die Farbe unabhaengig von Schriftglyphen-Eigenheiten aendert. */
  #notificationRecordBtn .notif-record-dot {
    width: 14px; height: 14px; background: #fff; border-radius: 1px;
  }
  #notificationRecordBtn.active .notif-record-dot { background: #ff3b30; }
  #notificationPlayBtn.active { color: #2ecc40; }
  #notifInputBox {
    position: fixed; z-index: 50; background: #fff; border: 2px solid #f39314;
    border-radius: 6px; padding: 6px; box-shadow: 0 2px 10px rgba(0,0,0,0.5);
  }
  #notifInputBox input {
    font-size: 14px; width: 240px; border: 1px solid #ccc; border-radius: 4px;
    padding: 4px 6px; font-family: system-ui, sans-serif;
  }
  #notifPlaybackPopup {
    position: fixed; z-index: 50; background: #fff8ec; border: 2px solid #f39314;
    border-radius: 6px; padding: 8px 12px; max-width: 320px; font-size: 14px;
    line-height: 1.4; color: #1c1c1c; box-shadow: 0 2px 10px rgba(0,0,0,0.5);
    font-family: system-ui, sans-serif; white-space: pre-wrap;
  }
  #projectInfoOverlay {
    display: none; position: fixed; inset: 0; z-index: 40;
    background: rgba(0,0,0,0.6); align-items: center; justify-content: center;
  }
  #projectInfoOverlay.open { display: flex; }
  #projectInfoPanel {
    position: relative; background: #111; color: #fff; border: 1px solid #333;
    border-radius: 8px; padding: 28px 32px; min-width: 340px; max-width: 90vw;
    font-family: system-ui, sans-serif;
  }
  #projectInfoPanel h2 { margin: 0 0 16px 0; font-size: 20px; line-height: 24px; }
  #projectInfoHeader { margin: 0 0 16px 0; }
  #projectInfoLogo { display: block; height: 40px; width: auto; }
  /* Position/Groesse bewusst absolut statt im Flow: soll bis zur Grundlinie von "Project
     Info" (h2 direkt darunter) reichen, waehrend die Oberkante mit dem Logo auf gleicher
     Hoehe bleibt - das laesst sich nur mit position:absolute exakt treffen (ein Flow-Element
     kann bestenfalls bis zur Oberkante des naechsten Elements reichen, nie bis zu dessen
     Grundlinie). top/right decken sich mit dem Panel-Padding (28px/32px), die Hoehe ist
     rechnerisch auf die Grundlinie von h2 abgestimmt (dessen line-height ist dafuer bewusst
     explizit gesetzt, siehe #projectInfoPanel h2) - je nach Schriftart/Browser ggf. noch
     minimal nachzujustieren. */
  #projectInfoQr {
    display: none; position: absolute; top: 28px; right: 56px; width: 76px; height: 76px;
    background: #fff; padding: 4px; border-radius: 4px; box-sizing: border-box;
  }
  #projectInfoQr.visible { display: block; }
  #projectInfoClose {
    position: absolute; top: 6px; right: 10px; background: none; border: none;
    color: #fff; font-size: 26px; cursor: pointer; line-height: 1;
  }
  .project-info-row {
    display: flex; justify-content: space-between; gap: 24px;
    font-size: 16px; padding: 6px 0; border-bottom: 1px solid #262626;
  }
  .project-info-row:last-child { border-bottom: none; }
  .project-info-row span { color: #aaa; }
  .marker--current {
    width: 264px; height: 264px;
    margin-left: -132px; margin-top: -132px;
    z-index: 6;
  }
  .marker--current .marker-imu-dot { display: block; }
  /* Zoom-/KML-/Ebenen-Buttons der Project Map rechtsbuendig UNTER dem Info-Kopf (#mapHeader,
     jetzt ebenfalls rechtsbuendig/oben, siehe #mapHeader-CSS) gestapelt - beide sitzen jetzt
     auf derselben (rechten) Seite, da der "3D"-Button seinen alten Platz oben links (wo
     #mapHeader vorher stand) uebernommen hat (siehe .goto-3d-btn). 8px (Header-Rand) + 40px
     (Header-Hoehe: 28px-Logo + 6px Polsterung oben/unten) + 8px Abstand = 56px. .zoom-controls
     selbst (top:8px statt bottom:16px) nicht direkt ueberschreiben, das ist eine von
     _VIEWER_CSS gemeinsam genutzte Klasse (auch von der eigenstaendigen Panorama-Einzelseite,
     siehe build_panorama_page_html, wo die Buttons bewusst unten bleiben sollen) -
     stattdessen hier, in der nur fuer diese Split-Ansicht geltenden _SPLIT_CSS, spezifischer
     (per #leftPane) nur fuer die Project Map ueberschrieben. */
  #leftPane .zoom-controls { top: 56px; bottom: auto; }

  #appModalOverlay {
    display: none; position: fixed; inset: 0; z-index: 60;
    background: rgba(0,0,0,0.6); align-items: center; justify-content: center;
  }
  #appModalOverlay.open { display: flex; }
  #appModalPanel {
    position: relative; background: #111; color: #fff; border: 1px solid #333;
    border-radius: 8px; padding: 28px 32px; min-width: 340px; max-width: 480px; width: 90vw;
    box-sizing: border-box; font-family: system-ui, sans-serif;
  }
  #appModalPanel h3 { margin: 0 0 16px 0; font-size: 18px; line-height: 24px; font-weight: 600; }
  #appModalPanel p { margin: 0 0 16px 0; font-size: 15px; line-height: 1.5; color: #ddd; }
  #appModalPanel p:last-child { margin-bottom: 0; }
  #appModalInput {
    width: 100%; box-sizing: border-box; padding: 8px 10px; font-size: 15px;
    border-radius: 6px; border: 1px solid #333; background: #1c1c1c; color: #fff; margin-bottom: 6px;
  }
  #appModalError { color: #ff6b6b; font-size: 13px; margin: 0 0 12px 0; min-height: 16px; }
  #appModalButtons { display: flex; justify-content: flex-end; gap: 10px; }
  #appModalButtons button {
    padding: 8px 18px; border-radius: 6px; border: none; background: rgba(255,255,255,0.12);
    color: #fff; font-size: 14px; cursor: pointer;
  }
  #appModalButtons button:hover { background: rgba(255,255,255,0.25); }
  #appModalButtons button.primary { background: #ff9500; color: #111; font-weight: 600; }
  #appModalButtons button.primary:hover { background: #ffaa33; }
  /* Design wie #projectInfoClose (i-Seite) - dieselbe Position/Optik fuer alle Modal-
     Schliessen-Buttons (Start-Hinweis, Hilfe). */
  #appModalNoticeClose, #appModalHelpClose {
    position: absolute; top: 6px; right: 10px; background: none; border: none;
    color: #fff; font-size: 26px; cursor: pointer; line-height: 1;
  }
