:root{
  /* Farbpalette. Vorher lagen diese Werte 213-mal als Literal in dieser Datei;
     eine Farbanpassung war damit eine Suchen-und-Ersetzen-Aktion mit Restrisiko.
     Die Namen sind absichtlich funktional (was ist es) statt beschreibend
     (welche Farbe ist es) - sonst heisst die Variable beim naechsten Theme falsch. */
  --bg: #131722;             /* Seitenhintergrund, tiefste Ebene */
  --surface: #1e222d;        /* Panels und Karten */
  --border: #2a2e39;         /* Standard-Rahmen und Trennlinien */
  --border-strong: #4a4e59;  /* betonter Rahmen, z. B. Hover */
  --text: #d1d4dc;           /* Fliesstext */
  --text-muted: #787b86;     /* Sekundaertext, Zeitstempel */
  --accent: #2962ff;         /* Markenblau: aktive Elemente, Links */
  --accent-dark: #1e40bf;    /* gedruecktes Blau */
  --accent-fade: #2962ff22;  /* Blau als Flaechenfuellung */
  --up: #089981;             /* steigender Kurs */
  --down: #ef5350;           /* fallender Kurs, Fehler */
  --down-fade: #ef535022;    /* Rot als Flaechenfuellung */
  --success: #4caf50;        /* ausgeloester Alarm */
  --text-strong: #fff;       /* hervorgehobener Text auf dunklem Grund */
--status-bar-height: 31px;}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%}
.sidebar{
  position:fixed;left:0;top:40px;bottom:24px;width:50px;
  background:var(--surface);border-right:1px solid var(--border);
  display:flex;flex-direction:column;align-items:center;
  padding-top:0;z-index:99
}
/* Trennt die Watchlist-Icons vom Rest der Leiste: einer unter dem Suche-Icon, einer
   darueber, wo das Einstellungen-Icon per `margin-top:auto` nach unten weggeschoben
   wird. `flex-shrink:0`, damit die Linie nicht verschwindet, wenn viele Listen da
   sind - dieselbe Falle wie beim SVG in `5f90e8d`. */
.sidebar-sep{
  width:24px;height:1px;flex-shrink:0;
  margin:6px 0;background:var(--border)
}
/* Der untere Trenner traegt den Auto-Abstand, nicht das Einstellungen-Icon.
   Vorher stand `margin-top:auto` am Icon: der Trenner klebte damit unmittelbar
   unter der letzten Watchlist, und zwischen ihm und den Einstellungen klaffte der
   ganze Rest der Leiste. Er soll aber das Icon abgrenzen, nicht die Watchlists nach
   unten abschliessen. */
.sidebar-sep.unten{margin-top:auto}
/* Nur ein Behaelter, kein eigenes Aussehen: die Icons darin sind `.sidebar-icon`
   wie alle anderen. Scrollt, sobald mehr Listen da sind als Platz - sonst schoebe
   die zwanzigste Watchlist die Einstellungen aus dem Bild. */
.sidebar-watchlists{
  display:flex;flex-direction:column;align-items:center;
  overflow-y:auto;overflow-x:hidden;min-height:0
}
.sidebar-icon{
  width:36px;height:36px;border-radius:8px;
  display:flex;align-items:center;justify-content:center;
  margin:4px 0;color:var(--text-muted);cursor:pointer;
  font-size:10px;
  position:relative /* Anker fuer .sidebar-icon-badge */
}
.sidebar-icon:hover{
  background:var(--border);color:var(--text)
}
.sidebar-icon.active{
  background:var(--accent);color:var(--text-strong)
}
.sidebar-icon[data-action="settings"]{
  margin-bottom:16px
}

/* Platzhalter fuer nachgeladene Icons (icon-loader.js).
   Die Groesse steht HIER und nicht am SVG: der Slot ist schon da, bevor die Datei
   geholt ist. Ohne feste Masse springt das Layout, sobald das SVG eintrifft.
   Farbe erbt ueber currentColor vom Container - deshalb wird inline eingesetzt
   statt per <img>. */
.icon-slot{
  display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;flex-shrink:0
}
.icon-slot svg{width:100%;height:100%;display:block}

/* Die Sidebar-Kacheln sind selbst schon 36px-Flexcontainer und zentrieren ihr Kind.
   Sie bekommen deshalb KEIN .icon-slot - die 20px kaemen sonst auf die Kachel statt
   auf das Icon. Die Groesse bringt das SVG als Attribut mit; diese Regel setzt sie
   nur durch, falls eine Datei sie einmal vergisst. */
.sidebar-icon svg{width:20px;height:20px;display:block}

/* Konto-Icon im Header (account-menu.js), an der frueheren Stelle des
   Alarm-Zustellung-Buttons - deshalb dasselbe margin-left:auto, das den
   Button vorher rechts im Header hielt (siehe .alarm-email-toggle, entfernt).
   Google-Profilbild als rundes <img>, sonst Initialen auf Akzentfarbe. */
.header-account{
  margin-left:auto;width:28px;height:28px;border-radius:50%;
  font-size:13px;font-weight:600;color:var(--text-strong);
  overflow:hidden;cursor:pointer;flex-shrink:0
}
.header-account img{width:100%;height:100%;border-radius:50%;object-fit:cover}
.header-account .account-initials{
  width:28px;height:28px;border-radius:50%;background:var(--accent);
  display:flex;align-items:center;justify-content:center
}

/* Dropdown-Menue am Konto-Icon: Name/E-Mail, Alarm-Zustellung, ggf.
   Nutzerverwaltung, Abmelden. top/right setzt account-menu.js dynamisch
   relativ zum Icon (das jetzt im Header sitzt, nicht mehr an einer festen
   Sidebar-Position). */
.account-menu{
  position:fixed;min-width:200px;
  background:var(--surface);border:1px solid var(--border);border-radius:8px;
  box-shadow:0 4px 16px #0006;padding:6px;z-index:200
}
.account-menu-info{padding:8px 10px;border-bottom:1px solid var(--border);margin-bottom:4px}
.account-menu-name{color:var(--text-strong);font-size:13px;font-weight:600}
.account-menu-email{color:var(--text-muted);font-size:11px;word-break:break-all}
.account-menu-item{
  display:block;width:100%;text-align:left;padding:8px 10px;border-radius:6px;
  background:none;border:none;color:var(--text);font-size:13px;cursor:pointer
}
.account-menu-item:hover{background:var(--border)}

/* Login-Screen: ersetzt den gesamten App-Rahmen, bis /api/auth/me eine
   gueltige Session bestaetigt (siehe components/auth.js). */
.login-screen{
  position:fixed;inset:0;background:var(--bg);z-index:1000;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px
}
/* `display:flex` oben schlaegt sonst IMMER das UA-Standardverhalten von
   [hidden] (display:none) - Klassen- und Attributselektor haben dieselbe
   Spezifitaet, aber Autoren-CSS gewinnt grundsaetzlich gegen die UA-Vorgabe.
   Ohne diese Regel blieb der Login-Screen dauerhaft sichtbar (leerer
   dunkler Vollbild-Layer), auch nach erfolgreichem Login und trotz per
   `el.hidden = true` gesetztem Attribut - beobachtet als "Seite bleibt
   schwarz" bei einem echten Google-Login-Testlauf. */
.login-screen[hidden]{display:none}
.login-screen .logo{font-size:28px;color:var(--text-strong)}
.login-screen .logo span{color:var(--accent)}
.login-screen-error{color:var(--down);font-size:13px;max-width:320px;text-align:center}
.login-google-btn{
  display:flex;align-items:center;gap:10px;padding:12px 24px;border-radius:6px;
  background:var(--surface);border:1px solid var(--border-strong);color:var(--text-strong);
  font-size:14px;cursor:pointer;text-decoration:none
}
.login-google-btn:hover{background:var(--border)}

/* Icon-Auswahl im Watchlist-Dialog. */
.watchlist-icon-picker{
  display:flex;gap:8px;flex-wrap:wrap;margin-top:10px
}
.watchlist-icon-picker:empty{display:none}
.icon-choice{
  width:34px;height:34px;border-radius:6px;border:1px solid var(--border);
  display:flex;align-items:center;justify-content:center;
  color:var(--text-muted);cursor:pointer;background:transparent
}
.icon-choice:hover{border-color:var(--border-strong);color:var(--text)}
.icon-choice.selected{border-color:var(--accent);color:var(--accent)}
.icon-choice:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* `flex-shrink:0` ist hier tragend, nicht kosmetisch.
   `.icon-choice` ist ein Flex-Container, das eingebettete SVG damit ein Flex-Element.
   Ohne diese Zeile drueckt der Browser es auf **Breite 0** zusammen - gemessen: 0x20
   statt 20x20. Sichtbar blieb ein leerer Kasten mit Rahmen, ohne Ladefehler und mit
   korrekter Farbe und Geometrie (getBBox 40x49), also ohne jeden Hinweis auf die
   Ursache. `.icon-slot` weiter oben setzt es aus demselben Grund. */
.icon-choice svg{width:20px;height:20px;display:block;flex-shrink:0}
.icon-choice-more{
  width:34px;height:34px;border-radius:6px;border:1px dashed var(--border-strong);
  display:flex;align-items:center;justify-content:center;
  color:var(--text-muted);cursor:pointer;background:transparent;
  font-size:16px;line-height:1
}
.icon-choice-more:hover{border-color:var(--accent);color:var(--accent)}
.icon-picker-more-overlay{
  position:fixed;inset:0;z-index:1001;
  background:rgba(0,0,0,0.75);
  display:none;align-items:center;justify-content:center
}
.icon-picker-more-overlay.open{display:flex}
.icon-picker-more-panel{
  background:var(--surface);border:1px solid var(--border);border-radius:8px;
  width:420px;max-width:90vw;max-height:80vh;
  display:flex;flex-direction:column;box-shadow:0 10px 40px rgba(0,0,0,0.5)
}
.icon-picker-more-header{
  display:flex;align-items:center;justify-content:space-between;
  padding:12px 16px;border-bottom:1px solid var(--border);
  color:var(--text-strong);font-size:14px;font-weight:600;flex-shrink:0
}
.icon-picker-more-close{
  background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:0
}
.icon-picker-more-close:hover{color:var(--text)}
.icon-picker-more-body{overflow-y:auto;padding:12px 16px}
.icon-picker-more-group{margin-bottom:14px}
.icon-picker-more-group-title{
  font-size:11px;font-weight:600;color:var(--text-muted);
  text-transform:capitalize;margin-bottom:6px
}
.icon-picker-more-grid{display:flex;flex-wrap:wrap;gap:8px}
body{font-family:Segoe UI,system-ui,sans-serif;background:var(--bg);color:var(--text);display:flex;flex-direction:column;overflow:hidden}
header{position:fixed;top:0;left:0;right:0;background:var(--surface);border-bottom:1px solid var(--border);padding:8px 12px;display:flex;align-items:center;gap:8px;flex-shrink:0;z-index:98;height:40px}
.logo{font-weight:700;color:var(--text-strong);font-size:16px}
.logo span{color:var(--accent)}
.search-wrapper{position:relative;flex:1}
.search-box{display:flex;background:var(--bg);border:1px solid var(--border);border-radius:4px;padding:0 8px}
.search-box input{flex:1;background:transparent;border:none;outline:none;color:var(--text);font-size:13px;padding:6px 4px;width:100%}
.search-box input::placeholder{color:var(--border-strong)}
.dropdown{position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(--surface);border:1px solid var(--border);border-radius:4px;max-height:240px;overflow-y:auto;z-index:100;display:none}
.dropdown.open{display:block}
.dropdown-section{padding:6px 0}
.dropdown-section-title{font-size:10px;font-weight:600;color:var(--border-strong);text-transform:uppercase;letter-spacing:.5px;padding:4px 10px 6px}
.dropdown-item{display:flex;align-items:center;gap:8px;padding:6px 10px;cursor:pointer;font-size:12px}
.dropdown-item:hover,.dropdown-item.active{background:var(--border)}
.dropdown-item .item-icon{width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;color:var(--text-strong);flex-shrink:0}
.dropdown-item .item-info{flex:1;min-width:0}
.dropdown-item .item-symbol{font-weight:600;color:var(--text)}
.dropdown-item .item-name{font-size:11px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dropdown-item .item-type{display:flex;align-items:center;gap:8px;padding:2px 6px;border-radius:3px;background:var(--border);color:var(--border-strong);font-size:10px}
.interval-bar{display:flex;gap:2px}
.int-btn{padding:4px 8px;border:1px solid var(--border);border-radius:4px;background:transparent;color:var(--text-muted);cursor:pointer;font-size:11px}
.int-btn:hover{background:var(--border);color:var(--text)}
.int-btn.active{background:var(--accent);border-color:var(--accent);color:var(--text-strong)}
.category-bar{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-left:12px}
.category-chip{padding:3px 8px;border:1px solid var(--border);border-radius:12px;background:transparent;color:var(--text-muted);cursor:pointer;font-size:11px}
.category-chip:hover{background:var(--border);color:var(--text)}
.category-chip.active{background:var(--accent);border-color:var(--accent);color:var(--text-strong)}
.category-chip.watchlist-chip{margin-left:8px}
.sector-select{margin-left:8px;padding:3px 6px;border:1px solid var(--border);border-radius:4px;background:var(--bg);color:var(--text-muted);cursor:pointer;font-size:11px}
.sector-select:hover{color:var(--text)}
.search-watchlist-names{display:flex;flex-wrap:wrap;gap:4px;align-items:center;margin-left:10px;font-size:11px;color:var(--text-muted)}
.search-watchlist-names a{color:var(--accent);cursor:pointer;text-decoration:none}
.search-watchlist-names a:hover{text-decoration:underline}
.search-watchlist-names .sep{color:var(--border-strong)}
#view{
  display:flex;
  flex-direction:column;
  flex:1;
  margin-left:50px;
  width:calc(100vw - 50px);
  height:calc(100vh - 64px);
  margin-top:40px;
  box-sizing:border-box;
  overflow:hidden;
  padding-bottom: var(--status-bar-height);
}
#view.sidebar-open{
  width:calc(100vw - 50px - 260px);
}
.stockdetails-view{height:100%}
.view{height:100%}
/* #main-chart und .chart-area sind mit der alten Suchansicht entfallen - beide
   kamen in keiner Vorlage mehr vor. Der Chart lebt jetzt ueberall in #detail-chart. */
#detail-chart{flex:1;width:100%;position:relative;min-height:0}
/* Loesch-Icon einer ausgewaehlten horizontalen Chart-Linie (Drawing-Tools) -
   absolut positioniert von chart-widget.js, `right` statt `left`, damit es
   nicht mit dem Preis-Achsen-Label derselben Linie ueberlappt. */
.chart-line-delete-btn{
  display:none;position:absolute;right:8px;z-index:5;
  width:20px;height:20px;align-items:center;justify-content:center;
  background:var(--down);color:#fff;border:none;border-radius:50%;
  cursor:pointer;font-size:12px;line-height:1;padding:0;
}
.chart-line-delete-btn:hover{filter:brightness(1.15)}
.info-bar{display:flex;gap:12px;font-size:11px;color:var(--text-muted);padding:4px 12px}
.info-item span{color:var(--text);font-weight:500}
.status{margin-left:auto;font-size:11px;padding:2px 6px;border-radius:3px}
.status.loading{background:var(--border);color:var(--text)}
.status.live{background:var(--accent-fade);color:var(--accent)}
.status.error{background:var(--down-fade);color:var(--down)}
.price-up{color:var(--up);font-weight:600}
.price-down{color:var(--down);font-weight:600}
/* Status Bar - Sticky Footer */
.status-bar{
  position:fixed;bottom:0;left:0;right:0;
  background:var(--surface);border-top:1px solid var(--border);
  padding:6px 12px;display:flex;align-items:center;
  font-size:11px;color:var(--text-muted);z-index:100
}
.status-bar .server-status{
  display:flex;align-items:center;gap:4px
}
.status-bar .server-dot{
  width:8px;height:8px;border-radius:50%;background:var(--up)
}
.status-bar .server-dot.offline{background:var(--down)}
.status-bar button{
  background:var(--border);border:1px solid var(--border);
  color:var(--text);border-radius:4px;padding:2px 8px;
  cursor:pointer;margin-left:8px;font-size:11px
}
.status-bar button:hover{background:var(--accent);border-color:var(--accent)}
/* Eigenstaendiges Overlay-Panel oberhalb der Status-Leiste, kein Kind mehr
   davon - vorher liess ein Kind mit max-height:120px in der Flex-Row die
   ganze Leiste mitwachsen (siehe grilling-Session dazu: "Konsolen-Panel wie
   im Browser" statt Leiste-die-sich-aufblaeht). Ueberdeckt bei Bedarf den
   Chart-Inhalt (Overlay), statt ihm Platz wegzunehmen - bewusste Entscheidung,
   da das Log nur ein kurzzeitig eingeblendetes Debug-Werkzeug ist. */
.log-panel{
  position:fixed;left:0;right:0;bottom:var(--status-bar-height);
  height:240px;overflow-y:auto;
  background:var(--bg);border-top:1px solid var(--border);
  padding:6px 12px;display:none;z-index:100
}
.log-panel.open{display:block}
.log-entry{font-size:10px;white-space:nowrap}
.status-bar .update-time{margin-left:auto;color:var(--border-strong)}
/* View Styles */
.view-header{
  background:var(--surface);border-bottom:1px solid var(--border);
  padding:8px 12px;display:flex;align-items:center;gap:8px;flex-shrink:0
}
.detail-grid{
  display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;
  gap:8px;margin:8px;flex:1
}
.detail-panel{
  background:var(--surface);border:1px solid var(--border);border-radius:8px;
  padding:12px;display:flex;flex-direction:column
}
.detail-panel h3{
  margin-top:0;margin-bottom:12px;color:var(--text);font-size:14px;
  border-bottom:1px solid var(--border);padding-bottom:8px
}
/* Legende der aktiven gleitenden Durchschnitte unter dem Chart.
   `flex-shrink:0`, weil #detail-chart daneben `flex:1` traegt - ohne das wuerde
   die Legende den Chart zusammendruecken statt selbst ihre Zeile zu behalten.
   Leer und ohne eigenes Aussehen, solange keine MA aktiv ist (siehe :empty) -
   chart-loader.js schreibt sie bei jedem Laden neu, auch leer. */
/* RSI/MACD/Stochastic-Sub-Panels (chart-widget.js): eigene Lightweight-Charts-
   Instanz je Panel statt gemeinsamer Preisskala mit `scaleMargins` - siehe
   Kommentar in ChartWidget._syncTimeScale(). `flex:1` verteilt den
   verbleibenden Platz automatisch gleichmaessig auf die AKTIVEN (nicht
   `display:none`) Sub-Panels, #detail-chart behaelt mit `flex:3` immer die
   groesste Flaeche - kein manuelles Nachrechnen der Anteile noetig, das
   erledigt Flexbox beim Ein-/Ausblenden eines Panels von selbst. */
.oscillator-pane{
  flex:1;
  min-height:0;
  border-top:1px solid var(--border);
}
/* `flex:1;min-width:0` statt des vorherigen `flex-shrink:0`: ohne eine echte
   Flex-Breite bemisst sich die Box an ihrem eigenen Inhalt (max-content) und
   `flex-wrap:wrap` greift nie, selbst wenn in der Zeile Platz fuer eine zweite
   Zeile waere - der Umbruch braucht eine tatsaechliche Breitenbeschraenkung,
   nicht nur die Erlaubnis dazu. */
.ma-legend{
  display:flex;flex-wrap:wrap;gap:4px 12px;
  flex:1;min-width:0;padding-top:8px;font-size:11px;color:var(--text-muted)
}
.ma-legend:empty{display:none}
.ma-legend-item{display:inline-flex;align-items:center;gap:5px}
.ma-legend-swatch{
  width:10px;height:10px;border-radius:2px;flex-shrink:0
}
.placeholder{
  color:var(--text-muted);font-size:13px
}
/* Profile Info */
.profile-section{
  padding:8px 0;
}
.profile-name{
  color:var(--text);
  font-weight:600;
  font-size:14px;
  margin-bottom:4px;
}
.profile-type, .profile-sector, .profile-industry{
  color:var(--text-muted);
  font-size:12px;
}
.profile-desc{
  color:#9598a1;
  font-size:12px;
  margin-top:8px;
  line-height:1.4;
}
/* Eigene Zeile mit dem Titel ("Bitcoin"), nicht mit der Untertitelzeile
   darunter (Kuerzel/Boerse/Typ/Sektor) - die ist ueber .profile-details als
   -webkit-box gesetzt (siehe dort) und haette Kurs/Aenderung sonst auf eine
   dritte, eigene Zeile gedrueckt. ID-Selektoren statt Klassen: updateInfo()
   in chart-loader.js ersetzt #info-change.className komplett
   (price-up/price-down), eine Klasse fuer den Abstand hier wuerde dabei mit
   verschwinden. */
.detail-layout .detail-title-row{display:flex;align-items:baseline;gap:8px}
.detail-layout .detail-header #info-price{font-weight:600;color:var(--text);font-size:14px}
.detail-layout .detail-header #info-change{font-size:12px}
.profile-details{
  color:var(--text-muted);
  font-size:12px;
  line-height:1.2;
  /* Feste Hoehe von EINER Zeile - unabhaengig vom Inhalt.
     Die Zeile ist beim Laden leer und wird erst gefuellt, wenn /api/profile
     antwortet. Ohne feste Hoehe sprang die Ansicht dadurch um 33 px: .detail-grid
     begann bei y=93 und rutschte auf y=126. Dazu kam ein zweiter Sprung beim
     Symbolwechsel, weil die Laenge der Beschreibung von Papier zu Papier
     verschieden ist.
     Reserviert waren zuerst zwei Zeilen. Nachgemessen brauchte kein Symbol sie:
     BTC (55 Zeichen), QSR (89), AAPL (94) und MCD (148) belegen ueber die volle
     Kopfbreite je genau eine Zeile von 14 px. Die zweite stand also praktisch
     immer leer und schob das Panel-Raster 15 px nach unten.
     1.2em = 1 x line-height bei 12px Schrift. Was nicht hineinpasst - etwa in der
     Detailansicht bei offener Sidebar, die 260 px schmaler ist - wird
     abgeschnitten statt umzubrechen; den vollen Text traegt das title-Attribut,
     das fundamental-component.js setzt. */
  display:-webkit-box;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:1;
  line-clamp:1;
  overflow:hidden;
  height:1.2em;
}

/* Fundamental-Panel (fundamental-component.js): nur die Kennzahlen-Kacheln.
   Name/Typ/Boerse/Sektor/Branche/Beschreibung stehen schon in der Titel-/
   Subtitle-Leiste (.profile-details oben), deshalb hier nicht wiederholt.
   Eigener Namensraum (fund-*) statt der aelteren .profile-*-Klassen oben -
   die sind nur noch von hier definiert, aber nicht mehr benutzt, absichtlich
   unangetastet gelassen. */
.fund-panel{
  overflow-y:auto;
}
/* Fundamental/Technisch (stockdetails-view.html): zwei eigenstaendige
   .detail-panel-Boxen (eigener Rahmen/Radius je Panel) statt einer
   gemeinsamen Box mit interner Trennlinie - `.fund-tech-stack` uebernimmt an
   der bisherigen Grid-Zelle nur die Rolle, die vorher `.detail-panel` selbst
   hatte (flex-Spalte, volle Zellenhoehe), damit Chart/Nachrichten/Analyse
   unveraendert gross bleiben. `.fund-tech-half` bekommt `flex:1;min-height:0`
   statt fester Prozentwerte, damit beide Boxen exakt die Haelfte der
   verfuegbaren Hoehe bekommen, unabhaengig vom Inhalt. */
.fund-tech-stack{
  display:flex;
  flex-direction:column;
  gap:8px;
  min-height:0;
}
.fund-tech-half{
  flex:1;
  min-height:0;
  overflow-y:auto;
}
.fund-stats{
  display:grid;
  /* Grid statt flex-wrap: flex brach abhaengig von der verfuegbaren
     Panel-Breite unterschiedlich um, die Kacheln landeten nicht zuverlaessig
     in gleichmaessigen Reihen. Ein echtes Grid fuellt immer links-oben nach
     rechts-unten auf, unabhaengig von der Panel-Breite.
     auto-fill statt fester Spaltenzahl: bei breiten Panels (grosse
     Aufloesung, .detail-grid gibt der rechten Spalte oft mehr als 436px)
     blieb rechts sonst eine grosse Luecke, weil 3 Spalten a max. 140px nie
     mehr Platz beanspruchten. minmax(140px, 1fr) haelt die Mindestbreite und
     verteilt uebrigen Platz gleichmaessig auf so viele Spalten, wie hinein-
     passen - bei schmalen Panels bleibt es bei den bisherigen 2-3 Spalten. */
  grid-template-columns:repeat(auto-fill, minmax(140px, 1fr));
  gap:8px;
  /* Kein border-top mehr: der trennte frueher Name/Chips/Beschreibung von den
     Kacheln, als das Panel noch mehr Inhalt hatte. Seit die Kacheln der erste
     (oft einzige) Inhalt sind, stand hier nur noch eine Linie ohne etwas zum
     Abtrennen darueber. */
}
.fund-stat-tile{
  background:var(--bg);border:1px solid var(--border);border-radius:6px;
  padding:8px 10px;
  position:relative;
}
.fund-stat-label{
  color:var(--text-muted);font-size:11px;margin-bottom:3px;
}
.fund-stat-value{
  color:var(--text);font-size:15px;font-weight:600;
}
.fund-stat-sub{
  color:var(--text-muted);font-size:11px;margin-top:2px;
}
/* Extremwert-Badges im Technisch-Panel (technical-panel.js): ueberkauft/hoch
   und ueberverkauft/niedrig ueberschreiben die neutrale .fund-stat-sub-Farbe. */
.tech-extreme-high{color:#ef5350;font-weight:600}
.tech-extreme-low{color:#26a69a;font-weight:600}
/* Historische Kennzahlen (Jahr -> KGV/KBV/KUV) frueher als eigene Tabelle
   unter den Kacheln, jetzt als Hover-Tooltip direkt auf der jeweiligen Kachel
   (nur KGV/KUV/KBV haben historische Werte) - spart Platz, die Zuordnung
   Kachel<->Historie ist so auch eindeutiger als in einer separaten Tabelle.
   Positionierung per JS (siehe fundamental-component.js attachTooltipHandlers):
   ein rein CSS-basiertes Oeffnen (oben oder unten fest) wird in beiden
   Richtungen vom umgebenden .fund-panel (overflow-y:auto) abgeschnitten,
   sobald die Kachel nah genug am Panel-Rand liegt. position:fixed entkommt
   dem Scroll-Container, die Richtung (oben/unten) wird bei jedem Hover
   anhand des tatsaechlich verfuegbaren Platzes im Viewport berechnet. */
.fund-stat-tile.has-history{
  cursor:default;
}
/* Ladephase in loadFundamental(): generische Platzhalter-Kacheln in der
   .fund-stat-tile-Struktur, damit das Panel beim Symbolwechsel sofort
   geleert wird statt die Kennzahlen des vorherigen Symbols zu zeigen, und
   die echten Kacheln ohne Layout-Sprung nachfolgen. */
.fund-skeleton-label,.fund-skeleton-value{
  border-radius:4px;
  background:linear-gradient(90deg,var(--border) 25%,var(--border-strong) 50%,var(--border) 75%);
  background-size:200% 100%;
  animation:fund-shimmer 1.4s ease-in-out infinite;
}
.fund-skeleton-label{
  width:60%;height:11px;margin-bottom:5px;
}
.fund-skeleton-value{
  width:40%;height:15px;
}
@keyframes fund-shimmer{
  0%{background-position:200% 0}
  100%{background-position:-200% 0}
}
.fund-tooltip{
  display:none;
  position:fixed;
  background:var(--bg);border:1px solid var(--border);border-radius:6px;
  padding:6px 10px;box-shadow:0 2px 8px rgba(0,0,0,0.15);
  white-space:nowrap;z-index:1000;
  font-size:11px;
}
.fund-tooltip-row{
  display:flex;justify-content:space-between;gap:12px;color:var(--text);
}
.fund-tooltip-row span:first-child{
  color:var(--text-muted);
}
.detail-label{
  font-style:italic;
}
.detail-value{
  font-weight:700;
  color:var(--text);
}
/* Settings Modal */
.settings-modal-overlay{
  position:fixed;top:0;left:0;right:0;bottom:0;
  background:rgba(0,0,0,0.75);
  backdrop-filter:blur(4px);
  z-index:1000;
  display:none;
  align-items:center;
  justify-content:center;
}
.settings-modal{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:12px;
  width:600px;
  max-width:90vw;
  max-height:80vh;
  padding:20px;
  box-shadow:0 10px 40px rgba(0,0,0,0.5);
  display:flex;
  flex-direction:column;
}
/* `max-height` auf .settings-modal allein reicht nicht: #settings-modal-content
   war ein ungestyltes Block-Div, wuchs also mit seinem Inhalt statt zu
   schrumpfen, und .settings-content darunter bekam nie eine begrenzte Hoehe,
   an der `overflow-y:auto` haette greifen koennen - bei allen drei Sektionen
   aufgeklappt waere das Modal einfach ueber 80vh hinausgewachsen (bzw. der
   Inhalt haette den abgerundeten Rand ueberragt, da .settings-modal kein
   eigenes `overflow` setzt). `min-height:0` ist hier kein Zufallswert, sondern
   der bekannte Flexbox-Fallstrick: ohne ihn verweigert ein Flex-Kind das
   Schrumpfen unter seine Inhaltsgroesse, egal was `flex:1` sagt.
*/
#settings-modal-content{display:flex;flex-direction:column;flex:1;min-height:0}
.settings-modal.open{display:flex}
.settings-modal-overlay.open{display:flex}
.settings-modal h1{margin-top:0;color:var(--text-strong);font-size:24px}
.settings-section{background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:16px;margin-bottom:16px}
.settings-section h3{margin-top:0;margin-bottom:12px;color:var(--text);font-size:14px;border-bottom:1px solid var(--border);padding-bottom:8px}
/* `summary` ersetzt `h3` als Sektionsueberschrift - dieselbe Optik, aber
   anklickbar. Der native Aufklapp-Pfeil bleibt, er ist die einzige Anzeige,
   dass da noch mehr ist. Der Fallback-Zweig in settings-view.js benutzt bei
   einem Ladefehler weiterhin `h3` ohne `details`, deshalb bleibt die Regel
   darueber bestehen statt ersetzt zu werden. */
.settings-modal .settings-section summary{
  margin-bottom:12px;color:var(--text);font-size:14px;
  border-bottom:1px solid var(--border);padding-bottom:8px;cursor:pointer
}
.settings-modal .settings-section[open] summary{margin-bottom:12px}
.settings-modal .setting-item{display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px solid var(--border)}
.settings-modal .setting-item:last-child{border-bottom:none}
.settings-modal .setting-label{font-weight:500}
.settings-modal .setting-input,.settings-modal .setting-value{
  background:var(--bg);border:1px solid var(--border);border-radius:4px;color:var(--text);padding:6px 10px;width:180px
}
.settings-modal .toggle-switch{position:relative;display:inline-block;width:40px;height:20px}
.settings-modal .toggle-switch input{opacity:0;width:0;height:0}
.settings-modal .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background:var(--border);transition:.4s;border-radius:20px}
.settings-modal .slider:before{position:absolute;content:"";height:16px;width:16px;left:2px;bottom:2px;background:white;transition:.4s;border-radius:50%}
.settings-modal input:checked + .slider{background:var(--accent)}
.settings-modal input:checked + .slider:before{transform:translateX(20px)}
/* Ein/Aus-Schalter und Farbwaehler pro MA-Zeile nebeneinander statt des vollen
   180px-Feldes - eine Farbe braucht keine 180px, sonst haette die Zeile mehr
   Leerraum als Inhalt. */
.settings-modal .ma-controls{display:flex;align-items:center;gap:10px}
/* Fuenf Zeilen mit dem normalen 10px-Zeilenabstand der uebrigen Einstellungen
   waren der groesste Einzelposten in der Hoehe des Chart-Fachs. Engerer
   Abstand plus kleinere Swatches sparen das ein, ohne Zeilen zusammenzulegen -
   Ein/Aus und Farbe pro Periode bleiben getrennt klickbar. */
.settings-modal .ma-row{padding:6px 0}
/* Eigene Regel statt `.setting-value`: das waere 180px breit und wuerde die
   Zeile sprengen, in der Schalter, Typ und acht Swatches nebeneinander stehen. */
.settings-modal .ma-type{
  background:var(--bg);border:1px solid var(--border);border-radius:4px;
  color:var(--text);padding:2px 4px;font-size:11px;cursor:pointer
}
/* Swatch-Palette statt input[type=color]: der native Picker oeffnet unter
   Windows einen Systemdialog fern vom Feld, hier bleibt die Auswahl in der
   Zeile. `.selected` bekommt einen hellen Ring statt die Groesse zu aendern,
   damit die Reihe beim Klicken nicht springt. */
.settings-modal .ma-color-picker{display:flex;gap:4px}
.settings-modal .color-swatch{
  width:16px;height:16px;border-radius:50%;border:2px solid transparent;
  padding:0;cursor:pointer;box-shadow:0 0 0 1px var(--border)
}
.settings-modal .color-swatch.selected{border-color:var(--text-strong)}
.modal-buttons{
  display:flex;justify-content:center;gap:12px;
  padding:16px;border-top:1px solid var(--border);
  background:var(--surface);border-radius:0 0 12px 12px;
  flex-shrink:0;
}
.settings-modal button{background:var(--accent);color:var(--text-strong);border:none;padding:8px 16px;border-radius:6px;cursor:pointer;font-size:13px}
.settings-modal button:hover{background:var(--accent-dark)}
.settings-modal button.secondary{background:var(--border);color:var(--text)}
.settings-modal button.secondary:hover{background:#3a3f4f}
/* Settings View Template */
.settings-view{
  /* `flex:1;min-height:0` statt der frueheren festen `min-height:400px` - das
     Modal soll bei zugeklappten Sektionen jetzt gerade so hoch sein wie sein
     Inhalt, nicht mehr. `min-height:0` ist Teil der Scroll-Kette zu
     .settings-content, siehe Kommentar bei #settings-modal-content oben. */
  display:flex;flex-direction:column;flex:1;min-height:0;
}
.settings-view h1{margin-top:0;color:var(--text-strong);font-size:24px;flex-shrink:0}
.settings-content{flex:1;min-height:0;overflow-y:auto}
.settings-section{background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:16px;margin-bottom:16px}
.settings-section h3{margin-top:0;margin-bottom:12px;color:var(--text);font-size:14px;border-bottom:1px solid var(--border);padding-bottom:8px}
/* View container already defined above with flex properties */
.hidden{display:none}
/* Dashboard view styling */
#dashboard-view{
  text-align:center;
  display:flex;
  flex-direction:column;
}
#dashboard-view h1{
  color:var(--text);
}
#dashboard-view p{
  color:var(--text-muted);
  margin-top:20px;
}
.detail-layout{
  display:flex;
  flex-direction:column;
  height:100%;
  position:relative;
  overflow:hidden;
}
.detail-layout .detail-header{
  /* Unten weniger als oben: zwischen Untertitelzeile und Panel-Raster standen
     28 px aus drei Posten - 8 px hier, 8 px `margin` von `.detail-grid` und 12 px
     dessen `padding-top`. Das war deutlich mehr, als die Trennung braucht. */
  padding:8px 20px 4px;
  flex-shrink:0;
  display:flex;
  align-items:flex-end;
  gap:12px;
}
.detail-layout .detail-header h1{
  color:var(--text);
  font-size:20px;
  margin:0;
  text-align:left;
  line-height:1;
}
.detail-layout .detail-grid{
  display:grid;
  grid-template-columns:1fr 1fr;
  grid-template-rows:1fr 1fr;
  gap:12px;
  /* Oben schmaler als unten, und der `margin:8px` der allgemeinen `.detail-grid`
     wird hier oben zurueckgenommen. Beide Werte zusammen ergaben 20 px zusaetzlich
     zum Innenabstand des Kopfes - der Untertitel schwebte dadurch weit ueber dem
     ersten Panel. Links, rechts und unten bleibt es beim bisherigen Abstand. */
  margin-top:0;
  padding:6px 20px 12px 20px;
  flex:1;
  min-height:0;
}
.detail-layout .detail-panel h3{
  color:var(--text-strong);
  margin-top:0;
  margin-bottom:15px;
  flex-shrink:0;
  font-size:16px;
  border-bottom:1px solid var(--border);
  padding-bottom:8px;
}
.detail-layout .detail-panel .placeholder{
  color:var(--text-muted);
  text-align:center;
  flex-grow:1;
  display:flex;
  align-items:center;
  justify-content:center;
  font-style:italic;
}
/* News Panel */
.news-panel{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:16px;display:flex;flex-direction:column;flex:1;min-height:0}
.news-panel h3{margin-top:0;margin-bottom:12px;color:var(--text);font-size:14px;border-bottom:1px solid var(--border);padding-bottom:8px}
.news-content{flex:1;overflow-y:auto;min-height:0;padding-right:12px}
.news-loading,.news-empty{color:var(--text-muted);font-size:13px;text-align:center;padding:20px}
.news-error{color:var(--down);font-size:13px;text-align:center;padding:20px}
.sentiment-badge{font-size:11px;font-weight:600;padding:2px 8px;border-radius:10px;white-space:nowrap}
.sentiment-badge.positive{color:var(--up);background:#0899812e}
.sentiment-badge.negative{color:var(--down);background:var(--down-fade)}
.sentiment-badge.neutral{color:var(--text-muted);background:var(--border)}
.news-item{padding:12px 0;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center}
.news-item:last-child{border-bottom:none}
.news-title{color:var(--text);font-weight:500;flex:1;text-decoration:none}
.news-title:hover{color:var(--accent);text-decoration:underline}
.news-meta{display:flex;justify-content:flex-end;font-size:11px;color:var(--text-muted);gap:8px}
/* Watchlist Sidebar */
.watchlist-toggle-container{
  margin-left:auto;
}
.watchlist-toggle-btn{
  background:var(--border);
  border:1px solid var(--border);
  color:var(--text);
  border-radius:4px;
  padding:4px 8px;
  cursor:pointer;
  font-size:14px;
}
.watchlist-toggle-btn:hover{
  background:var(--accent);
  border-color:var(--accent);
}
/* Ueberschreibt .icon-slots 20x20 - der Chevron war schon immer 16x16, seit
   dem Umstieg auf public/icons/ui/chevron-left.svg/chevron-right.svg bringt
   .icon-slot sonst die groessere Standardgroesse mit. */
.watchlist-toggle-btn .icon-slot{
  width:16px;
  height:16px;
}
/* Chart Zoom - #chart-panel wird als fixiertes Overlay ueber die ganze Seite
   gelegt (inkl. Sidebar/Header), das eigenstaendige Backdrop-Element sitzt
   knapp dahinter. Eine ID-Regel (#chart-panel.zoomed) schlaegt automatisch
   jede bestehende klassenbasierte Regel auf #chart-panel (.detail-panel,
   .detail-layout .detail-grid ...), kein !important noetig. */
/* Ohne das hier blieb die Grid-Spalte nach dem Entzoomen riesig: Lightweight
   Charts setzt beim Resize eine feste Inline-Breite auf sein internes
   Chart-Element; die wirkt als Mindestinhaltsgroesse (min-width:auto ist der
   Grid-Standard) und zwingt die 1fr-Spalte, sich daran auszurichten, statt zu
   schrumpfen. Gemessen: 1536px statt der haelftigen Spaltenbreite, nachdem der
   Chart einmal auf Zoom-Groesse aufgeloest hatte. Erst im echten Chrome
   sichtbar - die Sandbox-Browser-Umgebung dieser Session komponiert keine
   Frames und haette den Fehler nie gezeigt. */
#chart-panel{min-width:0;min-height:0}
/* .zoom-backdrop und .zoom-btn sind rein optisch und deshalb von Chart- und
   Nachrichten-Zoom gemeinsam genutzt (vorher .chart-zoom-backdrop/
   .chart-zoom-btn, hier umbenannt). Zustand, Verdrahtung und IDs bleiben pro
   Panel getrennt (chart-zoom.js/news-zoom.js) - siehe Plan-Datei zur
   Begruendung gegen eine gemeinsame Zoom-Funktion. */
.zoom-backdrop{
  display:none;
  position:fixed;inset:0;
  background:rgba(0,0,0,0.75);
  backdrop-filter:blur(4px);
  z-index:999;
}
.zoom-backdrop.open{display:block}
/* `inset:0;margin:auto` statt transform:translate(-50%,-50%) zum Zentrieren:
   ein transform auf #chart-panel wuerde einen neuen Containing Block fuer
   position:fixed-Nachfahren erzeugen und koennte mit Lightweight Charts'
   eigener interner Positionierung (Tooltip/Crosshair) kollidieren. Beim
   Nachrichten-Panel gibt es diese Kollisionsgefahr nicht, aber zwei
   baugleiche Overlays mit unterschiedlicher Zentriertechnik waeren nur
   verwirrend. */
#chart-panel.zoomed{
  position:fixed;inset:0;margin:auto;
  width:80vw;height:80vh;
  z-index:1000;
  background:var(--surface);
  box-shadow:0 10px 40px rgba(0,0,0,0.5);
}
/* #news-panel hat noch kein bekanntes Gegenstueck zur Lightweight-Charts-
   Inline-Breite, die beim Chart-Panel min-width:0 noetig machte - trotzdem
   vorsorglich gesetzt, news-component.js ersetzt nur innerHTML, aber eine
   spaetere Aenderung dort soll nicht denselben Grid-Bug wieder einschleppen
   koennen. */
#news-panel{min-width:0}
#news-panel.zoomed{
  position:fixed;inset:0;margin:auto;
  width:80vw;height:80vh;
  z-index:1000;
  background:var(--surface);
  box-shadow:0 10px 40px rgba(0,0,0,0.5);
}
.zoom-btn{
  background:var(--border);border:1px solid var(--border);color:var(--text);
  border-radius:4px;padding:4px 8px;cursor:pointer;font-size:14px;
  display:flex;align-items:center;justify-content:center;
}
.zoom-btn:hover{background:var(--accent);border-color:var(--accent)}
/* Kurzzeitiger Fehlerzustand von #chart-copy-toggle (chart-screenshot.js) -
   z.B. Browser ohne ClipboardItem-Unterstuetzung oder toBlob()-Fehler. */
.zoom-btn.screenshot-error{background:var(--down-fade);border-color:var(--down);color:var(--down)}
/* #alarm-lines-toggle traegt drei Glocken-SVGs uebereinander; welche sichtbar
   ist, bestimmt data-mode (siehe chart-loader.js bindAlarmLinesToggle()). */
#alarm-lines-toggle .mode-icon{display:none}
#alarm-lines-toggle[data-mode="all"] .mode-all{display:block}
#alarm-lines-toggle[data-mode="pending"] .mode-pending{display:block}
#alarm-lines-toggle[data-mode="off"] .mode-off{display:block}
/* Eigener Hover-Stil statt des geerbten .zoom-btn:hover (Akzentblau) - der
   Zustand wird hier bereits eindeutig durch das Glocken-Icon selbst
   angezeigt (durchgestrichen = aus, siehe mode-off oben), ein zusaetzliches
   Blau beim Drueberfahren war nur ein Highlight ohne eigene Bedeutung. */
#alarm-lines-toggle:hover{
  background:var(--border-strong);border-color:var(--border-strong);
}
/* #rsi-toggle sitzt links neben der Alarm-Glocke im Chart-Panel - schneller
   Schalter direkt am Chart statt im Einstellungen-Modal (siehe
   bindRsiToggle() in chart-loader.js). Aktiv-Zustand wie zoom-btn:hover, aber
   dauerhaft statt nur beim Hover. */
/* Eigener Hover-Stil statt des geerbten .zoom-btn:hover: der nutzt dieselbe
   Akzentfarbe wie "aktiv" - beim Drueberfahren sah ein ausgeschalteter Knopf
   optisch identisch mit einem eingeschalteten aus. Jetzt bleibt Hover
   neutral-grau (border-strong). "Aktiv" bekommt bewusst KEIN Farb-Highlight
   (siehe Kommentar an Ort und Stelle unten) - nur fette Schrift, dezenter als
   eine Akzentfarbe, aber trotzdem eindeutig vom Aus-Zustand unterscheidbar. */
#rsi-toggle:hover, #macd-toggle:hover, #stoch-toggle:hover, #bollinger-toggle:hover, #sr-toggle:hover{
  background:var(--border-strong);border-color:var(--border-strong);
}
#rsi-toggle.active, #macd-toggle.active, #stoch-toggle.active, #bollinger-toggle.active, #sr-toggle.active{
  font-weight:700;color:var(--text-strong);
}
/* Zeichenwerkzeuge (horizontale Linie/Trendlinie/Fibonacci plus "alle loeschen")
   als schmale vertikale Icon-Leiste am linken Chart-Rand, TradingView-aehnlich -
   vorher standen sie als Text-Knoepfe in derselben ueberladenen Zeile wie die
   Indikator-Umschalter. Bewusst eine eigene Leiste statt Erweiterung von
   .zoom-btn: Zeichenwerkzeuge sind ein "gerade aktiver Modus, wartet auf Klicks
   im Chart" (siehe armDrawLineMode() in chart-widget.js), keine Dauer-Anzeige
   wie RSI/MACD - eine eigene Klasse haelt beide Konzepte auseinander. */
.drawing-toolbar{
  display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:6px 4px 6px 0;flex-shrink:0;
  border-right:1px solid var(--border);
  margin-right:8px;
}
.draw-tool-btn{
  background:transparent;border:1px solid transparent;color:var(--text-muted);
  border-radius:4px;width:28px;height:28px;padding:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
}
/* Neutral-grau bei Hover UND aktivem Zeichenmodus statt Akzentblau - gleiche
   Begruendung wie beim RSI/MACD/Stoch-Umschalter oben: Blau war als Hervor­hebung
   schon einmal verworfen worden (siehe Git-Historie), hier von vornherein
   vermieden. */
.draw-tool-btn:hover{background:var(--border-strong);color:var(--text-strong)}
.draw-tool-btn.active{background:var(--border-strong);color:var(--text-strong)}
.draw-tool-sep{width:20px;height:1px;background:var(--border);margin:2px 0}
.watchlist-sidebar{
  position:fixed;
  top:40px;
  right:0;
  bottom:calc(var(--status-bar-height) + 1px);
  width:260px;
  background:var(--surface);
  border-left:1px solid var(--border);
  display:none;
  flex-direction:column;
  z-index:99;
}
.watchlist-sidebar.open{
  display:flex;
}
.watchlist-loading{
  display:flex;align-items:center;justify-content:center;flex:1;
  color:var(--text-muted);font-size:12px;gap:8px;
}
.watchlist-spinner{
  width:16px;height:16px;border:2px solid var(--border);
  border-top-color:var(--accent);border-radius:50%;
  animation:spin .6s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}
.watchlist-header{
  display:flex;
  justify-content:flex-end;
  align-items:center;
  padding:12px 16px;
  border-bottom:1px solid var(--border);
}
/* Icon links vom Titel. `.watchlist-title` hat flex:1 und schiebt das X weiterhin
   nach rechts; der Slot braucht deshalb nur seinen Abstand. Die Groesse kommt aus
   .icon-slot, damit vor dem Nachladen kein Layoutsprung entsteht. */
/* Das Kopf-Icon ist ein Button: ein Klick oeffnet die Auswahl. Es sieht bewusst nicht
   wie ein Knopf aus - erst der Hover zeigt, dass es eines ist. */
.watchlist-icon{
  color:var(--text-muted);
  margin-right:8px;
  border:0;
  padding:0;
  background:transparent;
  cursor:pointer;
}
.watchlist-icon:hover{color:var(--accent)}
.watchlist-icon:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}

/* Auswahl im Kopfbereich: unter der Kopfzeile, ueber der Liste. */
#watchlist-header-picker{
  padding:10px 16px;
  border-bottom:1px solid var(--border);
  margin-top:0;
}
#watchlist-header-picker[hidden]{display:none}
.watchlist-title{
  color:var(--text);
  font-weight:600;
  font-size:14px;
  flex:1;
}
.close-icon{
  cursor:pointer;
  font-size:16px;
  color:var(--text-muted);
  /* Ueberschreibt .icon-slots 20x20 (main.css oben) - das X war schon immer
     16x16, seit dem Umstieg auf public/icons/ui/x.svg bringt .icon-slot sonst
     die groessere Standardgroesse mit. */
  width:16px;
  height:16px;
}
.close-icon:hover{
  color:var(--down);
}
.watchlist-items{
  flex:1;
  overflow-y:auto;
  padding:8px 12px;
}
.watchlist-item{
  display:flex;
  justify-content:space-between;
  align-items:center;
  padding:6px 12px;
  margin-bottom:4px;
  background:var(--bg);
  border-radius:6px;
  cursor:pointer;
}
.watchlist-item:hover{
  background:var(--border);
}
.watchlist-item.active{
  background:var(--accent);
  color:var(--text-strong);
}
.watchlist-item.active .watchlist-item-symbol{
  color:var(--text-strong);
}
/* .alarm-bell.none (--border-strong, #4a4e59) und .alarm-bell.set (--accent,
   #2962ff - identisch mit dem Hintergrund!) sind auf dem blauen
   .active-Hintergrund sonst praktisch unsichtbar. .triggered bleibt gruen
   (--success) und damit unangetastet, ausreichend Kontrast. */
.watchlist-item.active .alarm-bell.none{
  color:var(--text-strong);
  opacity:0.6;
}
.watchlist-item.active .alarm-bell.set{
  color:var(--text-strong);
}
.watchlist-item-symbol{
  color:var(--text);
  font-weight:600;
  font-size:13px;
}
.watchlist-item.dragging {
  opacity: 0.5;
  background: #3a3e49;
}
.watchlist-item.drag-over {
  border-top: 2px solid var(--accent);
  background: var(--border);
}
.watchlist-item-name{
  color:var(--text-muted);
  font-size:11px;
}
.watchlist-empty{
  color:var(--text-muted);
  text-align:center;
  padding:20px;
  font-size:13px;
}
.alarm-bell{
  font-size:14px;
  cursor:pointer;
  width:18px;
  height:18px;
  display:flex;
  align-items:center;
  justify-content:center;
}
/* `.alarm-bell` ist seit dem Umstieg auf public/icons/ui/bell.svg der
   .icon-slot-Wrapper, nicht mehr das <svg> selbst - bell.svg traegt
   fill="currentColor" fest, "none" hier ueberschreibt das per CSS auf den
   Kind-<svg> (Praesentationsattribute verlieren gegen Stylesheet-Regeln).
   `fill` ist eine vererbte SVG-Eigenschaft, `.triggered{fill:var(--success)}`
   unten wirkt deshalb weiterhin bis in das nachgeladene <svg> hinein, ganz
   ohne eigene svg-Selektoren dafuer. */
.alarm-bell.none{color:var(--border-strong)}
.alarm-bell.none svg{fill:none}
.alarm-bell.set{color:var(--accent)}
.alarm-bell.triggered{color:var(--success);fill:var(--success)}
.alarm-bell.seen{opacity:0.6}
/* Haelt Glocke und Zahl uebereinander - dieselbe 18x18-Box wie .alarm-bell. */
.alarm-bell-holder{
  position:relative;
  width:18px;
  height:18px;
  display:flex;
  align-items:center;
  justify-content:center;
}
/* Anzahl ausgeloester, ungesehener Alarme, zentriert ueber der Glocke statt
   daneben - ohne eigenen Kreis-Hintergrund (wirkte auf der Glocke zu klein/
   gedraengt), dafuer eine feste dunkle Kontur statt weichem Schlagschatten
   fuer eine scharfe Kante gegen den gruenen Glockenbauch. pointer-events:none:
   rein dekorativ, Klicks sollen bei der Glocke darunter ankommen. */
.alarm-bell-count{
  position:absolute;
  display:inline-block;
  top:52%;
  left:50%;
  transform:translate(-50%, calc(-50% - 2px));
  pointer-events:none;
  color:var(--text-strong);
  -webkit-text-stroke:2px var(--success);
  paint-order:stroke fill;
  font-size:10px;
  font-weight:bold;
  line-height:1;
}
/* Watchlist Button (Eye) */
.watchlist-btn{
  width:18px;
  height:18px;
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  margin-left:8px;
}
/* Zwei Zustaende, beide ausdruecklich benannt.
   Vorher gab es nur `.filled`; der Zustand "nicht in einer Watchlist" entstand
   daraus, dass diese Klasse FEHLTE. Das `.outline`, das das JavaScript setzt und
   entfernt, hatte keine einzige Regel — eine Klasse, die aussieht wie ein Zustand
   und keiner war. Wer eine dritte Variante ergaenzt, tappt darauf herein. */
.watchlist-btn svg{
  fill:none;
  stroke:var(--border-strong);
}
.watchlist-btn.outline svg{
  fill:none;
  stroke:var(--border-strong);
}
.watchlist-btn.filled svg{
  fill:var(--accent);
  stroke:var(--accent);
}
.watchlist-btn:hover svg{
  stroke:var(--accent);
}
.watchlist-btn.disabled{cursor:default;pointer-events:none;opacity:.35}
/* Watchlist Select Dialog */
.watchlist-dialog-overlay{
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background:rgba(0,0,0,0.75);
  backdrop-filter:blur(4px);
  z-index:1000;
  display:none;
  align-items:center;
  justify-content:center;
}
.watchlist-dialog-overlay.open{display:flex}
.watchlist-dialog{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:12px;
  width:400px;
  max-width:90vw;
  max-height:70vh;
  padding:20px;
  box-shadow:0 10px 40px rgba(0,0,0,0.5);
  display:flex;
  flex-direction:column;
}
.watchlist-dialog h3{
  margin-top:0;
  margin-bottom:16px;
  color:var(--text-strong);
  font-size:18px;
}
.watchlist-options{
  flex:1;
  overflow-y:auto;
  margin-bottom:16px;
}
.watchlist-option{
  padding:12px;
  margin-bottom:4px;
  background:var(--bg);
  border-radius:6px;
  cursor:pointer;
  display:flex;
  justify-content:space-between;
  align-items:center;
}
/* Icon und Name als eine Gruppe links, der Sektor bleibt rechts. Ohne diese
   Zwischenebene schoebe `justify-content:space-between` die drei Kinder gleichmaessig
   auseinander und das Icon klebte am linken Rand statt am Namen. */
.watchlist-option-left{
  display:flex;
  align-items:center;
  gap:10px;
  min-width:0;
}
.watchlist-option:hover{background:var(--border)}
.watchlist-option.selected{
  background:var(--accent);
  color:var(--text-strong);
}
.watchlist-option .watchlist-name{
  color:var(--text);
  font-weight:500;
}
.watchlist-option.selected .watchlist-name{
  color:var(--text-strong);
}
.watchlist-option .watchlist-sector{
  color:var(--text-muted);
  font-size:12px;
}
.watchlist-create{
  padding:12px;
  background:var(--border);
  border-radius:6px;
  cursor:pointer;
  text-align:center;
  color:var(--text);
  margin-top:8px;
}
.watchlist-create:hover{background:var(--accent);color:var(--text-strong)}
/* Fehlermeldung im Watchlist-Dialog. Steht ueber den Knoepfen, damit sie den
   Dialog nicht springen laesst, wenn sie erscheint - `hidden` nimmt sie ganz aus
   dem Fluss, der Abstand kommt erst mit dem Text. */
.watchlist-dialog-error{
  margin:8px 0 0;
  padding:8px 10px;
  border-radius:4px;
  border:1px solid var(--danger, #f23645);
  background:rgba(242,54,69,0.12);
  color:var(--danger, #f23645);
  font-size:13px;
  line-height:1.4;
}
.watchlist-dialog-error[hidden]{ display:none; }

.watchlist-dialog-buttons{
  display:flex;
  justify-content:flex-end;
  gap:8px;
  padding-top:16px;
  border-top:1px solid var(--border);
}
.watchlist-dialog button{
  padding:6px 16px;
  border-radius:4px;
  cursor:pointer;
  font-size:13px;
}
.watchlist-dialog .btn-primary{
  background:var(--accent);
  color:var(--text-strong);
  border:1px solid var(--accent);
}
/* Ohne Auswahl und ohne offenes Anlegen-Formular tat "Hinzufuegen" bisher
   still gar nichts - jetzt sichtbar deaktiviert (siehe
   updateAddButtonState() in watchlist-dialog.js), statt kommentarlos
   ins Leere zu klicken. */
.watchlist-dialog .btn-primary:disabled{
  opacity:.45;
  cursor:not-allowed;
}
.watchlist-dialog .btn-secondary{
  background:var(--border);
  color:var(--text);
  border:1px solid var(--border);
}
.sector-badge {
  display: inline-block;
  padding: 2px 6px;
  margin-left: 6px;
  font-size: 10px;
  background: #3a3f4b;
  color: var(--text-strong);
  border-radius: 3px;
  vertical-align: middle;
}
.detail-layout .detail-header-actions{
  display:flex;
  align-items:center;
  gap:8px;
  margin-left:auto;
}
.detail-layout .aktienfinder-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:80px;
  height:26px;
  padding:4px 0;
  cursor:pointer;
  text-decoration:none;
  border:none;
  border-radius:4px;
  background:var(--text-strong);
}
.detail-layout .aktienfinder-btn:hover{
  background:var(--text-strong);
}
.detail-layout .aktienfinder-btn img{
  display:block;
  width:80px;
  height:18px;
  object-fit:contain;
}
/* Ariva und TradingView teilen sich die Plakette - gleiche Groesse, gleicher
   weisser Grund. Zwei Selektoren statt zweier Regelbloecke, damit eine spaetere
   Aenderung nicht nur den einen Knopf trifft. */
.detail-layout .ariva-btn,
.detail-layout .tradingview-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:80px;
  height:26px;
  padding:4px 0;
  cursor:pointer;
  text-decoration:none;
  border:none;
  border-radius:4px;
  background:var(--text-strong);
}
.detail-layout .ariva-btn:hover,
.detail-layout .tradingview-btn:hover{
  background:var(--text-strong);
}
.detail-layout .ariva-btn img,
.detail-layout .tradingview-btn img{
  display:block;
  width:80px;
  height:18px;
  object-fit:contain;
}
/* Ohne diese Regel gewinnt die display:inline-flex oben gegen die
   UA-Regel `[hidden]{display:none}` - zwei Klassen schlagen ein Attribut.
   `main.js` setzt bei fehlendem Profil-Link `.hidden = true`, aber der Knopf
   blieb sichtbar, nur ohne Ziel. Diese Regel hat mit Klasse+Attribut dieselbe
   Spezifitaet plus eins und gewinnt deshalb zuverlaessig. */
.detail-layout .aktienfinder-btn[hidden],
.detail-layout .ariva-btn[hidden],
.detail-layout .tradingview-btn[hidden]{
  display:none;
}
/* Alarm List Overlay */
.alarm-list-overlay{
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background:rgba(19,23,34,0.95);
  display:none;
  flex-direction:column;
  z-index:10;
}
.alarm-list-overlay.open{
  display:flex;
}
.alarm-list-header{
  display:flex;
  justify-content:space-between;
  align-items:center;
  padding:12px 16px;
  border-bottom:1px solid var(--border);
  flex-shrink:0;
}
.alarm-list-header h3{
  color:var(--text);
  font-size:14px;
  font-weight:600;
  margin:0;
}
.alarm-list-header .close-icon{
  cursor:pointer;
  font-size:16px;
  color:var(--text-muted);
}
.alarm-list-header .close-icon:hover{
  color:var(--down);
}
.alarm-list-items{
  flex:1;
  min-height:0;
  overflow-y:auto;
  padding:8px;
}
.alarm-item{
  display:flex;
  flex-direction:column;
  gap:2px;
  padding:8px 12px;
  margin-bottom:6px;
  background:var(--bg);
  border-radius:6px;
  border-left:3px solid transparent;
  cursor:pointer;
  font-size:12px;
}
.alarm-item:hover{
  background:var(--border);
}
/* Linker Farbstreifen statt umlaufendem Rahmen mit dunkelgruenem Text - der
   war auf dunklem Hintergrund kaum lesbar (#1b5e20 auf var(--bg)). */
.alarm-item.triggered{
  border-left-color:var(--success);
}
.alarm-item.selected{
  background:var(--accent);
  color:var(--text-strong);
}

/* Nutzerverwaltung (admin-view.js) - wiederverwendet .alarm-item fuer die
   Zeilen, braucht aber kein alarm-typisches cursor:pointer (die Zeile selbst
   ist nicht klickbar, nur der Entfernen-Button). */
.admin-invite-form{display:flex;gap:8px;padding:8px 12px}
.admin-invite-form input{
  flex:1;padding:6px 10px;border:1px solid var(--border);border-radius:4px;
  background:var(--bg);color:var(--text);font-size:13px
}
.admin-remove-btn{
  align-self:flex-start;margin-top:4px;padding:3px 8px;border-radius:4px;
  border:1px solid var(--border);background:none;color:var(--down);
  font-size:11px;cursor:pointer
}
.admin-remove-btn:hover{background:var(--down-fade)}
.alarm-item-condition{
  font-weight:600;
  color:var(--text);
}
.alarm-item.selected .alarm-item-condition{color:var(--text-strong);}
.alarm-item-warning{
  font-weight:400;
  font-size:11px;
}
.alarm-item-warning.urgent{color:var(--down);}
.alarm-item-warning.soon{color:#e8b923;}
.alarm-item-warning-row{margin-top:2px;}
.alarm-item-pivot{font-weight:400;color:var(--text-muted);font-size:11px}
.alarm-item-meta{
  color:var(--text-muted);
  font-size:11px;
}
.alarm-item.selected .alarm-item-meta,
.alarm-item.selected .alarm-item-pivot{color:var(--text-strong);opacity:0.85;}
.alarm-list-form{
  padding:10px 12px;
  border-top:1px solid var(--border);
  flex-shrink:0;
  display:flex;
  flex-direction:column;
  gap:6px;
  max-width:calc(100% - 24px);
  max-height:60vh;
  overflow-y:auto;
  box-sizing:border-box;
}
.alarm-form-row{
  display:flex;
  gap:8px;
  width:100%;
  box-sizing:border-box;
}
.alarm-label{
  flex-shrink:0;
  padding:6px 0;
  color:var(--text);
  font-size:12px;
  white-space:nowrap;
}
.alarm-form-row input[type="number"]{
  flex:1;
  padding:6px 8px;
  background:var(--bg);
  border:1px solid var(--border);
  border-radius:4px;
  color:var(--text);
  font-size:12px;
  box-sizing:border-box;
  min-width:0;
  -moz-appearance:textfield;
}
.alarm-form-row input[type="number"]::-webkit-outer-spin-button,
.alarm-form-row input[type="number"]::-webkit-inner-spin-button{
  -webkit-appearance:none;
  margin:0;
}
.alarm-form-row input[type="number"].input-error{
  border-color:var(--down);
  animation:alarm-input-shake 0.3s;
}
@keyframes alarm-input-shake{
  0%,100%{transform:translateX(0);}
  25%{transform:translateX(-4px);}
  75%{transform:translateX(4px);}
}
.alarm-form-row select{
  flex:1;
  min-width:0;
  padding:6px 8px;
  background:var(--bg);
  border:1px solid var(--border);
  border-radius:4px;
  color:var(--text);
  font-size:12px;
  box-sizing:border-box;
  text-overflow:ellipsis;
}
.alarm-form-row button.threshold-toggle{
  flex-shrink:0;
  padding:6px 12px;
  background:var(--bg);
  border:1px solid var(--border);
  border-radius:4px;
  color:var(--text);
  cursor:pointer;
  font-size:12px;
  min-width:60px;
}
.alarm-form-row button.pivot-mode-toggle{
  flex-shrink:0;
  padding:4px 8px;
  background:var(--bg);
  border:1px solid var(--border);
  border-radius:4px;
  cursor:pointer;
  font-size:13px;
  opacity:0.5;
}
.alarm-form-row button.pivot-mode-toggle.pressed{
  background:var(--accent);
  border-color:var(--accent);
  opacity:1;
}
.alarm-form-row button.pivot-mode-toggle:disabled{
  cursor:not-allowed;
}
/* Rechte Spalte des Formulars (siehe .alarm-form-columns) - das Feld fuellt
   die ganze Spalte, statt wie zuvor eine eigene, schmale Zeile mit fester
   Min-/Max-Hoehe zu sein. Deren Hoehe ist jetzt implizit: genauso hoch wie die
   zwei Zeilen links (Alarm-Typ + Kurs/Offset). */
#alarm-comment{
  flex:1;
  width:100%;
  padding:6px 8px;
  background:var(--bg);
  border:1px solid var(--border);
  border-radius:4px;
  color:var(--text);
  font-size:12px;
  font-family:inherit;
  box-sizing:border-box;
  resize:none;
  outline:none;
}
#alarm-comment:focus{
  border-color:var(--accent);
}
/* Formular zweigeteilt: links Alarm-Typ + Kurs/Offset (zwei Zeilen), rechts
   der Kommentar ueber deren volle Hoehe. */
.alarm-form-columns{
  display:flex;
  gap:12px;
}
.alarm-form-col-left{
  flex:1;
  min-width:0;
  display:flex;
  flex-direction:column;
  gap:6px;
}
.alarm-form-col-right{
  flex:1;
  min-width:0;
  display:flex;
}
.alarm-form-row button.threshold-toggle.pressed{
  background:var(--accent);
  border-color:var(--accent);
  color:var(--text-strong);
}
.alarm-form-row.buttons-row{
  justify-content:flex-end;
  flex-wrap:wrap;
  gap:4px;
}
.alarm-form-row.buttons-row button{
  flex-shrink:1;
  min-width:0;
  padding:6px 5px;
  font-size:11px;
}
/* Steht jetzt in derselben Zeile wie das Kurs/Offset-Feld, rechtsbuendig -
   deshalb hier eigenes display:flex statt der geteilten .alarm-form-row-Klasse
   (die nicht mehr auf diesem Element liegt) und margin-left:auto zum
   Rechtsschieben. Sichtbarkeit weiterhin ueber row.style.display in
   alarm-popup.js (initial "none" inline im Markup, siehe renderMarkup()). */
.alarm-pivot-row{
  display:flex;
  align-items:center;
  gap:6px;
  margin-left:auto;
  flex-shrink:0;
}
/* Feste Mindesthoehe fuer die Zeile, die die Pivot-Navigation traegt - deren
   eigener Inhalt (◀/▶-Knoepfe + Label) ist minimal hoeher als Eingabefeld und
   $/%-Knopf allein. Ohne das stretchte die ganze Zeile (align-items:stretch,
   der .alarm-form-row-Standard) beim Ein-/Ausblenden der Pivot-Navigation um
   ein paar Pixel - sichtbar als leichtes Huepfen der Formularhoehe und damit
   der Chart-Flaeche darueber (die den Platz per flex:1 ausgleicht). */
.alarm-threshold-row{
  min-height:30px;
}
.alarm-pivot-row button{
  flex-shrink:0;
  padding:4px 10px;
  background:var(--bg);
  border:1px solid var(--border);
  border-radius:4px;
  color:var(--text);
  cursor:pointer;
  font-size:12px;
}
.alarm-pivot-row button:disabled{
  opacity:0.4;
  cursor:default;
}
.alarm-pivot-label{
  flex:1;
  /* Verdoppelt gegenueber der urspruenglichen, rein inhaltsbestimmten Breite -
     mehr Luft fuer Pivot-Preis + Datum, auf Wunsch breiter als noetig. */
  min-width:220px;
  text-align:center;
  font-size:12px;
  color:var(--text-strong);
}
.alarm-form-row button{
  flex-shrink:0;
  padding:6px 12px;
  background:var(--accent);
  border:1px solid var(--accent);
  border-radius:4px;
  color:var(--text-strong);
  cursor:pointer;
  font-size:12px;
}
.alarm-form-row button.delete{
  background:var(--success);
  border-color:var(--down);
}
.alarm-form-row button.confirm{
  background:var(--success);
  border-color:var(--down);
}
.alarm-form-row button.confirm-cancel{
  background:var(--border);
  border-color:var(--border);
  color:var(--text);
  margin-left:auto;
}

/* Alarm-Popup: fast bildschirmfuellendes Modal, Nachfolger des in die Sidebar
   eingebetteten alarm-list-overlay. Oben Chart-Slot + Liste nebeneinander,
   unten das Formular ueber die volle Breite. Header, Liste und Formular
   nutzen dieselben alarm-list- und alarm-form-row-Klassen wie zuvor - nur der
   aeussere Rahmen ist neu. */
.alarm-popup-overlay{
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background:rgba(0,0,0,0.75);
  backdrop-filter:blur(4px);
  z-index:1000;
  display:none;
  align-items:center;
  justify-content:center;
}
.alarm-popup-overlay.open{display:flex;}
.alarm-popup{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:12px;
  width:80vw;
  max-width:80vw;
  height:80vh;
  max-height:80vh;
  box-shadow:0 10px 40px rgba(0,0,0,0.5);
  display:flex;
  overflow:hidden;
}
/* Linke Spalte: Chart oben, Formular darunter - beide exakt so breit wie der
   Chart. Die Liste rechts (.alarm-list-panel) ist ein eigenstaendiger
   Geschwisterknoten und geht deshalb ueber die volle Popup-Hoehe, statt nur
   neben dem Chart-Teil zu stehen. */
.alarm-popup-left{
  flex:1;
  min-width:0;
  display:flex;
  flex-direction:column;
  border-right:1px solid var(--border);
}
.alarm-popup-chart-slot{
  flex:1;
  min-width:0;
  min-height:0;
  display:flex;
  flex-direction:column;
}
/* Das echte #chart-panel wird hier hineingehaengt (attachChartPanel() in
   alarm-popup.js) - eigene Rahmung/Hintergrund/Rundung ausgeschaltet, damit es
   nicht wie eine zweite, verschachtelte Box wirkt, sondern wie ein nahtloser
   Teil des Popups. Der Vollbild-Button ergibt innerhalb des Popups keinen
   Sinn (das Popup deckt ohnehin fast den ganzen Bildschirm ab) und ist
   deshalb ausgeblendet. */
.alarm-popup-chart-slot #chart-panel.in-alarm-popup{
  flex:1;
  min-width:0;
  min-height:0;
  border:none;
  border-radius:0;
  background:transparent;
}
.alarm-popup-chart-slot #chart-panel.in-alarm-popup #chart-zoom-toggle{
  display:none;
}
.alarm-list-panel{
  width:360px;
  flex-shrink:0;
  display:flex;
  flex-direction:column;
  min-height:0;
}
/* Formular unter dem Chart, exakt dessen Breite - dieselben .alarm-form-row-
   Zeilen wie zuvor, nur ohne die Breiten-/Hoehen-Deckelung, die fuer die
   schmale Sidebar-Spalte gedacht war. */
.alarm-popup .alarm-list-form{
  max-width:100%;
  max-height:none;
  flex-shrink:0;
  border-top:1px solid var(--border);
}
.alarm-condition-row{
  flex-wrap:wrap;
}
/* .alarm-form-row button (weiter unten) faerbt jeden Button darin standardmaessig
   in Akzentfarbe - fuer Erstellen/Speichern gedacht. Ohne die zusaetzliche
   Element+Klassen-Bindung (statt nur .condition-btn) gewann diese allgemeinere
   Regel durch hoehere Spezifitaet, und alle sechs Alarm-Typ-Buttons sahen
   ununterscheidbar "aktiv" aus - genau das gleiche Muster wie
   .alarm-form-row button.threshold-toggle etc. weiter unten. */
.alarm-form-row button.condition-btn{
  flex:1;
  min-width:70px;
  padding:6px 8px;
  background:var(--bg);
  border:1px solid var(--border);
  color:var(--text);
}
.alarm-form-row button.condition-btn.active{
  background:var(--accent);
  border-color:var(--accent);
  color:var(--text-strong);
}
/* Loeschen-Icon je Listeneintrag - leichtgewichtige Sicherheitsabfrage direkt
   am Item statt eines eigenen Formular-Buttons, siehe bindDeleteIcon() in
   alarm-popup.js. Standardmaessig dezent, erst bei Hover/„scharf" auffaellig -
   ein dauerhaft rotes Icon neben jeder Zeile waere unruhiger als noetig. */
.alarm-item-condition{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:8px;
}
.alarm-item-delete{
  flex-shrink:0;
  padding:2px;
  background:none;
  border:none;
  color:var(--text-muted);
  cursor:pointer;
  opacity:0.5;
  line-height:0;
}
.alarm-item-delete svg{width:12px;height:12px;}
.alarm-item:hover .alarm-item-delete{opacity:0.85;}
.alarm-item-delete:hover{color:var(--down);opacity:1;}
.alarm-item-delete.confirm{
  color:var(--down);
  opacity:1;
}
.watchlist-item{
  position:relative;
}
/* Alarm-Kreis in der Watchlist-Zeile: Anzahl ausgeloester, ungesehener Alarme,
   zusaetzlich zur (weiterhin gruen gefaerbten) Glocke - nicht an ihrer Stelle.
   Teilt sich die Basis mit .sidebar-icon-badge (siehe dort). */
.alarm-badge{
  position:absolute;
  top:-6px;
  right:-6px;
  background:var(--success);
  color:var(--text-strong);
  font-size:10px;
  font-weight:bold;
  border-radius:50%;
  min-width:16px;
  height:16px;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:2px;
  line-height:1;
}
/* Alarm-Badge auf den Sidebar-Icons (eine Watchlist-Kachel statt einer Zeile) -
   teilt Kreis/Farbe/Schrift mit .alarm-badge. Anders als beim Zeilen-Badge ohne
   negativen Offset: `.sidebar-watchlists` ist exakt so breit wie eine Kachel
   (36px) und clippt (overflow-x:hidden, fuers Scrollen bei vielen Watchlists
   auch overflow-y:auto) alles, was darueber hinausragt - ein Ueberstand wie
   beim Zeilen-Badge waere rechts (und beim ersten Icon auch oben) abgeschnitten.
   Das Badge bleibt daher innerhalb der Kachel, in deren Ecke. */
.sidebar-icon-badge{
  top:0;
  right:0;
}

/* =========================================================================
   Dashboard
   ========================================================================= */
  /* Ab hier: Dashboard-eigene Regeln.
   Sie waren frueher ein <style>-Block in views/dashboard-view.html, der bei
   JEDEM Dashboard-Render erneut in den <head> geschrieben wurde - und global
   galt. Die Kommentare dort behaupteten "matches main.css", tatsaechlich wichen
   sieben Regeln ab: .dropdown-item wurde zur umrandeten Box (das Oeffnen des
   Dashboards veraenderte damit das Such-Dropdown), .alarm-item von Zeile zu
   Spalte, .detail-panel h3 zu Flex mit weisser Schrift. Die Kapselung unter
   #dashboard-view beendet das Auslaufen, ohne das Dashboard selbst zu aendern. */

/* Raster der zwei Dashboard-Panels. `grid-template-rows:1fr` explizit gesetzt,
   sonst erbt der Selektor die zwei Zeilen der allgemeinen .detail-grid-Regel
   (fuer das 4-Panel-Raster der Detailansicht gedacht) - eine unsichtbare zweite
   Zeile teilte sich dann die Hoehe zur Haelfte mit den beiden Panels, die
   dadurch nur halb so hoch wie moeglich blieben. `height:100%` durch `flex:1`
   allein ersetzt: #dashboard-view ist jetzt selbst ein Flex-Container, `flex:1`
   berechnet die Resthoehe NACH .view-header korrekt, waehrend `height:100%`
   (100% von #dashboard-view SAMT .view-header) das Raster unten aus dem
   sichtbaren Bereich schob. */
#dashboard-view .detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr;
  gap: 8px;
  flex: 1;
  min-height: 0;
  }
/* Panel-Rahmen im Dashboard: volle Hoehe, Inhalt schneidet ab */
#dashboard-view .detail-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  height: 100%;
  }
/* Panel-Kopf: traegt Zaehler-Badge und Filterleiste, deshalb Flex */
#dashboard-view .detail-panel h3 {
  color: var(--text-strong);
  margin: 0 0 15px 0;
  flex-shrink: 0;
  font-size: 14px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  }

  /* Panel count badge — left side, next to the header text */
#dashboard-view .panel-count {
  font-size: 11px;
  font-weight: 700;
  background: var(--accent);
  color: var(--text-strong);
  border-radius: 10px;
  padding: 1px 7px;
  min-width: 18px;
  text-align: center;
  flex-shrink: 0;
  margin-right: auto;
  }

  /* Filter bar — right side of the header row */
#dashboard-view .filter-bar {
  display: flex;
  align-items: center;
  margin-left: auto;
  flex-shrink: 0;
  }
/* Dropdown im Dashboard-Filter - NICHT das Such-Dropdown aus main.css */
#dashboard-view .dropdown-item {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 11px;
  color: var(--text);
  cursor: pointer;
  }

#dashboard-view .dropdown-item:hover {
  background: var(--border);
  }

  /* Alarms container fills remaining space */
#dashboard-view .alarms-container {
  flex: 1;
  overflow-y: auto;
  text-align: left;
  }

#dashboard-view .alarms-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--surface);
  text-align: left;
  }

#dashboard-view .alarm-item {
  background: var(--bg);
  border-radius: 6px;
  padding: 6px 12px;
  margin-bottom: 4px;
  cursor: pointer;
  font-size: 12px;
  transition: background 0.2s;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  }

#dashboard-view .alarm-item:hover {
  background: var(--border);
  }

  /* Two-line layout */
#dashboard-view .alarm-item-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  margin-bottom: 2px;
  width: 100%;
  }

#dashboard-view .alarm-item-sub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  width: 100%;
  }

#dashboard-view .alarm-left {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1 1 auto;
  min-width: 0;
  }

#dashboard-view .alarm-right {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  margin-left: auto;
  }

#dashboard-view .alarm-name {
  color: var(--text);
  font-weight: 600;
  font-size: 13px;
  flex-shrink: 0;
  }

#dashboard-view .alarm-condition {
  color: var(--text);
  font-size: 11px;
  }

#dashboard-view .alarm-current {
  color: #00c853;
  font-size: 11px;
  font-weight: 600;
  }

#dashboard-view .alarm-sector {
  color: var(--text-muted);
  font-size: 10px;
  flex-shrink: 0;
  }

/* Top-Aktien-Panel (top-indicators.js): eine .fund-stat-tile je extremem
   Indikator statt des einzeiligen .alarm-sector-Texts der Alarm-Liste -
   dieselben Kacheln wie im Technisch-Panel der Detailansicht, hier nur mit
   engerer Mindestbreite/kleinerer Schrift, weil die Dashboard-Spalte deutlich
   schmaler ist als das Detail-Panel. */
#dashboard-view .top-indicator-tiles {
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 6px;
  width: 100%;
  margin-top: 4px;
  }
#dashboard-view .top-indicator-tiles .fund-stat-tile {
  padding: 6px 8px;
  }
#dashboard-view .top-indicator-tiles .fund-stat-label {
  font-size: 10px;
  }
#dashboard-view .top-indicator-tiles .fund-stat-value {
  font-size: 13px;
  }
#dashboard-view .top-indicator-tiles .fund-stat-sub {
  font-size: 10px;
  }

#dashboard-view .alarm-divider {
  color: #3a3e4a;
  font-size: 10px;
  flex-shrink: 0;
  }

#dashboard-view .alarm-datetime {
  color: var(--text-muted);
  font-size: 10px;
  flex-shrink: 0;
  }

  /* Placeholder for right panel */
#dashboard-view .panel-placeholder {
  color: var(--text-muted);
  text-align: center;
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-style: italic;
  padding: 16px;
  gap: 8px;
  }

  /* Loading spinner */
#dashboard-view .alarms-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 40px;
  color: var(--text-muted);
  }

#dashboard-view .spinner {
  width: 16px;
  height: 16px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  }

  /* View header */
#dashboard-view .view-header {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 12px 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  flex-shrink: 0;
  }

#dashboard-view .view-header h3 {
  color: var(--text);
  font-size: 16px;
  font-weight: 600;
  margin: 0;
  }

/* Ziehen der Watchlist-Icons in der Navigationsleiste. Dieselben zwei Klassen wie
   bei den Watchlist-Eintraegen, damit beide Stellen gleich aussehen. */
.sidebar-icon.dragging{opacity:.4}
.sidebar-icon.drag-over{outline:2px solid var(--accent);outline-offset:-2px}

/* Kontextmenü der Watchlist-Zeile (watchlist-remove.js). Position setzt das Skript,
   weil sie vom Mauszeiger abhängt. */
.context-menu{
  position:fixed;z-index:1000;
  background:var(--surface);border:1px solid var(--border);border-radius:6px;
  padding:4px;min-width:160px;box-shadow:0 4px 16px rgba(0,0,0,.4)
}
.context-item{
  display:block;width:100%;text-align:left;
  padding:8px 10px;border:none;border-radius:4px;
  background:transparent;color:var(--text);font-size:13px;cursor:pointer;
  /* Firmennamen koennen lang sein („State Street SPDR S&P 500 ETF T"). Ohne Deckel
     zoege der Eintrag das Menue ueber den halben Bildschirm; das Kuerzel steht als
     `title` daran, falls abgeschnitten wird. */
  max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap
}
.context-item:hover{background:var(--border)}
.context-item.danger:hover{background:var(--down-fade);color:var(--down)}

/* Rückfrage vor dem Entfernen. Eigener Overlay statt des Watchlist-Dialogs: der
   trägt eigenen Zustand (Symbol, Sektor, Icon-Auswahl) und wäre für eine Ja/Nein-
   Frage der falsche Ort. */
.confirm-overlay{
  position:fixed;inset:0;z-index:1001;
  background:rgba(0,0,0,.5);
  display:none;align-items:center;justify-content:center
}
.confirm-overlay.open{display:flex}
.confirm-dialog{
  background:var(--surface);border:1px solid var(--border);border-radius:8px;
  padding:20px;min-width:320px;max-width:420px
}
.confirm-dialog h3{font-size:15px;margin-bottom:8px;color:var(--text-strong)}
.confirm-hinweis{font-size:13px;color:var(--text-muted);margin-bottom:12px}
.confirm-option{
  display:flex;align-items:center;gap:8px;
  font-size:13px;color:var(--text);margin-bottom:12px;cursor:pointer
}
.confirm-buttons{display:flex;gap:8px;justify-content:flex-end}
.btn-danger{
  padding:6px 14px;border:none;border-radius:4px;
  background:var(--down);color:var(--text-strong);font-size:13px;cursor:pointer
}
.btn-danger:hover{filter:brightness(1.1)}

/* Alarm-E-Mail-Mini-Panel (alarm-email-settings.js). Eigener, schlanker Overlay
   statt Erweiterung des Settings-Modals: jenes speichert ausschliesslich in
   localStorage (settings-store.js), die Alarm-Adresse muss aber serverseitig
   lesbar sein (AlarmService laeuft unabhaengig von einem offenen Tab).
   Frueher per eigenem Header-Button geoeffnet (.alarm-email-toggle, entfernt) -
   jetzt ueber den Menuepunkt "Alarm-Zustellung" im Konto-Menue, siehe
   account-menu.js. */
.alarm-email-overlay{
  position:fixed;top:0;left:0;right:0;bottom:0;
  background:rgba(0,0,0,0.75);backdrop-filter:blur(4px);
  z-index:1000;display:none;align-items:center;justify-content:center
}
.alarm-email-overlay.open{display:flex}
.alarm-email-panel{
  background:var(--surface);border:1px solid var(--border);border-radius:12px;
  width:360px;max-width:90vw;padding:20px;box-shadow:0 10px 40px rgba(0,0,0,0.5)
}
.alarm-email-panel h3{margin:0 0 12px;color:var(--text-strong);font-size:16px}
.alarm-email-panel p{margin:0 0 12px;color:var(--text-muted);font-size:12px;line-height:1.4}
.alarm-email-panel input{
  width:100%;padding:8px;border:1px solid var(--border);border-radius:4px;
  background:var(--bg);color:var(--text);font-size:14px;box-sizing:border-box
}
.alarm-email-smas-label{
  display:block;margin:14px 0 6px;color:var(--text-muted);font-size:12px
}
.alarm-email-error{
  margin-top:8px;padding:8px 10px;border-radius:4px;
  border:1px solid var(--danger,#f23645);background:rgba(242,54,69,0.12);
  color:var(--danger,#f23645);font-size:13px;line-height:1.4
}
.alarm-email-error[hidden]{display:none}
.alarm-email-buttons{display:flex;justify-content:flex-end;gap:8px;margin-top:16px}
.alarm-email-buttons button{padding:6px 16px;border-radius:4px;cursor:pointer;font-size:13px}
.alarm-email-buttons .btn-primary{background:var(--accent);color:var(--text-strong);border:1px solid var(--accent)}
.alarm-email-buttons .btn-secondary{background:var(--border);color:var(--text);border:1px solid var(--border)}
.alarm-test-row{display:flex;align-items:center;gap:10px;margin-top:8px}
.alarm-test-btn{
  padding:5px 12px;border-radius:4px;cursor:pointer;font-size:12px;
  background:var(--border);color:var(--text);border:1px solid var(--border);
  flex-shrink:0
}
.alarm-test-btn:hover{background:var(--border-strong);border-color:var(--border-strong)}
.alarm-test-btn:disabled{cursor:default;opacity:0.6}
.alarm-test-status{font-size:12px;line-height:1.3}
.alarm-test-status.success{color:var(--up,#26a69a)}
.alarm-test-status.error{color:var(--danger,#f23645)}
/* Jeder Kanal (E-Mail/Telegram/Web-Push/Taeglicher Report) ist ein eigener
   .alarm-channel-Block im HTML - der Trennstrich oben macht sichtbar, wo ein
   Kanal endet und der naechste beginnt, statt dass Kopf, Eingabefelder und
   Test-Zeile aller vier Kanaele optisch ununterscheidbar durchlaufen. */
.alarm-channel{padding-top:14px;margin-top:14px;border-top:1px solid var(--border)}
.alarm-channel:first-of-type{padding-top:0;margin-top:0;border-top:none}
.alarm-channel-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.alarm-channel-label{display:flex;align-items:center;gap:6px;min-width:0}
.alarm-channel-label span{color:var(--text-strong);font-size:13px;font-weight:600}
.alarm-info-btn{
  display:inline-flex;align-items:center;justify-content:center;
  background:none;border:none;padding:0;margin:0;color:var(--text-muted);
  cursor:pointer;flex-shrink:0
}
.alarm-info-btn:hover{color:var(--text)}
.alarm-info-popover{
  margin:6px 0 0;padding:4px 0 4px 10px;border-radius:0;
  background:none;border:none;border-left:2px solid var(--border-strong);
  color:var(--text-muted);font-size:12px;line-height:1.4;font-style:italic
}
.alarm-info-popover[hidden]{display:none}
.alarm-channel-toggle{
  position:relative;display:inline-block;width:36px;height:20px;
  flex-shrink:0;cursor:pointer
}
.alarm-channel-toggle input{
  position:absolute;inset:0;width:100%;height:100%;margin:0;
  opacity:0;cursor:pointer
}
.alarm-toggle-track{
  position:absolute;inset:0;border-radius:999px;background:var(--border);
  transition:background .15s
}
.alarm-toggle-thumb{
  position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;
  background:var(--text-strong);transition:transform .15s
}
.alarm-channel-toggle input:checked ~ .alarm-toggle-track{background:var(--accent)}
.alarm-channel-toggle input:checked ~ .alarm-toggle-track .alarm-toggle-thumb{transform:translateX(16px)}
.alarm-channel-toggle input:focus-visible ~ .alarm-toggle-track{outline:2px solid var(--accent);outline-offset:2px}
