/* Astrellum Frontend -- Basisstile (Kapitel 11.2: mobil-first, ca. 360-430px
   Basisbreite). Farbpalette/Komponentenstile bewusst an
   planning/ui-stand-meilenstein-1-2-3-4.html angelehnt, damit das echte
   Frontend optisch am ursprünglichen Konzept-Mockup bleibt. */

/* Palette-Überarbeitung ("Expedition Atlas", Nutzerfeedback "gefällt mir,
   setz es so um" -- siehe Design-Pitch-Artefakt): dieselben Variablennamen
   wie zuvor (kein Umbau der ~200 Stellen, die sie verwenden) -- nur die
   Werte wechseln vom kalten Cyan-HUD-Kommandozentrale-Look zu einem warmen
   Expeditions-/Kartografen-Feldjournal: tinten-violetter Grund statt
   blau-schwarz, Messing statt Cyan als Akzent, gedaempftes Verdigris statt
   Neongruen, Siegellack-Rot statt Alarm-Pink. `--accent-hi` ist neu (helleres
   Messing fuer Zahlen/Countdown, siehe font-hud-Stellen), ebenso die beiden
   neuen Schriftrollen `--font-serif` (grosse Planetennamen/Ueberschriften,
   wirkt wie eine gravierte Sternkarten-Plakette) und `--font-sans` (UI-Text/
   Labels -- eine geometrische Grotesk, die tatsaechlich in echten
   Raumfahrt-Grafiken verwendet wurde, z. B. Apollo-Missionsembleme).
   `--font-hud` bleibt unveraendert Monospace, jetzt aber bewusst NUR noch
   fuer echte tabellarische Zahlen (Ressourcen, Countdowns, Koordinaten) statt
   wie zuvor auch fuer Ueberschriften/Labels -- siehe die font-family-Stellen
   weiter unten, die dafuer einzeln auf --font-sans/--font-serif umgestellt
   wurden. */
:root {
  --bg: #150f1e;
  --bg-2: #1b1424;
  --panel: #1e1728;
  --panel-2: #241c30;
  --border: #3c3047;
  --border-hi: #5a4a67;
  --text: #ece4d6;
  --muted: #a99cb2;
  --muted-2: #776a86;
  --accent: #d3a05a;
  --accent-hi: #ecc384;
  --accent-dim: #8a6c42;
  --good: #74a08f;
  --warn: #ecc384;
  --danger: #c15a42;
  --font-hud: "SF Mono", ui-monospace, "Cascadia Mono", "Roboto Mono", Menlo, Consolas, monospace;
  --font-serif: "Big Caslon", "Didot", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --font-sans: Futura, "Century Gothic", "Avenir Next", "Avenir", -apple-system, "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

/* Nutzerfeedback (wiederholt, zuletzt erneut nach einem Reload in der als
   Android-App installierten PWA gemeldet): "Nach einem Seiten-Reload
   verschwindet die Menüleiste am Ende der Seite, es muss die ganze Seite
   ganz nach unten gescrollt werden, die Leiste ist nicht statisch über den
   System-Tasten." -- der vorherige Fix (100dvh + Service-Worker
   network-first, siehe service-worker.js) behebt zwei ECHTE, aber nicht die
   EIGENTLICHE Ursache dieses konkreten Symptoms: Wenn `.screen` (siehe
   unten) mehr Inhalt enthält als in den verfügbaren Flex-Platz passt, MUSS
   der Browser gemäß Flexbox-Spezifikation eigentlich `min-height: 0`
   annehmen (die "automatic minimum size" wird bei nicht-sichtbarem
   `overflow` auf 0 gesetzt) -- genau DAS wird aber offenbar von der
   WebView/Chrome-Version, die Android beim Ausführen einer installierten
   ("standalone") PWA benutzt, nach einem Reload nicht zuverlässig so
   umgesetzt. Die Folge: `.screen` wächst auf die volle Höhe seines Inhalts
   STATT intern zu scrollen, dieser Überlauf hat bisher NICHTS aufgehalten
   (kein `overflow:hidden` auf `.app-shell`) und hat sich deshalb bis zum
   Dokument durchgereicht -- das gesamte DOKUMENT wurde scrollbar statt nur
   `.screen`, wodurch die Bottom-Nav ans Ende des (jetzt sehr langen)
   Dokuments rutschte, weit unterhalb des sichtbaren Bereichs und der
   System-Tasten, statt dort fixiert zu bleiben. `overflow: hidden` auf
   `.app-shell` (siehe dort) verhindert das strukturell: ein zu hoch
   geratenes `.screen` kann jetzt gar nicht mehr über die App-Shell hinaus
   Platz beanspruchen, ganz gleich, ob eine bestimmte Browser-Variante die
   Flexbox-Regel korrekt umsetzt oder nicht. Bewusst NICHT global auf
   `html`/`body`/`#app` gesetzt (das wurde in einem ersten Anlauf erwogen):
   die Login-/Registrierungs-Seite (auth-view.js) und die Rechtstexte
   (legal-view.js, z. B. lange AGB/Datenschutz-Texte) rendern OHNE die
   `.app-shell`-Struktur direkt in `#app` und brauchen echtes
   Dokument-Scrolling -- ein globales `overflow:hidden` hätte dort auf
   kleinen Bildschirmen den unteren Teil der Seite (z. B. den
   "Konto erstellen"-Button) unerreichbar gemacht. */
html, body {
  margin: 0;
  height: 100%;
  /* Sternfeld aus reinen Radial-Gradienten statt eines Bild-Assets --
     kostet keinen Netzwerk-Request, skaliert verlustfrei auf jeder
     Bildschirmgröße/-dichte. Ein paar "Sterne" plus zwei diffuse
     Nebel-Flecken oben rechts/unten links geben der sonst reinen
     Void-Fläche etwas Tiefe, ohne die eigentliche Oberfläche (App-Shell)
     optisch zu konkurrenzieren. */
  background-color: var(--bg);
  background-image:
    radial-gradient(1.5px 1.5px at 12% 18%, #ffffff 0%, transparent 65%),
    radial-gradient(1.5px 1.5px at 78% 42%, #ffffff 0%, transparent 65%),
    radial-gradient(2px 2px at 34% 68%, #ffffff 0%, transparent 65%),
    radial-gradient(1.5px 1.5px at 62% 8%, #e8d9c2 0%, transparent 65%),
    radial-gradient(2px 2px at 91% 74%, #ffffff 0%, transparent 65%),
    radial-gradient(1.5px 1.5px at 8% 82%, #e8d9c2 0%, transparent 65%),
    radial-gradient(1.5px 1.5px at 50% 90%, #ffffff 0%, transparent 65%),
    radial-gradient(1.5px 1.5px at 24% 38%, #ffffff 0%, transparent 65%),
    radial-gradient(1.5px 1.5px at 46% 12%, #e8d9c2 0%, transparent 65%),
    radial-gradient(2px 2px at 68% 58%, #ffffff 0%, transparent 65%),
    radial-gradient(1.5px 1.5px at 88% 22%, #e8d9c2 0%, transparent 65%),
    radial-gradient(1.5px 1.5px at 4% 52%, #ffffff 0%, transparent 65%),
    radial-gradient(1.5px 1.5px at 58% 96%, #ffffff 0%, transparent 65%),
    radial-gradient(120% 80% at 80% -10%, #2a2036 0%, transparent 55%),
    radial-gradient(100% 70% at 10% 110%, #241a30 0%, transparent 55%),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%);
  /* WICHTIG: KEIN `background-size: cover` -- das würde jeden Layer
     (auch die winzigen 1.5px-Sterne) auf Container-Größe aufblähen und
     die Punkte zu einem verwaschenen, praktisch unsichtbaren Fleck
     verschmieren. `background-size: auto` (Default) respektiert die in
     jedem `radial-gradient()` selbst angegebene Größe. */
  background-repeat: no-repeat;
  background-attachment: fixed;
  color: var(--text);
  font-family: var(--font-sans);
}

#app {
  height: 100%;
  /* Nutzerfeedback: "das Menue unten verschwindet wenn der Browser (Chrome
     Pixel) die Adresszeile einblendet" -- `100vh` bemisst sich am GROESSTEN
     moeglichen Viewport (Adressleiste eingeklappt); ist sie eingeblendet,
     ist der tatsaechlich sichtbare Bereich kleiner, wodurch dieser (und
     jeder darauf aufbauende `height:100vh`-Container, siehe `.app-shell`
     unten) ueber den unteren Bildschirmrand hinausragt und die Bottom-Nav
     mit aus dem sichtbaren Bereich schiebt. `100dvh` (dynamic viewport
     height) folgt der Adressleiste live -- Fallback auf `100vh` bleibt als
     vorherige Deklaration fuer Browser ohne `dvh`-Unterstuetzung stehen
     (die ignorieren die unbekannte Einheit und behalten die Zeile davor). */
  min-height: 100vh;
  min-height: 100dvh;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

button {
  font-family: inherit;
  cursor: pointer;
}
button:disabled { cursor: not-allowed; opacity: 0.55; }

.note { color: var(--muted); font-size: 0.82rem; line-height: 1.5; margin: 0 0 10px; }
.note.small { font-size: 0.7rem; }

/* --- Auth-Seite --- */
.auth-page {
  min-height: 100vh;
  min-height: 100dvh; /* siehe Kommentar bei #app */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 20px 60px;
  max-width: 420px;
  margin: 0 auto;
}
.auth-logo {
  font-family: var(--font-sans); font-size: 1.4rem; font-weight: 500;
  letter-spacing: 0.24em; text-transform: uppercase; margin-bottom: 4px;
}
/* Kein Leucht-Schein mehr (siehe Palette-Kommentar oben) -- Messing traegt
   sich durch Kontrast und Tracking, nicht durch Glow. */
.auth-logo span { color: var(--accent-hi); }
.auth-sub { font-size: 0.8rem; color: var(--muted); margin-bottom: 24px; text-align: center; }

/* Nutzerfeedback: "Zeige auf der Login Seite ein Banner wenn die App auf
   einem Android oder IPhone installiert werden kann." -- siehe
   views/auth-view.js::renderInstallBanner. Bewusst dezent (kein Alarm-Ton
   wie z. B. der Angriffs-Banner in planet-view.js), es ist ein Hinweis,
   keine Warnung. */
.install-banner {
  width: 100%; display: flex; align-items: center; gap: 10px; margin-bottom: 18px;
  padding: 12px 14px; border-radius: 3px; border: 1px solid var(--border); background: var(--panel-2);
}
.install-banner-text { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.install-banner-text strong { font-size: 0.82rem; }
.install-banner-text span { font-size: 0.72rem; color: var(--muted); }
.install-banner-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }

/* Nutzerfeedback: "bei neuen Ereignissen, Nachrichten sollte auf dem
   Smartphone eine Pushbenachrichtigung erscheinen ... Dies soll im Konto je
   Nachrichten Typ ... aktivieren/deaktivieren werden können." -- siehe
   views/account-view.js::renderPushArea. */
.push-master-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 0.86rem; font-weight: 600; margin-bottom: 10px;
}
.push-category-list { display: flex; flex-direction: column; gap: 2px; }
.push-category-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 2px; font-size: 0.82rem; border-top: 1px solid var(--border);
}
.push-category-row:first-child { border-top: none; }
.push-category-row input[type="checkbox"] { flex-shrink: 0; width: 18px; height: 18px; accent-color: var(--accent); }

/* Reiter (UI-Politur "Expedition Atlas"): Wort-Reiter mit Haarlinie statt
   gefuellter Pille -- wie eine Registerkarte im Feldjournal, nicht wie ein
   Segmented-Control-Knopf. Gilt fuer .auth-tab/.sub-tab/.pill-tab gleich. */
.auth-tabs { display: flex; width: 100%; margin-bottom: 18px; border-bottom: 1px solid var(--border); }
.auth-tab {
  flex: 1; text-align: center; padding: 10px 4px 9px; font-family: var(--font-sans);
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); background: none; border: none; border-bottom: 1px solid transparent; margin-bottom: -1px;
}
.auth-tab.active { color: var(--accent-hi); border-bottom-color: var(--accent); }
.auth-field { width: 100%; margin-bottom: 12px; }
.auth-field label { display: block; font-size: 0.72rem; color: var(--muted); margin-bottom: 4px; }
.auth-field-optional { font-weight: 400; opacity: 0.7; }
/* Formularfelder (UI-Politur "Expedition Atlas"): einzeilige Felder als
   unterstrichene Zeile statt umrandeter Box -- wie eine auszufuellende
   Formular-Zeile auf Papier. Mehrzeilige Felder (`<textarea>`) behalten
   einen vollen Rahmen, weil eine reine Unterstreichung bei mehreren Zeilen
   Text visuell nicht mehr trägt. */
.auth-field input, .auth-field select {
  width: 100%; background: none; border: none; border-bottom: 1px solid var(--border-hi);
  border-radius: 0; color: var(--text); font-family: var(--font-hud); font-size: 0.9rem; padding: 8px 2px;
}
.auth-field input:focus, .auth-field select:focus { outline: none; border-bottom-color: var(--accent); }
.auth-field textarea {
  width: 100%; background: var(--panel); border: 1px solid var(--border); border-radius: 4px;
  color: var(--text); font-size: 0.9rem; padding: 12px 12px;
  resize: vertical;
  font-family: inherit;
}
.auth-field textarea:focus { outline: none; border-color: var(--accent-dim); }
.auth-checkbox { display: flex; align-items: flex-start; gap: 8px; font-size: 0.76rem; color: var(--muted); margin-bottom: 10px; }
.auth-checkbox input { margin-top: 3px; width: 16px; height: 16px; flex-shrink: 0; }
.auth-note { font-size: 0.68rem; color: var(--muted); margin-top: 16px; text-align: center; line-height: 1.6; }

/* --- Spieler-Namenssuche (spätere Überarbeitung "UX-Verbesserungen"),
   siehe components/player-search.js --- */
.player-search-field { position: relative; }
.player-search-results {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 20;
  background: var(--panel); border: 1px solid var(--border); border-radius: 3px;
  margin-top: 4px; overflow: hidden;
}
.player-search-results:empty { display: none; }
.player-search-hit {
  display: block; width: 100%; text-align: left; padding: 10px 12px;
  background: none; border: none; color: var(--text); font-size: 0.85rem; border-bottom: 1px solid var(--border);
}
.player-search-hit:last-child { border-bottom: none; }
.player-search-hit:hover, .player-search-hit:focus { background: var(--panel-2); }
.player-search-empty { padding: 10px 12px; margin: 0; }

form { width: 100%; }

/* --- Buttons (UI-Politur "Expedition Atlas") --- */
/* Umrandete Messing-Flaeche statt Glas-Verlauf mit Leucht-Rand -- wie ein
   gestempeltes Formular-Feld, nicht wie ein leuchtender HUD-Knopf. Kaum
   Rundung (3px bricht nur die Pixelkante), font-family bewusst NICHT hier
   gesetzt -- `.btn` erbt `var(--font-sans)` bereits vom Body-Default. */
.btn {
  border: 1px solid var(--border-hi);
  border-radius: 3px;
  padding: 11px 16px;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: none;
  color: var(--text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.btn:hover { border-color: var(--accent-dim); color: var(--accent); }
.btn-block { width: 100%; margin-bottom: 10px; }
.btn-small { padding: 7px 12px; font-size: 0.68rem; }
.btn-primary {
  background: none;
  border-color: var(--accent);
  color: var(--accent-hi);
}
.btn-primary:hover { background: rgba(211, 160, 90, 0.08); color: var(--accent-hi); }
.btn-secondary { background: var(--panel-2); color: var(--text); }
.btn-danger { background: none; border-color: var(--danger); color: var(--danger); }
.btn-danger:hover { background: rgba(193, 90, 66, 0.1); border-color: var(--danger); color: var(--danger); }

/* --- App-Shell (eingeloggter Bereich) --- */
/* Nutzerfeedback (DRITTER Anlauf zu diesem Bug -- weder Service-Worker-
   network-first noch `min-height:0`+`overflow:hidden` auf Basis von
   `100dvh` haben auf dem konkreten Android-Geraet des Nutzers geholfen,
   selbst nach Deinstallieren/Neuinstallieren der App): die bisherigen Fixes
   GINGEN ALLE davon aus, dass `100vh`/`100dvh` auf dem Geraet einen
   korrekten, zur tatsaechlich sichtbaren Flaeche passenden Pixelwert
   liefern -- in einer als Android-App installierten ("standalone") PWA mit
   sichtbarer 3-Tasten-Systemleiste ist genau DIESE Annahme offenbar nicht
   zuverlaessig erfuellt: je nach WebView-/Chrome-Version, die die
   installierte App tatsaechlich zum Rendern benutzt, kann `100dvh` (und im
   Fallback `100vh`) einen Wert liefern, der GROESSER ist als die wirklich
   sichtbare Flaeche -- die App-Shell ragt dann selbst schon zu weit nach
   unten, ganz unabhaengig davon, ob `.screen` intern sauber scrollt.
   STATT weiter einer Hoehen-EINHEIT zu vertrauen, die der Browser erst
   berechnen muss, wird die App-Shell jetzt direkt an den vier Kanten des
   tatsaechlichen sichtbaren Bereichs FESTGENAGELT (`position:fixed` +
   `top/right/bottom/left:0`) -- das ist eine Zusicherung des Compositors
   selbst, keine Berechnung, die je nach Geraet/Browser-Version abweichen
   kann. `height` wird dadurch ueberfluessig (ergibt sich aus
   top+bottom) und ist absichtlich NICHT mehr gesetzt, um keinen
   Ueberbestimmungs-Konflikt mit den top/bottom-Werten zu riskieren. */
.app-shell {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  /* siehe Kommentar bei html/body -- verhindert, dass ein zu hoch geratenes
     `.screen` (siehe dort) je ueber diese Box hinaus- und damit zum
     scrollbaren DOKUMENT werden kann. */
  overflow: hidden;
}

/* Umsetzung UI-Skizzen-Runde 2 (05.08.2026), Abschnitt "Ein Glocken-Symbol
   statt drei getrennter Hinweis-Orte": `.topbar-row` fasst Ressourcenleiste
   + neues Glocken-Symbol zu einer gemeinsamen Kopfzeile zusammen. Ersetzt
   `#resource-bar-slot` als direktes Flex-/Grid-Kind von `.app-shell` (siehe
   main.css `.app-shell` weiter oben + desktop.css @960px) -- `#resource-bar-
   slot` bleibt als Kind VON `.topbar-row` bestehen und wird von
   `updateResourceBar()` weiterhin unveraendert ausgetauscht (siehe
   components/app-shell.js). */
/* Nutzerfeedback: "die informationsbenachrichtigung landet hinter dem
   planeten selektor" -- `backdrop-filter` erzeugt einen eigenen Stacking-
   Context fuer `.topbar-row` (unabhaengig vom `z-index: 40` des
   `.notification-panel` DARIN, siehe main.css weiter unten). Ohne eigene
   Positionierung/`z-index` HIER wird dieser Stacking-Context in normaler
   Dokumentreihenfolge gemalt -- der nachfolgende `#planet-switcher-slot`
   (ein spaeteres Geschwisterelement, siehe components/app-shell.js)
   ueberdeckte das Benachrichtigungs-Panel deshalb, obwohl dessen eigener
   z-index hoeher ist. `position: relative` + `z-index` HIER traegt den
   gesamten Stacking-Context ueber den Planeten-Umschalter. */
.topbar-row {
  display: flex;
  align-items: stretch;
  flex-shrink: 0;
  position: relative;
  z-index: 30;
  background: #120c19e6;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}
.topbar-row #resource-bar-slot { flex: 1; min-width: 0; }

.resource-bar {
  display: flex;
  justify-content: space-around;
  align-items: center;
  padding: 14px 12px;
  flex-shrink: 0;
  height: 100%;
  font-family: var(--font-hud);
}
.resource-bar-empty { color: var(--muted); font-size: 0.8rem; text-align: center; }

.notification-bell-wrap { position: relative; display: flex; align-items: center; padding: 0 10px 0 2px; }
.bell-btn {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 3px; color: var(--text);
  background: transparent; border: 1px solid transparent;
}
.bell-btn:hover, .bell-btn[aria-expanded="true"] { color: var(--accent); border-color: var(--border); background: var(--panel-2); }
.bell-badge {
  position: absolute; top: 2px; right: 2px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 8px; background: var(--danger); color: #fff; font-size: 0.62rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center; line-height: 1;
}
.bell-badge[hidden] { display: none; }
.notification-panel {
  position: absolute; top: 46px; right: 0; z-index: 40; width: 280px; max-width: calc(100vw - 24px);
  max-height: 60vh; overflow-y: auto; background: var(--panel); border: 1px solid var(--border);
  border-radius: 4px; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
}
.notification-panel[hidden] { display: none; }
.notification-empty { padding: 16px; color: var(--muted); font-size: 0.8rem; text-align: center; }
.notification-row {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 12px 14px; text-align: left;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06); color: var(--text); background: transparent;
}
.notification-row:last-child { border-bottom: none; }
.notification-row:hover { background: var(--panel-2); }
.notification-row svg { color: var(--accent); flex-shrink: 0; }
.notification-row .name { font-size: 0.82rem; font-weight: 600; }
.notification-row .sub { font-size: 0.72rem; color: var(--muted); margin-top: 2px; }
.res-item { display: flex; align-items: center; gap: 5px; font-size: 0.74rem; color: var(--text); font-variant-numeric: tabular-nums; }
.res-item.metal svg { color: #9fb4d6; }
.res-item.crystal svg { color: #b98aff; }
.res-item.tritium svg { color: #5ed6a0; }
.res-item.energy svg { color: var(--warn); }
.res-item.energy.deficit { color: var(--danger); }
.res-item.energy.deficit svg { color: var(--danger); }
/* Stundenrate als zweite, kleinere Zeile unter dem Bestand (UI-Politur
   "Details, die uns von der Masse abheben") -- Kontoauszug-Optik statt nur
   im Tooltip versteckt. Nur Metall/Kristall/Tritium haben eine echte Rate;
   Energie ist bereits eine Bilanz, keine zusaetzliche Zeile noetig. */
.res-value-col { display: flex; flex-direction: column; line-height: 1.2; }
.res-value { font-weight: 600; }
.res-rate { font-size: 0.58rem; color: var(--good); font-weight: 400; }
.res-rate-negative { color: var(--danger); }

.screen {
  flex: 1;
  overflow-y: auto;
  /* KERNSTUECK des Fixes (siehe ausfuehrlichen Kommentar bei html/body):
     ein Flex-Kind bekommt ohne dieses `min-height:0` als Default
     `min-height:auto`, was es (je nach Browser/Spezifikations-Auslegung
     der "automatic minimum size") auf die volle Hoehe seines INHALTS statt
     auf den verfuegbaren `flex:1`-Platz wachsen lassen kann -- `overflow-y:
     auto` liefe dann ins Leere, weil nie ein kleinerer Rahmen entsteht, den
     es ueberhaupt zu scrollen gaebe. Explizit auf 0 gesetzt, ist `.screen`
     IMMER exakt so hoch wie der uebrige Platz in `.app-shell` und scrollt
     zuverlaessig intern. */
  min-height: 0;
  padding: 14px 14px 24px;
}

.bottom-nav {
  display: flex;
  flex-shrink: 0;
  background: #120c19e6;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.nav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 9px 4px 8px;
  color: var(--muted-2);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  min-height: 48px;
  border-radius: 10px;
  transition: color 0.15s ease;
}
.nav-item:hover { text-decoration: none; color: var(--text); }
.nav-item.active { color: var(--accent); }
.nav-item svg { color: inherit; }

/* Aktivitäts-Feed-Badge (Nutzerfeedback: "es fehlt eine Benachrichtigung im
   Hauptbild über neue Nachrichten") -- sitzt oben rechts über dem
   Nachrichten-Icon in der Bottom-Nav, siehe components/bottom-nav.js und
   app-shell.js::refreshUnreadBadge(). */
.nav-icon-wrap { position: relative; display: inline-flex; }
.nav-badge {
  position: absolute;
  top: -5px;
  right: -8px;
  background: var(--danger);
  color: #1a0505;
  font-size: 0.56rem;
  font-weight: 700;
  line-height: 1;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.nav-badge[hidden] { display: none; }

/* Nutzerfeedback: "Bei Querformat oder Desktop Ansicht, soll anstelle des
   Menüpunkt 'Mehr' alle Menüpunkte angezeigt werden" -- Basiszustand
   (Hochformat-Handy, nach wie vor der Default): die bisher nur im
   "Mehr"-Hub versteckten Punkte bleiben ausgeblendet, der "Mehr"-Button
   bündelt sie wie gehabt. Das eigentliche Umschalten auf "alle Punkte
   direkt sichtbar" passiert in css/desktop.css (siehe dort) -- diese Datei
   ist laut Kapitel 11.1 explizit fuer sämtliche Breakpoint-/
   Desktop-Anpassungen vorgesehen, main.css bleibt rein mobil-first. Siehe
   components/bottom-nav.js für die (einzige) Quelle der Eintrags-Liste. */
.nav-item-extended { display: none; }

/* AP6 (Desktop-Navigation gruppieren, siehe
   planning/gameplay-ui-verbesserungsplan-2026-08.md): Gruppen-Ueberschriften
   ("Spielen"/"Wirtschaft"/"Information"/"Verwaltung", siehe
   components/bottom-nav.js) sind in der mobilen Bottom-Leiste sinnlos -- dort
   stehen ohnehin nur wenige Punkte in einer Reihe, eine Ueberschrift haette
   keinen Platz UND keinen Nutzen. Mobiler Default also ausgeblendet, exakt
   wie `.nav-item-extended` oben; erst css/desktop.css blendet sie ab dem
   960px-Seitenleisten-Breakpoint ein. Die DOM-Struktur bleibt dabei fuer
   ALLE Breiten identisch (siehe Moduldocstring in bottom-nav.js). */
.nav-group-label { display: none; }

/* --- Karten / Listen --- */
.page-wrap { max-width: 480px; margin: 0 auto; padding: 20px 4px 40px; }
h1 { font-family: var(--font-serif); font-size: 1.15rem; letter-spacing: 0.01em; margin: 4px 0 6px; }
.section-title {
  font-family: var(--font-sans); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--muted-2); margin: 4px 0 14px;
}

.planet-hero { display: flex; flex-direction: column; align-items: center; margin-bottom: 14px; text-align: center; }
.planet-hero-canvas { border-radius: 50%; margin-bottom: 8px; filter: drop-shadow(0 0 26px rgba(211, 160, 90, 0.22)); }
.planet-icon { color: var(--accent); margin-bottom: 6px; }

/* Planeten-Animation (Nutzerfeedback: "gefällt die Planeten Animation" am
   Artefakt-Mockup): rotierendes Wolkenband + umkreisender Mond, siehe
   components/planet-canvas.js `drawPlanet(..., { detailed: true })`. Nur
   die grossen Einzel-Planetenbilder (Dashboard-Hero, Galaxie-Detailpanel)
   bekommen diese Klassen -- der Ring selbst braucht keine eigene Animation
   (er ist Teil der `.planet-cloud-band`-Gruppe? Nein: der Ring liegt fest,
   nur Wolken und Mond bewegen sich). `transform-origin` wird direkt inline
   vom JS gesetzt (Planetenmittelpunkt haengt vom jeweiligen `viewBox` ab). */
.planet-cloud-band { animation: planet-cloud-spin 90s linear infinite; }
.planet-orbit-group { animation: planet-moon-drift 26s linear infinite; }
@keyframes planet-cloud-spin { to { transform: rotate(360deg); } }
@keyframes planet-moon-drift { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .planet-cloud-band, .planet-orbit-group { animation: none; }
}
.planet-name { font-family: var(--font-serif); font-size: 1.5rem; font-weight: 400; text-wrap: balance; display: flex; align-items: center; gap: 6px; justify-content: center; }
/* Nutzerfeedback: Tritium-Temperaturbonus neben der Temperatur -- kälter
   ist gut (mehr Tritium, siehe Balancing.temperature_tritium_modifier). */
.temp-bonus-good { color: var(--good); }
.temp-bonus-bad { color: var(--danger); }

/* --- "Stage"-Panel (Planeten-Hero-Umrahmung, "Expedition Atlas"): keine
   Glas-/Leucht-Karte mehr, sondern eine "Objekttafel" -- flaches Panel mit
   vier gravierten Eckwinkeln (wie die Beschriftungstafel eines Exponats
   oder Vermessungsmarken auf einer Sternkarte), erzeugt rein per
   `background-image`-Verlaeufen auf `::after` (kein zusaetzliches HTML
   noetig). Der Rand selbst bleibt bewusst dezent (fast unsichtbar), die
   vier Winkel setzen die eigentliche Kontur. */
.eyebrow {
  font-family: var(--font-sans); font-size: 0.68rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted-2); margin: 0;
}
.stage {
  position: relative;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: var(--panel);
  padding: 18px 18px 16px;
  margin-bottom: 12px;
}
.stage::after {
  content: "";
  position: absolute; inset: 7px;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image:
    linear-gradient(to right, var(--accent-dim) 12px, transparent 0),
    linear-gradient(to bottom, var(--accent-dim) 12px, transparent 0),
    linear-gradient(to left, var(--accent-dim) 12px, transparent 0),
    linear-gradient(to bottom, var(--accent-dim) 12px, transparent 0),
    linear-gradient(to right, var(--accent-dim) 12px, transparent 0),
    linear-gradient(to top, var(--accent-dim) 12px, transparent 0),
    linear-gradient(to left, var(--accent-dim) 12px, transparent 0),
    linear-gradient(to top, var(--accent-dim) 12px, transparent 0);
  background-size: 12px 1.5px, 1.5px 12px, 12px 1.5px, 1.5px 12px, 12px 1.5px, 1.5px 12px, 12px 1.5px, 1.5px 12px;
  background-position: top left, top left, top right, top right, bottom left, bottom left, bottom right, bottom right;
  opacity: 0.55;
}
.stage-head, .stage-stats, .planet-hero { position: relative; z-index: 1; }
.stage-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 4px; }
/* Statusanzeige (UI-Politur "Expedition Atlas"): reiner Kleinschrift-Text
   statt gefuellter Pille mit Leucht-Punkt -- eine Feststellung, keine
   Alarmleuchte. Der Punkt davor bleibt als dezenter Marker, aber ohne
   eigenen Glow. */
.status-pill {
  font-family: var(--font-sans); font-size: 0.6rem; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--good); white-space: nowrap; display: inline-flex; align-items: center; gap: 5px;
}
.status-pill::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.status-pill-danger { color: var(--danger); }
.stage-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.alliance-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 14px; }
/* Allianz-Kopfzeile (UI-Politur, "modern wirken"): Icon-Badge vor Name +
   Tag statt reinem Fliesstext -- dieselbe kleine Aufwertung, die andere
   Listen-Header (Planet-Name, Werft-Zeilen) bereits per Icon bekommen. */
.alliance-header { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.alliance-header svg { color: var(--accent); flex-shrink: 0; }
/* Allianz-Siegel (UI-Politur "Expedition Atlas"): rundes, graviertes
   Wachssiegel mit dem Allianz-Tag statt eckiger "[TAG]"-Klammer -- ein
   zweiter, dünnerer Innenring gibt den geprägten Stempel-Look, `margin-left:
   auto` haelt es rechtsbuendig neben Icon + Namen in `.alliance-header`. */
.alliance-seal {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0; margin-left: auto;
  border: 2px solid var(--accent-dim);
  font-family: var(--font-serif); font-size: 0.64rem; font-weight: 700; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--accent);
}
.alliance-seal::before {
  content: ""; position: absolute; inset: 3px; border: 1px solid var(--accent-dim); border-radius: 50%; opacity: 0.5;
}

/* Achievement-Medaillen (Nutzerfeedback: "hast du noch eine Verbesserungs
   Idee?" -> Medaillen statt reinem "(Bronze)"-Text): dieselbe gravierte
   Doppelring-Sprache wie das Allianz-Siegel, nur je Stufe eingefaerbt --
   gesperrt bleibt sie ungefaerbt/gedaempft (nur Kontur, Medaillen-Icon
   innen), freigeschaltet bekommt sie die Stufenfarbe UND ein Haekchen statt
   des Medaillen-Icons, damit der Status auch ohne Farbe (Farbfehlsichtigkeit)
   erkennbar bleibt. */
.achievement-medal {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid var(--border); color: var(--muted-2);
}
.achievement-medal::before {
  content: ""; position: absolute; inset: 3px; border: 1px solid var(--border); border-radius: 50%; opacity: 0.5;
}
.achievement-medal.tier-bronze.unlocked { border-color: #8a6c42; color: #c58a3f; }
.achievement-medal.tier-bronze.unlocked::before { border-color: #8a6c42; }
.achievement-medal.tier-silver.unlocked { border-color: #9a9aa8; color: #c7c7d4; }
.achievement-medal.tier-silver.unlocked::before { border-color: #9a9aa8; }
.achievement-medal.tier-gold.unlocked { border-color: var(--warn); color: var(--warn); }
.achievement-medal.tier-gold.unlocked::before { border-color: var(--warn); }
/* Rollen-Chip (Mitgliederliste): ersetzt reinen Fliesstext ("Gründer") --
   Gold fuer den Gruender (analog zum Kronen-Icon), Verdigris fuer
   Diplomaten, gedaempft fuer normale Mitglieder. */
.role-chip {
  font-family: var(--font-sans); font-size: 0.6rem; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; white-space: nowrap; display: inline-block;
}
.role-chip.role-founder { color: var(--warn); background: rgba(236, 195, 132, 0.14); border: 1px solid rgba(236, 195, 132, 0.35); }
.role-chip.role-diplomat { color: var(--good); background: rgba(116, 160, 143, 0.14); border: 1px solid rgba(116, 160, 143, 0.35); }
.role-chip.role-member { color: var(--muted); background: rgba(255, 255, 255, 0.04); border: 1px solid var(--border); }
.stage-stat {
  border: 1px solid var(--border); border-radius: 3px; padding: 8px 10px; background: #150f1e80; text-align: center;
}
.stage-stat .k { font-family: var(--font-sans); font-size: 0.58rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-2); }
.stage-stat .v { font-family: var(--font-hud); font-size: 0.82rem; margin-top: 2px; }

/* --- "Weitere Planeten"-Streifen (Planet-Dashboard, UI-Redesign): dieselben
   Planeten wie im Umschalter-Dropdown (siehe components/app-shell.js), hier
   zusätzlich als anklickbare Mini-Karten direkt auf dem Dashboard -- die
   `data-switch-planet`-Buttons werden von app-shell.js::wirePlanetSwitcher
   automatisch mit-verdrahtet (die Klick-Delegation läuft über den ganzen
   `container`, nicht nur das Umschalter-Menü selbst), hier ist also kein
   eigener Event-Listener nötig. */
.strip-head { display: flex; align-items: baseline; justify-content: space-between; margin: 18px 0 12px; }
.strip-head h2 {
  margin: 0; font-family: var(--font-sans); font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text);
}
.empire-strip { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; }
.mini-planet {
  border: 1px solid var(--border); border-radius: 4px; padding: 12px;
  background: var(--panel);
  display: flex; gap: 10px; align-items: center; text-align: left;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.mini-planet:hover { border-color: var(--border-hi); transform: translateY(-1px); }
.mini-planet-thumb { flex-shrink: 0; width: 40px; height: 40px; display: block; }
.mini-planet .info { min-width: 0; display: flex; flex-direction: column; }
.mini-planet .name { font-size: 0.82rem; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-planet .coords { font-family: var(--font-hud); font-size: 0.66rem; color: var(--muted-2); margin-top: 1px; }
.mini-planet .temp { font-family: var(--font-hud); font-size: 0.7rem; color: var(--muted); margin-top: 3px; }

/* Nutzerfeedback: "Wir benötigen noch einen täglichen Login Bonus zur
   Motivation ... Dieser Bonus soll direkt im Planeten Bild unter der Grafik
   angezeigt werden, damit sie dem Spieler sofort auffällt." -- bewusst als
   auffaelliges, farbiges Badge (nicht nur ein Textzeile wie der
   Temperaturbonus), direkt zwischen Canvas und Namen platziert (siehe
   planet-view.js::renderLoginStreakBadge). Aktiver Bonus (>0%) bekommt den
   Erfolgs-Ton (gruen, analog zum Achievement-Banner), der "noch kein Bonus"-
   Zwischenzustand eine gedaempftere neutrale Variante. */
.login-streak-badge {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 6px;
  padding: 4px 10px; border-radius: 999px; font-size: 0.74rem; font-weight: 600;
  border: 1.5px solid var(--border); color: var(--muted);
}
.login-streak-badge svg { flex-shrink: 0; }
.login-streak-badge-active {
  border-color: var(--good); background: rgba(116, 160, 143, 0.12); color: var(--good);
}
.icon-btn {
  background: none; border: none; padding: 2px; color: var(--muted); cursor: pointer; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 6px;
}
.icon-btn:hover { color: var(--accent); }
.planet-rename-form { display: flex; align-items: center; gap: 6px; width: 100%; max-width: 280px; }
.planet-rename-form input {
  flex: 1; min-width: 0; background: none; border: none; border-bottom: 1px solid var(--accent-dim);
  color: var(--text); font-family: var(--font-serif); font-size: 1.1rem; padding: 4px 2px;
}
.planet-rename-form input:focus { outline: none; border-bottom-color: var(--accent); }
.planet-rename-actions { display: flex; gap: 4px; }
.planet-rename-actions .btn-small { padding: 6px 10px; }

/* --- Planeten-Umschalter mit Miniatur-Vorschau (spätere Überarbeitung
   "UX-Verbesserungen"), siehe views/planet-view.js --- */
/* Seit Nutzerfeedback "die Planeten Auswahl soll auf jeder Seite unter der
   Ressourcen Bar sichtbar sein" sitzt der Umschalter global in `.app-shell`
   direkt unter `.topbar-row` (siehe components/app-shell.js), nicht mehr
   nur innerhalb des gepolsterten `.screen` im Hauptbild -- deshalb hier das
   horizontale Padding, das vorher von `.screen` kam, plus etwas Abstand zur
   Ressourcenleiste darueber. */
#planet-switcher-slot { padding: 8px 14px 0; flex-shrink: 0; }
.planet-switcher { position: relative; width: 100%; margin-bottom: 14px; }
.planet-switcher-toggle {
  width: 100%; display: flex; align-items: center; gap: 10px; text-align: left;
  background: var(--panel); border: 1px solid var(--border); border-radius: 3px;
  color: var(--text); padding: 8px 10px;
}
.planet-switcher-chevron { margin-left: auto; color: var(--muted); }
.planet-switcher-thumb { flex-shrink: 0; width: 32px; height: 32px; display: block; }
.planet-switcher-thumb svg { display: block; border-radius: 50%; }
.planet-switcher-option-info { display: flex; flex-direction: column; min-width: 0; }
.planet-switcher-option-info .name { font-size: 0.85rem; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.planet-switcher-option-info .sub { font-size: 0.7rem; color: var(--muted); }
.planet-switcher-menu {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 20; margin-top: 4px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 3px;
  max-height: 300px; overflow-y: auto;
}
.planet-switcher-option {
  width: 100%; display: flex; align-items: center; gap: 10px; text-align: left;
  background: none; border: none; border-bottom: 1px solid var(--border); color: var(--text); padding: 8px 10px;
}
.planet-switcher-option:last-child { border-bottom: none; }
.planet-switcher-option:hover, .planet-switcher-option:focus { background: var(--panel-2); }
.planet-switcher-option.active { box-shadow: inset 2px 0 0 var(--accent); }

/* "Expedition Atlas"-Karten (UI-Politur, Nutzerfeedback "gefällt mir, setz
   es so um" -- siehe Design-Pitch-Artefakt): flache Plakette statt
   verlaufendem Glas-Panel -- ein Feldjournal-Eintrag hat keine Tiefe, nur
   einen Rahmen. Kantig statt stark abgerundet (4px reicht, um Pixelkanten
   zu brechen, ohne wie eine App-Store-Kachel zu wirken). */
.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 14px;
  margin-bottom: 12px;
}
.card-title {
  font-family: var(--font-sans);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted-2);
  margin-bottom: 10px;
  display: flex;
  justify-content: space-between;
}
/* Nutzerfeedback: "achte mehr auf Details" -- ein einzelnes Label (kein
   zweiter rechtsbuendiger Wert daneben) bekommt eine ausklingende Linie
   dahinter, wie eine Rubrik in einem Vermessungsbuch statt einer reinen
   Kleinschrift-Ueberschrift. Betrifft nur `span:only-child`, damit
   zweispaltige Titel (z. B. "Produktion" / "pro Stunde") unveraendert bleiben. */
.card-title span:only-child { display: flex; align-items: center; gap: 10px; flex: 1; }
.card-title span:only-child::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* Profil-Kopfkarte (Konto-Ansicht, UI-Redesign): Avatar-Badge + Name/
   Mitglied-seit statt direkt mit der ersten Einstellungs-Karte zu starten
   -- wie im Artefakt-Mockup. */
.profile-card { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 22px 14px; }
.avatar-badge {
  width: 64px; height: 64px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 35% 30%, #3a2a1a, #1a1210); border: 1px solid var(--border-hi);
  color: var(--accent); margin-bottom: 10px; box-shadow: 0 0 24px -6px rgba(211, 160, 90, 0.28);
}
.profile-card .pname { font-family: var(--font-serif); font-size: 1rem; font-weight: 600; }
.profile-card .prole { font-size: 0.76rem; color: var(--muted); margin-top: 3px; }

/* Nutzerfeedback: "Freunde-/Empfehlungssystem fehlt noch." -- Empfehlungscode-Anzeige in account-view.js. */
.referral-code-row { display: flex; align-items: center; gap: 10px; margin: 8px 0; }
.referral-code { background: var(--bg-alt, rgba(255,255,255,0.06)); border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; font-size: 0.9rem; letter-spacing: 0.03em; flex: 1; overflow-x: auto; white-space: nowrap; }

/* To-Do #10 ("Teilbare Kampf-/Spionageberichte"): Teilen-Button + Link-Anzeige
   in reports-view.js, wiederverwendet auch von shared-report-view.js. */
.share-row { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }

/* Bau-/Forschungs-Auftrag als "Fahrschein" (UI-Politur "Expedition Atlas"):
   gestrichelte Aussenkontur + eine perforierte Trennlinie (inkl. zweier
   Lochkreise) zwischen Icon und Auftragsdaten, wie ein abgerissener
   Bordkarten-Stub -- ersetzt die schlichte Flex-Zeile ohne Kontur. Die
   Lochkreise sind in der Panel-Hintergrundfarbe gehalten, damit sie wie
   echte Ausstanzungen wirken (siehe .card/.list-row `background: var(--panel)`).*/
.build-progress {
  position: relative;
  display: flex; align-items: center; gap: 14px;
  border: 1px dashed var(--border-hi); border-radius: 3px;
  padding: 10px 14px;
}
.build-progress svg {
  color: var(--accent); flex-shrink: 0;
  padding-right: 14px; border-right: 1px dashed var(--border-hi);
}
.build-progress::before, .build-progress::after {
  content: ""; position: absolute; left: 54px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--panel); border: 1px solid var(--border-hi);
}
.build-progress::before { top: -5px; }
.build-progress::after { bottom: -5px; }
.build-progress .info { flex: 1; }
.build-progress .name { font-size: 0.86rem; font-weight: 600; }
.build-progress .timer {
  font-family: var(--font-hud); font-size: 0.78rem; color: var(--warn);
  font-variant-numeric: tabular-nums; letter-spacing: 0.03em; margin-top: 2px;
}
.no-build { font-size: 0.8rem; color: var(--muted); text-align: center; padding: 4px 0; }

.storage-row { margin-bottom: 10px; }
.storage-row .label-row { display: flex; justify-content: space-between; font-size: 0.72rem; color: var(--muted); margin-bottom: 4px; }

/* Produktions-Karte (Planeten-Übersicht, siehe views/planet-view.js
   renderProductionCard) -- Nutzerfeedback: "keine Anzeige, wie viel
   produziert wird" / "was passiert bei -1 Energie". */
/* Mini-Schiffsbestand-Grid (Planet-Dashboard-Karte "Flotte", UI-Redesign) --
   kleinere Variante der `.ship-card`-Optik aus der vollen Werft-Ansicht
   (siehe fleet-view.js), nur als reine Anzeige ohne Bau-Formular. */
.mini-ship-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(78px, 1fr)); gap: 8px; }
.mini-ship-card {
  border: 1px solid var(--border); border-radius: 3px; padding: 8px 6px; text-align: center; background: #150f1e80;
}
.mini-ship-card svg { color: var(--accent); }
.mini-ship-card .count { font-family: var(--font-hud); font-size: 0.98rem; font-weight: 600; margin-top: 4px; font-variant-numeric: tabular-nums; }
.mini-ship-card .label {
  font-size: 0.6rem; color: var(--muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.production-row {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 0.8rem; padding: 5px 0; gap: 10px;
}
.production-row + .production-row { border-top: 1px solid var(--border); }
.production-row svg { vertical-align: -3px; margin-right: 4px; color: var(--accent); }
.production-row .energy-deficit { color: var(--danger); font-weight: 600; }
.production-warning {
  margin: 8px 0 0; padding: 8px 10px; border-radius: 8px;
  background: rgba(193, 90, 66, 0.1); border: 1px solid var(--danger);
  color: var(--text); font-size: 0.72rem; line-height: 1.5;
}
/* Frühwarnung vor ankommenden Angriffsflotten (Planeten-Übersicht, siehe
   views/planet-view.js renderIncomingAttackBanner) -- Nutzerfeedback: "eine
   Info wenn man angegriffen wird und wann die feindliche Flotte eintrifft".
   Bewusst auffälliger als `.production-warning` (dickerer Rand, eigene
   Icon-Farbe), da hier sofortiges Handeln (Verteidigung ausbauen/Flotte in
   Sicherheit bringen) gefragt sein kann. */
.incoming-attack-banner {
  display: flex; align-items: center; gap: 12px;
  border: 2px solid var(--danger); background: rgba(193, 90, 66, 0.12);
}
.incoming-attack-banner svg { color: var(--danger); flex-shrink: 0; }
.incoming-attack-banner .name { font-size: 0.86rem; font-weight: 700; color: var(--danger); }
.incoming-attack-banner .sub { font-size: 0.78rem; color: var(--text); margin-top: 2px; font-variant-numeric: tabular-nums; }
.incoming-attack-elsewhere { color: var(--danger); }

/* Nutzerfeedback: "es fehlt eine Benachrichtigung im Hauptbild über neue
   Nachrichten" -- klickbares Banner im Akzent-Ton (keine Bedrohung wie beim
   Angriffs-Banner oben, daher bewusst nicht rot). */
.unread-messages-banner {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  border: 2px solid var(--accent); background: rgba(211, 160, 90, 0.1);
}
.unread-messages-banner svg { color: var(--accent); flex-shrink: 0; }
.unread-messages-banner .name { font-size: 0.86rem; font-weight: 700; color: var(--accent); }
.unread-messages-banner .sub { font-size: 0.78rem; color: var(--text); margin-top: 2px; }

/* Nutzerfeedback: "Zeitlich befristete Events, steuerbar über das Admin
   Menü." -- gleicher Akzent-Ton wie das Nachrichten-Banner (eine
   Information, keine Bedrohung), aber `cursor: default` statt `pointer`, da
   dieses Banner (anders als die anderen hier) nicht klickbar ist. */
.active-events-banner {
  display: flex; align-items: center; gap: 12px; cursor: default;
  border: 2px solid var(--accent); background: rgba(211, 160, 90, 0.1);
}
.active-events-banner svg { color: var(--accent); flex-shrink: 0; }
.active-events-banner .name { font-size: 0.86rem; font-weight: 700; color: var(--accent); }
.active-events-banner .sub { font-size: 0.78rem; color: var(--text); margin-top: 2px; }

/* Bug-Check/UX-Runde 04.08.2026: Sammelkarte fuer die drei Welt-Zustands-
   Banner oben (Zeitevents/Community-Events/NPC-Wellen), wenn zwei oder mehr
   davon gleichzeitig aktiv sind -- siehe renderWorldStatusBanners in
   planet-view.js. Natives `<details>`/`<summary>` statt eigener Toggle-
   Logik: per Default eingeklappt (`.world-status-section` erbt daher via
   `<details>` automatisch `display: none`, solange kein `open`-Attribut
   gesetzt ist), Klick auf die Kopfzeile klappt auf/zu. */
.world-status-banner { border: 2px solid var(--accent); padding: 0; }
.world-status-summary {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  list-style: none; padding: 14px 16px; font-size: 0.86rem; font-weight: 700; color: var(--accent);
}
.world-status-summary::-webkit-details-marker { display: none; }
.world-status-summary svg { color: var(--accent); flex-shrink: 0; }
.world-status-section {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.world-status-section svg { color: var(--accent); flex-shrink: 0; }
.world-status-section .name { font-size: 0.86rem; font-weight: 700; color: var(--accent); }
.world-status-section .sub { font-size: 0.78rem; color: var(--text); margin-top: 2px; }

/* Nutzerfeedback: "wenn man neue Achievements erreicht hat sollte dies über
   eine Info mit Gratulation in der Planeten Ansicht angezeigt werden." --
   positiver/"Erfolgs"-Ton (grün) statt Bedrohung (rot) oder neutral (blau),
   damit eine Gratulation optisch sofort von einer Warnung unterscheidbar ist. */
.achievement-unlocked-banner {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  border: 2px solid var(--good); background: rgba(116, 160, 143, 0.12);
}
.achievement-unlocked-banner svg { color: var(--good); flex-shrink: 0; }
.achievement-unlocked-banner .name { font-size: 0.86rem; font-weight: 700; color: var(--good); }
.achievement-unlocked-banner .sub { font-size: 0.78rem; color: var(--text); margin-top: 2px; }

/* Nutzerfeedback ("Geführtes Onboarding für neue Spieler", Feature-Lücken-
   Analyse 2026-07): Checkliste im Akzent-Ton (wie das Nachrichten-Banner --
   eine Einladung, keine Warnung), jeder Schritt einzeln klickbar und springt
   direkt zur passenden Ansicht (siehe wireOnboardingBanner). */
.onboarding-banner { border: 2px solid var(--accent); }
.onboarding-step {
  display: flex; align-items: center; gap: 10px; padding: 8px 0; cursor: pointer;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.onboarding-step:first-of-type { border-top: none; }
.onboarding-step svg { color: var(--muted); flex-shrink: 0; }
.onboarding-step .name { font-size: 0.86rem; font-weight: 600; }
.onboarding-step .sub { font-size: 0.78rem; color: var(--muted); margin-top: 2px; }
.onboarding-step-done svg { color: var(--good); }
.onboarding-step-done .name { color: var(--good); text-decoration: line-through; text-decoration-color: rgba(116, 160, 143, 0.5); }
.onboarding-banner .btn { margin-top: 10px; }

/* AP4 (Onboarding von drei auf zwoelf Schritte, siehe
   planning/gameplay-ui-verbesserungsplan-2026-08.md): Fortschrittsbalken
   statt nur Text -- bei zwoelf Schritten liest sich "4 / 12" langsamer als
   ein Blick auf einen Balken. */
.onboarding-progress {
  height: 3px; border-radius: 0; background: rgba(255, 255, 255, 0.08);
  margin: 8px 0 10px; overflow: hidden;
}
.onboarding-progress-fill {
  height: 100%; transition: width 0.3s ease;
  background: var(--accent);
}

/* Der naechste offene Schritt bleibt die einzige PROMINENTE Karte
   (deutlich abgesetzt vom Rest, klickbarer Call-to-Action) -- alle zwoelf
   Schritte gleichzeitig ausgeklappt waeren laut Plan "eine Wand, kein
   Onboarding". Optisch bewusst kraeftiger als .onboarding-step (dickerer
   Rahmen, Akzent-Hintergrund), damit der Blick sofort dort landet. */
.onboarding-next-step {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; cursor: pointer;
  border: 1px solid var(--accent); border-radius: 8px; background: rgba(120, 170, 255, 0.08);
}
.onboarding-next-step svg:first-child { color: var(--accent); flex-shrink: 0; }
.onboarding-next-step svg:last-child { color: var(--muted); flex-shrink: 0; margin-left: auto; }
.onboarding-next-step .name { font-size: 0.86rem; font-weight: 700; }
.onboarding-next-step .sub { font-size: 0.78rem; color: var(--muted); margin-top: 2px; }

/* Alle zwoelf Schritte bleiben ueber "Alle Schritte anzeigen" erreichbar
   (native <details>, gleiches Muster wie .dashboard-hints-strip weiter
   unten) -- fuer einen Spieler, der gezielt einen spaeteren Schritt
   vorziehen will (die Reihenfolge ist eine Empfehlung, keine Sperre). */
.onboarding-all-steps { margin-top: 10px; }
.onboarding-all-steps summary { cursor: pointer; font-size: 0.78rem; color: var(--muted); padding: 4px 0; }
.onboarding-all-steps summary::-webkit-details-marker { display: none; }

/* Umsetzung UI-Skizzen-Runde 2 (05.08.2026), Abschnitt "Planeten-Dashboard":
   sobald Onboarding-Hinweis UND Achievement-Gratulation gleichzeitig aktiv
   sind, werden sie statt zwei einzelner Karten zu einer Sammelkarte mit
   Kopfzeile zusammengefasst -- exakt das gleiche `<details>`/`<summary>`-
   Muster wie .world-status-banner oben, nur inhaltlich fuer die Dashboard-
   Hinweise (Einsteiger-Tour/Achievements). Ist nur EIN Hinweis aktiv, bleibt
   es weiterhin die einzelne .onboarding-banner/.achievement-unlocked-banner
   Karte wie bisher -- siehe renderDashboardHintsStrip in planet-view.js. */
.dashboard-hints-strip { border: 2px solid var(--accent); padding: 0; }
.dashboard-hints-summary {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  list-style: none; padding: 14px 16px; font-size: 0.86rem; font-weight: 700; color: var(--accent);
}
.dashboard-hints-summary::-webkit-details-marker { display: none; }
.dashboard-hints-summary svg { color: var(--accent); flex-shrink: 0; }
.dashboard-hints-section {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  padding: 12px 16px; border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.dashboard-hints-section svg { color: var(--accent); flex-shrink: 0; }
.dashboard-hints-section .name { font-size: 0.86rem; font-weight: 700; color: var(--accent); }
.dashboard-hints-section .sub { font-size: 0.78rem; color: var(--text); margin-top: 2px; }
.dashboard-hints-section.achievement-unlocked-banner {
  border: none; background: none; padding: 12px 16px;
}
.dashboard-hints-section.achievement-unlocked-banner svg { color: var(--good); }
.dashboard-hints-section.achievement-unlocked-banner .name { color: var(--good); }

.storage-track { height: 3px; background: var(--border); overflow: hidden; }
.storage-fill { height: 100%; transition: width 0.3s; }
.storage-fill.metal { background: #9fb4d6; }
.storage-fill.crystal { background: #b98aff; }
.storage-fill.tritium { background: #5ed6a0; }
.progress-fill {
  height: 100%; transition: width 0.3s;
  background: var(--accent);
}

.list-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px; padding: 12px 14px; margin-bottom: 8px;
  transition: border-color 0.15s ease;
}
.list-row:hover { border-color: var(--border-hi); }
.list-row.locked { opacity: 0.6; }
.list-row svg { color: var(--accent); flex-shrink: 0; }
.list-row .info { flex: 1; min-width: 0; }
.list-row .name { font-size: 0.86rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-row .sub { font-size: 0.72rem; color: var(--muted); margin-top: 3px; }
.list-row .sub.effect { color: var(--good); }
/* Nutzerfeedback: "Allianzkriege" -- Kriegszustand in der Diplomatie-Liste
   (alliances-view.js::renderDiplomacySection) farblich analog zu anderen
   negativen Zustaenden (Energiedefizit etc.) hervorgehoben. */
.list-row .sub.effect-negative { color: var(--danger); }
/* Nutzerfeedback: "es fehlt eine Freundesliste ..." -- Aktions-Buttons
   (Annehmen/Ablehnen/Nachricht/Entfernen) rechtsbündig in einer .list-row,
   siehe friends-view.js. */
.list-row .row-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
/* Kosten-/Dauer-Zeile als umbrechende Reihe ganzer "12.345 Metall"-Einheiten
   statt eines einzelnen Fließtext-Satzes (Nutzerfeedback: auf schmalen
   Mobil-Breiten brach der Satz sonst faktisch nach jedem einzelnen Wort um,
   weil `white-space: normal` jedes Leerzeichen als moeglichen Umbruchpunkt
   behandelt). `.cost-chip` haelt jede Einheit (Zahl + Ressourcenname bzw.
   Zeit) mit `white-space: nowrap` zusammen -- bricht die Zeile doch um,
   dann immer zwischen ganzen Einheiten, nie mitten im Wort. */
/* Werft-Zeile (fleet-view.js::renderUnitRow, Nutzerfeedback 06.08.2026:
   "alles immer in einer neuen Zeile für bessere Übersicht") -- Ressourcen,
   Kampf-/Sonstige Stats und Bauzeit als drei getrennte, jeweils selbst
   umbrechende Zeilen statt einer einzigen überladenen Zeile. Gleiches
   Umbruchverhalten wie `.cost-line` (siehe Kommentar dort), deshalb hier
   zusammengefasst statt dreifach dupliziert. */
.list-row .sub.cost-line,
.list-row .sub.stats-line,
.list-row .sub.time-line { display: flex; flex-wrap: wrap; gap: 3px 10px; }
.cost-chip { white-space: nowrap; }
/* Aktuelle Produktions-/Energiebilanz je Gebäude (siehe
   views/buildings-view.js renderCurrentOutputLine) -- optisch von der
   Kosten-/Dauer-Zeile darunter abgesetzt (grün statt gedämpft), Energie-
   Verbrauch (negativ) sticht zusätzlich rot hervor. */
.list-row .sub.current-output { color: var(--good); }
.list-row .sub.current-output .cost-chip.energy-deficit { color: var(--danger); }
.level-badge { font-size: 0.66rem; color: var(--muted); font-weight: 500; margin-left: 4px; }
/* Mehrfach-Bau-Warteschlange (To-Do #12, buildings-view.js/fleet-view.js):
   eigene Karte über der Gebäude-/Werft-Liste mit allen wartenden
   Aufträgen in Reihenfolge. `.queue-badge` markiert innerhalb einer
   normalen Zeile, dass für dieses Gebäude/diese Einheit bereits Aufträge
   in der Warteschlange stehen (ersetzt die alte reine is_building-Anzeige). */
.queue-card { margin-bottom: 14px; }
.section-subtitle { font-size: 0.8rem; color: var(--muted); margin: 0 0 8px; text-transform: uppercase; letter-spacing: 0.02em; }
.queue-row .name { white-space: normal; }
.queue-badge { color: var(--accent); }
/* `flex-shrink: 0` allein reicht nicht: ohne eine harte Obergrenze durfte
   dieses Element so breit werden, wie sein Inhalt "am liebsten" wäre --
   und genau das sprengte bei Forschungen mit mehreren offenen
   Voraussetzungen (z. B. "Benötigt: Lasertechnik Stufe 10, Ionentechnik
   Stufe 5, Energietechnik Stufe X") die Zeile: `.info` (flex:1,
   min-width:0) wurde auf nahezu 0px zusammengequetscht, wodurch dort
   praktisch jedes einzelne Wort umbrach (Nutzerfeedback/Screenshot).
   `max-width` deckelt `.action` unabhängig von flex-shrink, damit `.info`
   immer einen nutzbaren Mindestanteil der Zeile behält. */
.list-row .action { flex-shrink: 0; max-width: 50%; text-align: right; }
.list-row .timer { font-size: 0.78rem; color: var(--warn); font-variant-numeric: tabular-nums; }
/* Abbrechen-Button unter dem Countdown (Nutzerfeedback: "es fehlt noch ein
   Abbruch-Button für Bau, Forschung und Schiffswerft") -- etwas Abstand zum
   Timer darüber, damit beides nicht zusammenklebt. */
.list-row .action .btn-cancel { margin-top: 6px; }

/* Admin-Detailansicht: Planeten-Karte (Nutzerfeedback: "im Adminmenü sollte
   die Planeten übersicht auch schön wie die Forschung angezeigt werden")
   -- kleine Abschnitts-Ueberschrift vor den `.list-row`-Zeilen je Kategorie
   (Gebäude/Schiffe/Verteidigung), analog zu `.activity-day-label`.
   `margin-top` groesser als `margin-bottom`, damit sich die Gruppe optisch
   klar vom vorherigen Abschnitt absetzt, aber eng an ihre eigenen Zeilen
   anschliesst. Erste Gruppe direkt nach der Rohstoffzeile bekommt dank
   `:first-of-type` weniger Abstand nach oben. */
.group-label {
  font-size: 0.68rem; font-weight: 700; color: var(--muted); text-transform: uppercase;
  letter-spacing: 0.04em; margin: 14px 0 6px;
}
.group-label:first-of-type { margin-top: 8px; }

/* Admin-Debug-Werkzeug "Ressourcen setzen" (Nutzerfeedback: "auch wären mehr
   Administrative Optionen sinnvoll für debug zwecke") -- schmales,
   gestapeltes Formular direkt in der Planeten-Karte, nutzt dieselben
   `.auth-field`-Eingabefelder wie die Auth-/Welteinstellungen-Formulare. */
.admin-resource-form { margin-top: 8px; }
.req-missing {
  font-size: 0.68rem; color: var(--muted); display: flex; flex-wrap: wrap;
  align-items: flex-start; justify-content: flex-end; gap: 4px; text-align: left;
}
/* Nutzerfeedback: Zeilenumbruch statt Komma zwischen mehreren fehlenden
   Voraussetzungen ("Benötigt: X Stufe 10<br>Y Stufe 5..."). Der Text steckt
   bewusst in einem eigenen, NICHT-flex Kindelement -- <br> innerhalb eines
   flex-Containers selbst wird von Browsern nicht zuverlässig als Zeilenumbruch
   behandelt, in einem normalen Block/Inline-Element dagegen schon. */
.req-missing-text { display: block; }

/* Fussnoten-System (UI-Politur "Expedition Atlas", siehe
   components/footnotes.js): ersetzt das Schloss-Icon an gesperrten Gebäude-/
   Forschungszeilen durch eine hochgestellte Marke direkt am Namen -- der
   volle Voraussetzungstext steht dafür nur einmal gesammelt unter der
   Liste, wie die Fussnoten eines gedruckten Handelsregisters. */
/* Nutzerfeedback: "die Zahlen der Fußnoten sind zu klein, schwer lesbar" --
   `<sup>` schrumpft per Browser-Standard auf ~75% der Elterngroesse; ohne
   eigene, feste `font-size` hier wuerde das bei ohnehin schon kleinem
   Zeilentext (`.list-row .name`, ~0.86rem) auf eine kaum lesbare Marke
   hinauslaufen. `font-weight` zusaetzlich angehoben, damit die Marke trotz
   kleinerer Groesse als Zahl klar erkennbar bleibt statt zu verschwimmen. */
.footnote-mark { color: var(--accent); cursor: help; margin-left: 1px; font-size: 0.76rem; font-weight: 700; }
.manifest-footnotes {
  margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border);
  font-size: 0.78rem; color: var(--muted);
}
/* Zweispaltiges Raster statt frei fliessendem Text (Nutzerfeedback: "die
   Fußnoten sollten strukturiert angezeigt werden") -- die Marke bekommt
   eine feste Spaltenbreite, der Text bricht bei mehreren Voraussetzungen
   haengend unter sich selbst um, nicht unter die naechste Marke. */
.footnote-entry { display: grid; grid-template-columns: 24px 1fr; column-gap: 4px; margin-bottom: 6px; align-items: baseline; }
.footnote-entry:last-child { margin-bottom: 0; }
.footnote-num { color: var(--accent); font-weight: 700; font-size: 0.86rem; }
.footnote-text { color: var(--muted); }

/* Nutzerfeedback: die Forschungs-Ansicht hatte hier zuvor ein eigenes
   Tech-Karten-Grid (`.tech-grid`/`.tech-card`, UI-Redesign) statt der
   `.list-row`-Zeilen, die praktisch jede andere Liste in der App verwendet
   (Gebäude, Werft, Rangliste, Nachrichten, ...) -- dadurch sahen Gebäude-
   und Forschungs-Ausbau inkonsequent unterschiedlich aus (u. a. andere
   Button-Position: Button am Kartenende statt rechtsbündig in der Zeile)
   und die Stufe stand doppelt da (`.lvl`-Text UND `.tech-level-badge`).
   research-view.js nutzt jetzt wieder `.list-row` wie buildings-view.js;
   `.researching` markiert hier nur noch dezent die aktiv laufende Zeile. */
.list-row.researching { border-color: var(--accent-dim); box-shadow: 0 0 0 1px rgba(211, 160, 90, 0.13), 0 0 22px -12px rgba(211, 160, 90, 0.5); }

/* --- Welt-Auswahl --- */
.world-card-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.world-card-title { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 0.92rem; }
.pill {
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 20px;
  padding: 3px 10px; font-size: 0.62rem; color: var(--muted); text-transform: uppercase;
  font-family: var(--font-sans); letter-spacing: 0.06em;
}
/* Community-Events (To-Do #8): noch nicht erreichte Belohnungsstufe -- dezenter als die
   Standard-`.pill` (die z. B. auch fuer "aktiv" genutzt wird), damit bereits ausgezahlte
   Stufen optisch hervorstechen. */
.pill-muted { opacity: 0.55; }
.world-card-meta { display: flex; flex-wrap: wrap; gap: 10px; font-size: 0.72rem; color: var(--muted); margin-bottom: 8px; }
.world-runtime { display: flex; align-items: center; gap: 5px; font-size: 0.7rem; color: var(--warn); margin-bottom: 8px; }
.world-card-actions { display: flex; justify-content: flex-end; }

/* --- Rechtstexte --- */
.legal-page { padding-top: 30px; }
.back-link { display: inline-block; margin-bottom: 16px; font-size: 0.82rem; }
/* Nutzerfeedback: "im Allianz Board unter dem Button 'Zurück zur Threadliste'
   fehlt etwas leer raum." -- der Button (kein <a class="back-link">, sondern
   ein normaler .btn, siehe alliances-view.js::renderThreadDetailSection) hat
   von Haus aus keinen margin-bottom, die direkt folgende .card ihrerseits
   nur margin-BOTTOM (main.css .card-Regel), nicht -top -- beide Ränder
   kollabieren also auf 0. Gleicher 16px-Abstand wie die etablierte
   .back-link-Konvention oben. */
#back-to-threads-btn { display: inline-block; margin-bottom: 16px; }
.legal-draft-badge {
  background: rgba(255, 199, 94, 0.12); border: 1px solid var(--warn); color: var(--warn);
  border-radius: 3px; padding: 10px 12px; font-size: 0.74rem; margin-bottom: 16px;
}
.legal-markdown h1 { font-size: 1.15rem; }
.legal-markdown h2 { font-size: 0.95rem; margin-top: 20px; color: var(--accent); }
.legal-markdown p, .legal-markdown li { font-size: 0.82rem; line-height: 1.6; color: var(--text); }
.legal-markdown blockquote {
  border-left: 3px solid var(--warn); margin: 0 0 14px; padding: 8px 12px; background: rgba(255,199,94,0.08);
  font-size: 0.78rem; color: var(--warn);
}
.legal-markdown ul { padding-left: 20px; }

/* --- Sub-Tabs (Ausbau/Flotte/Berichte, Frontend-Meilenstein F3-F5) --- */
.sub-tabs { display: flex; gap: 18px; margin-bottom: 14px; border-bottom: 1px solid var(--border); }
.sub-tab {
  text-align: center; padding: 0 0 9px; font-family: var(--font-sans);
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); background: none; border: none; border-bottom: 1px solid transparent; margin-bottom: -1px;
}
.sub-tab.active { color: var(--accent-hi); border-bottom-color: var(--accent); }

/* --- Pill-Tabs (Rangliste, UI-Politur): gleiche Rolle wie `.sub-tabs`
   oben (Kategorie waehlen), aber fuer mehr Eintraege als sinnvoll gleich
   breit nebeneinander passen (7 Rangliste-Kategorien) -- statt gleich
   breiter Reiter eine waagerecht scrollbare Pille-Reihe, jede Pille so
   breit wie ihr Text braucht. Scrollbar bewusst unsichtbar (`scrollbar-
   width`/`::-webkit-scrollbar`), der Scroll-Hinweis kommt allein vom
   abgeschnittenen letzten Pill am rechten Rand. */
.pill-tabs { display: flex; gap: 20px; overflow-x: auto; margin-bottom: 14px; border-bottom: 1px solid var(--border); scrollbar-width: none; }
.pill-tabs::-webkit-scrollbar { display: none; }
.pill-tab {
  flex: none; font-family: var(--font-sans); font-size: 0.7rem; font-weight: 500; letter-spacing: 0.07em; text-transform: uppercase; white-space: nowrap;
  padding: 0 0 9px; border: none; border-bottom: 1px solid transparent; margin-bottom: -1px; background: none; color: var(--muted);
}
.pill-tab.active { color: var(--accent-hi); border-bottom-color: var(--accent); }

/* --- Werft / Flotte --- */
.qty-input { width: 56px; background: none; border: none; border-bottom: 1px solid var(--border-hi); color: var(--text); font-family: var(--font-hud); padding: 6px 2px; font-size: 0.78rem; text-align: center; margin-right: 6px; }
.qty-input:focus { outline: none; border-bottom-color: var(--accent); }
/* Bug-Check/UX-Runde 04.08.2026: der neue "Max"-Button (siehe
   computeMaxAffordableQuantity in fleet-view.js) reiht sich zwischen Mengen-
   Eingabe und "Bauen"-Button ein -- `flex-wrap` verhindert, dass die Zeile
   auf sehr schmalen Bildschirmen (< 360px) über die `max-width: 50%` von
   `.list-row .action` hinausläuft, statt einfach in eine zweite Zeile
   umzubrechen. */
.unit-action { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 4px 6px; }
.stepper { display: flex; align-items: center; gap: 6px; }
.stepper-btn { width: 30px; height: 30px; border-radius: 8px; background: var(--panel-2); border: 1px solid var(--border); color: var(--text); font-size: 1rem; font-weight: 700; }
.stepper .qty-input { margin-right: 0; width: 46px; }

/* Schiffs-/Verteidigungs-Karten-Grid (UI-Redesign): dieselben `.list-row`-
   Zeilen (JS wiring bleibt auf `.closest(".list-row")` angewiesen, siehe
   fleet-view.js), aber innerhalb `.ship-grid` als vertikal gestapelte Karte
   statt horizontaler Zeile -- passender fuer ein Karten-Raster wie im
   Artefakt-Mockup. */
.ship-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px; margin-bottom: 12px; }
.ship-grid .list-row { flex-direction: column; align-items: stretch; gap: 6px; }
/* Nutzerfeedback: "achte mehr auf Details" -- duenne gestrichelte
   Trennlinie unter Icon/Name, dieselbe Manifest-Perforation wie beim
   Bau-Fahrschein (`.build-progress`), damit eine Werft-Karte wie ein
   eigener Eintrag im Bestandsbuch wirkt statt nur gestapelten Zeilen. */
.ship-card-top { display: flex; align-items: center; gap: 10px; padding-bottom: 8px; border-bottom: 1px dashed var(--border); margin-bottom: 2px; }
.ship-card-top .info { flex: 1; min-width: 0; }
.ship-grid .list-row .action { max-width: none; text-align: left; margin-top: auto; padding-top: 4px; }
.ship-grid .unit-action { justify-content: flex-start; }

/* --- Wizard (Kapitel 11.3) --- */
/* Umsetzung UI-Skizzen-Runde 2 (05.08.2026), Abschnitt "Flotte-senden-
   Wizard: Auswahl bleibt sichtbar" -- siehe renderWizardSummary in
   fleet-view.js. Bewusst dezent (kleinere Schrift, gedämpfte Farbe) und
   ueber `flex-wrap` umbruchfreundlich, damit die Zeile auch auf schmalen
   Bildschirmen bei vielen ausgewaehlten Schiffstypen nicht überläuft. */
.wizard-summary {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  padding: 10px 12px; margin-bottom: 14px; border-radius: 3px;
  background: var(--panel-2); border: 1px solid var(--border);
  font-size: 0.78rem; color: var(--text);
}
.wizard-summary-item { display: inline-flex; align-items: center; gap: 5px; }
.wizard-summary-item svg { width: 15px; height: 15px; color: var(--accent); flex-shrink: 0; }
.wizard-summary-mission { font-weight: 700; color: var(--accent); }
.wizard-summary-sep { color: var(--muted); }
.wizard-steps { display: flex; align-items: center; margin-bottom: 18px; }
.wizard-step { display: flex; flex-direction: column; align-items: center; gap: 4px; flex: 1; }
/* Nutzerfeedback: "achte mehr auf Details" -- Wegpunkt-Ringe statt reiner
   Vollkreise, dieselbe gravierte Ring-Sprache wie die Astrolabium-Blende
   am Planeten und das Allianz-Siegel: ein aktiver Schritt bekommt einen
   weichen Halo-Ring (wird gerade anvisiert), ein erledigter einen duennen
   Aussenring (abgehakter Wegpunkt). */
.wizard-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); display: block; position: relative; }
.wizard-step.active .wizard-dot { background: var(--accent); box-shadow: 0 0 0 3px rgba(211, 160, 90, 0.2); }
.wizard-step.done .wizard-dot { background: var(--good); }
.wizard-step.done .wizard-dot::after {
  content: ""; position: absolute; inset: -4px; border: 1px solid var(--good); border-radius: 50%; opacity: 0.4;
}
.wizard-step-label { font-size: 0.58rem; color: var(--muted); text-align: center; }
.wizard-step.active .wizard-step-label { color: var(--accent); font-weight: 700; }
.wizard-connector { flex: 0.6; height: 1px; background: var(--border); margin-bottom: 16px; }
.wizard-body { min-height: 120px; margin-bottom: 16px; }
.wizard-nav { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.wizard-nav .btn { flex: 1; }

/* Nutzerfeedback: "Beim Flotte senden sollte eine Vorschau für den
   benötigten Treibstoff angezeigt werden, nicht erst nach dem senden." --
   siehe views/fleet-view.js::refreshFuelPreview. */
.fuel-preview-box { margin-top: 10px; padding: 10px 14px; }
.fuel-preview-box p { margin: 0; }
.fuel-preview-box p + p { margin-top: 4px; }
.fuel-preview-warning { color: var(--danger); font-weight: 700; }

/* Missionstyp-Auswahl (UI-Politur "Expedition Atlas"): schlichte umrandete
   Kachel statt gefuellter Karte mit starkem Radius -- dieselbe flache,
   Umriss-Optik wie `.btn`/`.type-select`, nur als Raster statt Zeile (zehn
   Missionstypen passen nicht als einzeilige Wort-Tabs auf einen schmalen
   Bildschirm). */
.mission-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.mission-choice {
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 8px;
  background: none; border: 1px solid var(--border); border-radius: 3px;
  color: var(--muted); font-family: var(--font-sans); font-size: 0.66rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.mission-choice svg { color: var(--muted); }
.mission-choice.active { border-color: var(--accent); color: var(--accent); }
.mission-choice.active svg { color: var(--accent); }
.mission-choice:disabled { opacity: 0.45; }
/* Bug-Check/UX-Runde 04.08.2026: markiert Missionstypen, für die der
   aktuelle Planet keine passenden Schiffe stationiert hat, schon auf der
   Missionstyp-Kachel selbst (siehe renderMissionStep in fleet-view.js) --
   `opacity` bewusst weniger stark reduziert als bei `:disabled`, die Kachel
   bleibt ja klickbar. */
.mission-choice-warn { border-color: var(--warn); opacity: 0.75; }
.mission-choice-warn svg:last-child { color: var(--warn); }
.mission-ships-warn { display: flex; align-items: center; gap: 6px; color: var(--warn); margin-top: 10px; }
.mission-ships-warn svg { flex-shrink: 0; }

.target-fields { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.target-fields .auth-field { min-width: 0; }
.target-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.target-chip { background: var(--panel-2); border: 1px solid var(--border); color: var(--accent); }

/* --- Galaxie --- */
.galaxy-form { display: flex; align-items: flex-end; gap: 8px; margin-bottom: 14px; }
.galaxy-form .auth-field { flex: 1; margin-bottom: 0; }
.galaxy-form .btn { flex-shrink: 0; }
.note-inline { color: var(--muted); }

/* Sternkarte (Kapitel 5.9/11): ein Punkt pro tatsächlich existierendem
   Planeten auf dem system_grid_size x system_grid_size-Koordinatenraster
   (Standard 100x100) -- der ganz überwiegende Rest bleibt echter leerer
   Raum. Bewusst KEINE Spielernamen auf der Karte selbst; Details erscheinen
   erst im Panel unterhalb nach Antippen eines Punktes. Farbe = Temperatur
   (siehe components/planet-canvas.js tempPalette), Grau = unerforscht,
   Blau mit Ring = eigener Planet. */
/* Nutzerfeedback: "die Karte darf auch in der Breite + Höhe skalieren" --
   `.galaxy-page`/`.galaxy-results` (siehe unten) spannen dafuer erst den
   kompletten verfuegbaren `.screen`-Platz als Flex-Spalte auf; `.starmap-wrap`
   ist darin selbst `flex:1` und wird dadurch automatisch so hoch wie der
   uebrige Platz zwischen Modus-Umschalter und Legende/Hinweistext -- die
   tatsaechliche Canvas-Kantenlaenge berechnet computeCanvasSize() in
   galaxy-view.js aus der resultierenden Breite UND Hoehe dieses Elements.
   Bug-Check (Nutzerfeedback: "beim Auswählen eines Planeten schrumpft die
   Karte nachdem die Informationen unten eingeblendet werden und die Seite
   kann nicht gescrollt werden"): `min-height: 0` hier UND auf
   `.galaxy-page`/`.galaxy-results` (siehe dort) hiess in der Summe, dass
   das Detail-Panel unterhalb der Karte (siehe renderDetailPanel) beim
   Erscheinen der Karte ihren Platz reinweg WEGNAHM statt eigenen Platz
   einzufordern -- der starre `height: 100%`-Rahmen von `.galaxy-page`
   liess nichts ueberlaufen, wodurch `.screen` (siehe dort) nie etwas zum
   Scrollen hatte. Jetzt bekommt `.starmap-wrap` stattdessen eine konkrete
   Mindesthoehe (260px MIN_CANVAS_SIZE aus galaxy-view.js + 2x8px Padding),
   und `.galaxy-page`/`.galaxy-results` duerfen ueber ihre 100%-Vorgabe
   hinauswachsen (siehe dort) -- reicht der Platz nicht fuer Karte UND
   Detail-Panel gleichzeitig, waechst die Seite jetzt echt und `.screen`
   scrollt, statt die Karte bis zur Unkenntlichkeit zusammenzudruecken. */
.starmap-wrap {
  display: flex; align-items: center; justify-content: center; background: var(--panel);
  border: 1px solid var(--border); border-radius: 3px; padding: 8px; margin-bottom: 10px;
  flex: 1; min-height: 276px;
}
/* Kein eigener Radius mehr auf dem Canvas selbst (siehe drawStarmap in
   galaxy-view.js): der neue Messingrahmen mit Gradmarken wird als eckiges
   Rechteck INS Canvas-Pixelbild gezeichnet -- ein CSS-`border-radius` hier
   wuerde dessen Ecken abschneiden und nicht zum gezeichneten Rahmen passen. */
/* Nutzerfeedback: "die Galaxy Karte sollte gezoomt werden können ohne die
   App zu zoomen" -- `touch-action: none` uebergibt dem Canvas die
   VOLLSTAENDIGE Kontrolle ueber Touch-Gesten (Pinch, Drag), sodass der
   Browser sie NICHT mehr als Seiten-Zoom/Scroll interpretiert, bevor
   wireCanvasInteractions() in galaxy-view.js sie selbst auswertet. War
   vorher `manipulation` (erlaubt native Gesten ausser Doppeltipp-Zoom) --
   genau das liess ein Pinch auf der Karte bisher die ganze App zoomen. */
.starmap-canvas { max-width: 100%; touch-action: none; cursor: pointer; }
/* Zoom-Kontrollen unter der Karte (Nutzerfeedback s.o.) -- Pinch/Mausrad/
   Ziehen auf der Karte selbst (siehe wireCanvasInteractions) decken die
   eigentliche Bedienung ab, diese Buttons sind die entdeckbare, tastatur-/
   maus-freundliche Ergänzung dazu (u.a. fuer Nutzer, die die Geste nicht
   von selbst finden) plus ein Reset, um wieder auf die volle Systemansicht
   zurueckzukommen. */
.starmap-zoom-controls { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 10px; }
.starmap-zoom-level { font-size: 0.72rem; color: var(--muted); min-width: 3.4em; text-align: center; font-variant-numeric: tabular-nums; }
.starmap-legend {
  display: flex; flex-wrap: wrap; gap: 10px; font-size: 0.68rem; color: var(--muted);
  margin-bottom: 14px;
}
.starmap-legend span { display: inline-flex; align-items: center; gap: 4px; }
.legend-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.starmap-detail-card { display: flex; flex-direction: column; }
.starmap-mode-tabs { margin-bottom: 10px; }
/* Zielfilter ("Alle Planeten"/"Lohnende Ziele", siehe galaxy-view.js) --
   gleiche .sub-tab-Optik wie der Karte/Liste-Umschalter direkt darueber,
   nur mit eigenem Abstand nach unten, damit beide Zeilen klar getrennt
   bleiben statt optisch zu verschmelzen. */
.starmap-target-filter-tabs { margin-bottom: 10px; }
/* Aktivitaets-/Schutz-Badges (Zielfindung im Angriffs-Loop, siehe
   app/api/v1/galaxy.py): kompakte Pillen neben Liste-/Detail-Statuszeilen.
   Farbwahl bewusst NICHT rot=schlecht/gruen=gut aus Sicht des BESITZERS,
   sondern aus Sicht des BETRACHTERS (Angreifers): "lange inaktiv" ist gruen
   eingefaerbt, weil das aus Angreifersicht eine GUTE Nachricht ist (ein
   risikoarmes Ziel) -- obwohl es fuer den Besitzer selbst einen negativen
   Zustand beschreibt. "geschützt" ist bewusst neutral (--muted) statt rot/
   gruen, weil es weder eine Chance noch ein Warnsignal ist, sondern schlicht
   "hier geht nichts" -- der Angriffs-Button bleibt trotzdem klickbar (siehe
   renderDetailPanel), nur eben ohne Erfolgsaussicht. */
/* UI-Politur "Expedition Atlas": reines Kleinschrift-Wort statt gefuellter
   Farb-Pille -- passt zur Register-Tabellen-Optik der Sternkarten-Liste
   (Objekt/Status als schlichter Text, keine bunten Chips). */
.activity-badge {
  font-size: 0.62rem; margin-left: 6px; white-space: nowrap;
  font-family: var(--font-sans); text-transform: uppercase; letter-spacing: 0.05em;
}
.activity-inactive { color: var(--warn); }
.activity-long-inactive { color: var(--good); }
.activity-protected { color: var(--muted); }
.activity-protected-hint { color: var(--muted); margin-top: 4px; }
/* Nutzerfeedback: "in der Galaxy Karte sollte bei Auswahl eines Planeten
   nicht nur seine Informationen angezeigt werden, sondern auch eine
   Grafik wie die, des Planeten aus dem Hauptbild." -- dieselbe kreisrunde
   Darstellung wie `.planet-hero-canvas`, nur kleiner und links neben statt
   über den Textzeilen (hier ist deutlich weniger vertikaler Platz als im
   Hauptbild). */
.starmap-detail-head { display: flex; align-items: center; gap: 12px; }
.starmap-detail-planet-canvas { border-radius: 50%; flex-shrink: 0; filter: drop-shadow(0 0 14px rgba(211, 160, 90, 0.22)); }
.starmap-detail-head-info { flex: 1; min-width: 0; }

/* Listen-Ansicht (Nachtrag): dieselben Planeten wie auf der Karte, aber als
   normal große, garantiert treffsichere Zeilen -- Fallback für kleine
   Bildschirme/ungenaue Tipp-Gesten, wo einzelne Punkte auf der Karte zu
   dicht beieinander liegen koennten.
   Nutzerfeedback: "die Galaxie Liste darf die volle Höhe nutzen" -- vorher
   fest bei 420px gedeckelt, unabhaengig vom tatsaechlich verfuegbaren Platz
   (auf einem hohen Desktop-Fenster blieb darunter viel ungenutzter Raum
   leer, siehe `.galaxy-page`/`.galaxy-results` weiter unten). `flex: 1`
   laesst die Liste stattdessen den kompletten Rest von `.galaxy-results`
   einnehmen, `min-height` ist nur noch eine Komfort-Untergrenze fuer sehr
   niedrige Fenster (dann faellt `.screen` wie gehabt auf normales
   Dokument-Scrolling zurueck, siehe dortiger Kommentar). */
.starmap-list { flex: 1; min-height: 240px; overflow-y: auto; margin-bottom: 10px; }

/* Nutzerfeedback: "die Galaxie Liste darf die volle Höhe nutzen und die
   Karte darf auch in der Breite + Höhe skalieren" -- gemeinsamer Flex-
   Rahmen fuer die gesamte Sternkarten-Seite (galaxy-view.js). `.galaxy-page`
   spannt den kompletten verfuegbaren `.screen`-Platz auf (100% dessen
   bereits durch main.css/desktop.css definierter Hoehe), Titel und
   Galaxie/System-Formular behalten ihre natuerliche Groesse, `.galaxy-results`
   bekommt als einziges `flex: 1`-Kind den gesamten Rest -- darin wachsen
   wiederum `.starmap-list` bzw. `.starmap-wrap` (siehe oben) je nach
   aktivem Modus in die verbleibende Hoehe. */
/* Bug-Check (siehe ausfuehrlichen Kommentar bei `.starmap-wrap` oben):
   `min-height: 100%` statt `height: 100%` -- als reine UNTERGRENZE lässt das
   der Seite weiterhin die volle `.screen`-Hoehe, WENN alles hineinpasst
   (normaler Fall ohne Detail-Panel), erlaubt ihr aber auch, ueber diese
   Grenze hinauszuwachsen, sobald Karte (mit ihrer eigenen Mindesthoehe,
   siehe `.starmap-wrap`) UND Detail-Panel zusammen mehr Platz brauchen --
   `.screen` (siehe dort, bereits `overflow-y: auto`) uebernimmt das
   Scrollen dann automatisch, ganz ohne zusaetzlichen Code hier. */
.galaxy-page { display: flex; flex-direction: column; min-height: 100%; }
.galaxy-results { display: flex; flex-direction: column; flex: 1; }
/* --- Generische Tabellen-Optik (UI-Redesign): wiederverwendet von der
   Galaxie-Liste, der Allianz-Mitgliederliste usw. -- ein Glass-Rahmen mit
   klarer Kopfzeile statt gestapelter `.list-row`-Karten, siehe
   Artefakt-Mockup. */
.table-wrap { border: 1px solid var(--border); border-radius: 4px; overflow: auto; background: var(--panel); }
.table-wrap table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.table-wrap thead th {
  text-align: left; font-family: var(--font-sans); font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted-2); font-weight: 500; padding: 10px 12px; border-bottom: 1px solid var(--border);
  background: #150f1e80; position: sticky; top: 0;
}
.table-wrap tbody td { padding: 9px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.table-wrap tbody tr:last-child td { border-bottom: none; }
.table-wrap tbody tr:hover td { background: rgba(211, 160, 90, 0.05); }
.table-wrap .name { font-size: 0.86rem; font-weight: 600; }
.table-wrap .sub { font-size: 0.72rem; color: var(--muted); margin-top: 3px; }
.table-wrap .timer { font-size: 0.78rem; color: var(--warn); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Icon + Name nebeneinander in einer Tabellenzelle (Rangliste, Galaxie) --
   `.num` haelt Zahlenspalten (Rang, Punkte) in der HUD-Monospace-Schrift
   mit `tabular-nums`, damit Ziffern beim Sortieren/Aktualisieren nicht
   seitlich "wandern". */
.table-wrap .slot-obj { display: flex; align-items: center; gap: 10px; }
.table-wrap td.num, .table-wrap th.num { font-family: var(--font-hud); font-variant-numeric: tabular-nums; color: var(--muted); }

/* Podium (Rangliste, UI-Politur): Top 3 als eigene Kacheln oberhalb der
   Tabelle -- Rang 1 bekommt einen dezenten Gold-Akzent, damit die Spitze
   auf den ersten Blick auffaellt, ohne die App-weite Akzentfarbe (Cyan) fuer
   "das ist wichtig" umzudefinieren. */
.podium { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
.podium-tile {
  border: 1px solid var(--border); border-radius: 3px; padding: 12px 8px; text-align: center;
  background: var(--panel);
}
.podium-tile svg { color: var(--accent); }
/* Rang 1 ist der einzige bewusste Akzent-Moment der Rangliste (siehe
   artifact-design-Prinzip "spend your boldness in one place") -- Gold-
   Rahmen + ein sehr dezenter warmer Verlauf statt Leucht-Schatten. */
.podium-tile.rank-1 {
  border-color: var(--warn);
  background: linear-gradient(180deg, rgba(236, 195, 132, 0.1), var(--panel) 65%);
}
.podium-tile.rank-1 svg { color: var(--warn); }
.podium-tile .rank { font-family: var(--font-sans); font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-2); margin-top: 4px; }
.podium-tile .name { font-size: 0.8rem; font-weight: 700; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.podium-tile .value { font-family: var(--font-hud); font-size: 0.86rem; color: var(--accent); margin-top: 3px; }
.podium-tile.rank-1 .value { color: var(--warn); }

/* "Mein Rang"-Pin (Nutzerfeedback: "meinen eigenen Rang anpinnen") -- eine
   dezent hervorgehobene Zeile ueber dem Podium, NUR sichtbar, wenn der
   eigene Rang nicht ohnehin schon unter den geladenen Eintraegen ist (siehe
   rankings-view.js::renderResults). Gedaempfter Messing-Rahmen/-Wash statt
   der helleren Gold-Note von Rang 1 im Podium -- "das bist du" ist eine
   andere Aussage als "das ist die Spitze", der Akzent bleibt Rang 1 vorbehalten. */
.my-rank-pin {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px; margin-bottom: 14px;
  border: 1px solid var(--accent-dim); border-radius: 3px; background: rgba(211, 160, 90, 0.08);
}
.my-rank-pin svg { color: var(--accent); flex-shrink: 0; }
.my-rank-pin .info { flex: 1; min-width: 0; }
.my-rank-pin .name { font-size: 0.84rem; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.my-rank-pin .value { font-family: var(--font-hud); font-size: 0.84rem; color: var(--accent); flex-shrink: 0; }

.starmap-list-row { cursor: pointer; }
.starmap-list-row.active td { background: rgba(211, 160, 90, 0.08); }
.starmap-list-row.active td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.starmap-list-thumb-cell { width: 1%; white-space: nowrap; }
.starmap-list-status-cell { text-align: right; }
.starmap-list-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; }
/* Nutzerfeedback: "Galaxy Karte in der Listen Ansicht sollte statt einfachen
   punkten ein kleiner planet ... wie im Dropdown der Planeten Auswahl"
   -- ersetzt `.starmap-list-dot` fuer bekannte Planeten (siehe
   galaxy-view.js::renderListMode/LIST_PLANET_CANVAS_SIZE). `display:block`
   verhindert den sonst ueblichen kleinen Leerraum unter Inline-Canvas-
   Elementen (Baseline-Ausrichtung), analog zu `.planet-switcher-thumb`. */
.starmap-list-thumb { width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; display: block; }

/* --- Ranglisten --- */
.type-select {
  width: 100%; background: none; border: none; border-bottom: 1px solid var(--border-hi); border-radius: 0;
  color: var(--text); font-family: var(--font-hud); font-size: 0.85rem; padding: 8px 2px; margin-bottom: 14px;
}
.type-select:focus { outline: none; border-bottom-color: var(--accent); }

/* --- Allianz --- */
.alliance-actions { display: flex; flex-direction: column; gap: 4px; align-items: flex-end; }
.alliance-actions .btn { width: auto; }

/* --- Nachrichten --- */
.message-row { cursor: pointer; }
.message-row.unread .name { font-weight: 800; }
.message-row .message-checkbox { flex-shrink: 0; width: 18px; height: 18px; accent-color: var(--accent); }
/* Nutzerfeedback: "Der Inhalt einer Nachricht sollte unter dem Feld der
   Nachricht angezeigt werden, die man angewählt hat." -- jede Zeile hat
   jetzt ihren eigenen Detail-Slot direkt darunter (siehe messages-view.js)
   statt eines einzigen globalen Slots am Ende der ganzen Liste. Der
   `.list-row`-eigene `margin-bottom` entfaellt fuer die Zeile INNERHALB
   eines Wraps (der Wrap selbst traegt den Abstand), damit zwischen Zeile
   und ausgeklapptem Inhalt kein Luecken-Sprung entsteht.
*/
.message-row-wrap { margin-bottom: 10px; }
.message-row-wrap .message-row { margin-bottom: 0; }
.message-detail-slot:not(:empty) { margin-top: 8px; }
.message-detail-slot:empty { display: none; }
/* Nutzerfeedback (06.08.2026): "der Allianz Administrator und Offiziere
   sollten stationierte Truppen an den Außenposten sehen können im Detail."
   -- Garnisons-Aufschlüsselung nach Schiffstyp, siehe
   alliances-view.js::renderGarrisonDetail. Gleicher Abstands-Grundsatz wie
   .message-detail-slot oben (margin auf dem Wrap, nicht auf den einzelnen
   .list-row-Zeilen darin). */
.garrison-detail { margin-top: 8px; border-top: 1px solid var(--border); padding-top: 8px; }
/* Nutzerfeedback: "Es fehlt eine Möglichkeit auf Nachrichten zu antworten
   (Antworten button)" -- Antworten- und Löschen-Button nebeneinander statt
   volle Breite (wie schon bei .planet-rename-actions). */
.message-detail-actions { display: flex; gap: 8px; margin-top: 4px; }
.message-detail-actions .btn { width: auto; }
/* Sammel-Aktionsleiste (Nutzerfeedback: "es fehlt eine Möglichkeit mehrere
   Nachrichten gleichzeitig zu löschen oder als gelesen zu markieren"). */
.bulk-action-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; padding: 8px 12px; margin-bottom: 8px; background: var(--panel-2);
  border: 1px solid var(--border); border-radius: 3px; font-size: 0.78rem;
}
.bulk-select-all { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.bulk-select-all input { accent-color: var(--accent); }
.bulk-action-buttons { display: flex; gap: 8px; flex-wrap: wrap; }
.bulk-action-buttons .btn { width: auto; }

/* Aktivitäts-Feed (Nutzerfeedback: "es fehlt eine In-App-Chronik, was seit
   dem letzten Login passiert ist") -- Kategorie-Filter + "Alle als gelesen
   markieren" oberhalb der nach Tag gruppierten Liste, siehe messages-view.js
   ::renderActivityTab(). */
.activity-filter-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; margin-bottom: 12px;
}
.activity-filter-row .type-select { flex: 1; min-width: 140px; }
.activity-filter-row .btn { width: auto; }
.activity-day-group { margin-bottom: 18px; }
.activity-day-label {
  font-size: 0.7rem; font-weight: 700; color: var(--muted); text-transform: uppercase;
  letter-spacing: 0.04em; margin-bottom: 8px;
}

/* --- Berichte --- */
.round-row { font-size: 0.74rem; color: var(--muted); line-height: 1.7; border-top: 1px solid var(--border); padding-top: 8px; margin-top: 8px; }

/* --- Toast (Bug-Check/UX-Runde 04.08.2026: Stapel-Warteschlange statt
   einzelnem Element, siehe components/toast.js) --- */
.toast-root {
  position: fixed; left: 50%; bottom: 76px; transform: translateX(-50%);
  max-width: 90vw; display: flex; flex-direction: column-reverse; gap: 8px;
  z-index: 100; pointer-events: none;
}
.toast {
  background: var(--panel-2); border: 1px solid var(--border); color: var(--text);
  padding: 10px 16px; border-radius: 3px; font-size: 0.8rem; opacity: 0;
  transform: translateY(20px); transition: opacity 0.2s, transform 0.2s; text-align: center;
}
.toast.visible { opacity: 1; transform: translateY(0); }
.toast.toast-error { border-color: var(--danger); }
.toast.toast-success { border-color: var(--good); }

/* --- Bestätigungsdialog (Bug-Check/UX-Runde 04.08.2026, siehe
   components/confirm-dialog.js) -- ersetzt native window.confirm()-
   Dialoge, gleiche .card/.btn-Optik wie der Rest der App. --- */
.confirm-overlay {
  position: fixed; inset: 0; background: rgba(4, 7, 16, 0.72);
  display: flex; align-items: center; justify-content: center;
  padding: 20px; z-index: 200;
}
.confirm-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 4px;
  padding: 20px; max-width: 360px; width: 100%;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}
.confirm-message { font-size: 0.88rem; line-height: 1.5; margin: 0 0 16px; }
.confirm-actions { display: flex; gap: 10px; }
.confirm-actions .btn { flex: 1; margin-bottom: 0; }

/* --- Command Palette / Schnellsprung (Umsetzung UI-Skizzen-Runde 2,
   05.08.2026, Abschnitt "Desktop: Schnellsprung per Tastenkürzel", siehe
   components/command-palette.js) -- gleiche Overlay-Optik wie der
   Bestätigungsdialog oben, aber oben statt mittig positioniert (klassisches
   Command-Palette-Muster) und ueber `z-index: 210` bewusst noch VOR einem
   evtl. gleichzeitig offenen Bestätigungsdialog. Per Default via `hidden`
   ausgeblendet, das JS schaltet nur dieses Attribut um (kein Neuaufbau des
   DOM bei jedem Öffnen/Schließen). --- */
.cmdk-overlay {
  position: fixed; inset: 0; background: rgba(4, 7, 16, 0.72);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 12vh 20px 20px; z-index: 210;
}
.cmdk-overlay[hidden] { display: none; }
.cmdk-box {
  background: var(--panel); border: 1px solid var(--border); border-radius: 4px;
  max-width: 480px; width: 100%; max-height: 60vh; display: flex; flex-direction: column;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5); overflow: hidden;
}
.cmdk-input-row {
  display: flex; align-items: center; gap: 10px; padding: 14px 16px;
  border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.cmdk-input-row svg { color: var(--muted); flex-shrink: 0; }
.cmdk-input { flex: 1; background: transparent; border: none; color: var(--text); font-size: 0.92rem; outline: none; }
.cmdk-rows { overflow-y: auto; }
.cmdk-empty { padding: 20px 16px; color: var(--muted); font-size: 0.8rem; text-align: center; }
.cmdk-row {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 16px; text-align: left;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06); color: var(--text); background: transparent;
}
.cmdk-row:last-child { border-bottom: none; }
.cmdk-row:hover { background: var(--panel-2); }
.cmdk-row svg { color: var(--accent); flex-shrink: 0; }
.cmdk-row .name { font-size: 0.86rem; font-weight: 600; }
.cmdk-row .sub { font-size: 0.72rem; color: var(--muted); margin-top: 2px; }

/* --- Konto: Spielername/E-Mail ändern (Nutzerfeedback: "Im Konto fehlt
   eine Möglichkeit seinen Spielernamen oder Email zu ändern") --
   `.planet-rename-form` (planet-view.js) ist für EIN Eingabefeld in einer
   Zeile ausgelegt; hier kommen zwei Felder (Wert + aktuelles Passwort)
   dazu, deshalb ein eigenes, gestapeltes Layout statt der Flex-Zeile. */
#username-form.planet-rename-form,
#email-form.planet-rename-form {
  flex-direction: column;
  align-items: stretch;
  max-width: none;
}
#username-form.planet-rename-form input,
#email-form.planet-rename-form input {
  font-weight: 400;
}

/* --- Wiki (Nutzerfeedback: "wir benötigen ein Wiki, dass alle Stats
   anzeigt ... so dass der Spieler sich ausrechnen kann was ihn die
   nächste Stufe an Energie kostet und Produktion bringt") --
   Annahmen-Leiste (Welt-Speed/Gebäudestufen/Techstufen) + je Karte ein
   Zielstufen-/Stückzahl-Eingabefeld, siehe views/wiki-view.js. */
/* Inhaltsverzeichnis + Kapitel-Ueberschriften (Nutzerfeedback: "das Wiki
   optisch überarbeiten und Strukturieren damit es evtl durch Kapitel
   besser lesbar und übersichtlich wird") -- der bisher flach
   aneinandergereihte "Einstieg"-Tab bekommt sechs roemisch nummerierte
   Kapitel, mit einem Inhaltsverzeichnis oben zum direkten Anspringen
   (siehe wireTabBody in wiki-view.js fuer die Sprunglogik). */
.wiki-toc {
  border: 1px solid var(--border); border-radius: 3px; padding: 6px 16px; margin-bottom: 20px; background: var(--panel);
}
.wiki-toc-title {
  font-family: var(--font-sans); font-size: 0.66rem; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--muted-2); margin: 10px 0 2px;
}
.wiki-toc-item {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: none; border: none; border-top: 1px solid var(--border); padding: 9px 0;
  color: var(--text); font-size: 0.85rem; cursor: pointer;
}
.wiki-toc-item:hover { color: var(--accent); }
.wiki-toc-num { font-family: var(--font-serif); color: var(--accent); font-size: 0.92rem; width: 18px; flex-shrink: 0; }
.wiki-chapter-title {
  display: flex; align-items: baseline; gap: 10px; margin: 30px 0 14px; padding-top: 18px;
  font-family: var(--font-serif); font-size: 1.15rem; font-weight: 400; color: var(--text);
  border-top: 1px solid var(--border-hi);
}
.wiki-chapter-title:first-of-type { margin-top: 0; padding-top: 0; border-top: none; }
.wiki-chapter-num { color: var(--accent); font-size: 1rem; }
.wiki-assumptions-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; margin-top: 6px;
}
/* Nutzerfeedback: "Auch sollte es einen Button geben um in die Rechner die
   aktuellen Daten des Planeten und der Forschung zu übernehmen." */
#wiki-import-current-data-btn { margin-top: 12px; width: 100%; }
#import-own-tech-btn { margin-top: 12px; }
.wiki-assumption {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 0.74rem; color: var(--muted);
}
.wiki-assumption input {
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  color: var(--text); padding: 4px 6px; font-size: 0.85rem;
}
.wiki-level-label {
  display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--muted);
  margin-bottom: 6px;
}
.wiki-level-label input {
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  color: var(--text); padding: 4px 6px; font-size: 0.9rem; font-weight: 700;
}
