/*
 * Star Control Online - gemeinsame Design-Tokens und Basiskomponenten.
 * Visuelle Sprache aus der Design-Vorlage uebernommen
 * (_Design-Vorlage/weltraumspiel-starcontrol/project/Basis.dc.html,
 * Hauptmenue.dc.html) - dunkler Weltraum-Hintergrund, Chakra Petch fuer
 * Ueberschriften/Label, IBM Plex Mono fuer Fliesstext, Cyan-Akzent.
 * Reines CSS, kein Build-Schritt, passend zu "PHP + Vanilla JS".
 */

:root {
  --bg: #05060f;
  --bg-deep: #04050c;
  --surface: rgba(10, 14, 26, 0.92);
  --surface-active: rgba(120, 180, 255, 0.08);
  --border: rgba(120, 180, 255, 0.16);
  --border-strong: rgba(120, 180, 255, 0.4);

  --text-primary: #e6ecff;
  --text-body: #cdd6f0;
  --text-muted: #8b96ba;
  --text-dim: #63709a;
  --text-dimmer: #4f5a7a;

  --accent: #46d9d0;
  --accent-bright: #7fe9ff;
  --accent-blue: #4a90e2;
  --accent-gold: #ffd76a;
  --accent-green: #5fd88a;
  --accent-red: #e05a4a;
  --accent-lavender: #9ea8f0;

  --font-heading: 'Chakra Petch', sans-serif;
  --font-body: 'IBM Plex Mono', ui-monospace, monospace;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;

  /* Zweizeilige Topbar (Nutzeranfrage 2026-07-31): erste Zeile Ressourcen +
     Universum/Speed/Glocke, zweite, schmalere Zeile die Flottenkennzahlen.
     --topbar-height ist beide Zeilen PLUS den 1px-Unterrand der Topbar - alles
     hier rechnet mit border-box, der Rand zaehlt also in die Hoehe hinein.
     Stimmt die Summe nicht, wird die zweite Zeile unten abgeschnitten. Und
     .app-main bezieht seinen oberen Abstand aus derselben Variable, sonst
     entsteht dort eine Luecke oder eine Ueberdeckung. */
  --topbar-row-height: 44px;
  --topbar-row2-height: 30px;
  --topbar-height: 75px;
  --sidebar-width: 76px;

  /* Kit-Ergänzungen (Sprint 0 Design-Angleichung) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-6: 24px;
  --space-8: 32px;
  --glow-sm: 0 0 6px;
  --glow-md: 0 0 12px;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
}

body {
  font-family: var(--font-body);
  color: var(--text-body);
}

a {
  color: var(--accent);
  text-decoration: none;
}
a:hover {
  color: var(--accent-bright);
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  color: var(--text-primary);
  margin: 0;
}

/* WIDTH GILT NUR FUER SENKRECHTE BALKEN, HEIGHT NUR FUER WAAGERECHTE.
   Bis zum 2026-09-14 stand hier allein `width` - jeder waagerechte Balken der
   Anwendung lief deshalb in der Windows-Vorgabe von rund 15 bis 17 Pixeln.
   Aufgefallen ist es im Forscher-Log (Nutzerbefund: "Scrollbalken verdeckt
   obige Log Buttons"): Die Sprungmarkenreihe haelt 11 px Innenabstand fuer
   den Balken bereit, der echte Balken war breiter und lag auf den Knoepfen.
   Betrifft sieben waagerechte Scrollbereiche im Projekt. */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-thumb {
  background: rgba(120, 180, 255, 0.18);
  border-radius: 8px;
}

/* — Hintergrund mit radialem Verlauf und Sternenfeld (siehe starfield.js) — */
.space-backdrop {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: var(--bg-deep);
}
.space-backdrop__gradient {
  position: absolute;
  inset: 0;
  background: radial-gradient(160% 130% at 30% 15%, #0a0f22 0%, #05060f 55%, #020308 100%);
}
.space-backdrop__star {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  border-radius: 50%;
  background: #fff;
}

/* — Formulare — */
.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.field label {
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--text-dim);
}
.field input {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 11px 12px;
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--text-primary);
}
.field input::placeholder {
  color: var(--text-dimmer);
}
.field input:focus {
  outline: none;
  border-color: rgba(70, 217, 208, 0.6);
}

.btn-primary {
  display: block;
  width: 100%;
  text-align: center;
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: 0.14em;
  font-size: 12.5px;
  padding: 13px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, #1a2a52, #2a3f78);
  color: #cfe0ff;
  border: 1px solid rgba(120, 170, 255, 0.4);
}
.btn-primary:hover {
  background: linear-gradient(90deg, #20305e, #33488a);
}
.btn-primary:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

/* — Zustände (Laden / Fehler / Leer) — */
.state-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  padding: 48px 20px;
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.6;
}
.state-block--error {
  color: var(--accent-red);
}
.state-block__retry {
  margin-top: 6px;
  cursor: pointer;
  color: var(--accent);
  font-size: 12px;
  letter-spacing: 0.05em;
}
.state-block__retry:hover {
  color: var(--accent-bright);
}

/* — App-Shell (Topbar + Sidebar + Hauptbereich), siehe game.php — */
.app-topbar {
  position: absolute;
  top: 0;
  left: var(--sidebar-width);
  right: 0;
  height: var(--topbar-height);
  background: rgba(9, 12, 24, 0.98);
  border-bottom: 1px solid var(--border);
  z-index: 25;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 0;
  gap: 0;
}
/* Die Zeilen tragen jetzt das waagerechte Scrollen und die Innenabstaende,
   nicht mehr die Topbar selbst - sonst wuerde die schmale zweite Zeile mit
   der ersten mitwandern. */
.app-topbar__row {
  display: flex;
  align-items: center;
  height: var(--topbar-row-height);
  flex: none;
  padding: 0 14px;
  gap: 0;
  overflow-x: auto;
}
.app-topbar__row--secondary {
  height: var(--topbar-row2-height);
  border-top: 1px solid rgba(120, 180, 255, 0.08);
  background: rgba(120, 180, 255, 0.022);
}
/* Der Countdown der letzten Konvergenz (Spec 2026-09-11 C2). Nutzerwunsch:
   mittig in der zweiten Zeile, deutlich fett und gross, die Zeile darf dafuer
   doppelt so hoch werden. Die Klasse setzt game.js, solange der Countdown
   steht. --topbar-height waechst mit (44 + 60 + 1 Rand), sonst schnitte die
   Topbar die zweite Zeile ab und .app-main laege darunter. */
body.endgame-active {
  --topbar-row2-height: 60px;
  --topbar-height: 105px;
}
.app-topbar__countdown {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: none;
  gap: 3px;
  padding: 0 18px;
  line-height: 1;
}
.app-topbar__countdown-label {
  font-size: 9px;
  letter-spacing: 0.26em;
  color: #ff8a6a;
}
.app-topbar__countdown-value {
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 26px;
  letter-spacing: 0.06em;
  color: #ffd76a;
  text-shadow: 0 0 14px rgba(255, 120, 80, 0.35);
  font-variant-numeric: tabular-nums;
}
.app-topbar__stat {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 14px;
  border-right: 1px solid rgba(120, 180, 255, 0.1);
  height: 22px;
  flex: none;
}
.app-topbar__stat-icon {
  font-size: 15px;
}
.app-topbar__stat-text {
  display: flex;
  flex-direction: column;
  line-height: 1.05;
}
.app-topbar__stat-value {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 12.5px;
  color: var(--text-primary);
  letter-spacing: 0.02em;
}
.app-topbar__stat-label {
  font-size: 8.5px;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  white-space: nowrap;
}
.app-topbar__spacer {
  margin-left: auto;
}
.app-topbar__user {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 11.5px;
  color: var(--text-muted);
  flex: none;
  padding-left: 14px;
}
.app-topbar__user a {
  font-size: 11px;
  letter-spacing: 0.05em;
}
/* Gesamtpunkte rechts in der zweiten Statusleistenzeile (Nutzerwunsch
   2026-08-23). Erst als Kachel links, dann neben dem Spielernamen - dort
   ueberlappte sie mit der fiktiven Uhr, weil die erste Zeile voll ist. */
.app-topbar__points {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: #ffd76a;
  font-weight: 600;
  white-space: nowrap;
  font-size: 11.5px;
  letter-spacing: 0.06em;
  padding-right: 14px;
  flex: none;
}
.app-topbar__reputation {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-weight: 600;
  white-space: nowrap;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  padding-right: 14px;
  flex: none;
}

.app-topbar__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-left: 14px;
  flex: none;
}
/* Admin-Test-Speed-Regler (1x-instant), nur fuer Admins gerendert. */
.topbar-speed {
  display: flex;
  align-items: center;
  gap: 2px;
  padding-left: 14px;
  flex: none;
}
.topbar-speed__label {
  font-size: 8.5px;
  letter-spacing: 0.14em;
  color: #63709a;
  margin-right: 4px;
}
.topbar-speed__btn {
  font-family: var(--font-heading);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: #8b96ba;
  background: rgba(120, 180, 255, 0.06);
  border: 1px solid rgba(120, 180, 255, 0.14);
  border-radius: 5px;
  padding: 3px 7px;
  cursor: pointer;
}
.topbar-speed__btn:hover {
  color: #cfe0ff;
  border-color: rgba(120, 180, 255, 0.3);
}
.topbar-speed__btn.is-active {
  color: #0a0c18;
  background: linear-gradient(135deg, #46d9d0, #7fe9ff);
  border-color: transparent;
}
.topbar-speed__grant {
  font-family: var(--font-heading);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: #0a0c18;
  background: linear-gradient(135deg, #7fe98f, #46d9a0);
  border: 1px solid transparent;
  border-radius: 5px;
  padding: 3px 7px;
  margin-left: 6px;
  cursor: pointer;
  /* Sonst bricht "+RESS START" in der ohnehin engen Topbar-Zeile um. */
  white-space: nowrap;
}
/* Zwei Zuschuss-Knoepfe seit 2026-08-01 - unterschiedlicher Farbton, damit sie
   sich auf einen Blick unterscheiden und man nicht den falschen trifft. Der
   Farbton folgt den Familien: Grundstoffe gruen wie bisher, alles Weitere
   violett wie die exotischen Ressourcen. */
.topbar-speed__grant[data-grant-scope="REST"] {
  background: linear-gradient(135deg, #c4a2f5, #9a7ce8);
}
.topbar-speed__grant:hover {
  filter: brightness(1.1);
}
.topbar-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: #14192b;
  color: #cfe0ff;
  border: 1px solid rgba(120, 180, 255, 0.3);
  border-radius: 6px;
  padding: 8px 16px;
  font-size: 12px;
  z-index: 200;
  opacity: 1;
  transition: opacity 0.3s ease;
}
.topbar-toast--hide {
  opacity: 0;
}
.topbar-radar {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: var(--radius-sm);
  font-family: var(--font-heading);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  white-space: nowrap;
  z-index: 1;
}
.topbar-radar--inactive {
  color: var(--text-dim);
  background: rgba(120, 180, 255, 0.06);
  border: 1px solid var(--border);
}
.topbar-radar--active {
  color: var(--accent-green);
  background: rgba(95, 216, 138, 0.12);
  border: 1px solid rgba(95, 216, 138, 0.3);
}
.topbar-radar--alert {
  color: #fff;
  background: var(--accent-red);
  border: 1px solid var(--accent-red);
}
.topbar-bell {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text-muted);
  font-size: 15px;
}
.topbar-bell:hover {
  color: var(--accent-bright);
  background: var(--surface-active);
}
.topbar-bell__badge {
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 8px;
  background: var(--accent-red);
  color: #fff;
  font-size: 9px;
  line-height: 15px;
  text-align: center;
}

.message-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(2, 3, 8, 0.5);
  z-index: 40;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.message-drawer-backdrop--visible {
  opacity: 1;
  pointer-events: auto;
}
.message-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 360px;
  max-width: 90vw;
  background: rgba(9, 12, 24, 0.98);
  border-left: 1px solid var(--border-strong);
  z-index: 45;
  transform: translateX(100%);
  transition: transform 0.25s ease;
  overflow-y: auto;
}
.message-drawer--open {
  transform: translateX(0);
}
.message-drawer__header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
}
.message-drawer__title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 14px;
  color: var(--text-primary);
  flex: 1;
}
.message-drawer__mark-all {
  font-size: 11px;
  color: var(--accent);
  cursor: pointer;
}
.message-drawer__mark-all:hover {
  color: var(--accent-bright);
}
.message-drawer__close {
  cursor: pointer;
  color: var(--text-muted);
  font-size: 14px;
}
.message-drawer__close:hover {
  color: var(--text-primary);
}
.message-drawer__list {
  display: flex;
  flex-direction: column;
}
.message-drawer__list .message-card {
  border-bottom: 1px solid var(--border);
}
.message-drawer__empty {
  padding: 20px 18px;
  color: var(--text-muted);
  font-size: 12px;
}
.message-drawer__tabs {
  display: flex;
  border-bottom: 1px solid var(--border);
}
.message-drawer__tab {
  flex: 1;
  text-align: center;
  padding: 10px 0;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
}
.message-drawer__tab--active {
  color: var(--accent-bright);
  border-bottom-color: var(--accent-bright);
}
.action-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(2, 3, 8, 0.6);
  z-index: 50;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}
.action-modal-backdrop--visible {
  opacity: 1;
  pointer-events: auto;
}
.action-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.96);
  width: 360px;
  max-width: 90vw;
  background: rgba(14, 17, 32, 0.99);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: 20px;
  z-index: 55;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.action-modal--open {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}
.action-modal__icon {
  display: flex;
  justify-content: center;
  margin-bottom: 12px;
}
.action-modal__eyebrow {
  text-align: center;
  font-size: 10px;
  letter-spacing: 0.2em;
  color: var(--text-dim);
  margin-bottom: 4px;
}
.action-modal__title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 15px;
  color: var(--text-primary);
  margin-bottom: 10px;
  text-align: center;
}
.action-modal__btn--danger {
  background: var(--accent-red);
  color: #fff;
}
.action-modal__btn--danger:hover {
  background: #f0715f;
}
.action-modal__message {
  font-size: 12.5px;
  color: var(--text-muted);
  line-height: 1.5;
  margin-bottom: 18px;
}
.action-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
.action-modal__btn {
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  cursor: pointer;
  text-align: center;
}
.action-modal__btn--cancel {
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.action-modal__btn--cancel:hover {
  color: var(--text-primary);
  border-color: var(--border-strong);
}
.action-modal__btn--confirm {
  color: #fff;
  background: var(--accent);
}
.action-modal__btn--confirm:hover {
  background: var(--accent-bright);
}
.message-card__dismiss {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 13px;
  flex-shrink: 0;
}
.message-card__dismiss:hover {
  color: var(--accent-red);
}

.app-sidebar {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--sidebar-width);
  bottom: 0;
  background: rgba(10, 12, 22, 0.97);
  border-right: 1px solid var(--border);
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 14px 0;
  gap: 4px;
}
.app-sidebar__item {
  position: relative;
  width: 56px;
  min-height: 56px;
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 6px 2px;
  text-decoration: none;
  cursor: pointer;
  color: var(--text-dim);
}
.app-sidebar__item i {
  font-size: 20px;
}
.app-sidebar__label {
  font-size: 8px;
  line-height: 1.15;
  text-align: center;
  letter-spacing: .01em;
  overflow-wrap: break-word;
  max-width: 100%;
}
/* EIN WORT, DAS NICHT PASST (Nutzerbefund 2026-09-22: "Wort Multiversum im
   Menue in eine Zeile anzeigen, das n wird umgebrochen").

   Der Menuepunkt ist 56 px breit, davon 52 nutzbar; "Multiversum" misst bei
   8 px knapp mehr und brach deshalb nach dem vorletzten Buchstaben um.
   Beschriftungen mit Leer- oder Bindestrich ("Das Versteck", "Xeno-Labor")
   trifft das nicht - sie brechen an der Fuge, und das sieht gewollt aus.

   NUR FUER DIESEN EINEN FALL und nicht fuer alle Beschriftungen: Die anderen
   neunzehn passen bei 8 px, und sie kleiner zu setzen machte das ganze Menue
   schlechter lesbar, um ein einziges Wort zu retten. `overflow-wrap: normal`
   hebt das Brechen IM Wort wieder auf, das die Regel darueber erlaubt. */
.app-sidebar__label--tight {
  font-size: 7.5px;
  letter-spacing: 0;
  overflow-wrap: normal;
}
/* Laufender Bau / laufende Forschung / laufender Schiffbau als duenner Balken
   am unteren Rand des Menuepunkts (Nutzerwunsch 2026-08-30). Absolut
   positioniert, damit er weder Icon noch Beschriftung verschiebt - der
   Menuepunkt ist eine feste 56x56-Flexbox und wuerde sonst umbrechen.

   Die Fuellfarbe setzt das JS je Bereich (dieselben Farben wie die
   Statuskacheln der Uebersicht); hier steht nur die Spur. */
/* Der Stapel traegt seit dem 2026-09-01 bis zu drei Spuren untereinander -
   beim Abbau eine je Flotte. Er sitzt absolut am Menuepunkt, die Spuren darin
   liegen im normalen Fluss; so bleibt der 56x56-Kasten unveraendert, egal ob
   eine oder drei Spuren da sind. */
.app-sidebar__progress-stack {
  position: absolute;
  left: 6px;
  right: 6px;
  bottom: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  pointer-events: none;
}
.app-sidebar__progress-stack .app-sidebar__progress {
  position: static;
  left: auto;
  right: auto;
  bottom: auto;
}
.app-sidebar__progress {
  position: absolute;
  left: 6px;
  right: 6px;
  bottom: 4px;
  height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.09);
  overflow: hidden;
  pointer-events: none;
}
.app-sidebar__progress span {
  display: block;
  height: 100%;
  border-radius: 2px;
  transition: width .9s linear;
}
.app-sidebar__item--active {
  color: var(--accent-bright);
  background: rgba(70, 217, 208, 0.1);
}
.app-sidebar__item:hover {
  color: var(--accent-bright);
}
/* Nutzerwunsch 2026-08-25: DEFCON wird rot und gluehend, sobald ein Angriff
   hereinkommt. Die Stufe steht als data-threat-level am Element (WARNING /
   ALERT / CRITICAL) - heute sehen alle drei gleich aus, aber die Unterscheidung
   liegt schon im Markup, falls spaeter abgestuft werden soll.

   Der Puls laeuft ueber box-shadow und color, nicht ueber transform: ein
   wachsendes Element wuerde die Menueleiste bei jedem Takt umbrechen lassen. */
.app-sidebar__item--threat {
  color: var(--accent-red);
  background: rgba(224, 90, 74, .12);
  animation: sidebarThreatPulse 1.6s ease-in-out infinite;
}
.app-sidebar__item--threat i {
  color: var(--accent-red);
}
@keyframes sidebarThreatPulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(224, 90, 74, 0);
    background: rgba(224, 90, 74, .10);
  }
  50% {
    box-shadow: 0 0 14px 2px rgba(224, 90, 74, .55);
    background: rgba(224, 90, 74, .22);
  }
}
/* Wer Bewegung im Interface abgestellt hat, bekommt die Warnung als ruhigen
   Dauerzustand - sichtbar bleibt sie trotzdem. */
@media (prefers-reduced-motion: reduce) {
  .app-sidebar__item--threat {
    animation: none;
    box-shadow: 0 0 12px 1px rgba(224, 90, 74, .45);
  }
}

/* Aufklaerung statt Alarm (Nutzerwunsch 2026-08-25): fremde Flotten in
   Sensorreichweite faerben den DEFCON-Punkt orange. Bewusst ruhiger als der
   rote Bedrohungszustand - ein Dauerpuls fuer jeden beobachteten Kontakt
   waere nach zwei Minuten nur noch Hintergrundrauschen. Deshalb ein
   stehender Schein statt einer Animation. */
.app-sidebar__item--contacts {
  color: #e8a24a;
  background: rgba(232, 162, 74, .10);
  box-shadow: 0 0 12px 1px rgba(232, 162, 74, .38);
}
.app-sidebar__item--contacts i {
  color: #e8a24a;
}
/* Nutzerwunsch 2026-08-25: die Sternenkarte ist der wichtigste
   Navigationspunkt und darf sich aus der Reihe abheben. Tuerkis, dieselbe
   Akzentfarbe, die im Spiel ohnehin fuer Sensorik und Karte steht - deshalb
   die vorhandene Variable statt eines neuen Farbwerts.

   Der aktive Zustand gewinnt weiterhin: sonst saehe die Karte immer
   ausgewaehlt aus. */
.app-sidebar__item[data-route="starmap"]:not(.app-sidebar__item--active) {
  color: var(--accent-bright);
}
.app-sidebar__item[data-route="starmap"]:not(.app-sidebar__item--active) i {
  color: var(--accent-bright);
}

/* Menü-Progressive-Reveal (2026-07-26): "NEU"-Label an frisch freigeschalteten
   Menüpunkten, verschwindet nach dem ersten Anklicken dauerhaft. */
.app-sidebar__badge {
  position: absolute;
  top: 2px;
  right: 2px;
  background: #e05a4a;
  color: #fff;
  /* 8 statt 7 px (2026-09-05): das NEU-Label blieb bei sieben lesbar, eine
     Ziffer im engen Zahlenbadge nicht - Nutzerbefund "die Zahl im Badge ist
     nicht zu erkennen, ich seh nur einen runden Kreis". */
  font-size: 8px;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 1px 3px;
  border-radius: 4px;
  line-height: 1.3;
  pointer-events: none;
}
/* Das Antennen-Abzeichen (Nutzerwunsch 2026-09-15). Es haengt an der
   Sternenkarte und meldet: Eine Gravitron-Richtantenne steht und wartet auf
   ihre Ausrichtung.

   EIN SYMBOL STATT EINER ZAHL, solange es nur eine ist - ein Zaehler "1" sagt
   nichts, was das Icon nicht schon sagt. Ab zwei kommt die Ziffer daneben.

   Tuerkis wie die Sensorik, nicht rot: Hier ist nichts passiert, hier ist
   etwas MOEGLICH. */
.app-sidebar__badge--beam {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  background: #1b4a5c;
  color: #7fe9ff;
  padding: 1px 4px;
  box-shadow: 0 0 0 1.5px rgba(4, 8, 20, .85), 0 0 7px rgba(127, 233, 255, .35);
}
.app-sidebar__badge--beam i {
  font-size: 11px;
  line-height: 1;
}
.app-sidebar__badge--beam b {
  font-size: 9px;
  font-weight: 800;
}

/* Zaehler-Badge (2026-08-20): blau statt rot, weil es keine Neuigkeit meldet,
   sondern eine laufende Menge - aktuell die aktiven Abbauauftraege. */
/* Das Zahlenbadge traegt eine Ziffer, kein Wort - es braucht mehr Groesse als
   das NEU-Label und einen kraeftigen Kontrast (Nutzerbefund 2026-09-05). */
.app-sidebar__badge--count {
  background: #4a90e2;
  color: #04121f;
  font-size: 11px;
  font-weight: 800;
  padding: 1px 5px;
  min-width: 17px;
  text-align: center;
  line-height: 1.35;
  /* Der dunkle Ring trennt das Badge vom Menuepunkt darunter; ohne ihn
     verschwimmt es bei orangem Schein mit dem gluehenden Rand. */
  box-shadow: 0 0 0 1.5px rgba(4, 8, 20, .85);
}

/* NACH der Basisregel, nicht davor: gleiche Spezifitaet, also gewinnt die
   spaetere. Vorher stand sie oberhalb und wurde von `.app-sidebar__badge`
   still ueberschrieben - der Kontaktzaehler war blau statt orange, obwohl
   der Menuepunkt daneben orange gluehte. */
.app-sidebar__badge--contacts {
  background: #e8a24a;
  color: #2a1a06;
}
/* Rufzeichen am Versteck (Nutzerwunsch 2026-09-03): dort wartet ein Kapitel
   der Zivilisationsgeschichte. Golden statt rot - es ist keine Warnung und
   keine Menge, sondern eine Einladung. Das leichte Pulsieren hebt es vom
   ruhigen NEU-Label ab, ohne so laut zu sein wie ein Alarm. */
.app-sidebar__badge--alert {
  background: #d8a13a;
  color: #1a1206;
  font-size: 10px;
  font-weight: 800;
  padding: 0 4px;
  min-width: 12px;
  text-align: center;
  animation: sidebarAlertPulse 2.6s ease-in-out infinite;
}
@keyframes sidebarAlertPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.18); }
}
@media (prefers-reduced-motion: reduce) {
  .app-sidebar__badge--alert { animation: none; }
}

/* Blaues Rufzeichen: eine abholbereite Missionsbelohnung (Nutzerwunsch
   2026-09-05). Bewusst dieselbe Form wie das goldene, aber in der
   Akzentfarbe des Spiels - beide koennen gleichzeitig am Versteck haengen
   und muessen sich auf einen Blick unterscheiden. Es sitzt links vom
   goldenen, damit die Reihenfolge stabil bleibt, egal welches zuerst kam. */
.app-sidebar__badge--reward {
  background: var(--accent-bright);
  color: #04121a;
  font-size: 10px;
  font-weight: 800;
  padding: 0 4px;
  min-width: 12px;
  text-align: center;
  order: -1;
  animation: sidebarAlertPulse 2.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .app-sidebar__badge--reward { animation: none; }
}

.app-main {
  position: absolute;
  top: var(--topbar-height);
  left: var(--sidebar-width);
  right: 0;
  bottom: 0;
  overflow-y: auto;
  padding: 28px 36px 40px;
}

/* Nutzerentscheidung 2026-07-28: quadratische Box mit rotierendem Heimat-
   planeten links neben den Basis-Infos - grafischer Akzent, dieselbe
   Textur/Kugel-Darstellung wie in der System-Vollansicht. */
.dashboard-hero {
  display: flex;
  gap: 24px;
  align-items: flex-start;
}
.dashboard-hero__planet {
  flex-shrink: 0;
  width: 160px;
  height: 160px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: radial-gradient(circle at 35% 30%, rgba(70, 217, 208, 0.08), rgba(0, 0, 0, 0.25));
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.dashboard-hero__info { min-width: 0; flex: 1; }
@media (max-width: 640px) {
  .dashboard-hero { flex-direction: column; }
}

.dashboard-eyebrow {
  font-size: 10.5px;
  letter-spacing: 0.28em;
  color: var(--accent);
}
.dashboard-title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 30px;
  letter-spacing: 0.03em;
  color: var(--text-primary);
  margin-top: 6px;
}
.dashboard-subtitle {
  font-size: 12.5px;
  color: var(--text-muted);
  margin-top: 8px;
  max-width: 640px;
  line-height: 1.6;
}

.dashboard-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
  margin-top: 18px;
}
.dashboard-meta__item {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.dashboard-meta__label {
  font-size: 9.5px;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  text-transform: uppercase;
}
.dashboard-meta__value {
  font-size: 12.5px;
  color: var(--text-body);
}

.protection-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
}
.protection-badge--active {
  color: var(--accent-green);
}
.protection-badge--expired {
  color: var(--text-dim);
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
  margin-top: 24px;
}
.resource-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  /* Rasterelemente haben von sich aus die Mindestbreite ihres Inhalts. Ein
     einzelnes ueberlanges Wort (ein Ressourcenname in Grossbuchstaben mit
     Sperrung) hebelt damit das minmax(200px, 1fr) des Rasters aus und macht
     genau diese eine Kachel breiter als ihre Nachbarn. min-width: 0 und ein
     erlaubter Wortumbruch halten die Reihe gleichmaessig, auch wenn spaeter
     ein Name dazukommt, an den beim Kuerzen niemand gedacht hat. */
  min-width: 0;
}
.resource-card__label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  overflow-wrap: anywhere;
  /* Platz fuer den Leeren-Knopf in der Ecke - sonst laeuft ein langer Name
     darunter durch. */
  padding-right: 26px;
}
/* Das ausgeschnittene Vorlagen-Icon (siehe core/resources.js). Pixel-Art:
   nicht glaetten, sonst wird aus den Kanten Matsch.

   Groesse auf Nutzerwunsch 2026-09-06 angehoben (26 -> 38). Die Kachel wird
   dadurch NICHT hoeher: Die Beschriftungszeile ist eine Flex-Reihe, und das
   NEU-Label darin ist am selben Tag entfallen - der gewonnene Platz geht ans
   Bild. */
.resource-icon {
  width: 38px;
  height: 38px;
  flex: none;
  object-fit: contain;
  image-rendering: pixelated;
}
.resource-card__amount {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: var(--text-primary);
  margin-top: 8px;
}
.resource-card__capacity {
  font-size: 11px;
  color: var(--text-muted);
}
/* Die Familie als blosse Einordnung unter dem Ressourcennamen
   (Nutzerwunsch 2026-09-22: "Das Familienwort kann ja unter Metallerz
   geschrieben werden"). Kleiner und blasser als die Menge darueber: Es ist
   eine Zuordnung, keine Zahl, die man liest. */
.resource-card__family {
  font-size: 10px;
  color: var(--text-muted);
  letter-spacing: .04em;
  text-transform: uppercase;
}
.resource-card__bar-track {
  height: 4px;
  border-radius: 2px;
  background: rgba(120, 180, 255, 0.12);
  margin-top: 10px;
  overflow: hidden;
}
.resource-card__bar-fill {
  height: 100%;
  background: var(--accent);
}
.resource-card__bar-fill--near {
  background: var(--accent-gold);
}
.resource-card__bar-fill--full {
  background: var(--accent-red);
}
.resource-card__production {
  font-size: 10.5px;
  color: var(--text-dim);
  margin-top: 6px;
}
.resource-card__warn {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 10px;
  letter-spacing: 0.03em;
  margin-top: 8px;
}
.resource-card__warn--near {
  color: var(--accent-gold);
}
.resource-card__warn--full {
  color: var(--accent-red);
}

.section-heading {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 14.5px;
  color: var(--text-primary);
  letter-spacing: 0.03em;
  margin-top: 36px;
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Die Familienbloecke des Lagers (Nutzerwunsch 2026-09-05: "Grundstoffe und
   Vorraete nebeneinander", nachgeschaerft am selben Tag: "die exotischen
   Ressourcen koennten dann neben die Industriestoffe").

   ALLE Bloecke sind gleich breit - auch die Industriestoffe, die als einzige
   vier Ressourcen tragen. Ihre Karten brechen auf halber Breite um, statt zu
   schrumpfen; ein Block ueber die volle Breite riss dagegen ein Loch in die
   Spalten, und die Familien darunter standen versetzt zu denen darueber.

   `align-items: start` haelt beide Spalten oben buendig - ohne das streckte
   sich ein einzeiliger Block auf die Hoehe seines zweizeiligen Nachbarn. */
.storage-families {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 28px;
  align-items: start;
}

/* Der Blockabstand steckt im Gitter, nicht in den Karten: die
   .card-grid-Regel bringt 24 px Vorlauf mit, was zwischen zwei
   nebeneinanderstehenden Bloecken zu einer schiefen Kante fuehrte. */
.storage-family .card-grid { margin-top: 12px; }
.storage-family + .storage-family { margin-top: 0; }

@media (max-width: 900px) {
  .storage-families { grid-template-columns: minmax(0, 1fr); }
}

/* Sub-A5: Summe eines Familientopfs rechts im Gruppenkopf der Lageransicht. */
.storage-family__sum {
  margin-left: auto;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 12px;
  color: var(--text-dim);
  letter-spacing: 0;
}

/* Frisch entdeckte Ressource: bleibt hervorgehoben, bis der Spieler sie
   anklickt und damit bestaetigt. */
.message-list, .activity-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.message-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 18px;
  background: var(--surface);
}
.message-card--unread {
  background: var(--surface-active);
}
.message-card__icon {
  font-size: 16px;
  margin-top: 2px;
  flex-shrink: 0;
}
.message-card__body {
  flex: 1;
  min-width: 0;
}
.message-card__title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-primary);
}
.message-card__text {
  font-size: 11.5px;
  color: var(--text-muted);
  margin-top: 4px;
  line-height: 1.5;
}
.message-card__meta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
}
.message-card__time {
  font-size: 10px;
  color: var(--text-dim);
}
.message-card__mark-read {
  font-size: 10px;
  color: var(--accent);
  cursor: pointer;
  letter-spacing: 0.03em;
}
.message-card__mark-read:hover {
  color: var(--accent-bright);
}

.activity-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 18px;
  background: var(--surface);
}
.activity-item__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  margin-top: 6px;
  flex-shrink: 0;
}
.activity-item__body {
  flex: 1;
  min-width: 0;
}
.activity-item__title {
  font-size: 12px;
  color: var(--text-body);
}
.activity-item__desc {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 3px;
}
.activity-item__time {
  font-size: 10px;
  color: var(--text-dim);
  margin-top: 4px;
}

.building-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
}
.building-card__name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13.5px;
  color: var(--text-primary);
}
.building-card__level {
  font-size: 11px;
  color: var(--accent);
  margin-top: 4px;
}
.building-card__status {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  margin-top: 6px;
  text-transform: uppercase;
}
.building-card__purpose {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 8px;
  line-height: 1.5;
}

.tech-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
}
.tech-card__name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13.5px;
  color: var(--text-primary);
}
.tech-card__level {
  font-size: 11px;
  color: var(--accent);
  margin-top: 4px;
}
.tech-card__category {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  margin-top: 6px;
  text-transform: uppercase;
}
.tech-card__description {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 8px;
  line-height: 1.5;
}
.tech-card__status {
  display: inline-block;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: var(--radius-sm);
  padding: 3px 8px;
  margin-top: 10px;
}
.tech-card__status--available {
  color: var(--accent-green);
  background: rgba(95, 216, 138, 0.12);
}
.tech-card__status--locked {
  color: var(--text-dim);
  background: rgba(120, 180, 255, 0.08);
}
.tech-card__status--max-level {
  color: var(--accent-gold);
  background: rgba(255, 215, 106, 0.12);
}
.tech-card__next {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.tech-card__next-title {
  font-size: 11px;
  color: var(--text-primary);
  font-weight: 600;
}
.tech-card__next-cost {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 4px;
}
.tech-card__next-time {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 2px;
}
.building-card__next-effects,
.tech-card__next-effects {
  font-size: 11px;
  color: var(--accent-green);
  line-height: 1.5;
  margin: 4px 0;
}
.tech-card__blocked {
  font-size: 10.5px;
  color: var(--accent-red);
  margin-top: 8px;
  line-height: 1.5;
}

.progress-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px 24px;
}
.progress-box--empty {
  color: var(--text-muted);
  font-size: 12.5px;
}
.progress-box__title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 15px;
  color: var(--text-primary);
}
/* Zweizeiliger Auftragstitel (Nutzeranfrage 2026-08-19): oben das Gebaeude bzw.
   die Technologie, darunter kleiner die Zielstufe. */
.progress-box__job-name { display: block; }
.progress-box__job-level {
  display: block; margin-top: 2px;
  font-family: var(--font-body); font-weight: 400; font-size: 11px;
  letter-spacing: 0.04em; color: var(--text-muted);
}
.progress-box__bar-track {
  height: 6px;
  border-radius: 3px;
  background: rgba(120, 180, 255, 0.12);
  margin-top: 12px;
  overflow: hidden;
}
.progress-box__bar-fill {
  height: 100%;
  background: var(--accent);
  transition: width 1s linear;
}
.progress-box__remaining {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 8px;
}
.progress-box__cancel-btn {
  margin-top: 12px;
  background: var(--surface-active);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 11px;
  padding: 7px 12px;
  cursor: pointer;
}

.status-box-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px;
  margin-top: 10px;
}

/* Admin: Kopfzeile mit Aktion (Liste/Formular) + Universum-erstellen-Formular. */
.admin-page {
  max-width: 1080px;
}
.admin-list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
/* Sekundaerer Button (Zurueck/Abbrechen) im dunklen Design - ersetzt den im
   Nicht-Starmap-Kontext ungestylten .starmap-toolbar__btn. */
.btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: 0.08em;
  font-size: 12px;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  color: var(--text-muted);
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.btn-secondary:hover {
  border-color: var(--border-strong);
  color: #cfe0ff;
  background: rgba(255, 255, 255, 0.06);
}
/* Aktions-Buttons im Admin-Bereich sollen ihre natuerliche Breite behalten
   (btn-primary ist global width:100% fuer Formulare). */
.admin-create-btn,
.admin-form-actions .btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  white-space: nowrap;
}
.admin-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
  margin-top: 18px;
  align-items: start;
}
.admin-form-section {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
}
.admin-form-section__head {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.08em;
  color: var(--accent-bright);
  padding-bottom: 12px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.admin-form-section__head i {
  font-size: 18px;
  color: var(--accent);
}
.admin-form-section__body {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.admin-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.admin-field-row { display: flex; gap: 14px; }
.admin-field-row .admin-field { flex: 1; min-width: 0; }
.admin-field__label {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.admin-field__info {
  font-size: 11px;
  color: var(--text-dim);
  line-height: 1.45;
}
.admin-input {
  width: 100%;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 9px 11px;
  color: #e6ecff;
  font-family: var(--font-mono);
  font-size: 13px;
}
.admin-input:focus {
  outline: none;
  border-color: var(--border-strong);
  background: rgba(255, 255, 255, 0.06);
}
.admin-textarea { resize: vertical; line-height: 1.5; }
/* Die Auswahlliste erbt sonst die Systemfarben und wird auf dunklem Grund
   unlesbar - betrifft das Startpaket-Feld im Universums-Formular. */
select.admin-input { appearance: none; cursor: pointer; }
select.admin-input option { background: #101827; color: #e6ecff; }

/* Slider mit Live-Wert-Chip. */
.admin-slider { display: flex; align-items: center; gap: 12px; }
.admin-slider__range {
  flex: 1;
  accent-color: var(--accent);
  height: 4px;
  cursor: pointer;
}
.admin-slider__val {
  flex: none;
  min-width: 54px;
  text-align: right;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--accent-bright);
  font-variant-numeric: tabular-nums;
}

/* Segment-Buttons für Enum-Auswahl. */
.admin-segment {
  display: flex;
  gap: 3px;
  background: rgba(255, 255, 255, 0.03);
  border-radius: var(--radius-sm);
  padding: 3px;
}
.admin-segment__btn {
  flex: 1;
  padding: 8px 6px;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.admin-segment__btn:hover { color: #cfe0ff; }
.admin-segment__btn.is-active {
  background: rgba(70, 217, 208, 0.14);
  color: var(--accent-bright);
}
.admin-form-actions {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding-top: 4px;
}
.admin-form-error {
  margin-top: 16px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: rgba(224, 90, 74, 0.1);
  border: 1px solid rgba(224, 90, 74, 0.4);
  color: #f0a89c;
  font-size: 12.5px;
  line-height: 1.5;
}

/* Ressourcen-Lieferungen (Sub-C): kompakte KPI-Kacheln, je Kachel eine
   laufende Lieferung. Akzentfarbe kommt per --transport-color vom Rohstofftyp. */
.transport-tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
  margin-top: 18px;
}
.transport-tile {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--transport-color, var(--accent));
  border-radius: var(--radius-md);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow: hidden;
}
.transport-tile::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 90% at 100% 0%, var(--transport-color, var(--accent)), transparent 60%);
  opacity: 0.07;
  pointer-events: none;
}
.transport-tile__head {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.transport-tile__icon {
  color: var(--transport-color, var(--accent));
  font-size: 18px;
  line-height: 1;
  align-self: center;
}
.transport-tile__amount {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  color: #e6ecff;
  letter-spacing: 0.02em;
}
.transport-tile__res {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.transport-tile__route {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: #aab4d4;
  min-width: 0;
}
.transport-tile__route i {
  color: var(--text-muted);
  font-size: 12px;
}
.transport-tile__arrow {
  color: var(--transport-color, var(--accent)) !important;
  flex: none;
}
.transport-tile__from,
.transport-tile__to {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.transport-tile__to {
  color: #cfe0ff;
}
.transport-tile__elements {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.transport-tile__element {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  font-size: 11.5px;
}
.transport-tile__element-name {
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.transport-tile__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
  box-shadow: 0 0 4px currentColor;
}
.transport-tile__element-amount {
  color: #cfe0ff;
  font-variant-numeric: tabular-nums;
}
.transport-tile__eta {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: 12px;
}
.transport-tile__eta > i {
  color: var(--transport-color, var(--accent));
}
.transport-tile__label {
  color: var(--text-muted);
}
.transport-tile__countdown {
  margin-left: auto;
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--accent-bright);
  letter-spacing: 0.04em;
}
/* Nutzerwunsch 2026-08-20: die Status-Kacheln nehmen rund die Haelfte des
   frueheren Platzes ein. Alle Innenmasse sind halbiert; die Schriftgroessen
   sind nur so weit gesenkt, dass die Kacheln lesbar bleiben. Die Regeln sind
   auf .status-box begrenzt - .progress-box wird auch ausserhalb benutzt. */
.status-box {
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 9px 11px;
  cursor: pointer;
}
.status-box:hover {
  border-color: var(--border-strong);
}
.status-box__icon {
  font-size: 14px;
  color: var(--accent);
  flex-shrink: 0;
}
.status-box__content {
  flex: 1;
  min-width: 0;
}
.status-box .progress-box {
  border: none;
  background: none;
  padding: 0;
}
.status-box .progress-box--empty { font-size: 11px; }
.status-box .progress-box__title { font-size: 12.5px; }
.status-box .progress-box__job-level { font-size: 10px; margin-top: 1px; }
.status-box .progress-box__bar-track { height: 4px; margin-top: 6px; }
.status-box .progress-box__remaining { font-size: 10.5px; margin-top: 4px; }
.status-box .progress-box__cancel-btn { margin-top: 6px; font-size: 10px; padding: 4px 8px; }

.tech-card__research-btn {
  margin-top: 12px;
  width: 100%;
  background: var(--surface-active);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 11px;
  padding: 8px 10px;
  cursor: pointer;
}
.tech-card__research-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

.ship-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
}
.ship-card__name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13.5px;
  color: var(--text-primary);
}
.ship-card__class {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  margin-top: 6px;
  text-transform: uppercase;
}
.ship-card__description {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 8px;
  line-height: 1.5;
}
.ship-card__status {
  display: inline-block;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: var(--radius-sm);
  padding: 3px 8px;
  margin-top: 10px;
}
.ship-card__status--available {
  color: var(--accent-green);
  background: rgba(95, 216, 138, 0.12);
}
.ship-card__status--locked {
  color: var(--text-dim);
  background: rgba(120, 180, 255, 0.08);
}
.ship-card__cost {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 10px;
}
.ship-card__time {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 2px;
}
.ship-card__blocked {
  font-size: 10.5px;
  color: var(--accent-red);
  margin-top: 8px;
  line-height: 1.5;
}
.ship-card__build-row {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}
.ship-card__quantity {
  width: 56px;
  background: var(--surface-active);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 11px;
  padding: 8px 6px;
  text-align: center;
}
.ship-card__build-btn {
  flex: 1;
  background: var(--surface-active);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 11px;
  padding: 8px 10px;
  cursor: pointer;
}
.ship-card__build-btn:disabled {
  opacity: 0.5;
  cursor: default;
}
.shipyard-queue__entry {
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.shipyard-queue__entry:last-child {
  border-bottom: none;
}
.shipyard-queue__title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--text-primary);
}
.shipyard-queue__remaining {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 4px;
}
.shipyard-queue__position {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-top: 4px;
}

.panel {
  margin-top: 32px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 26px;
}

/* — Sternenkarte (Zone 10, Sprint 3; Etappe 2: Vollflaechen-Layout) — */
.app-main--starmap {
  padding: 0;
  overflow: hidden;
}
.starmap-shell {
  position: absolute;
  inset: 0;
}
.starmap-viewport {
  position: absolute;
  top: 0;
  left: 0;
  /* Die Aussenmasse der Minikarte, damit der Navigator sich daran ausrichten
     kann (2026-09-14). Beides folgt aus .starmap-minimap weiter unten:
     180 px Feld + 12 px Polsterung + 2 px Rahmen = 194 breit; das Feld ist
     quadratisch (180), dazu Beschriftung (~14), Polsterung (10) und Rahmen
     (2) = 206 hoch. WER DORT ETWAS AENDERT, AENDERT HIER MIT - sonst steht
     der Navigator auf der Minikarte oder mit einer Luecke daneben. */
  --starmap-minimap-outer: 194px;
  --starmap-minimap-height: 206px;
  /* Muss die Breite von .starmap-sidepanel spiegeln - die Leiste liegt
     absolut rechts, dieser Wert haelt ihr den Platz frei. Aendert sich das
     eine, muss das andere mit. */
  right: 562px;
  bottom: 0;
  overflow: hidden;
  background: radial-gradient(160% 130% at 30% 20%, #0a0f22 0%, #05060f 55%, #020308 100%);
  cursor: grab;
  /* Ziehen soll ziehen, nicht markieren (Nutzerbefund 2026-09-04). Seit die
     Panels in der rechten Leiste sitzen, liegt ueber der Karte zwar kein Text
     mehr - aber Sternnamen und Beschriftungen liegen sehr wohl darin, und eine
     Ziehgeste ueber sie hinweg markierte sie. */
  user-select: none;
  -webkit-user-select: none;
}
/* Nutzervorgabe 2026-07-25: der Flotten-Button sitzt links unter dem
   "Stellarer Navigator" statt oben mittig - genau an der Stelle, an der
   vorher das schwebende Schiffsinfo-Overlay (.starmap-fleet-overlay, jetzt
   entfernt) stand. Die Schiffsinfo lebt seitdem als aufgeklappte Zeile IM
   Dropdown (siehe .starmap-fleet-selector__item--expanded weiter unten). */
/* .starmap-left-panels ist am 2026-09-04 entfallen: Flottenwahl und Questlog
   stehen jetzt im NAVIGATOR-Reiter der rechten Leiste, nicht mehr als
   Ueberlagerung ueber der Karte. */
.starmap-fleet-selector {
  position: relative;
  overflow-x: hidden;
}
.starmap-fleet-selector__btn {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 12px;
  letter-spacing: .08em;
  color: #e6ecff;
  background: rgba(9, 12, 24, .9);
  border: 1px solid rgba(120, 180, 255, .3);
  border-radius: 8px;
  padding: 8px 14px;
}
.starmap-fleet-selector__list {
  background: rgba(9, 12, 24, .97);
  border: 1px solid rgba(120, 180, 255, .3);
  border-radius: 8px;
  margin-top: 4px;
  overflow-y: auto;
  overflow-x: hidden;
  max-height: calc(100% - 238px);
}
/* FESTE SPALTEN STATT SPACE-BETWEEN (Nutzerbefund 2026-09-17: "die Infos
   schwimmen, je nach Laenge des Flottennamens").

   Mit `justify-content: space-between` bestimmte der laengste Name, wo die
   Statusspalte beginnt - untereinander stehende Zeilen begannen deshalb an
   verschiedenen Stellen, und die Liste war nicht mehr quer zu lesen. Ein Grid
   mit drei Spuren legt beide Kanten fest: Name (dehnbar), Status (feste
   Breite), Fadenkreuz (so breit wie noetig).

   `minmax(0, 1fr)` statt `1fr`: Eine Grid-Spur ist von sich aus mindestens so
   breit wie ihr Inhalt - ohne die 0 als Minimum haette ein langer Flottenname
   die Spur aufgeblaeht und das Abschneiden per text-overflow nie gegriffen. */
.starmap-fleet-selector__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 150px auto;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  cursor: pointer;
  font-size: 11.5px;
  color: #cfd7f5;
  border-top: 1px solid rgba(120, 180, 255, .1);
}
.starmap-fleet-selector__item:first-child { border-top: none; }
.starmap-fleet-selector__item:hover { background: rgba(127, 233, 255, .08); }
.starmap-fleet-selector__item--active { color: #7fe9ff; }
.starmap-fleet-selector__item-identity {
  min-width: 0; display: inline-flex; align-items: center; gap: 7px;
}
.starmap-fleet-selector__item-icon { flex: none; color: var(--accent); font-size: 15px; }
.starmap-fleet-selector__item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Der Status darf umbrechen ("Bergung", "Abbau · Foerderung"), aber nie die
   Namensspalte verdraengen - die Breite steht im Grid oben. */
.starmap-fleet-selector__item-status {
  color: #8b96ba;
  min-width: 0;
  overflow-wrap: anywhere;
}
.starmap-fleet-selector__item-ort { display: block; }

/* Die laufende Ankunftszeit in der Flottenliste (Nutzerwunsch 2026-09-20:
   "Seitenleiste Flotten soll auch ETA anzeigen runterzaehlend ... in orange
   anzeigen").

   ORANGE UND NICHT DIE STATUSFARBE: Die Zeile nennt darueber, WAS die Flotte
   tut. Die ETA sagt, wie lange noch - eine eigene Aussage, und sie soll im
   Vorbeischauen auffindbar sein, ohne die Zeile zu lesen.

   #e8a24a IST DAS ORANGE DES PROJEKTS - dasselbe, das den DEFCON-Menuepunkt
   bei Sensorkontakten faerbt. `--accent-gold` (#ffd76a) waere GELB gewesen;
   der Variablenname traegt hier in die Irre.

   TABULAR-NUMS: Ohne sie wandert der Text jede Sekunde ein paar Pixel, weil
   die Ziffern unterschiedlich breit sind. Bei einem Zaehler faellt genau das
   auf. */
.starmap-fleet-eta {
  display: block;
  color: #e8a24a;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/* Am eingeklappten Knopf steht sie in der Zeile, nicht darunter - dort ist
   sie die einzige Zahl und braucht den Platz nicht fuer sich. */
.starmap-fleet-eta--head {
  display: inline;
  margin-left: 8px;
  font-size: 0.9em;
}
.starmap-fleet-selector__empty {
  padding: 8px 14px;
  font-size: 11.5px;
  color: #8b96ba;
  cursor: default;
}
/* Aufgeklappte Flotte: das eingebettete Schiffsinfo-Panel (.starmap-shippanel)
   bringt bereits eigenes Padding/Hintergrund/Rahmen mit - die Zeile selbst
   verliert daher Padding/Hover/Cursor, damit keine doppelte Box entsteht. */
.starmap-fleet-selector__item--expanded {
  /* Kein Raster: Die aufgeklappte Zeile traegt EIN Panel, keine drei Spalten
     (2026-09-17, zusammen mit der Spaltenaufteilung oben eingefuehrt). */
  display: block;
  padding: 0;
  cursor: default;
}
.starmap-fleet-selector__item--expanded:hover {
  background: none;
}
.starmap-fleet-selector__item--expanded .starmap-shippanel {
  border-radius: 0;
  box-shadow: none;
}

.starmap-questlog { overflow: hidden; border-radius: 8px; }
.starmap-questlog__toggle {
  width: 100%;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 12px;
  letter-spacing: .08em;
  color: #e6ecff;
  background: rgba(9, 12, 24, .9);
  border: 1px solid rgba(120, 180, 255, .3);
  border-radius: 8px;
  padding: 8px 14px;
}
.starmap-questlog__toggle span { flex: 1; text-align: left; }
.starmap-questlog__list {
  margin-top: 4px;
  /* HOEHER SEIT 2026-09-17 (Nutzerwunsch: "Missionslog nach unten verlaengern,
     es ist genug Platz"). 260 px stammten aus der Zeit, als das Questlog als
     Ueberlagerung AUF der Karte lag - dort war jede Zeile mehr eine Zeile, die
     die Karte verdeckte. Seit dem 2026-09-14 ist es ein eigener Reiter der
     rechten Leiste und hat die ganze Hoehe fuer sich.

     Relativ zur Fensterhoehe statt einer festen Zahl: Auf einem hohen Schirm
     sollen mehr Auftraege zu sehen sein, ohne dass jemand die Zahl nachzieht.
     Die 320 px Abzug decken Kopfzeile, Reiter und Rand der Leiste ab; der
     Boden von 260 px haelt das Feld auf kleinen Schirmen genau so gross wie
     bisher. */
  max-height: max(260px, calc(100vh - 320px));
  overflow-y: auto;
  background: rgba(9, 12, 24, .97);
  border: 1px solid rgba(120, 180, 255, .3);
  border-radius: 8px;
}
.starmap-questlog__item {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 12px;
  text-align: left;
  color: #cfd7f5;
  background: transparent;
  border: 0;
  border-top: 1px solid rgba(120, 180, 255, .1);
  cursor: pointer;
}
.starmap-questlog__item:first-child { border-top: 0; }
.starmap-questlog__item:hover { background: rgba(127, 233, 255, .08); }
.starmap-questlog__title { font-weight: 600; }
.starmap-questlog__meta,
.starmap-questlog__progress { font-size: 10.5px; color: #8b96ba; }
.starmap-questlog__progress { color: #7fe9ff; }
/* Der Aufklapper und die Details (Nutzerwunsch 2026-09-05: "die aktuellen
   Schritte anzeigen, den ggf. vorhandenen Missionstext anzeigen ... darf gern
   mit einem [Mehr] aufklappbar werden").

   Vorher stand im Log nur "3/5 · Zum Ziel reisen" - der Auftragstext und die
   unterwegs gefundenen Hinweise standen ausschliesslich im Versteck. */
/* "Mehr" oeffnet das Detailmodal - keine eigene Farbe noetig, es ist die
   neutrale der drei Handlungen. */

/* Form und Farbe kommen aus .starmap-questlog__action - hier steht nur noch,
   was die einzelnen Knoepfe unterscheidet. */

/* Die Details stehen seit 2026-09-05 im MODAL, nicht mehr aufgeklappt in der
   Leiste - dort schoben sie alles nach unten. */
.starmap-questlog__details {
  padding: 8px 0 0;
  border-left: 0;
  background: none;
}

/* Der Inhalt bringt Rahmen und Grund SELBST mit - `.detail-modal` ist nur die
   Huelle mit Position und Schliessknopf (Nutzerbefund 2026-09-05: "Modal fuer
   Missionen hat keinen Rahmen, sieht nicht so gut aus"). Dieselben Werte wie
   .detail-panel, damit alle Modalinhalte gleich aussehen. */
.quest-modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 18px 20px 20px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .55);
}

.quest-modal__title {
  /* Rechts Platz fuer den Schliessknopf der Huelle - sonst laeuft ein langer
     Titel darunter hindurch. */
  margin: 4px 34px 2px 0;
  font-family: var(--font-heading);
  font-size: 17px;
  color: var(--text-primary);
}

.quest-modal__meta {
  font-size: 11px;
  letter-spacing: .04em;
  color: var(--text-muted);
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}

.starmap-questlog__desc {
  margin: 0 0 8px;
  font-size: 11px;
  line-height: 1.55;
  color: var(--text-body);
}

.starmap-questlog__steps {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: schritt;
}

.starmap-questlog__step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 6px;
  padding: 3px 0;
  font-size: 10.5px;
  color: var(--text-muted);
}

.starmap-questlog__step i { font-size: 12px; }
.starmap-questlog__step.is-done { color: var(--text-dim); }
.starmap-questlog__step.is-done i { color: var(--accent-green); }

/* Der laufende Schritt ist der einzige, an dem man gerade etwas tun kann -
   er traegt deshalb als einziger die Akzentfarbe. */
.starmap-questlog__step.is-current { color: var(--text-primary); }
.starmap-questlog__step.is-current i { color: var(--accent-bright); }

/* Der Fundtext einer erledigten Etappe: eingerueckt unter seinem Schritt. */
.starmap-questlog__find {
  grid-column: 2;
  font-style: normal;
  font-size: 10px;
  line-height: 1.5;
  color: var(--accent-gold);
}

.starmap-questlog__row--completed { border-top: 1px solid rgba(95, 216, 138, .16); }
.starmap-questlog__row--completed .starmap-questlog__item { cursor: default; }
.starmap-questlog__row--completed .starmap-questlog__item:hover { background: transparent; }
.starmap-questlog__progress--completed { color: var(--accent-green); }
/* Form und Groesse kommen seit dem 2026-09-15 von .starmap-questlog__action -
   beide Abschlussknoepfe stehen jetzt in derselben Spalte wie die Knoepfe der
   laufenden Missionen. Hier bleibt nur die Farbe: rot raeumt weg. */
.starmap-questlog__delete {
  border-color: rgba(224, 90, 74, .22);
  background: rgba(224, 90, 74, .06);
  color: #e08a7a;
}
.starmap-questlog__delete:hover { background: rgba(224, 90, 74, .16); color: #ff8f80; }
.starmap-questlog__delete:disabled { opacity: .45; cursor: wait; }

/* Der Weg zur wartenden Belohnung (Nutzerwunsch 2026-09-13). Er steht an
   derselben Stelle wie sonst der Papierkorb - aber gruen statt rot, denn hier
   ist etwas zu holen und nichts wegzuraeumen. */
/* Gruen statt rot: hier ist etwas zu holen und nichts wegzuraeumen. */
.starmap-questlog__claim {
  border-color: rgba(95, 216, 138, .3);
  background: rgba(95, 216, 138, .1);
  color: #8fe0a0;
}
.starmap-questlog__claim:hover { background: rgba(95, 216, 138, .2); color: #b6f0c4; }
.starmap-questlog__row--claimable {
  border-color: rgba(95, 216, 138, .4);
  box-shadow: inset 2px 0 0 rgba(95, 216, 138, .5);
}
.starmap-questlog__row--claimable .starmap-questlog__progress--completed { color: #8fe0a0; }

.starmap-planet-chip.is-mission-target {
  border-color: rgba(255, 215, 106, .75) !important;
  box-shadow: 0 0 12px rgba(255, 215, 106, .24);
}
.starmap-planet-chip__mission {
  margin-left: auto;
  color: var(--accent-gold);
  font-size: 8px;
  letter-spacing: .08em;
}
.starmap-sysmodal-mission-target {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 6px;
  border: 1px solid rgba(255, 215, 106, .65);
  border-radius: 5px;
  background: rgba(18, 14, 4, .92);
  color: var(--accent-gold);
  font-size: 8px;
  letter-spacing: .08em;
  white-space: nowrap;
  animation: mission-target-pulse 1.4s ease-in-out infinite;
  z-index: 8;
}
@keyframes mission-target-pulse {
  0%, 100% { box-shadow: 0 0 5px rgba(255, 215, 106, .3); }
  50% { box-shadow: 0 0 16px rgba(255, 215, 106, .8); }
}

.starmap-sysmodal-archive-notice {
  position: relative;
  z-index: 5;
  max-width: 560px;
  padding: 9px 14px;
  border: 1px solid rgba(120, 180, 255, .25);
  border-radius: 7px;
  background: rgba(5, 6, 15, .86);
  color: #8b96ba;
  font-size: 11px;
  line-height: 1.45;
  text-align: center;
}

/* DEPOT-RAHMEN DER LAGERSEITE (Bildvorlage _uploads/lager-leer.png,
   Nutzerwunsch 2026-09-04).

   Das Bild liegt als Hintergrund und wird auf die tatsaechliche Groesse des
   Kastens gezogen; der Inhalt sitzt ueber das Innenabstand-Verhaeltnis in
   seinem dunklen Feld. Die Abstaende sind aus der Vorlage abgemessen (1672 x
   941): die Metallkante endet links bei rund 6 %, rechts bei 5 %, oben und
   unten bei rund 8 % - dazu etwas Luft, damit Text nicht an der Kante klebt.

   PROZENTUALE ABSTAENDE beziehen sich in CSS immer auf die BREITE, auch oben
   und unten. Genau das ist hier erwuenscht: der Rahmen wird mitskaliert, und
   ein an der Hoehe haengender Abstand liefe bei viel Inhalt aus dem Bild.

   GRENZE, die man kennen sollte: background-size 100% 100% streckt die
   Vorlage auf die Inhaltshoehe. Bei sehr langem Inhalt werden die obere und
   untere Leiste dadurch hoeher, als sie gezeichnet sind. Fuer die zwoelf
   Ressourcen dieses Spiels bleibt das unauffaellig; wer die Seite deutlich
   verlaengert, sollte auf border-image mit 9-slice wechseln. */
.storage-frame {
  position: relative;
  /* WebP verlustfrei statt PNG (2026-09-04): pixelidentisch bei 74 % der
     Groesse. Kein Rueckfall noetig - WebP koennen alle Browser, die dieses
     Spiel ohnehin voraussetzt. */
  background-image: url('../img/frames/storage-frame.webp');
  background-size: 100% 100%;
  background-repeat: no-repeat;
  /* Pixel-Art soll pixelig bleiben - ohne das glaettet der Browser beim
     Skalieren und macht aus den Kanten Matsch. */
  image-rendering: pixelated;

  /* DIE HOEHE ALS VARIABLE, weil das Padding gleich davon abhaengt. */
  --storage-frame-h: calc(100vh - var(--topbar-height) - 68px);

  /* OBEN UND UNTEN AN DER HOEHE, links und rechts an der Breite
     (Nutzerbefund 2026-09-20: "Lager: soll auf eine Seite passen.
     Biologische Ress sind unten und man muss scrollen. Ganz oben und ganz
     unten gibts einen Abstand, den man verkleinern kann").

     DER GRUND WAR EINE CSS-EIGENHEIT: Ein prozentuales padding bezieht sich
     IMMER auf die BREITE des Elternelements - auch padding-top und
     padding-bottom. Die frueheren 7.5 % / 8 % waren damit rund 14 % der
     Rahmenhoehe; gemessen bei WQHD 356 px, also 28 % der nutzbaren Hoehe
     fuer Zierrand.

     DIE NEUEN WERTE SIND AM BILD GEMESSEN (storage-frame.webp, 1672x941):
     Die Zierkante endet oben bei 6,3 % der Bildhoehe und beginnt unten bei
     91,5 %. Mit 7 % und 9,5 % liegt der Inhalt knapp innerhalb der Kante -
     und weil `background-size: 100% 100%` das Bild auf die Elementgroesse
     streckt, gilt das bei jeder Fenstergroesse.

     WER HIER WEITER VERKLEINERT, schiebt den Text auf die Zierkante. Dann
     lieber am Inhalt sparen, wie es der Block darunter schon tut. */
  padding: calc(var(--storage-frame-h) * 0.07) 6% calc(var(--storage-frame-h) * 0.095) 7%;

  /* Der Rahmen soll GANZ zu sehen sein, ohne die Seite zu scrollen
     (Nutzerwunsch 2026-09-05). Vorher wuchs er mit seinem Inhalt und ragte
     unten aus dem Bild - man scrollte an der Zierkante entlang, statt in den
     Bestaenden zu lesen.

     Die Rechnung: .app-main sitzt unter der Topbar und traegt 28 px oben und
     40 px unten Innenabstand. Was davon uebrig bleibt, ist die Hoehe des
     Rahmens; gescrollt wird darin.

     Kein max-height statt height: das Hintergrundbild skaliert ueber
     `background-size: 100% 100%` und braucht eine feste Hoehe, sonst zoege
     ein kurzer Bestand den Rahmen zusammen und die Kulisse waere gestaucht. */
  height: var(--storage-frame-h);
  min-height: 420px;
  box-sizing: border-box;
}

/* ALLES AUF EINE SEITE (Nutzerwunsch 2026-09-06: "Ziel ist es, dass alle
   Ressourcen auf eine Seite ohne Scrollen passen, bei meiner Aufloesung
   WQHD").

   Der Rahmen hat eine feste Hoehe - er soll ganz zu sehen sein -, also musste
   der Inhalt schrumpfen, nicht der Kasten. Vier Hebel, vom groessten zum
   kleinsten:

   1. Der Leeren-Knopf wanderte aus der Kachel heraus in ihre Ecke (siehe
      .resource-card__discard). Das allein nimmt jeder der zwoelf Kacheln rund
      40 Pixel.
   2. Weniger Innenabstand in den Kacheln und kleinere Zahlen.
   3. Der Vorlauf ueber der ersten Familie (.section-heading traegt 36 px fuer
      die Uebersicht) faellt hier auf 14 px - unter dem Zierrahmen ist ohnehin
      schon Luft.
   4. Der Untertitel darf schmal bleiben und kurz sein.

   Die Familien stehen weiter in zwei Spalten. Drei waeren zu eng: Die
   Industriestoffe tragen vier Kacheln, die dann nur noch rund 130 px breit
   waeren - schmaler als der laengste Ressourcenname. */
.storage-frame .section-heading {
  margin-top: 14px;
  margin-bottom: 8px;
  font-size: 13.5px;
}
.storage-frame .storage-family .card-grid {
  margin-top: 8px;
  gap: 10px;
}
.storage-frame .storage-families {
  gap: 2px 22px;
}
.storage-frame .resource-card {
  padding: 10px 12px;
  border-radius: var(--radius-md, 6px);
}
.storage-frame .resource-card__amount {
  font-size: 18px;
  margin-top: 4px;
}
.storage-frame .resource-card__bar-track {
  margin-top: 7px;
}
.storage-frame .resource-card__production {
  margin-top: 4px;
}
.storage-frame .resource-icon {
  width: 38px;
  height: 38px;
}
.storage-frame .dashboard-subtitle {
  margin-top: 4px;
  font-size: 11.5px;
  line-height: 1.45;
}
.storage-frame .dashboard-title {
  font-size: 24px;
  margin-top: 2px;
}
.storage-frame .storage-bar {
  margin: 12px 0 4px;
  padding: 10px;
}

/* Der Inhalt scrollt INNERHALB des Rahmens. `height: 100%` bezieht sich auf
   den Innenraum, den das Padding des Rahmens uebrig laesst - der Scrollbalken
   bleibt dadurch innerhalb der Zierkante. */
.storage-frame__inner {
  position: relative;
  height: 100%;
  overflow-y: auto;
  /* Etwas Luft zum rechten Rahmenrand, damit der Scrollbalken nicht auf der
     gezeichneten Kante klebt. */
  padding-right: 6px;
}

/* Innerhalb des Rahmens traegt die Leiste keinen eigenen Kasten mehr - der
   Rahmen IST der Kasten. */
.storage-frame .storage-bar {
  border-color: rgba(120, 180, 255, .28);
  background: rgba(6, 10, 22, .55);
}

.storage-bar {
  margin: 20px 0 8px;
  padding: 14px;
  border: 1px solid rgba(120, 180, 255, .18);
  border-radius: 10px;
  background: rgba(9, 12, 24, .65);
}

/* Bloecke statt Balken (Bildvorlage 2026-09-04: "rechteckig, Pixel Art").
   Rechteckig heisst hier woertlich: keine Rundung, kein Verlauf, eine feste
   Luecke zwischen den Kaestchen. */
.storage-bar__track {
  display: flex;
  gap: 2px;
  width: 100%;
  height: 16px;
  background: none;
}
.storage-bar__block {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  border-radius: 0;
  /* Der Innenschatten gibt dem flachen Rechteck die Kante der Vorlage. */
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .45);
}
.storage-bar__block--free {
  background: rgba(120, 180, 255, .10);
  box-shadow: inset 0 0 0 1px rgba(120, 180, 255, .16);
}
.storage-bar--full .storage-bar__track { box-shadow: 0 0 0 1px #ff6b6b, 0 0 12px rgba(255, 107, 107, .3); }
.storage-bar__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 10px;
  font-size: 10.5px;
  letter-spacing: .04em;
  color: #aab4d4;
}
.storage-bar__legend-item { display: inline-flex; align-items: center; gap: 5px; }
/* Eckig wie die Bloecke, nicht rund - dieselbe Formensprache. */
.storage-bar__legend-item i { width: 7px; height: 7px; border-radius: 0; }
.storage-bar__free-label { margin-left: auto; color: #7fe9ff; }
.storage-bar__warning { margin-top: 10px; color: #ff6b6b; font-size: 11.5px; }

/* Der Stellare Navigator: eine Ueberlagerung NEBEN der Minikarte
   (Nutzerwunsch 2026-09-14: "Der Stellare Navigator kann wieder als Overlay
   Fenster neben die Minimap platziert werden. Auch nicht mega gross, gleiche
   height wie Minimap, aber etwas breiter").

   ZUM ZWEITEN MAL HIER. Bis zum 2026-09-04 lag er schon einmal ueber der
   Karte, zusammen mit Flottenwahl und Questlog; der Umzug in die rechte
   Leiste kam von der Meldung "beim drag and drop auf der sternenkarte
   markiere ich oft alles (linke seitenleiste, navigator, questlog)".

   WARUM ER JETZT TROTZDEM WIEDER DARF: Markiert wurde, was man anfassen
   kann. Der Navigator ist reine Anzeige - `pointer-events: none` laesst
   jede Maustaste durch ihn hindurch auf die Karte, und `user-select: none`
   erbt er von .starmap-viewport. Eine Ziehgeste ueber ihn hinweg zieht die
   Karte, statt seinen Text zu markieren. Flottenwahl und Questlog sind
   bedienbar und deshalb in der Leiste geblieben.

   z-index 6 wie die Minikarte, mit der er eine Zeile bildet: ueber Nebel
   (3), Kontur (4) und Unbekannt-Kulisse (5). */
.starmap-navigator {
  position: absolute;
  top: 12px;
  /* Buendig neben der Minikarte, mit 10 px Abstand. Beide Masse kommen aus
     .starmap-viewport - siehe die Begruendung dort. */
  left: calc(12px + var(--starmap-minimap-outer) + 10px);
  z-index: 6;
  /* "Etwas breiter" als die Minikarte (194), nicht viel: er soll neben ihr
     stehen, nicht die Karte zustellen. */
  width: 250px;
  /* GLEICHE HOEHE wie die Minikarte. min-height statt height, damit die
     Zeilen nicht abgeschnitten werden, falls jemand eine sechste ergaenzt -
     der Inhalt braucht heute rund 170 px, sichtbar sind 206. */
  min-height: var(--starmap-minimap-height);
  box-sizing: border-box;
  padding: 14px 16px;
  background: rgba(10, 14, 28, 0.95);
  border: 1px solid rgba(120, 180, 255, 0.16);
  border-radius: 10px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(6px);
  pointer-events: none;
}

/* Unter 900 px blendet das CSS die Minikarte aus (siehe dort). Der Navigator
   rueckt dann auf ihren Platz, statt mit zu verschwinden - Position, Zoom und
   Kartierungsstufe sind gerade auf kleinen Schirmen die Auskunft, die man
   sonst nirgends mehr bekommt. */
@media (max-width: 900px) {
  .starmap-navigator {
    left: 12px;
  }
}
.starmap-navigator__head {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.12em;
  color: #7fe9ff;
}
.starmap-navigator__sub {
  font-size: 9.5px;
  letter-spacing: 0.16em;
  color: #63709a;
  margin-top: 2px;
}
.starmap-navigator__divider {
  height: 1px;
  background: rgba(120, 180, 255, 0.14);
  margin: 11px 0;
}
.starmap-navigator__row {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  font-size: 11px;
  color: #8b96ba;
  margin-top: 5px;
}
.starmap-navigator__row:first-child {
  margin-top: 0;
}
.starmap-navigator__val--pos {
  color: #e6ecff;
}
.starmap-navigator__val--coord {
  color: #7fe9ff;
}
.starmap-navigator__val--target {
  color: #f0a8f4;
}
.starmap-navigator__val--zoom {
  color: #46d9d0;
}
.starmap-shippanel {
  background: rgba(10, 14, 28, 0.97);
  border: 1px solid rgba(120, 180, 255, 0.16);
  border-radius: 10px;
  padding: 16px 18px 18px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(6px);
}
.starmap-shippanel__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
}
.starmap-shippanel__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.08em;
  color: #e6ecff;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.starmap-shippanel__close {
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  font-size: 14px;
  font-weight: 700;
  color: #e0554a;
}
.starmap-shippanel__close:hover {
  color: #ff7a6b;
}
.starmap-shippanel__type {
  font-size: 10px;
  letter-spacing: 0.06em;
  color: #63709a;
  margin-top: 3px;
}
.starmap-shippanel__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 11px;
  color: #8b96ba;
  margin-top: 9px;
}
.starmap-shippanel__row--sm {
  font-size: 10px;
  color: #63709a;
  margin-top: 4px;
}
.starmap-shippanel__row--gap {
  margin-top: 9px;
}
.starmap-shippanel__row--sm > span:last-child {
  color: #aab4d4;
}
.starmap-shippanel__val--muted {
  color: #4f5a7a;
}
.starmap-shippanel__val--scan {
  color: #46d9d0;
}
.starmap-shippanel__val--accent {
  color: #7fe9ff;
}
.starmap-shippanel__bar {
  height: 6px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(120, 180, 255, 0.1);
  margin-top: 5px;
  overflow: hidden;
}
.starmap-shippanel__bar > div {
  height: 100%;
  transition: width 0.2s;
}
.starmap-shippanel__bar--placeholder {
  height: 9px;
  border-radius: 6px;
  margin-top: 6px;
}
.starmap-shippanel__bar--placeholder > div {
  background: repeating-linear-gradient(
    45deg,
    rgba(79, 90, 122, 0.55),
    rgba(79, 90, 122, 0.55) 5px,
    rgba(79, 90, 122, 0.25) 5px,
    rgba(79, 90, 122, 0.25) 10px
  );
}
.starmap-shippanel__more {
  margin-top: 11px;
  border-top: 1px solid rgba(120, 180, 255, 0.12);
  padding-top: 9px;
}
.starmap-shippanel__more > summary {
  cursor: pointer;
  list-style: none;
  font-size: 9.5px;
  letter-spacing: 0.12em;
  color: #63709a;
}
.starmap-shippanel__more > summary::-webkit-details-marker {
  display: none;
}
.starmap-shippanel__more > summary:hover {
  color: #aab4d4;
}
.starmap-shippanel__creature {
  font-size: 11px; color: var(--text-dim); padding: 4px 0;
}
.starmap-shippanel__ship {
  margin-top: 9px;
}
.starmap-shippanel__ship-head {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  align-items: baseline;
  min-width: 0;
}
.starmap-shippanel__ship-name {
  font-size: 11px;
  color: #aab4d4;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.starmap-shippanel__ship-type {
  font-size: 9px;
  letter-spacing: 0.06em;
  color: #4f5a7a;
  flex-shrink: 0;
  white-space: nowrap;
}
.starmap-shippanel__ship-bars {
  display: grid;
  grid-template-columns: auto 1fr auto 1fr;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
}
.starmap-shippanel__ship-bar-label {
  font-size: 8.5px;
  color: #4f5a7a;
}
.starmap-shippanel__bar--slim {
  height: 4px;
  margin-top: 0;
}
.starmap-shippanel__travel {
  margin-top: 11px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(120, 180, 255, 0.14);
  border-radius: 8px;
  padding: 11px 12px;
}
.starmap-shippanel__travel-eyebrow {
  font-size: 9.5px;
  letter-spacing: 0.1em;
  color: #63709a;
}
.starmap-shippanel__travel-target {
  font-size: 13px;
  color: #f0a8f4;
  margin-top: 2px;
}
.starmap-shippanel__abort {
  margin-top: 10px;
  text-align: center;
  cursor: pointer;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: #e0a44a;
  border: 1px solid rgba(224, 164, 74, 0.4);
  border-radius: 6px;
  padding: 6px;
}
.starmap-shippanel__abort:hover {
  background: rgba(224, 164, 74, 0.1);
}
.starmap-flightcalc-loading {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 10px;
}
.starmap-viewport.system-orbit-viewport {
  height: calc(100vh - 260px);
  min-height: 480px;
}
.starmap-world {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  transform-origin: 0 0;
}
/* Lage und Groesse kommen aus dem Markup (starmapGridStyle() in game.js) -
   sie haengen an den echten Universumsgrenzen. Hier standen bis zum
   2026-09-06 feste -10000/+10000, und alles jenseits davon lag ohne Raster
   da: Der Spieler sah das Muster bei einem Mitspieler ganz, beim naechsten
   halb und bei sich selbst gar nicht. */
.starmap-grid {
  position: absolute;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(76, 116, 196, 0.10) 1px, transparent 1px),
    linear-gradient(90deg, rgba(76, 116, 196, 0.10) 1px, transparent 1px);
  background-size: 46px 46px;
}
/* Anomaliezonen sind Flaechen und deshalb die unterste Fachebene der Karte:
   ueber dem Raster, aber unter Asteroiden (2), Nebel (3), Kontur (4),
   Unbekannt-Kulisse (5) und allen Markern (6+). */
.starmap-anomaly-zone {
  position: absolute;
  z-index: 1;
  border-radius: 50%;
  pointer-events: none;
  box-sizing: border-box;
}
.starmap-anomaly-zone > span {
  position: absolute;
  inset: 12%;
  border-radius: inherit;
  pointer-events: none;
}
.starmap-anomaly-zone--dead-space {
  border: 1px dashed rgba(92, 116, 145, .48);
  background: radial-gradient(circle, rgba(4, 6, 14, .7), rgba(30, 47, 67, .26) 58%, transparent 74%);
  box-shadow: inset 0 0 28px rgba(5, 7, 16, .72);
}
.starmap-anomaly-zone--dead-space > span {
  border: 1px solid rgba(112, 140, 166, .18);
  background: repeating-radial-gradient(circle, transparent 0 7px, rgba(115, 137, 164, .05) 8px 9px);
}
.starmap-anomaly-zone--rift-echo {
  border: 1px solid rgba(199, 146, 234, .46);
  background: radial-gradient(ellipse at 42% 54%, transparent 0 28%, rgba(199, 146, 234, .16) 31%, transparent 36%, rgba(127, 233, 255, .08) 52%, transparent 67%);
  box-shadow: inset 0 0 22px rgba(199, 146, 234, .12), 0 0 18px rgba(127, 233, 255, .08);
}
.starmap-anomaly-zone--rift-echo > span {
  border: 1px dashed rgba(127, 233, 255, .28);
  transform: rotate(-17deg) scaleX(.74);
}
/* Die klickbare Zeile im Navigator (Nutzeridee 2026-09-15).

   DER NAVIGATOR TRAEGT pointer-events: none - er liegt ueber der Karte und
   soll keinen Klick abfangen. Genau deshalb braucht diese eine Zeile eine
   ausdrueckliche Ausnahme; ohne sie waere der Knopf sichtbar, aber tot. */
.starmap-navigator__val--action {
  pointer-events: auto;
  cursor: pointer;
  color: var(--accent-bright, #7fe9ff);
  text-decoration: underline dotted;
  text-underline-offset: 2px;
}
.starmap-navigator__val--action:hover {
  color: #b9f3ff;
}

/* Der Haken fuer den Richtstrahl-Schein (Nutzerwunsch 2026-09-20).

   POINTER-EVENTS MUESSEN HIER WIEDER AN: Der ganze Navigator traegt
   `pointer-events: none`, damit eine Ziehgeste durch ihn hindurch auf die
   Karte laeuft. Ein Haken, den man nicht anklicken kann, waere Zierrat. */
.starmap-navigator__toggle {
  pointer-events: auto;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 10px;
  font-size: 0.82em;
  color: var(--text-dim, #8f9bb3);
  user-select: none;
}
.starmap-navigator__toggle input {
  pointer-events: auto;
  cursor: pointer;
  width: 12px;
  height: 12px;
  margin: 0;
  accent-color: var(--accent-bright, #7fe9ff);
}
.starmap-navigator__toggle:hover {
  color: var(--accent-bright, #7fe9ff);
}

/* Waehrend der Zielmodus laeuft, faellt die Zeile auf - man soll sehen, dass
   der naechste Klick etwas anderes tut als sonst. */
.starmap-navigator__row--aiming {
  color: var(--accent-gold, #ffd76a);
}
.starmap-navigator__row--aiming .starmap-navigator__val {
  pointer-events: auto;
  cursor: pointer;
  color: var(--accent-gold, #ffd76a);
}

/* Der Richtstrahl der Gravitron-Richtantenne (Nutzeridee 2026-09-15).

   EIN SCHIMMER, KEIN BALKEN. Der Strahl macht die Sterne in seinem Korridor
   sichtbar, oeffnet aber den Nebel NICHT - wer dorthin will, muss sich
   vorarbeiten. Ein kraeftiger Strich haette einen Weg behauptet, den es nicht
   gibt.

   Er blendet zum Ende hin aus: Nah an der Antenne ist die Richtung eindeutig,
   weit draussen ist es eine Ahnung. Gedreht wird um die LINKE Kante
   (transform-origin: 0 50%) - dort steht der Stern mit der Antenne; um die
   Mitte gedreht zeigte er in zwei Richtungen.

   Unter den Markern (z6) und unter der Sperrzone: Er ist Kulisse, nichts zum
   Anklicken. */
.starmap-beam {
  position: absolute;
  /* z1 WIE DIE ANOMALIEZONEN, nicht darueber: Sternmarker tragen gar keinen
     z-index (sie liegen bei auto). Alles mit einer positiven Zahl legt sich
     ueber sie - bei z2 daempfte der halbtransparente Strahl die Sterne, die
     er zeigen soll. Er ist Kulisse und gehoert ganz nach unten. */
  z-index: 1;
  transform-origin: 0 50%;
  pointer-events: none;
  /* SPITZ AM STERN, DANN AUF BREITE (Nutzerwunsch 2026-09-15: "er soll auch
     spitz vom Stern kommend in seine Breite gehen und dann lang bis zum
     Ende"). Die 800 px sind WELTKOORDINATEN, keine Prozent - so ist der Keil
     bei der kurzen Vorschau und beim 40.000 Einheiten langen Strahl gleich
     lang, und beide sehen aus wie dasselbe Ding. */
  clip-path: polygon(0 50%, 800px 0, 100% 0, 100% 100%, 800px 100%);
  /* DEZENT (Nutzerwunsch 2026-09-15): Der fertige Strahl begleitet die Karte
     dauerhaft. Er soll auffindbar sein, nicht auffaellig - was er zeigt, sind
     die Sterne in ihm, nicht er selbst. */
  background: linear-gradient(
    to right,
    rgba(127, 233, 255, .13) 0%,
    rgba(127, 233, 255, .07) 14%,
    rgba(127, 233, 255, .035) 42%,
    rgba(127, 233, 255, .012) 72%,
    transparent 100%);
  /* Die Kanten sollen nicht scharf abbrechen - der Korridor ist eine
     Peilung, keine Mauer. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 42%, #000 58%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 42%, #000 58%, transparent 100%);
}

/* Die Zielvorschau des Richtstrahls (Nutzerwunsch 2026-09-15: "bewege ich die
   Maus, dreht sich das Teil um den Heimatstern bis ich klicke").

   HELLER UND KUERZER als der fertige Strahl: Sie ist eine Absicht, keine
   Tatsache. Der gestrichelte Rand sagt dasselbe - noch ist nichts gesetzt.

   Sie dreht sich um die LINKE Kante (transform-origin erbt sie von
   .starmap-beam), also um den Heimatstern. Der Winkel kommt bei jeder
   Mausbewegung per style.transform - ohne Uebergang, sonst liefe die Vorschau
   der Maus hinterher. */
.starmap-beam--preview {
  z-index: 5;
  background: linear-gradient(
    to right,
    rgba(255, 215, 106, .34) 0%,
    rgba(255, 215, 106, .18) 45%,
    rgba(255, 215, 106, .04) 85%,
    transparent 100%);
  /* KEINE gestrichelten Kanten mehr: Sie liefen quer durch den Keil, weil ein
     Rahmen dem Element folgt und nicht der beschnittenen Form. Die Spitze
     macht die Richtung ohnehin deutlicher als jeder Rand. */
  box-sizing: border-box;
}

/* Im Zielmodus zeigt der Zeiger ein Fadenkreuz - der naechste Klick tut etwas
   anderes als sonst, und das soll man sehen, bevor man klickt. */
.starmap-viewport.is-aiming,
.starmap-viewport.is-aiming * {
  cursor: crosshair !important;
}

/* Die Sperrzone in der Kartenmitte (Spec 2026-09-09, neu gezeichnet
   2026-09-15).

   SIE WAR UNSICHTBAR. Bis zum 2026-09-15 stand hier ein schwarzer Kreis auf
   schwarzem Grund, ohne Rand und ohne Muster - die Absicht war "man sieht,
   DASS dort nichts ist", aber ein Loch in der Schwaerze ist kein Loch.
   Nutzerbefund: "ich seh aktuell in der Kartemitte gar nix. alles schwarz."
   Gleichzeitig kuendigt Kapitel 7 an, die Stoerung sei "erwacht", und optisch
   geschah nichts.

   DREI SCHICHTEN, VIER STUFEN. Der Zug (__pull) streckt die Sterne am Rand,
   der Kern (__core) verschluckt das Licht, der Ring (__ring) kreist darum.
   Die Stufen verstellen nur Tempo, Farbe und Deckkraft dieser drei - kein
   Zustand bringt neue Elemente mit ausser den Sternen im Inneren.

   DIE ZONE IST FUER JEDEN SICHTBAR, von Tag eins der Runde an und ohne
   Ruecksicht auf Nebel oder Sensorreichweite (StarmapQueryService). Das ist
   die Ausnahme von den sechs Sichtbarkeitsschichten und sie ist gewollt: Der
   Fleck soll Fragen aufwerfen, bevor irgendjemand eine Antwort hat. */
.starmap-anomaly-zone--rift {
  border: none;
  background: none;
  box-shadow: none;
  overflow: visible;
  /* UEBER NEBEL UND KULISSE (Nutzerwunsch 2026-09-15: "dies sollte auch IMMER
     fuer alle sichtbar sein"). Zonen liegen sonst auf z1 - unter dem
     Fog-Overlay (z3), dem Kontur-Canvas (z4) und der schwarzen
     Unbekannt-Kulisse (z5). Die Kartenmitte liegt bei den meisten Spielern
     ausserhalb des Sichtradius; dort haette die Kulisse den ganzen Effekt
     wieder verschluckt - und genau dieselbe Unsichtbarkeit war der Anlass
     dieser Arbeit.
     z6 und nicht hoeher: Marker und Ringe liegen ebenfalls auf z6 und werden
     SPAETER gezeichnet, behalten bei Gleichstand also die Oberhand. Eine
     Flotte am Rand der Zone verschwindet nicht hinter ihr. */
  z-index: 6;
}
.starmap-anomaly-zone--rift > span {
  border: none;
  background: none;
}

/* Die drei Schichten. Sie sind <i>-Elemente ohne Inhalt und nehmen wie die
   Zone selbst keine Pointer-Ereignisse an. */
.starmap-rift > i {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

/* Der Kern: das Loch. */
/* Der Kern: das Loch. Der Rand ist 1 px und pulst - er traegt den Effekt, der
   Ring setzt nur den wandernden Glanzpunkt darauf. */
.starmap-rift__core {
  inset: 0;
  background: radial-gradient(circle, #000 0 72%, rgba(0, 0, 0, .9) 88%, rgba(0, 0, 0, .55) 97%, transparent 100%);
  box-shadow: inset 0 0 18px rgba(0, 0, 0, 1);
  border: 1px solid rgba(178, 120, 240, .45);
  animation: riftRand 6s ease-in-out infinite;
}

/* Der gezogene Lichtsaum: Sterne am Rand erscheinen zur Mitte hin gestreckt.
   Er liegt AUSSERHALB der Zone (negatives inset) - deshalb traegt die Zone
   overflow: visible. */
.starmap-rift__pull {
  inset: -14%;
  background:
    radial-gradient(2px 9px at 50% 6%, rgba(255, 255, 255, .75), transparent),
    radial-gradient(9px 2px at 92% 48%, rgba(215, 232, 255, .65), transparent),
    radial-gradient(2px 8px at 46% 93%, rgba(255, 255, 255, .6), transparent),
    radial-gradient(8px 2px at 7% 55%, rgba(255, 233, 201, .6), transparent),
    radial-gradient(2px 7px at 72% 12%, rgba(255, 255, 255, .5), transparent),
    radial-gradient(7px 2px at 20% 20%, rgba(207, 227, 255, .45), transparent);
  animation: riftAtem 9s ease-in-out infinite;
}

/* Der kreisende Saum. Die Maske schneidet aus dem Kegelverlauf einen Reif -
   ohne sie waere es eine gefuellte Scheibe. */
/* Der kreisende Saum - ein SCHMALER REIF, kein breiter Kranz (Nutzerbefund
   2026-09-15: "das ist zu fett... der spieler sieht ja kaum mehr seine
   karteninhalte. Der Ringeffekt muss deutlich kleiner ausfallen.. vielleicht
   wirklich nur 2-3 pixel breiter rand der pulsiert").

   DIE MASKE RECHNET IN PIXELN, nicht in Prozent: Ein Prozentwert waere bei
   einer grossen Zone ein breites Band und bei einer kleinen ein Haar - die
   Zone misst je nach Universumsgroesse ein Vielfaches. Mit calc() bleibt der
   Reif bei jeder Groesse gleich duenn. */
.starmap-rift__ring {
  inset: 0;
  background: conic-gradient(from 0deg,
    transparent 0deg,
    rgba(170, 110, 255, .45) 50deg,
    rgba(235, 210, 255, .75) 78deg,
    rgba(140, 90, 220, .25) 120deg,
    transparent 190deg,
    transparent 280deg,
    rgba(150, 100, 235, .28) 325deg,
    transparent 360deg);
  -webkit-mask: radial-gradient(circle,
    transparent calc(50% - 3px), #000 calc(50% - 2px), #000 50%, transparent calc(50% + 1px));
  mask: radial-gradient(circle,
    transparent calc(50% - 3px), #000 calc(50% - 2px), #000 50%, transparent calc(50% + 1px));
  filter: blur(.4px);
  animation: riftDreh 26s linear infinite;
}

/* Der Schimmer im Inneren - erst ab 75 %, wenn der Server die Sterne darin
   ueberhaupt mitliefert. */
.starmap-rift__inner {
  inset: 12%;
  background:
    radial-gradient(1.5px 1.5px at 30% 35%, #fff, transparent),
    radial-gradient(1.3px 1.3px at 62% 28%, #e8d2ff, transparent),
    radial-gradient(1.4px 1.4px at 45% 68%, #fff, transparent),
    radial-gradient(1.2px 1.2px at 72% 62%, #d7e8ff, transparent),
    radial-gradient(1.3px 1.3px at 25% 60%, #fff, transparent);
  opacity: .9;
}

.starmap-rift__name {
  position: absolute;
  left: 50%;
  top: 100%;
  transform: translate(-50%, 10px);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(222, 196, 255, .8);
  white-space: nowrap;
  pointer-events: none;
}

/* "Unbekanntes Phänomen" mittig im Kreis, bis die Zone offen ist
   (Nutzerwunsch 2026-09-15). Von Tag eins an - sie soll nicht nur auffallen,
   sondern auch sagen duerfen, dass niemand weiss, was sie ist.

   DIE SCHRIFT SKALIERT GEGEN DEN KARTENZOOM. Der Weltcontainer traegt
   `transform: scale(zoom)`; ohne den Ausgleich waere der Text bei 25 % Zoom
   ein Strich und bei 300 % eine Schlagzeile. `--starmap-fleet-icon-scale`
   steht dafuer schon bereit (1/zoom, gesetzt in applyStarmapTransform) und
   haelt die Bildschirmgroesse konstant - dieselbe Loesung wie bei den
   Flottensymbolen. */
.starmap-rift__unknown {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) scale(var(--starmap-fleet-icon-scale, 1));
  font-family: var(--font-heading), sans-serif;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  text-align: center;
  color: rgba(214, 178, 255, .62);
  text-shadow: 0 0 10px rgba(0, 0, 0, .95), 0 0 18px rgba(0, 0, 0, .8);
  white-space: nowrap;
  pointer-events: none;
  animation: riftSchrift 6s ease-in-out infinite;
}

/* Sie atmet mit dem Rand, nur schwaecher - eine still stehende Schrift auf
   einem sich bewegenden Objekt wirkt aufgeklebt. */
@keyframes riftSchrift {
  0%, 100% { opacity: .5; }
  50% { opacity: .85; }
}

/* Im Finale wird auch die Schrift unruhiger. */
.starmap-rift.is-wach .starmap-rift__unknown {
  color: rgba(232, 205, 255, .8);
  animation-duration: 3.2s;
}

@keyframes riftDreh { to { transform: rotate(360deg); } }
@keyframes riftRand {
  0%, 100% { border-color: rgba(178, 120, 240, .30); box-shadow: inset 0 0 18px rgba(0, 0, 0, 1); }
  50% { border-color: rgba(214, 170, 255, .62); box-shadow: inset 0 0 18px rgba(0, 0, 0, 1), 0 0 9px rgba(150, 80, 230, .30); }
}
@keyframes riftAtem { 0%, 100% { opacity: .62; transform: scale(1); } 50% { opacity: .85; transform: scale(1.03); } }
@keyframes riftPuls { 0%, 100% { opacity: .82; } 50% { opacity: 1; } }

/* ---- Stufe 1: RUHIG. Ab Tag eins der Runde, fuer jeden.
   BEWUSST ZURUECKGENOMMEN gegenueber allen spaeteren Stufen (Nutzerwunsch
   2026-09-15: "ein design (abgeschwaecht) von Tag 1 des universums"): Sie
   begleitet die ganze Runde und darf sich nicht abnutzen. Man soll sie sehen
   und nichts wissen - nicht sie anstarren muessen. */
.starmap-rift.is-ruhig .starmap-rift__ring {
  opacity: .55;
  filter: blur(.8px);
  animation-duration: 42s;
}
.starmap-rift.is-ruhig .starmap-rift__core { animation-duration: 9s; }
.starmap-rift.is-ruhig .starmap-rift__pull {
  opacity: .38;
  animation-duration: 13s;
}

/* ---- Stufe 2: ERWACHT. Sobald das Finale laeuft (dashboard.endgame).
   Schneller, heller, und der Kern glimmt - das ist der Augenblick, den
   Kapitel 7 beschreibt. */
.starmap-rift.is-wach .starmap-rift__ring {
  background: conic-gradient(from 0deg,
    transparent 0deg,
    rgba(205, 140, 255, .7) 45deg,
    rgba(255, 240, 255, .95) 75deg,
    rgba(175, 105, 255, .4) 125deg,
    transparent 195deg,
    rgba(145, 85, 235, .25) 285deg,
    transparent 360deg);
  filter: blur(.4px);
  animation-duration: 11s;
}
.starmap-rift.is-wach .starmap-rift__pull { animation-duration: 3.4s; }
.starmap-rift.is-wach .starmap-rift__core {
  border-color: rgba(226, 186, 255, .7);
  animation: riftRand 3.2s ease-in-out infinite;
}

/* ---- Stufe 3: ENTHUELLT, ab 75 % Gesamtfortschritt. Der Kern gibt den Blick
   frei, die Sterne darin erscheinen, der Name steht darunter. */
.starmap-rift.is-enthuellt .starmap-rift__core {
  background: radial-gradient(circle, rgba(18, 6, 34, .30) 0 70%, rgba(60, 24, 96, .16) 88%, transparent 99%);
  box-shadow: inset 0 0 28px rgba(120, 60, 180, .22);
  border-style: dashed;
  border-color: rgba(199, 146, 234, .55);
  animation: none;
}
.starmap-rift.is-enthuellt .starmap-rift__ring { animation-duration: 16s; opacity: .8; }

/* ---- Stufe 4: OFFEN, ab 100 %. Aus dem Loch wird ein Tor: Der Kern leuchtet,
   statt zu schlucken. Bis hierher war die Zone ein Hindernis - jetzt ist sie
   ein Ziel, und das muss man ihr ansehen. */
.starmap-rift.is-tor .starmap-rift__core {
  background: radial-gradient(circle,
    rgba(235, 205, 255, .26) 0 22%,
    rgba(150, 80, 230, .22) 46%,
    rgba(50, 16, 90, .20) 74%,
    transparent 99%);
  box-shadow: 0 0 22px rgba(180, 110, 255, .38), inset 0 0 24px rgba(120, 60, 200, .26);
  border-color: rgba(220, 180, 255, .55);
  animation: riftRand 5s ease-in-out infinite;
}
.starmap-rift.is-tor .starmap-rift__ring { animation-duration: 7s; }

@media (prefers-reduced-motion: reduce) {
  .starmap-rift__ring,
  .starmap-rift__pull,
  .starmap-rift__core,
  .starmap-rift__unknown {
    animation: none !important;
  }
}

/* Die Raumverzerrung eines laufenden Umzugs (2026-09-12). Anders als die
   Sperrzone ist sie hell und in Bewegung: Sie soll auffallen und vergeht
   wieder — ein schwarzer Fleck würde sie mit dem Endgame verwechselbar
   machen. */
.starmap-anomaly-zone--wormhole {
  border: 1px solid rgba(170, 120, 255, .5);
  background: radial-gradient(circle, rgba(170, 120, 255, .26) 0 38%, rgba(120, 90, 220, .12) 66%, transparent 92%);
  box-shadow: 0 0 40px rgba(170, 120, 255, .35), inset 0 0 50px rgba(140, 100, 240, .3);
  animation: whZonePuls 3.4s ease-in-out infinite;
}
.starmap-anomaly-zone--wormhole > span {
  border: 1px dashed rgba(200, 170, 255, .45);
  background: none;
}
@keyframes whZonePuls {
  0%, 100% { opacity: .72; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.03); }
}
@media (prefers-reduced-motion: reduce) {
  .starmap-anomaly-zone--wormhole { animation: none; }
}

/* Der ANGEKUENDIGTE Umzug (Nutzerwunsch 2026-09-14: "Starmap soll Umzug schon
   mit einem fetten animierten Radius anzeigen, um den Radius steht drumrum,
   ETA xxT XXh xxm XXs").

   EIN RING, KEINE FLAECHE - und das ist der ganze Unterschied zur echten
   Verzerrung darueber: Die sperrt, diese hier warnt nur vor. Eine gefuellte
   Flaeche saehe aus wie ein Hindernis, und der Spieler mied ein Gebiet, das
   er noch gefahrlos durchfliegen kann.

   "FETT" WOERTLICH GENOMMEN: 6 px Rand statt 1 px. Bei einem Radius von 250
   Weltpixeln, die je nach Zoom auf ein Zehntel schrumpfen, ist alles
   Duennere auf der herausgezoomten Karte unsichtbar - und genau dort soll
   die Ankuendigung auffallen. */
.starmap-anomaly-zone--wormhole-announced {
  border: 6px dashed rgba(200, 170, 255, .7);
  background: radial-gradient(circle, transparent 0 82%, rgba(170, 120, 255, .12) 100%);
  box-shadow: 0 0 34px rgba(170, 120, 255, .3);
  animation: whAnkuendigungPuls 2.2s ease-in-out infinite;
}
.starmap-anomaly-zone--wormhole-announced > span { border: none; background: none; }
@keyframes whAnkuendigungPuls {
  0%, 100% { opacity: .55; transform: scale(.985); }
  50% { opacity: 1; transform: scale(1.015); }
}

/* Die ETA sitzt AM Ring, oben mittig (Nutzervorgabe "um den radius steht
   drumrum"). Absolut ueber der Zone statt darin: Der Text soll lesbar
   bleiben, waehrend der Ring pulsiert - eine mitskalierte Schrift flackerte.

   GEGENSKALIERUNG GIBT ES HIER NICHT: Die Zone liegt in der gezoomten Welt,
   der Text zoomt also mit. Das ist gewollt - er gehoert zu diesem Ort, nicht
   an den Bildschirmrand, und beim Herauszoomen verschwindet er mit dem Ring
   zusammen. */
/* Die Restzeit des angekuendigten Umzugs laeuft AM RAND DES RINGS ENTLANG
   (Nutzerwunsch 2026-09-15: "die umzugs ETA anzeige bitte rund um den radius
   setzen"). Vorher stand sie als gerader Block ueber dem Kreis; bei einem
   Ring, der die halbe Karte einnimmt, sah das aus wie eine Bildunterschrift
   zu etwas anderem.

   Das SVG deckt die ganze Zone ab, der Bogen darin liegt in einer viewBox von
   100x100 - so wandert der Text mit jeder Ringgroesse an dieselbe Stelle, und
   die Schrift waechst mit. font-size zaehlt in viewBox-Einheiten: 6 von 100
   sind bei einem 600-px-Ring 36 Pixel. */
.starmap-anomaly-zone__eta-arc {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
.starmap-anomaly-zone__eta-arc text {
  fill: #d9c4ff;
  font-family: var(--font-heading), sans-serif;
  font-size: 6px;
  font-weight: 700;
  letter-spacing: .12px;
  paint-order: stroke;
  stroke: rgba(0, 0, 0, .85);
  stroke-width: .9px;
  stroke-linejoin: round;
}

@media (prefers-reduced-motion: reduce) {
  .starmap-anomaly-zone--wormhole-announced { animation: none; }
}

/* Die Beschriftung der SCHARFEN Verzerrung (Nutzerwunsch 2026-09-15:
   "Wurmloch - Umzug - [Spielername]" um den aeusseren Radius).

   Heller und mit kraeftigerem Umriss als die ETA-Schrift der Ankuendigung:
   Die liegt auf einem duennen Ring vor schwarzem Grund, diese hier auf einer
   gefuellten, pulsierenden Flaeche. Mit derselben Farbe verschwaemme sie
   darin. */
.starmap-anomaly-zone__arc--wormhole text {
  fill: #f2e9ff;
  font-size: 5.4px;
  letter-spacing: .3px;
  stroke: rgba(0, 0, 0, .92);
  stroke-width: 1.1px;
}
/* Die gelichtete Sperrzone (Spec 2026-09-11 C2, ab 75 % Gesamtfortschritt).
   DURCHSCHEINEND, damit die Sterne darin zu sehen sind - die Zone liegt
   unter ihnen (z-index 1), eine deckende Fuellung saehe trotzdem nach
   Verbot aus. Der violette Rand sagt: Hier ist noch etwas. */
.starmap-anomaly-zone--rift-unveiled {
  border: 1px dashed rgba(199, 146, 234, .55);
  background: radial-gradient(circle, rgba(18, 6, 34, .35) 0 55%, rgba(60, 24, 96, .18) 80%, transparent 96%);
  box-shadow: inset 0 0 50px rgba(120, 60, 180, .25), 0 0 26px rgba(199, 146, 234, .12);
}
.starmap-anomaly-zone--rift-unveiled > span {
  border: 1px solid rgba(199, 146, 234, .16);
  background: none;
}
/* Sterne: Struktur/Werte 1:1 aus Vorlage (Sternenkarte.dc.html Z.89-106) -
   Positionierung, Opacity (Fog-Tier), Cursor und Sternkoerper werden inline
   gesetzt; hier nur der Hover-Ring (Vorlage Z.91). */
.starmap-system {
  position: absolute;
}
.starmap-system[data-in-reach="1"]:hover::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 30px;
  height: 30px;
  border: 1.5px solid rgba(70, 217, 208, 0.85);
  transform: translate(-50%, -50%);
  pointer-events: none;
}
/* Reise-Linie 1:1 aus Vorlage Z.165: gestrichelt gelb, haengt am Schiff und
   wird mit dem Flugfortschritt kuerzer (Position/Breite per Tick aktualisiert). */
/* Abfangpunkt und Zielbahn (Spec 2026-09-18). Die Z-Ebenen folgen der
   Schichtung aus docs/architecture: Nebel 3 < Kontur 4 < Unbekannt 5 <
   Marker 6+; das Fadenkreuz liegt mit 8 knapp ueber den Reiselinien (7),
   damit es nicht von ihnen durchkreuzt wird. */
/* Freund und Feind am Stern (Spec 2026-09-19). Der Ring liegt UNTER den
   Markern (z-index 6+) und ueber Nebel und Kontur - er gehoert zum Stern, nicht
   zur Auswahl. */
.starmap-standing {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 30px;
  height: 30px;
  margin: -15px 0 0 -15px;
  border: 1px solid var(--standing-color);
  border-radius: 50%;
  box-shadow: 0 0 9px color-mix(in srgb, var(--standing-color) 55%, transparent);
  pointer-events: none;
  z-index: 5;
}
.starmap-standing--enemy { animation: starmap-standing-pulse 2.4s ease-in-out infinite; }
.starmap-standing__corner {
  position: absolute;
  width: 6px;
  height: 6px;
  border: 1px solid var(--standing-color);
}
.starmap-standing__corner--tl { left: -4px; top: -4px; border-right: 0; border-bottom: 0; }
.starmap-standing__corner--tr { right: -4px; top: -4px; border-left: 0; border-bottom: 0; }
.starmap-standing__corner--bl { left: -4px; bottom: -4px; border-right: 0; border-top: 0; }
.starmap-standing__corner--br { right: -4px; bottom: -4px; border-left: 0; border-top: 0; }
.starmap-standing__dot {
  position: absolute;
  left: 50%;
  top: -3px;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--standing-color);
}
@keyframes starmap-standing-pulse {
  0%, 100% { opacity: .6; }
  50% { opacity: 1; }
}
.starmap-intercept-mark {
  position: absolute;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 8;
}
.starmap-intercept-mark__ring {
  position: absolute;
  left: -13px;
  top: -13px;
  width: 26px;
  height: 26px;
  border: 1px solid rgba(255, 139, 112, .85);
  border-radius: 50%;
  box-shadow: 0 0 10px rgba(255, 139, 112, .45);
  animation: starmap-intercept-pulse 1.8s ease-in-out infinite;
}
.starmap-intercept-mark__ring::before,
.starmap-intercept-mark__ring::after {
  content: '';
  position: absolute;
  background: rgba(255, 139, 112, .85);
}
.starmap-intercept-mark__ring::before { left: 50%; top: -7px; width: 1px; height: 38px; }
.starmap-intercept-mark__ring::after { top: 50%; left: -7px; height: 1px; width: 38px; }
.starmap-intercept-mark__eta {
  position: absolute;
  left: 18px;
  top: -8px;
  padding: 1px 5px;
  border-radius: 3px;
  background: rgba(10, 12, 20, .8);
  color: #ffb9a6;
  font-size: 10px;
  letter-spacing: .04em;
  white-space: nowrap;
}
.starmap-intercept-trail {
  position: absolute;
  height: 0;
  border-top: 1px dashed rgba(255, 139, 112, .5);
  transform-origin: 0 0;
  pointer-events: none;
  z-index: 7;
}
@keyframes starmap-intercept-pulse {
  0%, 100% { opacity: .55; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.12); }
}
.starmap-travel-line {
  position: absolute;
  height: 0;
  border-top: 1px dashed rgba(240, 208, 90, 0.6);
  transform-origin: 0 0;
  pointer-events: none;
  z-index: 7;
  transition: left 0.9s linear, top 0.9s linear, width 0.9s linear;
}
.starmap-travel-ship {
  position: absolute;
  width: 10px;
  height: 10px;
  background: var(--accent-bright);
  clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
  box-shadow: 0 0 8px var(--accent-bright), 0 0 14px rgba(127, 233, 255, 0.6);
  pointer-events: none;
  z-index: 8;
  transition: left 0.9s linear, top 0.9s linear;
}
/* ETA-Badge, urspruenglich 1:1 aus Vorlage Z.166.
   Nutzerbefund 2026-09-02: zu gross, und es sass mittig AUF der gestrichelten
   Linie. Kleiner und schmaler; den Querversatz zur Linie setzt das JS als
   eigenes transform (starmapEtaTransform), weil er vom Streckenwinkel
   abhaengt. Das translate hier bleibt als Rueckfall fuer den Fall, dass ein
   Aufrufer keinen Winkel mitgibt. */
.starmap-travel-eta {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: var(--font-heading);
  font-size: 9px;
  letter-spacing: 0.03em;
  color: #f0d05a;
  background: rgba(9, 12, 24, 0.9);
  border: 1px solid rgba(240, 208, 90, 0.5);
  border-radius: 4px;
  padding: 1px 5px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 9;
  transition: left 0.9s linear, top 0.9s linear;
}
/* Vorlage: gestrichelte gelbe Ziel-Linie beim Anwaehlen (vor dem Start). */
.starmap-preview-line {
  position: absolute;
  height: 0;
  border-top: 1px dashed rgba(240, 208, 90, 0.6);
  transform-origin: 0 0;
  pointer-events: none;
  z-index: 7;
}
/* Gleiche Verkleinerung wie beim Reise-Badge darueber (Nutzerbefund 2026-09-02). */
.starmap-preview-eta {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: var(--font-heading);
  font-size: 9px;
  letter-spacing: 0.03em;
  color: #f0d05a;
  background: rgba(9, 12, 24, 0.9);
  border: 1px solid rgba(240, 208, 90, 0.5);
  border-radius: 4px;
  padding: 1px 5px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 9;
}
.starmap-fog-overlay {
  position: absolute;
  background: rgba(6, 7, 16, 0.72);
  -webkit-mask-image: url(#starmap-fog-mask);
  mask-image: url(#starmap-fog-mask);
  pointer-events: none;
  z-index: 3;
}
/* Deep-Space-Mapping (Spec 2026-07-24): schwarze "Unbekanntes Universum"-Kulisse
   ausserhalb des Sichtradius, Grenzlinie am Radius, gekruemmte Labels. */
/* Kulisse ueber Fog-Overlay (z3) und Kontur-Canvas (z4), damit das Schwarz die
   rechteckigen Nebel-Raender sauber auf den runden Sichtkreis beschneidet.
   Marker/Ringe (z6+) und die transparente Kreisflaeche bleiben unberuehrt. */
.starmap-unknown-veil {
  position: absolute;
  pointer-events: none;
  z-index: 5;
}
.starmap-unknown-border {
  position: absolute;
  transform: translate(-50%, -50%);
  border: 2px dashed #b8c2cc;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0.5;
  z-index: 6;
}
.starmap-unknown-label {
  position: absolute;
  pointer-events: none;
  overflow: visible;
  z-index: 6;
}
/* Ankunfts-Radar 1:1 aus Vorlage (Sternenkarte.dc.html Z.141-142): Ring plus
   rotierender Sektor, laeuft nach der Ankunft kurz am Zielsystem. */
.starmap-arrival-scan {
  position: absolute;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 1px solid rgba(70, 217, 208, 0.35);
  pointer-events: none;
  z-index: 9;
}
.starmap-arrival-scan__sweep {
  position: absolute;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: conic-gradient(from 0deg, rgba(70, 217, 208, 0.55), rgba(70, 217, 208, 0) 70deg, transparent);
  animation: radarSpin 0.9s linear infinite;
  pointer-events: none;
  z-index: 9;
}
/* Scan-Ringe + Heimat-Marker 1:1 aus Vorlage (Sternenkarte.dc.html Z.130-155).
   Farbe/Rahmen werden inline gesetzt (Heimat rosa, Schiff cyan). */
.starmap-scan-ring {
  position: absolute;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
  z-index: 6;
}
.starmap-scan-label {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
  overflow: visible;
  z-index: 6;
}
.starmap-home-marker {
  position: absolute;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid #ffd76a;
  transform: translate(-50%, -50%);
  box-shadow: 0 0 12px rgba(255, 215, 106, 0.45);
  pointer-events: none;
  z-index: 6;
}
.system-aux-row--fleet-here {
  outline: 2px solid var(--accent-gold);
  outline-offset: 2px;
}
.system-fleet-panel--highlight {
  animation: system-fleet-highlight-pulse 1.2s ease-out;
}
@keyframes system-fleet-highlight-pulse {
  from { box-shadow: 0 0 0 3px var(--accent-gold); }
  to { box-shadow: 0 0 0 0 transparent; }
}
/* Aus der Design-Vorlage (Sternenkarte.dc.html) uebernommene Effekte -
   reine Optik, keine Positions-/Logikaenderung. */
@keyframes pulsering {
  0% { transform: translate(-50%, -50%) scale(1); opacity: 0.7; }
  70% { transform: translate(-50%, -50%) scale(2); opacity: 0; }
  100% { opacity: 0; }
}
@keyframes zoomIn {
  from { opacity: 0; transform: scale(0.5); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes warpFlash {
  0% { opacity: 0; transform: scale(0.25); }
  42% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(2.4); }
}
/* Weitere Keyframes 1:1 aus der Design-Vorlage (Sternenkarte.dc.html Z.32-38). */
@keyframes spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
@keyframes orbit { from { transform: translate(-50%, -50%) rotate(0deg); } to { transform: translate(-50%, -50%) rotate(360deg); } }
/* Gegenrotation, damit Planeten-Labels im Systemansicht-Modal aufrecht bleiben,
   waehrend der Orbit-Rotor sie um die Sonne fuehrt (Sternenkarte.dc.html Z.545). */
@keyframes orbitCounter { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } }
/* Systemansicht-Modal steigt beim Oeffnen auf (Sternenkarte.dc.html Z.429). */
@keyframes modalRise { from { opacity: 0; transform: translateY(24px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes radarSpin { from { transform: translate(-50%, -50%) rotate(0deg); } to { transform: translate(-50%, -50%) rotate(360deg); } }
@keyframes starFlash { 0%, 100% { filter: brightness(1) saturate(1); } 50% { filter: brightness(2.6) saturate(1.8); } }

.system-zoom-view {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  animation: zoomIn 0.6s ease-out;
}
.system-zoom-warp-flash {
  position: fixed;
  inset: 0;
  z-index: 150;
  pointer-events: none;
  background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.95), rgba(150, 195, 255, 0.4) 32%, transparent 66%);
  animation: warpFlash 0.9s cubic-bezier(0.3, 0, 0.7, 1) forwards;
}
/* Eigenes Flottensymbol + Auswahlrahmen. Die Karte setzt
   --starmap-fleet-icon-scale invers zum Zoom, damit die 18px-Symbole auch bei
   maximalem Herauszoomen lesbar bleiben. */
.starmap-map-ship {
  position: absolute;
  z-index: 8;
  cursor: pointer;
  /* Die Groesse MUSS hier stehen: Schild und Symbol sind beide absolut
     positioniert und pointer-events: none. Ohne eigene Ausdehnung faellt
     dieser Traeger auf 0x0 zusammen und laesst sich nicht mehr anklicken -
     die Flotte ist dann sichtbar, aber nicht mehr auswaehlbar
     (Nutzerbefund 2026-08-25). Der Marker traegt deshalb die Ausdehnung des
     Schildes samt Zoom-Ausgleich, die Kinder fuellen ihn nur noch aus. */
  width: 20px;
  height: 24px;
  transform: translate(-50%, -50%) scale(var(--starmap-fleet-icon-scale, 1));
  transform-origin: center;
}
/* Wappenschild als Traeger des Rollensymbols (Nutzerentscheidung 2026-08-25).
   Das frei schwebende Icon wirkte auf dem Sternenfeld verloren; die Form
   verankert es, ohne es so stark zu beschneiden wie ein echtes Dreieck - und
   bleibt vom Dreieck der FREMDEN Flotten unterscheidbar, das die
   Aufklaerungsmechanik ausdrueckt.

   Beide Ebenen tragen dieselbe Verschiebung und dieselbe Skalierung: Schild
   und Symbol muessen bei jedem Zoomschritt deckungsgleich bleiben. */
/* Das Wappenschild in der Systemansicht (Nutzerwunsch 2026-08-25). Es nutzt
   dieselben Bausteine wie der Kartenmarker - eine zweite Formdefinition waere
   die sichere Art, beide Ansichten auseinanderlaufen zu lassen -, braucht hier
   aber eine eigene Groesse: Die Buehne des Modals ist deutlich groesser als
   die Karte, ein 20-px-Schild verschwaende darauf. */
.starmap-sysmodal-ship-shield {
  position: relative;
  width: 26px;
  height: 31px;
}
.starmap-sysmodal-ship-shield .starmap-map-ship__shield,
.starmap-sysmodal-ship-shield .starmap-map-ship__icon {
  left: 50%;
  top: 50%;
  width: 26px;
  height: 31px;
  transform: translate(-50%, -50%);
}
.starmap-sysmodal-ship-shield .starmap-map-ship__icon {
  font-size: 14px;
  padding-bottom: 9px;
}
.starmap-map-ship__shield {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}
.starmap-map-ship__shield path {
  fill: rgba(8, 12, 22, 0.82);
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 4px currentColor);
}
.starmap-map-ship__icon {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Nicht mittig, sondern im oberen, breiten Teil des Schildes - unten sitzt
     die Spitze. Ohne die Verschiebung stuende das Symbol halb im Auslauf. */
  padding-bottom: 7px;
  font-size: 11px;
  line-height: 1;
  color: #eaf4ff;
  pointer-events: none;
}
.starmap-map-ship-highlight {
  position: absolute;
  width: 26px;
  height: 26px;
  transform: translate(-50%, -50%);
  border: 1.5px solid #f0d05a;
  border-radius: 6px;
  box-shadow: 0 0 10px rgba(240, 208, 90, 0.5);
  pointer-events: none;
  z-index: 8;
}
/* Sprint 5b-3: Dauerauftrags-Flotten amberfarben statt cyan/gelb - konsistent
   mit der bestehenden Bergbau-Themenfarbe (BUILDING_META.mining_facility). */
/* Der Dauerauftrags-Ton faerbt seit dem Schild-Umbau (2026-08-25) die KONTUR,
   nicht das Symbol: Das Symbol steht auf dunklem Grund und bleibt hell,
   damit es lesbar bleibt - erkennbar ist der Auftrag am Rand, genau wie die
   Flottenfarbe. Der stroke wird gezielt ueberschrieben, weil er sonst
   currentColor und damit die inline gesetzte Flottenfarbe erbt. */
.starmap-map-ship--mining-order .starmap-map-ship__shield path {
  stroke: #e0a44a;
  filter: drop-shadow(0 0 5px rgba(224, 164, 74, 0.9));
}
.starmap-map-ship__guard-ring {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 29px;
  height: 33px;
  /* KEIN eigenes scale(): der Traeger skaliert bereits, ein zweites hier
     wuerde den Zoom-Ausgleich quadrieren. Der Ring ist absichtlich groesser
     als der 20x24-Traeger und ragt heraus - er ist pointer-events: none und
     veraendert die Klickflaeche deshalb nicht. */
  transform: translate(-50%, -50%);
  border: 1.5px solid #45e6d1;
  border-radius: 50%;
  box-shadow: 0 0 8px rgba(69, 230, 209, 0.85), inset 0 0 5px rgba(69, 230, 209, 0.35);
  pointer-events: none;
}
.starmap-travel-line--mining-order {
  border-top-color: rgba(224, 164, 74, 0.7);
}
.starmap-travel-ship--mining-order {
  background: #e0a44a;
  box-shadow: 0 0 8px #e0a44a, 0 0 14px rgba(224, 164, 74, 0.6);
}
.starmap-travel-eta--mining-order {
  color: #e0a44a;
  border-color: rgba(224, 164, 74, 0.5);
}
.starmap-sidepanel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  /* 562 statt 468 (+20 %, Nutzervorgabe 2026-09-05; davor 468 statt 390,
     ebenfalls +20 %, Nutzer 2026-08-25): Die roten Angriffsleisten der
     Sensorkontakte brachen um, und die Reiterinhalte hatten zu wenig Raum.
     Platz ist da - die Karte daneben ist scrollbar und verliert durch die
     breitere Leiste keinen Inhalt. */
  width: 562px;
  overflow-y: auto;
  background: rgba(9, 12, 24, 0.98);
  border-left: 1px solid rgba(120, 180, 255, 0.16);
  padding: 20px;
  box-shadow: -14px 0 50px rgba(2, 4, 12, 0.5);
}
.starmap-info-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px 18px;
}
/* In der randlosen Sidebar: Kaesten-Optik entschaerfen (nahtloser Inhalt).
   Die geteilte .starmap-info-panel-Klasse (auch System-Detail) bleibt global. */
/* Die Reiter der rechten Leiste (Nutzerwunsch 2026-09-04; seit 2026-09-14
   sechs statt fuenf - NAVIGATOR ist entfallen, FLOTTEN und MISSIONEN sind
   dazugekommen).

   ZWEI ZEILEN ZU DREI, nicht sechs nebeneinander: bei 522 px nutzbarer
   Breite blieben je 82 px, und "SYSTEMINFOS" passt da nicht hinein. Der
   Umbruch kostet rund 28 px Hoehe und traegt auch noch einen siebten
   Reiter, ohne dass jemand die Regel anfassen muss. */
.starmap-sidepanel__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: -4px 0 14px;
}
.starmap-sidepanel__tab {
  /* 33,333 % minus zwei Dritteln der Luecke: drei Reiter plus zwei Luecken
     ergeben genau eine volle Zeile. */
  flex: 1 1 calc(33.333% - 4px);
  padding: 7px 4px;
  border: 1px solid rgba(120, 180, 255, 0.16);
  border-radius: 6px;
  background: rgba(10, 14, 28, 0.6);
  color: #8b96ba;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .08em;
  cursor: pointer;
}
.starmap-sidepanel__tab:hover { color: #c9d0e0; }
.starmap-sidepanel__tab.is-active {
  border-color: rgba(127, 233, 255, .45);
  background: rgba(127, 233, 255, .10);
  color: #7fe9ff;
}
/* Der DEFCON-Reiter traegt dieselbe Warnfarbe wie sein Menuepunkt in der
   linken Leiste (2026-09-05) - orange bei blossen Kontakten, rot pulsierend
   ab Warnstufe. Der aktive Zustand gewinnt: ein geoeffneter Reiter soll als
   geoeffnet erkennbar bleiben, auch wenn er warnt. */
.starmap-sidepanel__tab.is-contacts:not(.is-active) {
  border-color: rgba(232, 162, 74, .45);
  background: rgba(232, 162, 74, .10);
  color: #e8a24a;
}

.starmap-sidepanel__tab.is-threat:not(.is-active) {
  border-color: rgba(224, 90, 74, .5);
  color: var(--accent-red);
  animation: sidebarThreatPulse 1.6s ease-in-out infinite;
}

/* Geoeffnet UND bedroht (Nutzerwunsch 2026-09-05): "er sollte bei akuter
   Gefahr weiterhin einen roten Glow haben - aber Rahmen tuerkis, damit man
   weiss, der Menuepunkt wurde ausgewaehlt."
 *
 * Zwei Aussagen, zwei Traeger: der RAHMEN sagt "hier bist du", der SCHEIN
 * sagt "da draussen brennt es". Vorher schaltete `:not(.is-active)` die
 * Warnung beim Oeffnen komplett ab - ausgerechnet dann, wenn man hinsieht.
 *
 * Eigene Animation statt sidebarThreatPulse: jene faerbt auch den
 * Hintergrund rot, und eine Animation gewinnt gegen jede normale
 * Deklaration - der tuerkise Auswahlgrund waere darunter verschwunden.
 * Diese hier ruehrt ausschliesslich den Schein an. */
.starmap-sidepanel__tab.is-threat.is-active {
  animation: starmapTabThreatGlow 1.6s ease-in-out infinite;
}

@keyframes starmapTabThreatGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(224, 90, 74, 0); }
  50% { box-shadow: 0 0 14px 2px rgba(224, 90, 74, .6); }
}

@media (prefers-reduced-motion: reduce) {
  .starmap-sidepanel__tab.is-threat.is-active {
    animation: none;
    box-shadow: 0 0 12px 1px rgba(224, 90, 74, .5);
  }
}

/* Die Zahl neben der Beschriftung. Im Fluss statt absolut positioniert: die
   Knoepfe teilen sich die Breite zu gleichen Teilen, ein ueberlappendes
   Abzeichen laege bei "SYSTEMINFOS" halb ausserhalb.

   KEIN `background: currentColor` (Nutzerbefund 2026-09-05: "die Zahl im
   Badge ist nicht zu erkennen, ich seh nur einen runden Kreis"). currentColor
   loest sich auf die `color` DESSELBEN Elements auf - und die stand hier auf
   Dunkel. Ergebnis war ein dunkler Kreis mit dunkler Ziffer darin. Jede
   Zustandsfarbe steht deshalb jetzt ausdruecklich da. */
.starmap-sidepanel__tab-badge {
  display: inline-block;
  margin-left: 5px;
  padding: 0 5px;
  border-radius: 8px;
  background: rgba(120, 180, 255, .22);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  line-height: 15px;
  vertical-align: 1px;
}

.starmap-sidepanel__tab.is-contacts .starmap-sidepanel__tab-badge {
  background: #e8a24a;
  color: #2a1a06;
}

.starmap-sidepanel__tab.is-threat .starmap-sidepanel__tab-badge {
  background: var(--accent-red);
  color: #1c0705;
}

/* Im geoeffneten Reiter gewinnt dessen Akzent - der Reiter selbst ist dann
   tuerkis, und ein oranges Abzeichen darin saehe nach zwei Zustaenden aus. */
.starmap-sidepanel__tab.is-active .starmap-sidepanel__tab-badge {
  background: var(--accent-bright);
  color: #04121a;
}

/* Bei akuter Gefahr aber NICHT: dort ist die Zahl eine Warnung und keine
   Auswahlbestaetigung. Zwei Klassen schlagen die eine darueber. */
.starmap-sidepanel__tab.is-threat.is-active .starmap-sidepanel__tab-badge {
  background: var(--accent-red);
  color: #1c0705;
}

/* Ein Reiter ohne Inhalt sagt "keine Daten", nicht "kaputt" (2026-09-14).
   Gebraucht seit der MISSIONEN-Reiter eigenstaendig ist: ohne laufende
   Auftraege zeichnet das Questlog gar nichts. */
.starmap-pane-empty {
  padding: 14px 16px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-muted);
}
.starmap-sidepanel__pane[hidden] { display: none; }
.starmap-sidepanel__pane > * + * { margin-top: 8px; }

/* ------------------------------------------------------------- Minikarte
   Oben links im Kartenfenster (Nutzerwunsch 2026-09-05). Sie liegt UEBER der
   Karte und faengt Klicks selbst ab - deshalb ein eigener Stapelwert und
   pointer-events: auto, waehrend die uebrigen Auflagen durchlassen.

   z-index 6: ueber Nebel (3), Kontur (4) und der Unbekannt-Kulisse (5), aber
   unter den Markern und Ringen, die weiter oben liegen. */
.starmap-minimap {
  position: absolute;
  left: 12px;
  top: 12px;
  z-index: 6;
  width: 180px;
  padding: 6px 6px 4px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: rgba(6, 10, 22, .82);
  box-shadow: 0 6px 20px -8px rgba(0, 0, 0, .8);
  pointer-events: auto;
  user-select: none;
}

.starmap-minimap__field {
  position: relative;
  width: 100%;
  /* Quadratisch, weil squareBounds() einen quadratischen Weltausschnitt
     liefert - jede andere Form staucht die Entfernungen. */
  aspect-ratio: 1 / 1;
  border: 1px solid rgba(120, 180, 255, .14);
  border-radius: 4px;
  background:
    radial-gradient(ellipse at 40% 35%, rgba(70, 120, 210, .12), transparent 65%),
    #05070f;
  cursor: crosshair;
  overflow: hidden;
}

.starmap-minimap__dot {
  position: absolute;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: #4d5878;
}

.starmap-minimap__dot--known { background: #8b96ba; }

.starmap-minimap__dot--own {
  width: 3px;
  height: 3px;
  background: var(--accent);
}

.starmap-minimap__dot--home {
  width: 5px;
  height: 5px;
  background: var(--accent-gold);
  box-shadow: 0 0 5px var(--accent-gold);
}

/* Was Kameraden der Organisation kennen (2026-09-05): blasser und ohne
   Leuchten - das ist Hoerensagen, kein eigener Sensorwert. Auf 180 Pixeln
   muss der Unterschied zu einem eigenen Stern trotzdem erkennbar sein,
   deshalb eine eigene Farbe statt nur weniger Deckkraft. */
.starmap-minimap__dot--organization {
  background: #4a6a8a;
  opacity: .8;
}

.starmap-minimap__dot--fleet {
  width: 3px;
  height: 3px;
  border-radius: 0;
  background: var(--accent-bright);
  box-shadow: 0 0 4px var(--accent-bright);
}

/* Die Mitgliedertabelle der eigenen Organisation auf der Uebersicht
   (2026-09-05). Dieselbe Dichte wie der Highscore - sie beantwortet
   dieselbe Art Frage, nur fuer eine Handvoll Leute. */
/* GENAU WIE DIE ABBAU-FUHREN (Nutzerbefund 2026-09-05: "bei der einen ist der
   Kopf anders gestyled als bei der anderen, das sollte gleich aussehen").
   Werte 1:1 aus .mining-log-table uebernommen - Rahmen an der Tabelle statt
   am Umschlag, heller Kopfbalken, dieselben Abstaende und Schriftgroessen. */
.org-roster { overflow-x: auto; }

/* Der Credit-Fluss neben der Organisation (Nutzerwunsch 2026-09-06). Er nutzt
   die Tabellenstile der Mitgliederliste - zwei Tabellen nebeneinander, die
   verschieden aussehen, wirken wie zwei verschiedene Dinge.

   Eigen ist nur die Betragsspalte: Zahlen rechtsbuendig und in der
   Ziffernbreite der Schrift, damit Tausender untereinander stehen. */
.credit-log__amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: #5fd88a;
  white-space: nowrap;
}
/* Ausgaben rot. Sie gehen bewusst mit in die Liste: Ein Fluss, der nur
   Zufluesse zeigt, erklaert den Kontostand nicht. */
.credit-log__amount--out { color: #e05a4a; }
.credit-log__time {
  color: var(--text-dim);
  font-size: 12px;
  white-space: nowrap;
}

.org-roster__table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  font-size: 13px;
}

.org-roster__table th {
  text-align: left;
  padding: 10px 14px;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: rgba(120, 180, 255, 0.05);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.org-roster__table td {
  padding: 10px 14px;
  border-bottom: 1px solid rgba(120, 180, 255, 0.08);
  color: var(--text-body);
  vertical-align: top;
}

.org-roster__table tr:last-child td { border-bottom: none; }

/* ALLES LINKSBUENDIG, Kopf wie Werte (Nutzerwunsch 2026-09-05). Die feste
   Ziffernbreite bleibt - so stehen die Zahlen trotzdem ruhig untereinander. */
.org-roster__table td { font-variant-numeric: tabular-nums; }

.org-roster__name { white-space: nowrap; }

/* Die Symbolspalten schmal halten - sie tragen ein Zeichen, keine Ueberschrift. */
.org-roster__table th .ph { font-size: 14px; color: var(--text-muted); }

/* Nur fuer Vorleseprogramme: der volle Spaltenname hinter dem Symbol. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Abbau-Fuhren und Organisation nebeneinander (2026-09-05). Beide sind
   schmale Listen; untereinander liessen sie die halbe Breite ungenutzt. */
.dashboard-bottom {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 28px;
  align-items: start;
}

/* Steht nur eine der beiden Listen zur Verfuegung, nimmt sie die volle
   Breite - eine Tabelle auf halber Seite mit Leere daneben saehe nach einem
   fehlenden Block aus. */
.dashboard-bottom--single { grid-template-columns: minmax(0, 1fr); }

.dashboard-bottom__col { min-width: 0; }

@media (max-width: 1100px) {
  .dashboard-bottom { grid-template-columns: minmax(0, 1fr); }
}

.org-roster__name small {
  display: block;
  margin-top: 1px;
  font-size: 9.5px;
  letter-spacing: .04em;
  color: var(--text-dim);
}

/* Der Punkt sagt, ob jemand gerade erreichbar ist - die Frage, die man vor
   einer Bitte um Hilfe stellt. */
.org-roster__dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--text-dimmer);
  vertical-align: 1px;
}

.org-roster__dot.is-online {
  background: var(--accent-green);
  box-shadow: 0 0 5px var(--accent-green);
}

.org-roster__row--online td { background: rgba(95, 216, 138, .04); }

/* Das Fundstueck-Modal (2026-09-05). Der Text ist Erzaehlung, kein
   Datenblatt - er bekommt deshalb Zeilenhoehe und Ruhe statt der dichten
   Satzweise der uebrigen Kaesten. */
.story-discovery__text {
  margin: 0;
  font-size: 13px;
  line-height: 1.65;
  color: var(--text-body);
  text-align: left;
}

.story-discovery__note {
  margin: 12px 0 0;
  font-size: 10.5px;
  letter-spacing: .04em;
  color: var(--text-muted);
  text-align: left;
}

/* Die Kapitel des Finales (Nutzerwunsch 2026-09-18, Spec B4).
   Eigene Klassen statt der Fundstueck-Stile: Ein Fundstueck ist ein Fund und
   traegt eine Randnotiz, ein Kapitel ist Erzaehlung plus Auftrag - die zweite
   Zeile ist hier keine Fussnote, sondern das, was der Spieler jetzt tun
   soll. */
.endgame-chapter__text {
  margin: 0;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-body);
  text-align: left;
}

.endgame-chapter__task {
  margin: 14px 0 0;
  padding: 10px 12px;
  border-left: 2px solid var(--accent-gold);
  background: rgba(255, 255, 255, 0.03);
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-muted);
  text-align: left;
}

/* Suchgebiete und Sektorhoheiten (2026-09-05). Als Umriss, nicht gefuellt:
   auf 180 Pixeln verdeckte eine Flaeche die Sternpunkte darunter.

   Die Kreise koennen groesser als die Minikarte sein - `overflow: hidden` am
   Feld schneidet sie an der Kante ab, was richtig ist: der Rest liegt
   ausserhalb der Welt. */
.starmap-minimap__ring {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

.starmap-minimap__ring--mission {
  border: 1px dashed rgba(110, 170, 255, .75);
  background: rgba(110, 170, 255, .05);
}

/* Die Farbe der Organisation kommt aus dem Markup und ueberschreibt diese
   Vorgabe - sie steht hier nur fuer den Fall, dass keine geliefert wird. */
.starmap-minimap__ring--territory {
  border: 1px solid rgba(224, 90, 74, .7);
  background: rgba(224, 90, 74, .05);
}

/* Die Sperrzone auf der Uebersicht (Nutzerwunsch 2026-09-15: "Man soll wissen
   - da ist was!"). Dieselbe violette Signatur wie auf der grossen Karte, aber
   ohne Bewegung: Bei zwoelf Pixeln Durchmesser waere eine Animation nur
   Unruhe, und die Minikarte beantwortet die Frage "wo bin ich", nicht "was
   passiert dort". Dunkel gefuellt statt nur umrandet - der Fleck soll auch
   zwischen Sternpunkten als Flaeche lesbar bleiben. */
.starmap-minimap__ring--rift {
  border: 1px solid rgba(178, 120, 240, .75);
  background: radial-gradient(circle, rgba(8, 2, 16, .92) 0 55%, rgba(80, 40, 140, .30) 100%);
  box-shadow: 0 0 5px rgba(150, 80, 230, .35);
}

/* Der Rahmen des sichtbaren Ausschnitts. Kein Hintergrund - er soll die
   Punkte darunter nicht verdecken, sondern sie einrahmen. */
.starmap-minimap__view {
  position: absolute;
  border: 1px solid rgba(127, 233, 255, .75);
  background: rgba(127, 233, 255, .06);
  border-radius: 2px;
  pointer-events: none;
}

.starmap-minimap__label {
  margin-top: 3px;
  font-family: var(--font-heading);
  font-size: 8px;
  letter-spacing: .14em;
  color: var(--text-dim);
  text-align: center;
}

/* Auf schmalen Fenstern nimmt sie der Karte zu viel weg. Die Grenze steht
   auch in starmap-minimap.js (MINIMAP_MIN_VIEWPORT). */
@media (max-width: 900px) {
  .starmap-minimap { display: none; }
}

/* ---------------------------------------------------------- DEFCON-Reiter
   Die Lage neben der Karte (2026-09-05). Dieselbe Bildsprache wie die
   DEFCON-Seite - Warnstufen faerben die linke Kante, nicht die ganze Zeile:
   fuenf farbige Bloecke untereinander waeren als Liste nicht mehr lesbar. */

.starmap-defcon__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--border);
}

.starmap-defcon__level {
  font-family: var(--font-heading);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--accent);
}

.starmap-defcon__level--notice { color: var(--accent-gold); }
.starmap-defcon__level--warning { color: var(--accent-gold); }
.starmap-defcon__level--alert { color: #ff8b58; }
.starmap-defcon__level--critical { color: var(--accent-red); }

.starmap-defcon__count { font-size: 10px; color: var(--text-muted); }

.starmap-defcon__empty {
  margin: 10px 0 0;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-muted);
}

.starmap-defcon__list {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
}

/* GRUPPEN STATT EINER LANGEN LISTE (Nutzervorgabe 2026-09-17: "DEFCON in
   Seitenleiste gruppieren ... nach jeder Gruppe kleiner Abstand").

   Die Hoehenbegrenzung sitzt jetzt am ganzen Reiter statt an jeder Liste:
   Bei fuenf Gruppen haette jede ihren eigenen Rollbalken bekommen, und man
   haette fuenfmal scrollen muessen, um eine Uebersicht zu bekommen. */
.starmap-defcon__groups {
  max-height: 58vh;
  overflow-y: auto;
}

.starmap-defcon__group + .starmap-defcon__group { margin-top: 14px; }

.starmap-defcon__group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 10px;
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(120, 180, 255, .14);
  font-family: 'Chakra Petch', sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  /* Die Farbe kommt aus der Gruppe (unten), nicht von hier - dies ist nur
     der Rueckfall fuer eine Gruppe ohne eigene Farbe. */
  color: var(--text-dim);
}

.starmap-defcon__group-count {
  font-weight: 400;
  opacity: .7;
}

/* Die vier Farben aus der Nutzervorgabe, plus Gelb fuer die fuenfte Gruppe
   (fremde Spieler), die auf Nachfrage dazukam. Gefaerbt wird die
   UEBERSCHRIFT und die linke Kante der Zeilen darunter - der Zeilenhintergrund
   bleibt neutral, damit die Warnstufen-Faerbung (orange/rot am linken Rand)
   nicht mit der Gruppenfarbe streitet. */
.starmap-defcon__group--null .starmap-defcon__group-head { color: #c86bff; border-bottom-color: rgba(200, 107, 255, .3); }
.starmap-defcon__group--pirate .starmap-defcon__group-head { color: var(--accent-red); border-bottom-color: rgba(224, 90, 74, .3); }
.starmap-defcon__group--player .starmap-defcon__group-head { color: var(--accent-gold); border-bottom-color: rgba(255, 215, 106, .3); }
.starmap-defcon__group--unknown .starmap-defcon__group-head { color: #e8a24a; border-bottom-color: rgba(232, 162, 74, .3); }
.starmap-defcon__group--member .starmap-defcon__group-head { color: #6ba8ff; border-bottom-color: rgba(107, 168, 255, .3); }

.starmap-defcon__row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border-left: 2px solid var(--border);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: rgba(255, 255, 255, 0.02);
}

.starmap-defcon__row + .starmap-defcon__row { margin-top: 5px; }

.starmap-defcon__row--warning { border-left-color: var(--accent-gold); }
.starmap-defcon__row--alert { border-left-color: #ff8b58; }
.starmap-defcon__row--critical { border-left-color: var(--accent-red); }

/* Ein Kontakt ausserhalb der Aufklaerung: gedaempft, aber da. Er steht als
   Schemen auf der Karte, und die Liste soll ihn nicht verschweigen - nur
   deutlich machen, dass hier Einzelheiten fehlen (2026-09-05). */
.starmap-defcon__row.is-fogged {
  border-left-color: rgba(232, 162, 74, .5);
  background: rgba(255, 255, 255, .012);
  opacity: .72;
}

.starmap-defcon__row.is-fogged .starmap-defcon__ident small { color: #e8a24a; }

.starmap-defcon__ident { min-width: 0; }

.starmap-defcon__ident b {
  display: block;
  font-size: 11.5px;
  color: var(--text-body);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.starmap-defcon__ident i { color: var(--accent-red); font-size: 11px; }

.starmap-defcon__ident small {
  display: block;
  margin-top: 1px;
  font-size: 9.5px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.starmap-defcon__eta { text-align: right; }

.starmap-defcon__eta small {
  display: block;
  font-size: 8.5px;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}

.starmap-defcon__eta b {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-body);
}

/* Der Lokalisieren-Knopf. Beschriftet statt nur bebildert - ein einzelnes
   Fadenkreuz zwischen zwei Textspalten liest niemand als Knopf. */
.starmap-defcon__locate {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 7px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: rgba(127, 233, 255, .08);
  color: var(--accent-bright);
  font-size: 9.5px;
  letter-spacing: .06em;
  white-space: nowrap;
  cursor: pointer;
}

.starmap-defcon__locate:hover { background: rgba(127, 233, 255, .18); }
.starmap-defcon__locate i { font-size: 11px; }

.starmap-defcon__nolocate {
  color: var(--text-dimmer);
  font-size: 11px;
  padding: 0 6px;
}

/* Der Favoritenknopf und die Flottenwahl lagen bis zum 2026-09-04 absolut
   ueber der Karte. Im Reiter stehen sie im normalen Fluss - die
   Positionsangaben muessen weg, sonst kleben sie an der Ecke des Viewports.
   (Der Navigator stand hier bis zum 2026-09-14 mit drin; er ist zurueck auf
   die Karte gezogen und braucht die Zuruecksetzung nicht mehr.) */
.starmap-sidepanel .starmap-fleet-selector {
  position: static;
  top: auto;
  left: auto;
  width: 100%;
  z-index: auto;
}

.starmap-sidepanel .starmap-info-panel {
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
  margin: 0;
}
.starmap-sidepanel .starmap-info-panel + .starmap-info-panel {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}
/* Herkunftsbanner in der Systemleiste (Nutzerwunsch 2026-09-06).

   Blau wie die uebrigen Organisationsmarken auf der Karte, damit der Bezug
   ohne Erklaerung sitzt. Steht GANZ OBEN in der Leiste: Der Stern sieht aus
   wie jeder andere, laesst sich aber nicht anfliegen - wer das erst unten
   erfaehrt, hat vorher schon geklickt. */
.starmap-orgsource {
  border: 1px solid rgba(74, 144, 226, .45);
  border-left-width: 3px;
  background: rgba(74, 144, 226, .1);
  border-radius: 4px;
  padding: 7px 9px;
  margin-bottom: 10px;
}
.starmap-orgsource__title {
  font-family: 'Chakra Petch', sans-serif;
  font-size: 11.5px;
  letter-spacing: .06em;
  color: #7fb4ff;
  display: flex;
  align-items: center;
  gap: 5px;
}
.starmap-orgsource__hint {
  font-size: 10.5px;
  line-height: 1.45;
  color: #8b96ba;
  margin-top: 3px;
}
.starmap-info-panel__eyebrow {
  font-size: 10.5px;
  letter-spacing: 0.2em;
  color: var(--text-dim);
}
.starmap-info-panel__title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 17px;
  color: var(--text-primary);
  margin-top: 4px;
}
.starmap-info-panel__title.starmap-system-title {
  font-size: 22px;
}
.starmap-system-sub {
  font-size: 11px;
  letter-spacing: 0.04em;
  margin-top: 2px;
}
.starmap-cta--primary {
  background: linear-gradient(135deg, var(--accent), var(--accent-bright));
  color: #0a0c18;
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: 0.14em;
  border: none;
}
/* Compound-Selektor: gewinnt gegen die spaeter definierte __center-btn/__open-btn
   color-Regel (gleiche Spezifitaet, sonst heller Text auf hellem Gradient). */
.starmap-info-panel__center-btn.starmap-cta--primary,
.starmap-info-panel__open-btn.starmap-cta--primary {
  color: #0a0c18;
}
.starmap-info-panel__hint {
  font-size: 11.5px;
  color: var(--text-muted);
  line-height: 1.5;
  margin-top: 8px;
}
.starmap-info-panel__row {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 8px;
}
.starmap-info-panel--compact {
  max-width: 420px;
}
.starmap-info-panel--compact .starmap-info-panel__row {
  gap: 24px;
}
.starmap-info-panel--compact .starmap-info-panel__row > span:last-child {
  text-align: right;
  color: var(--text-body);
}
.starmap-info-panel__badge {
  margin-top: 12px;
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--accent-gold);
  border: 1px dashed rgba(255, 215, 106, 0.4);
  border-radius: var(--radius-md);
  padding: 6px;
}
.starmap-info-panel__center-btn {
  margin-top: 12px;
  text-align: center;
  cursor: pointer;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  color: var(--accent-bright);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: 8px;
}
/* Die zwei Sonderformen des Panelknopfs (2026-09-05, Kontaktauswahl):
   der Angriff sticht heraus, das Aufheben der Auswahl tritt zurueck. */
.starmap-info-panel__center-btn.is-attack {
  color: var(--accent-red);
  border-color: rgba(224, 90, 74, 0.55);
  background: rgba(224, 90, 74, 0.08);
  font-weight: 600;
}
.starmap-info-panel__center-btn.is-attack:hover {
  background: rgba(224, 90, 74, 0.16);
}
.starmap-info-panel__center-btn.is-secondary {
  color: var(--text-muted);
  border-color: var(--border);
  margin-top: 6px;
  padding: 6px;
  font-size: 10.5px;
}
.starmap-info-panel__center-btn.is-busy { opacity: 0.5; pointer-events: none; }

.starmap-info-panel__subheading {
  font-size: 10.5px;
  letter-spacing: 0.2em;
  color: var(--text-dim);
  margin-top: 14px;
}
/* Mini-System als DOM (Vorlage Z.256-269): Sonne + Orbit-Ringe + rotierende Planeten. */
.starmap-minisys {
  position: relative;
  width: 100%;
  height: 320px;
  margin: 12px 0 2px;
}
.starmap-minisys--loading {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;
  font-size: 12px;
  color: var(--text-muted);
}
.starmap-minisys__sun {
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  pointer-events: none;
}
.starmap-minisys__ring {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border: 1px solid rgba(160, 190, 255, 0.1);
  border-radius: 50%;
  pointer-events: none;
}
/* Rotor faengt keine Klicks ab - sonst verdeckt der aeusserste (groesste) Rotor
   die inneren Planeten. Nur der Planeten-Punkt ist klickbar. */
.starmap-minisys__rotor {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.starmap-minisys__planet {
  position: absolute;
  left: 50%;
  top: 0;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  cursor: pointer;
  pointer-events: auto;
}
.starmap-minisys__planet.is-selected {
  outline: 2px dashed #c9b6ff;
  outline-offset: 2px;
}
/* Planeten-Chips (Vorlage Z.271-277). */
.starmap-planet-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 8px;
}
.starmap-planet-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 10.5px;
  padding: 5px 9px;
  border-radius: 6px;
  border: 1px solid transparent;
  color: #e6ecff;
}
.starmap-planet-chip.is-selected {
  outline: 1px solid #c9b6ff;
}
.starmap-planet-chip__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.starmap-planet-detail {
  margin-top: 16px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(120, 180, 255, 0.14);
  border-radius: 10px;
  padding: 15px;
}
/* Planeten-Detailkarte 1:1 aus Vorlage (Z.279-345). */
.starmap-pd__head {
  display: flex;
  align-items: center;
  gap: 9px;
}
.starmap-pd__dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  flex: none;
}
.starmap-pd__name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 16px;
  color: #e6ecff;
}
.starmap-pd__section-label {
  color: #63709a;
  font-size: 9.5px;
  letter-spacing: 0.1em;
  margin-top: 14px;
}
.starmap-pd__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 9px 16px;
  margin-top: 8px;
  font-size: 11px;
}
.starmap-pd__k {
  color: #63709a;
}
.starmap-pd__v {
  color: #e6ecff;
  margin-top: 2px;
}
.starmap-pd__scannote {
  margin-top: 15px;
  padding: 12px;
  border: 1px dashed rgba(120, 180, 255, 0.28);
  border-radius: 9px;
  text-align: center;
  font-size: 11px;
  color: #8b96ba;
}
/* Langstrecken-Analyse (Spec 2026-07-24): Remote-Scan-Steuerung + Radar-Scope. */
.starmap-pd__scanbtn {
  margin-top: 10px;
  cursor: pointer;
  text-align: center;
  font-family: 'Chakra Petch', sans-serif;
  font-weight: 600;
  letter-spacing: 0.14em;
  font-size: 12px;
  padding: 10px;
  border-radius: 8px;
  background: linear-gradient(90deg, #124b6b, #1a6f8a);
  color: #eafcff;
  border: 1px solid rgba(70, 180, 217, 0.5);
}
.starmap-pd__scanbtn:hover { filter: brightness(1.12); }
.starmap-pd__scanwarn {
  margin-top: 10px;
  padding: 10px 12px;
  border: 1px dashed rgba(224, 90, 74, 0.4);
  border-radius: 9px;
  text-align: center;
  font-size: 11px;
  color: #e0a44a;
}
.starmap-pd__scanhint {
  margin-top: 10px;
  font-size: 10.5px;
  color: #63709a;
  text-align: center;
}
.starmap-scan-scope {
  margin: 14px auto 4px;
  position: relative;
  width: 130px;
  height: 130px;
}
.starmap-scan-scope__ring,
.starmap-scan-scope__sweep {
  position: absolute;
  inset: 0;
  border-radius: 50%;
}
.starmap-scan-scope__ring {
  border: 1px solid rgba(70, 217, 208, 0.35);
  box-shadow: inset 0 0 0 24px rgba(70, 217, 208, 0.05), inset 0 0 0 48px rgba(70, 217, 208, 0.04);
}
.starmap-scan-scope__sweep {
  background: conic-gradient(from 0deg, rgba(70, 217, 208, 0.45), rgba(70, 217, 208, 0) 60deg, transparent);
  animation: starmap-scan-spin 1.1s linear infinite;
}
.starmap-scan-scope__pct {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 17px;
  color: #7fe9ff;
  letter-spacing: 0.06em;
}
@keyframes starmap-scan-spin {
  to { transform: rotate(360deg); }
}
.starmap-pd__res {
  margin-top: 8px;
}
.starmap-pd__res-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 10.5px;
  color: #aab4d4;
}
.starmap-pd__res-name {
  display: flex;
  align-items: center;
  gap: 6px;
}
.starmap-pd__res-tier {
  font-size: 8.5px;
  letter-spacing: 0.06em;
  padding: 1px 5px;
  border-radius: 4px;
}
.starmap-pd__res-pct {
  color: #7fe9ff;
}
.starmap-pd__res-bar {
  height: 5px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.06);
  margin-top: 3px;
  overflow: hidden;
}
.starmap-pd__res-bar > div {
  height: 100%;
  opacity: 0.85;
}
.starmap-sidepanel-divider {
  height: 1px;
  background: rgba(120, 180, 255, 0.14);
  margin: 18px 0 16px;
}
/* Kontext-Aktionen (Vorlage Z.356-366): Sonnensystem anzeigen / Basis besuchen. */
.starmap-cta {
  margin-top: 10px;
  text-align: center;
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: 0.14em;
  font-size: 12.5px;
  padding: 12px;
  border-radius: 9px;
}
.starmap-cta--system {
  background: linear-gradient(90deg, #1a2a52, #2a3f78);
  color: #cfe0ff;
  border: 1px solid rgba(120, 170, 255, 0.4);
}
.starmap-cta--base {
  background: linear-gradient(90deg, #1a3a2e, #256b4a);
  color: #d6ffe9;
  border: 1px solid rgba(95, 216, 138, 0.4);
}
.starmap-cta--guard {
  background: linear-gradient(90deg, rgba(25, 82, 83, 0.9), rgba(35, 116, 112, 0.9));
  color: #cafff8;
  border: 1px solid rgba(69, 230, 209, 0.55);
}
.starmap-cta--guard:hover {
  border-color: #45e6d1;
}
.starmap-cta--system:hover {
  border-color: rgba(120, 170, 255, 0.7);
}
/* Gate: "System betreten" ohne Flotte im System (Vorlage - nur mit Flotte). */
.starmap-cta--disabled {
  background: rgba(255, 255, 255, 0.04);
  color: #63709a;
  border: 1px solid rgba(120, 180, 255, 0.14);
  cursor: not-allowed;
}
.starmap-cta--disabled:hover {
  border-color: rgba(120, 180, 255, 0.14);
}
.starmap-cta--base:hover {
  border-color: rgba(95, 216, 138, 0.7);
}
/* Leerzustand (Vorlage Z.389-392). */
.starmap-empty {
  min-height: 62vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 20px;
  color: #63709a;
}
.starmap-empty__icon {
  width: 54px;
  height: 54px;
  border: 1px solid rgba(120, 180, 255, 0.25);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 18px;
  font-size: 22px;
  color: #46d9d0;
}
.starmap-empty__title {
  font-family: var(--font-heading);
  font-size: 15px;
  color: #aab4d4;
  letter-spacing: 0.06em;
}
.starmap-empty__hint {
  font-size: 11.5px;
  line-height: 1.6;
  margin-top: 10px;
  max-width: 230px;
}
.starmap-stat-bar {
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.06);
  overflow: hidden;
  margin-top: 4px;
}
.starmap-stat-bar__fill {
  height: 100%;
  background: var(--accent-bright);
}
.starmap-fleet-ship {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.starmap-fleet-ship__name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  color: var(--text-primary);
}
.starmap-fleet-ship__type {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  margin-top: 1px;
}
.starmap-fleet-ship-table {
  width: 100%;
  margin-top: 10px;
  border-collapse: collapse;
  font-size: 11.5px;
}
.starmap-fleet-ship-table th {
  text-align: left;
  font-size: 10px;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.starmap-fleet-ship-table td {
  padding: 5px 6px 5px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  vertical-align: middle;
}
.starmap-fleet-ship-table__stat-cell {
  width: 70px;
}
.starmap-fleet-ship-table__stat-value {
  font-size: 10px;
  color: var(--text-dim);
  white-space: nowrap;
}
.starmap-list-wrap {
  margin-top: 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.starmap-list-table {
  width: 100%;
  border-collapse: collapse;
}
.starmap-list-table th {
  text-align: left;
  font-size: 10.5px;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.starmap-list-table td {
  padding: 10px 16px;
  font-size: 12.5px;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
}
.starmap-list__row {
  cursor: pointer;
}
.starmap-list__row:hover {
  background: var(--surface-active);
}
.starmap-list__row--selected {
  background: var(--surface-active);
}
.starmap-list__home-tag {
  font-size: 9.5px;
  letter-spacing: 0.08em;
  color: var(--accent-gold);
  border: 1px solid rgba(255, 215, 106, 0.4);
  border-radius: 4px;
  padding: 1px 5px;
  margin-left: 6px;
}

/* — Systemansicht (Zone 10, Sprint 4) — */
.system-orbit-viewport {
  display: flex;
  flex-direction: column;
  padding: 20px;
}
.system-orbit-canvas {
  flex: 1;
  min-height: 380px;
  width: 100%;
  cursor: default;
}
.system-zoom-toolbar {
  display: flex;
  justify-content: flex-end;
  flex: none;
  margin-bottom: 10px;
}
.system-zoom-toolbar__back {
  cursor: pointer;
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 6px 14px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.system-zoom-canvas {
  flex: 1;
  min-height: 380px;
  width: 100%;
  border-radius: 10px;
  background: radial-gradient(120% 100% at 50% 40%, #0a0f22, #04050c 70%);
}
.system-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 12px;
}
.system-chip {
  cursor: pointer;
  font-size: 10.5px;
  padding: 5px 10px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 6px;
}
.system-chip--selected {
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.system-chip__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.system-aux-list {
  margin-top: 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.system-aux-row {
  display: flex;
  justify-content: space-between;
  padding: 10px 16px;
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.system-aux-row:last-child {
  border-bottom: none;
}
.system-aux-row:hover, .system-aux-row--selected {
  background: var(--surface-active);
}
.system-aux-row__meta {
  color: var(--text-dim);
}
.starmap-info-panel__open-btn {
  margin-top: 8px;
  text-align: center;
  cursor: pointer;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  color: var(--accent-gold);
  border: 1px solid rgba(255, 215, 106, 0.4);
  border-radius: var(--radius-md);
  padding: 8px;
}
.system-move-block {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.starmap-flightcalc {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 10px;
}
.starmap-flightcalc__card {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 8px 10px;
}
.starmap-flightcalc__label {
  font-size: 9px;
  letter-spacing: 0.14em;
  color: var(--text-dim);
}
.starmap-flightcalc__value {
  font-family: var(--font-heading);
  font-size: 17px;
  color: var(--text-primary);
  margin-top: 4px;
}
.starmap-flightcalc__unit {
  font-size: 10px;
  color: var(--text-muted);
}

/* ====================================================================
   Kurzinfo ueber dem Startknopf (Nutzerwunsch 2026-09-15): welche Flotte
   angewaehlt ist und was in ihr steckt. Bewusst gedraengt - sie sitzt in der
   schmalen Seitenleiste und darf den Knopf nicht aus dem Bild schieben.
   Die ausfuehrliche Fassung ist der Frachtbrief im Bestaetigungsdialog
   (.travel-confirm__*), an dessen Farben sich das hier anlehnt.
   ==================================================================== */
.starmap-travelbrief {
  margin-top: 10px;
  padding: 8px 10px;
  border: 1px solid rgba(120, 180, 255, .16);
  border-radius: var(--radius-md);
  background: rgba(20, 30, 54, .45);
}
.starmap-travelbrief__head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-heading);
  font-size: 12.5px;
  letter-spacing: .04em;
  color: #e6ecff;
}
.starmap-travelbrief__head i { color: #7fe9ff; font-size: 14px; }
/* Der Name darf kuerzen, die Schiffszahl nie - sie ist nur zwei Zeichen
   lang und beantwortet die Haelfte der Frage. */
.starmap-travelbrief__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.starmap-travelbrief__count {
  flex: 0 0 auto;
  font-family: 'Share Tech Mono', monospace;
  font-size: 10.5px;
  color: var(--text-dim);
}
.starmap-travelbrief__list {
  display: flex;
  flex-wrap: wrap;
  gap: 3px 12px;
  margin-top: 6px;
}
.starmap-travelbrief__item {
  font-size: 11.5px;
  color: #dbe3f7;
}
.starmap-travelbrief__mult {
  font-family: 'Share Tech Mono', monospace;
  color: #7fe9ff;
}
/* Ladung faellt auf - dieselbe Begruendung wie im Frachtbrief. */
.starmap-travelbrief__item--cargo { color: #e8c489; flex-basis: 100%; }
.starmap-travelbrief__item--cargo .starmap-travelbrief__mult { color: #e0a44a; }
.starmap-travelbrief__hint {
  margin-top: 5px;
  font-size: 11.5px;
  color: var(--text-muted);
}

.starmap-system:focus,
.starmap-list__row:focus,
.starmap-toolbar__btn:focus,
.system-chip:focus,
.system-aux-row:focus,
.starmap-info-panel__center-btn:focus,
.starmap-info-panel__open-btn:focus {
  outline: 2px solid var(--accent-bright);
  outline-offset: 2px;
}

/* — Beitritts-/Startpositions-Flow (join.php) — */
.join-shell {
  position: relative;
  z-index: 5;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
}
.join-panel {
  width: 100%;
  max-width: 760px;
  background: rgba(9, 12, 24, 0.92);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  padding: 28px 32px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  transition: max-width 220ms ease;
}

/* Der Zivilisationsschritt bekommt mehr Breite als die uebrigen (2026-08-21,
   Nutzerwunsch: "damit die bilder besser zur geltung kommen ... leicht
   unscharf").
   Die Spezieskarten sind 1536 px breit und tragen ihre Texte IM BILD. Bei den
   frueheren 640 px Panelbreite blieben davon rund 576 px - eine Verkleinerung
   auf gut ein Drittel, bei der gezeichnete Schrift zwangslaeufig weich wird.
   Mit 1240 px stehen etwa 1176 px zur Verfuegung, also nahezu 1:1.
   Nur dieser Schritt wird breit: das Grundformular mit 1200 px breiten
   Eingabefeldern saehe verloren aus. */
.join-panel--wide {
  max-width: 1240px;
}

.step-indicator {
  display: flex;
  gap: 6px;
  margin-bottom: 20px;
}
.step-indicator__dot {
  flex: 1;
  height: 3px;
  border-radius: 2px;
  background: rgba(120, 180, 255, 0.16);
}
.step-indicator__dot--done,
.step-indicator__dot--active {
  background: var(--accent);
}

.swatch-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.swatch {
  width: 34px;
  height: 34px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  border: 2px solid transparent;
}
.swatch--selected {
  border-color: var(--text-primary);
}
.emblem-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.emblem-choice {
  width: 42px;
  height: 42px;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  cursor: pointer;
  color: var(--text-dim);
  background: var(--surface);
  border: 1px solid var(--border);
}
.emblem-choice--selected {
  color: var(--accent-bright);
  background: var(--surface-active);
  border-color: var(--border-strong);
}

.field-hint {
  font-size: 10.5px;
  color: var(--text-dimmer);
  margin-top: 3px;
}
.field-error {
  font-size: 11px;
  color: var(--accent-red);
  margin-top: 4px;
}

.checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
}
.checkbox-row input {
  margin-top: 2px;
}

/* — Startpositionskarten — */
.option-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
  margin-top: 18px;
}
.option-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  cursor: pointer;
}
.option-card:hover {
  border-color: var(--border-strong);
}
.option-card__profile {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 14px;
  color: var(--text-primary);
}
.option-card__desc {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.5;
  min-height: 32px;
}
.option-card__rating {
  display: flex;
  justify-content: space-between;
  font-size: 10.5px;
  color: var(--text-dim);
}
.option-card__rating-value {
  color: var(--text-primary);
}

.countdown-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 18px;
  font-size: 11.5px;
  color: var(--text-muted);
}
.countdown-bar__extend {
  cursor: pointer;
  color: var(--accent);
}
.countdown-bar__extend:hover {
  color: var(--accent-bright);
}

.initializing-list {
  margin-top: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: 12.5px;
  color: var(--text-muted);
}

/* — Zone 11 Sprint 6: Erkundung/Scanberichte — */
.sensor-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-top: 12px;
}
.sensor-warning-btn {
  max-width: 280px;
}
.empty-state {
  text-align: center;
  padding: 40px 20px;
}
.empty-state__icon {
  display: flex;
  justify-content: center;
  margin-bottom: 14px;
}
.empty-state__title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 15px;
  color: var(--text-primary);
}
.empty-state__hint {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.5;
  margin-top: 6px;
  max-width: 360px;
  margin-left: auto;
  margin-right: auto;
}
.empty-state__action {
  display: inline-block;
  margin-top: 14px;
  padding: 8px 18px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  color: var(--accent-bright);
  font-size: 12px;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.empty-state__action:hover {
  border-color: var(--accent-bright);
  background: rgba(127, 233, 255, 0.08);
}
.empty-state--compact {
  padding: 24px 16px;
}
.picker-card {
  display: block;
  text-decoration: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px;
  cursor: pointer;
  transition: border-color 0.15s ease;
}
.picker-card:hover { border-color: var(--accent-bright); }
.picker-card__head { display: flex; align-items: center; gap: 10px; }
.picker-card__name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 16px;
  color: var(--text-primary);
}
.picker-card__status {
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--text-dim);
  margin-top: 12px;
}
.picker-card__meta {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 4px;
}
.admin-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-top: 12px;
}

/* Admin-Universumsdetail: Zwei-Spalten-Layout (Spec 2026-07-24). */
.admin-detail-cols {
  display: grid;
  grid-template-columns: minmax(300px, 380px) 1fr;
  gap: 20px;
  margin-top: 16px;
  align-items: start;
}
@media (max-width: 1000px) {
  .admin-detail-cols { grid-template-columns: 1fr; }
}
.admin-universe-controls {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  background: rgba(10, 14, 28, 0.6);
  border: 1px solid rgba(120, 180, 255, 0.16);
  border-radius: 10px;
}
.admin-universe-controls__status { font-size: 13px; color: #aab4d4; }
/* Startsignal (Spec 2026-08-20): angezeigter Rundenstart. */
.admin-universe-controls__start { font-size: 13px; color: #aab4d4; }
.admin-status-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: rgba(120, 180, 255, 0.14);
  color: #8fb4ff;
}
.admin-status-badge--active { background: rgba(95, 216, 138, 0.18); color: #5fd88a; }
.admin-status-badge--draft { background: rgba(224, 164, 74, 0.18); color: #e0a44a; }
.admin-universe-controls__gen { font-size: 12px; color: #8b96ba; }
.admin-universe-controls__gen--ok { color: #5fd88a; }
.admin-universe-controls__gen--fail { color: #e05a4a; }
.admin-universe-controls__quality--ok { font-size: 12px; color: #5fd88a; }
.admin-universe-controls__quality--fail { font-size: 12px; color: #e05a4a; }
.admin-status-btn { width: 100%; }

/* Admin-Toolbar: echte horizontale Buttons statt ungestylter Text-Links. */
.admin-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin: 14px 0;
}

/* Admin-Universum-Viewer (Spec 2026-07-24). */
.admin-starmap-wrap {
  margin-top: 12px;
  width: 100%;
  height: calc(100vh - 220px);
  min-height: 400px;
  border: 1px solid rgba(120, 180, 255, 0.16);
  border-radius: 10px;
  overflow: hidden;
  background: #060710;
}
.admin-starmap-svg { width: 100%; height: 100%; display: block; }
/* Farblegende der Admin-Universumskarte (Nutzerwunsch 2026-08-22). Die Karte
   faerbt nach Spieler-Id; ohne Legende war nicht ablesbar, wem welche Farbe
   gehoert. */
.admin-starmap-layout {
  display: flex;
  gap: 12px;
  align-items: stretch;
}
.admin-starmap-layout .admin-starmap-wrap { flex: 1; min-width: 0; }
.admin-starmap-legend {
  margin-top: 12px;
  width: 260px;
  flex: 0 0 260px;
  max-height: calc(100vh - 220px);
  overflow-y: auto;
  border: 1px solid rgba(120, 180, 255, 0.16);
  border-radius: 10px;
  background: rgba(10, 14, 28, 0.7);
  padding: 10px 12px;
}
.admin-starmap-legend__head {
  font-family: 'Chakra Petch', sans-serif;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #8fa0c8;
  margin-bottom: 8px;
}
.admin-starmap-legend__empty { font-size: 12px; color: #63709a; }
.admin-starmap-legend__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: 12px;
}
.admin-starmap-legend__swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  flex: 0 0 12px;
  border: 1px solid rgba(0, 0, 0, 0.5);
}
/* Objektlegende (Nutzerwunsch 2026-08-30): die Wischer sind dieselben
   SVG-Formen wie auf der Karte, damit die Legende die FORMEN erklaert und
   nicht nur Farben. Dieselbe Grundflaeche wie ein Farbwischer, damit die
   beiden Bloecke buendig untereinander stehen. */
.admin-starmap-legend__shape {
  flex: 0 0 18px;
  width: 18px;
  height: 18px;
  margin: 0 -3px;
  overflow: visible;
}
/* Spielerzeile als Schalter fuer die Hervorhebung auf der Karte. */
.admin-starmap-legend__row--clickable { cursor: pointer; border-radius: 5px; }
.admin-starmap-legend__row--clickable:hover { background: rgba(120, 180, 255, 0.08); }
.admin-starmap-legend__row--active {
  background: rgba(120, 180, 255, 0.14);
  box-shadow: inset 2px 0 0 var(--accent-bright);
}
.admin-starmap-legend__hint {
  font-size: 10.5px;
  color: #63709a;
  padding: 4px 0 8px;
  line-height: 1.4;
}
.admin-starmap-legend__hint--active {
  color: var(--accent-bright);
  cursor: pointer;
}
.admin-starmap-legend__hint--active:hover { text-decoration: underline; }
/* Zuklappbarer Piratenblock (Nutzerentscheidung 2026-08-31). */
.admin-starmap-legend__head--toggle {
  cursor: pointer;
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 5px;
}

/* Sektorhoheiten in der Admin-Legende (2026-09-05): die Organisation als
   Kopfzeile, ihre Mitglieder eingerueckt darunter. */
.admin-starmap-legend__row--group {
  margin-top: 6px;
  font-weight: 600;
}

.admin-starmap-legend__row--sub { padding-left: 14px; }

/* Ein Ring statt eines gefuellten Kaestchens: auf der Karte ist die Hoheit
   ein Umriss, und die Legende soll dieselbe Form zeigen. */
.admin-starmap-legend__swatch--ring {
  background: none !important;
  border: 2px solid currentColor;
  border-radius: 50%;
}
.admin-starmap-legend__head--toggle:hover { color: var(--accent-bright); }
.admin-starmap-legend__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #dbe4ff;
}
.admin-starmap-legend__counts {
  color: #8fa0c8;
  font-size: 11px;
  white-space: nowrap;
}
@media (max-width: 900px) {
  .admin-starmap-layout { flex-direction: column; }
  .admin-starmap-legend { width: auto; flex: 0 0 auto; max-height: 220px; }
}
.starmap-toolbar__info { color: #8b96ba; font-size: 12px; align-self: center; margin-left: 12px; }

.scan-report-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}

.scan-report-row {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  cursor: pointer;
}

.scan-report-row--unread {
  border-color: var(--accent-bright);
}

.scan-report-row__header {
  display: flex;
  align-items: center;
  gap: 10px;
}

.scan-report-row__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-bright);
  flex-shrink: 0;
}

.scan-report-row__title {
  flex: 1;
}

.scan-report-row__date {
  color: var(--text-muted);
  font-size: 0.85em;
}

.scan-report-row__details {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.scan-report-anomaly {
  color: var(--accent-gold);
}

/* Die Aktionen einer Anomalie AM Objekt (2026-09-12). Eingerückt und mit
   Randlinie, weil ein Planet mehrere Anomalien tragen kann und sonst nicht
   erkennbar wäre, welcher Knopf zu welchem Phänomen gehört. */
.anomaly-actions {
  margin: 4px 0 8px 9px;
  padding-left: 9px;
  border-left: 1px solid rgba(255, 215, 106, .25);
}
.anomaly-actions:empty {
  display: none;
}

.sensor-contact-row__level {
  font-weight: 600;
  min-width: 90px;
}

.sensor-contact-row__warning {
  color: #0b0f1a;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
}

.sensor-contact-detail {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sensor-mode-select {
  background: var(--surface-2, #131a2c);
  color: var(--text-body);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 2px 6px;
  font-family: inherit;
  font-size: 0.85rem;
}

.starmap-contact-marker {
  position: absolute;
  transform: translate(-50%, -50%);
  cursor: pointer;
}

/* Reputationsausrichtung als Zielrechteck. Die Farbe kommt aus dem kleinen
   gemeinsamen JS-Modul; Piraten und nicht identifizierte Kontakte rendern
   den Baustein gar nicht. */
.starmap-reputation-frame {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 30px;
  height: 34px;
  transform: translate(-50%, -50%);
  border: 1.5px solid currentColor;
  box-shadow: 0 0 7px currentColor, inset 0 0 5px color-mix(in srgb, currentColor 35%, transparent);
  opacity: 0.82;
  pointer-events: none;
}

.starmap-contact-marker__ring {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 1px dashed;
  border-radius: 50%;
  opacity: 0.5;
  pointer-events: none;
}

/* Der Fortschrittsring einer laufenden Flottenanalyse (2026-09-05).
 *
 * Er sitzt ENGER als der Konfidenzring (.starmap-contact-marker__ring), der
 * je nach Kenntnisstand zwischen 40 und 200 px misst - ein Fortschritt, der
 * seine Groesse mit dem Kontakt aendert, waere nicht vergleichbar. Feste
 * 40 px, direkt um das Dreieck.
 *
 * Der Strich laeuft ueber stroke-dashoffset zu; der Sekundentakt in game.js
 * schreibt den Wert fort. transform: rotate(-90deg) laesst ihn oben statt
 * rechts beginnen - eine Uhr, die bei drei Uhr anfaengt, liest niemand. */
.starmap-contact-marker__analysis {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 40px;
  height: 40px;
  transform: translate(-50%, -50%) rotate(-90deg);
  pointer-events: none;
  overflow: visible;
}

.starmap-contact-marker__analysis-track {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  opacity: 0.18;
}

.starmap-contact-marker__analysis-fill {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  filter: drop-shadow(0 0 3px currentColor);
  /* Eine Sekunde: genau der Abstand zwischen zwei Schlaegen des Taktes, damit
     der Strich gleitet statt zu springen. `linear` und nicht `ease`, weil
     eine gleichmaessig verrinnende Zeit auch gleichmaessig aussehen soll. */
  transition: stroke-dashoffset 1s linear;
}

@media (prefers-reduced-motion: reduce) {
  .starmap-contact-marker__analysis-fill { transition: none; }
}

/* Die Fortschrittsringe an der eigenen Flotte: Bergung (Nutzerwunsch
   2026-09-11: "wie bei Piraten, die analysiert werden") und seit 2026-09-13
   auch die Anomalieuntersuchung. Dieselbe Form wie oben, nur groesser - das
   Schiffssymbol ist breiter als ein Kontaktpunkt.

   DIE FARBE STEHT IM JS, nicht hier: Sie kommt als `color` am SVG an, und
   Rand wie Schein leiten sich mit `currentColor` davon ab. Die Klassen
   --salvage und --investigation sind deshalb nur Haken zum Wiederfinden; sie
   tragen selbst keine Farbe, und ein Ring ohne passende Regel bliebe
   trotzdem sichtbar. */
.starmap-map-ship__salvage {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 46px;
  height: 46px;
  transform: translate(-50%, -50%) rotate(-90deg);
  pointer-events: none;
  overflow: visible;
}

.starmap-map-ship__salvage-track {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  opacity: 0.18;
}

.starmap-map-ship__salvage-fill {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  filter: drop-shadow(0 0 3px currentColor);
  transition: stroke-dashoffset 1s linear;
}

@media (prefers-reduced-motion: reduce) {
  .starmap-map-ship__salvage-fill { transition: none; }
}

/* Nur Haken, keine Farbe - siehe oben. Die Bergung liegt eine Spur weiter
   aussen als die Untersuchung: Sollte doch einmal beides zugleich laufen,
   stehen zwei Ringe nebeneinander statt uebereinander. */
.starmap-map-ship__ring--salvage { width: 46px; height: 46px; }
.starmap-map-ship__ring--investigation { width: 52px; height: 52px; }
/* Der dritte Ring (Artefaktbergung, 2026-09-14). Wieder sechs Pixel weiter
   aussen als der davor: Die drei Arbeiten koennen nicht gleichzeitig laufen,
   aber faende sich doch ein Weg dazu, laegen die Ringe nebeneinander statt
   uebereinander - und das faellt auf, statt sich zu verstecken. */
.starmap-map-ship__ring--recovery { width: 58px; height: 58px; }

/*
 * Das Warndreieck an einem bedrohlichen Sensorkontakt (2026-08-25).
 *
 * Reines CSS-Dreieck ueber Rahmenkanten - kein Bild, keine Schriftart. Es
 * sitzt UEBER dem Punkt, damit die Silhouette auch dann lesbar bleibt, wenn
 * Punkt und Stern dicht beieinanderstehen.
 */
.starmap-contact-marker__alert {
  position: absolute;
  left: 50%;
  bottom: 9px;
  width: 0;
  height: 0;
  transform: translateX(-50%);
  border-left: 7px solid transparent;
  border-right: 7px solid transparent;
  border-bottom: 12px solid currentColor;
  filter: drop-shadow(0 0 4px currentColor);
  animation: pulsering 1.8s ease-out infinite;
  pointer-events: none;
}

.starmap-contact-marker__triangle {
  position: relative;
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 11px solid currentColor;
  filter: drop-shadow(0 0 4px currentColor);
}

.starmap-contact-marker.is-stale {
  opacity: 0.48;
}

.starmap-contact-marker.is-stale .starmap-contact-marker__ring {
  border-style: dotted;
}

/* Kontakt im Nebel (Nutzerwunsch 2026-09-03): sichtbar, damit man weiss, dass
   sich dort etwas bewegt - aber nicht bedienbar, genau wie ein vernebelter
   Stern. pointer-events: none laesst den Klick zum Stern darunter durch,
   statt ihn zu verschlucken. */
.starmap-contact-marker.is-fogged {
  opacity: 0.34;
  filter: grayscale(0.75) blur(0.4px);
  pointer-events: none;
  cursor: default;
}
.starmap-contact-marker.is-fogged .starmap-contact-marker__ring {
  border-style: dashed;
}

/* Die Nullflotte (Nutzerwunsch 2026-09-15: "Nullflotten muessen sich von
   anderen Piraten oder boesen Spielern abheben. bedrohlicher, anderes icon,
   effekt um die Flotte").

   DREI ZEICHEN, die zusammen wirken: eine eigene Farbe (sie kommt aus
   NULL_FLEET_META in game.js, nicht von hier), die Spirale statt des
   Totenkopfs - und dieser Schein, der langsam atmet.

   DER SCHEIN IST EIN EIGENES ELEMENT unter dem Dreieck. Eine Animation am
   Marker selbst haette ihn von seinen Koordinaten geschoben: er wird ueber
   left/top positioniert, und `transform: scale()` verschiebt dann auch das
   Klickfeld. */
.starmap-contact-marker__void {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(176, 76, 255, 0.42) 0%,
    rgba(176, 76, 255, 0.14) 45%,
    transparent 70%);
  animation: nullfleet-breath 2.6s ease-in-out infinite;
  pointer-events: none;
  z-index: 0;
}

@keyframes nullfleet-breath {
  0%, 100% { transform: scale(0.82); opacity: 0.5; }
  50% { transform: scale(1.2); opacity: 1; }
}

/* Das Dreieck leuchtet aus dem Schein heraus - doppelter Schlagschatten statt
   des einfachen, den alle anderen Kontakte tragen. */
.starmap-contact-marker.is-nullfleet .starmap-contact-marker__triangle {
  filter: drop-shadow(0 0 7px currentColor) drop-shadow(0 0 14px currentColor);
  z-index: 1;
}

/* Durchgezogen statt gestrichelt: Beim Nullprotokoll ist nicht die Frage, wie
   sicher der Kontakt ist. */
.starmap-contact-marker.is-nullfleet .starmap-contact-marker__ring {
  border-style: solid;
  opacity: 0.7;
}

/* Das Auswahlquadrat um einen fremden Kontakt (Nutzerwunsch 2026-09-20:
   "Aktuell sieht man nicht, das man sie ausgewaehlt hat").

   ECKIG MIT ABSICHT: Der Marker traegt schon einen Ring (den Sensorradius)
   und bei bekanntem Ruf einen farbigen Rahmen. Ein dritter runder Rahmen
   waere von beiden nicht zu unterscheiden.

   AUF ::before UND NICHT ::after: Das ::after des Kontaktmarkers gehoert dem
   Lokalisieren (starmap-contact-marker--located) - und genau dort trifft es
   sich, denn wer einen Kontakt sucht, waehlt ihn danach aus. Zwei Regeln auf
   demselben Pseudoelement, und eine der beiden verschwindet stillschweigend.

   GROESSER ALS DER REPUTATIONSRAHMEN (30x34): Das Quadrat liegt aussen
   herum, damit beides nebeneinander lesbar bleibt. */
.starmap-contact-marker.is-selected::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 38px;
  height: 38px;
  transform: translate(-50%, -50%);
  border: 1.5px solid rgba(180, 230, 255, 0.9);
  box-shadow: 0 0 8px rgba(120, 200, 255, 0.5);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .starmap-contact-marker__void {
    animation: none;
    opacity: 0.8;
  }
}

/* Dasselbe Violett im DEFCON-Reiter und im Kontaktpanel - ein Zeichen, eine
   Farbe, egal wo es steht. */
.starmap-defcon__void {
  color: #b04cff;
}

.starmap-info-panel__hint--void {
  color: #d6b3ff;
  border-left: 2px solid #b04cff;
  padding-left: 8px;
  margin-top: 0;
  margin-bottom: 8px;
}

.scan-mode-row {
  display: flex;
  gap: 6px;
  margin-bottom: 10px;
}

.scan-mode-btn {
  flex: 1;
  text-align: center;
  padding: 6px 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 0.8em;
}

.scan-mode-btn--selected {
  border-color: var(--accent-bright);
  color: var(--accent-bright);
}

.mining-risk-badge {
  font-weight: 600;
}

.mining-risk-badge--safe {
  color: var(--accent-bright);
}

.mining-risk-badge--low {
  color: #5fd88a;
}

.mining-risk-badge--moderate {
  color: var(--accent-gold);
}

.mining-risk-badge--high {
  color: #e05a4a;
}

/* — Mobil (Abschnitt 21 des Zone-5-Plans): Sidebar bleibt schmale
   Icon-Leiste mit 44x44px-Touch-Zielen (Barrierefreiheits-Minimum),
   Ressourcen zweispaltig statt vierspaltig, Gebäudekarten einspaltig
   untereinander, weniger Rand für mehr nutzbare Breite. — */
@media (max-width: 640px) {
  :root {
    --sidebar-width: 56px;
  }
  .app-sidebar__item {
    width: 44px;
    min-height: 44px;
    padding: 0;
  }
  .app-sidebar__item i {
    font-size: 18px;
  }
  .app-sidebar__label {
    display: none;
  }
  .app-main {
    padding: 18px 14px 32px;
  }
  .dashboard-title {
    font-size: 22px;
  }
  .dashboard-meta {
    gap: 14px;
  }
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }
  .card-grid--buildings {
    grid-template-columns: 1fr;
  }
  .starmap-shell {
    flex-direction: column;
  }
  .starmap-sidepanel {
    width: auto;
  }
  .starmap-viewport {
    height: 400px;
  }
  .join-shell {
    padding: 16px;
  }
  .join-panel {
    padding: 20px 18px;
  }
  /* Auf schmalen Schirmen greift die Breite ohnehin nicht - die Regel wuerde
     nur das Padding gegen den Rand druecken. */
  .join-panel--wide {
    max-width: 760px;
  }
  .option-grid {
    grid-template-columns: 1fr;
  }
}

/* ══════════════════════════════════════════════════════════════════
   Komponenten-Kit (Sprint 0 Design-Angleichung)
   Wird von public/assets/js/kit.js (window.SCKit) erzeugt.
   Farb-/Größen-Parameter kommen als inline Custom-Properties.
   ══════════════════════════════════════════════════════════════════ */

.icon-tile {
  width: var(--tile-size, 42px);
  height: var(--tile-size, 42px);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--tile-color, var(--accent)) 13%, transparent);
  color: var(--tile-color, var(--accent));
  display: flex; align-items: center; justify-content: center;
  font-size: calc(var(--tile-size, 42px) * 0.47);
  flex: none;
}

.cost-chip {
  display: inline-flex; align-items: center;
  font-size: 10.5px; padding: 3px 8px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--chip-color, var(--accent)) 10%, transparent);
  color: var(--chip-color, var(--accent));
  border: 1px solid color-mix(in srgb, var(--chip-color, var(--accent)) 33%, transparent);
  white-space: nowrap;
}

.hud-stat {
  display: flex; align-items: center; gap: 7px;
  padding: 0 14px; height: 22px; flex: none;
  border-right: 1px solid rgba(120, 180, 255, 0.1);
}
.hud-stat > i { font-size: 15px; color: var(--stat-color, var(--accent)); }
.hud-stat__text { display: flex; flex-direction: column; line-height: 1.05; }
.hud-stat__value {
  font-family: var(--font-heading); font-weight: 600; font-size: 12.5px;
  color: var(--text-primary); letter-spacing: 0.02em;
}
.hud-stat__label {
  font-size: 8.5px; letter-spacing: 0.1em; color: var(--text-dim); white-space: nowrap;
}

.progress-bar {
  height: 6px; border-radius: 4px;
  background: rgba(255, 255, 255, 0.06); overflow: hidden;
}
.progress-bar__fill {
  height: 100%; border-radius: 4px;
  background: var(--bar-color, var(--accent)); transition: width 0.2s;
}

.section-panel {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 26px 28px;
}
.section-panel__head { display: flex; align-items: center; gap: 14px; }
.section-panel__title {
  font-family: var(--font-heading); font-weight: 700; font-size: 19px;
  color: var(--text-primary); letter-spacing: 0.03em;
}
.section-panel__status { font-size: 11px; color: var(--text-dim); letter-spacing: 0.08em; margin-top: 2px; }
.section-panel__divider { height: 1px; background: rgba(120, 180, 255, 0.12); margin: 20px 0; }

.ship-figure { display: block; width: 56px; height: 70px; filter: drop-shadow(0 0 6px var(--fig-accent, var(--accent))); }
.resource-figure { display: block; width: 56px; height: 84px; filter: drop-shadow(0 0 6px var(--fig-accent, var(--accent))); }

.glow-accent { box-shadow: var(--glow-md) color-mix(in srgb, var(--accent) 40%, transparent); }

/* ══════════════════════════════════════════════════════════════════
   Hauptmenü / Login — Port aus Hauptmenue.dc.html (Sprint 1 Entry)
   ══════════════════════════════════════════════════════════════════ */

.menu-grid {
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(76, 116, 196, 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(76, 116, 196, 0.07) 1px, transparent 1px);
  background-size: 46px 46px;
}
.menu-vignette {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(60% 55% at 50% 52%, transparent 0%, rgba(4, 5, 12, 0.55) 62%, rgba(4, 5, 12, 0.92) 100%);
}
.menu-ring {
  position: absolute; left: 50%; top: 50%; border-radius: 50%;
  transform: translate(-50%, -50%); pointer-events: none;
}
.menu-ring--inner { width: 520px; height: 520px; border: 1px solid rgba(70, 217, 208, 0.1); }
.menu-ring--outer { width: 760px; height: 760px; border: 1px dashed rgba(70, 217, 208, 0.07); }

@keyframes menuOrbit {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to { transform: translate(-50%, -50%) rotate(360deg); }
}
.menu-orbit {
  position: absolute; transform: translate(-50%, -50%);
  width: var(--orbit-size, 80px); height: var(--orbit-size, 80px);
  animation: menuOrbit var(--orbit-dur, 40s) linear infinite; pointer-events: none;
}
.menu-orbit__planet {
  position: absolute; left: 50%; top: 0; width: 4px; height: 4px;
  border-radius: 50%; transform: translate(-50%, -50%);
  background: var(--planet-color, #c9d0e0); box-shadow: 0 0 5px var(--planet-color, #c9d0e0);
}

.auth-cols {
  display: flex; align-items: stretch; gap: 28px;
  /* Nutzerwunsch 2026-09-01: mehr Platz links. Das Panel traegt jetzt acht
     Kennzahlen und acht Merkmale statt vier Saetzen - mit 920 px stand die
     Anmeldekarte darunter statt daneben. */
  max-width: 1180px; width: 100%; flex-wrap: wrap; justify-content: center; margin: auto;
}
.lore-panel {
  flex: 1 1 460px; max-width: 620px;
  background: rgba(9, 12, 24, 0.86); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 26px 30px; backdrop-filter: blur(2px);
}
.lore-panel__eyebrow { font-size: 10.5px; letter-spacing: 0.28em; color: var(--accent); }
.lore-panel__title {
  font-family: var(--font-heading); font-weight: 700; font-size: 34px;
  letter-spacing: 0.03em; color: var(--text-primary); margin-top: 10px; line-height: 1.1;
}
.lore-panel__desc { font-size: 12.5px; color: var(--text-muted); margin-top: 14px; line-height: 1.6; }
/* Zwei Spalten fuer die acht Merkmale - untereinander waere das Panel
   deutlich hoeher als die Anmeldekarte daneben. */
.lore-features {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px 18px;
}
@media (max-width: 900px) {
  .lore-features { grid-template-columns: 1fr; }
}

/* "30 Tage angemeldet bleiben" (Nutzerwunsch 2026-09-01). Bewusst schlicht:
   die Anmeldekarte lebt von wenigen, klaren Feldern. */
.auth-remember { margin-top: 2px; }
.auth-remember__label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  cursor: pointer;
}
.auth-remember__label:hover { color: var(--text-primary); }
.auth-remember__box {
  width: 14px;
  height: 14px;
  accent-color: var(--accent-bright);
  cursor: pointer;
}
.lore-feature { display: flex; align-items: flex-start; gap: 11px; margin-top: 12px; }
.lore-feature__dot {
  flex: none; width: 8px; height: 8px; border-radius: 2px; margin-top: 4px;
  background: var(--feat-color, var(--accent)); box-shadow: 0 0 6px var(--feat-color, var(--accent));
}
.lore-feature__title {
  font-family: var(--font-heading); font-weight: 600; font-size: 12.5px;
  letter-spacing: 0.05em; color: #cfe0ff;
}
.lore-feature__desc { font-size: 11px; color: var(--text-dim); margin-top: 2px; line-height: 1.5; }
.auth-card {
  flex: 1 1 340px; max-width: 380px;
  background: rgba(9, 12, 24, 0.92); border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg); padding: 24px 28px 22px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

/* Join-Startoptionen — Kit-Aufwertung (Sprint 1 Entry) */
.option-card__head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }

/* ══════════════════════════════════════════════════════════════════
   Basis-Hub (Overview) — Port aus Basis.dc.html (Sprint 2)
   ══════════════════════════════════════════════════════════════════ */

/* Die Schnellzugriffskacheln ("Basis-Sektionen") sind am 2026-08-20 entfallen -
   dieselben Ziele stehen im Menue. */

/* Status-Box Icon-Bereich nimmt jetzt eine Kit-Icon-Kachel auf (Sprint 2) */
.status-box__icon { display: flex; align-items: center; justify-content: center; padding: 0; background: none; }

/* ══════════════════════════════════════════════════════════════════
   Werft-Schiffskarten — Port aus Basis.dc.html (Sprint 3)
   ══════════════════════════════════════════════════════════════════ */

.ship-card__header { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 6px; }
.ship-card__heading { flex: 1; min-width: 0; }
.ship-card__cost-label {
  font-size: 10px; letter-spacing: 0.1em; color: var(--text-dim);
  margin-top: 12px; margin-bottom: 7px;
}
/* .ship-card__cost war eine Textzeile — jetzt Chip-Container */
.ship-card__cost { display: flex; gap: 6px; flex-wrap: wrap; }

/* ══════════════════════════════════════════════════════════════════
   Gebäude-/Tech-Karten — Kit-Aufwertung (Sprint 4)
   ══════════════════════════════════════════════════════════════════ */

.card-icon-head { display: flex; gap: 12px; align-items: center; margin-bottom: 8px; }
.card-icon-head__group { flex: 1; min-width: 0; }
.cost-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }

/* ══════════════════════════════════════════════════════════════════
   System-Detail Seitenpanel — chirurgischer Kit-Slice (Sprint 5)
   .starmap-info-panel* bleibt unveraendert (auch von der Starmap genutzt);
   nur diese neuen Kompositions-Klassen kommen hinzu.
   ══════════════════════════════════════════════════════════════════ */

.panel-eyebrow-head { display: flex; align-items: center; gap: 9px; margin-bottom: 4px; }
.resource-analysis-head { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.resource-analysis-head .resource-figure { width: 30px; height: 45px; }

/* --- Techtree Sprint 2: Stat-Zeile (view-uebergreifend) --- */
.stat-row {
  display: grid;
  grid-template-columns: 84px 1fr 44px;
  gap: 10px;
  align-items: center;
  margin-bottom: 6px;
}
.stat-row__label {
  font-size: 10.5px;
  color: var(--text-dim);
}
.stat-row__bar {
  height: 6px;
  background: rgba(120, 180, 255, 0.08);
  border-radius: 4px;
  overflow: hidden;
}
.stat-row__fill {
  height: 100%;
  border-radius: 4px;
  background: var(--bar-color, var(--accent));
}
.stat-row__value {
  font-size: 11px;
  color: var(--text-primary);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* --- Techtree Sprint 2: Schaltet-frei-Box --- */
.unlock-box {
  background: rgba(70, 217, 208, 0.08);
  border: 1px solid rgba(70, 217, 208, 0.3);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  margin: 10px 0;
}
.unlock-box__head {
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 6px;
}
.unlock-box__item {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  color: var(--text-primary);
  margin-bottom: 4px;
}
.unlock-box__item i {
  color: var(--accent);
  font-size: 13px;
}

/* --- Techtree Sprint 2: Voraussetzungs-Box --- */
.requirement-box {
  background: rgba(224, 90, 74, 0.07);
  border: 1px solid rgba(224, 90, 74, 0.28);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  margin: 10px 0;
}
.requirement-box__head {
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-red);
  margin-bottom: 6px;
}
.requirement-box__item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--text-primary);
  margin-bottom: 4px;
}
.requirement-box__badge {
  font-size: 8px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(120, 180, 255, 0.1);
  border: 1px solid var(--border);
  color: var(--text-dim);
  flex-shrink: 0;
}

/* Nutzervorgabe 2026-07-26: blockierende Hinweise (z.B. "Hyperraumantrieb
   muss erforscht sein") auf der Sternenkarte statt einer schlichten Zeile
   als auffaellige rot umrandete Box mit Warnschild-Icon. */
.warning-box {
  background: rgba(224, 90, 74, 0.1);
  border: 1px solid var(--accent-red);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  margin: 10px 0;
}
.warning-box__item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 12px;
  color: var(--text-primary);
}
.warning-box__item + .warning-box__item {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid rgba(224, 90, 74, 0.2);
}
.warning-box__icon {
  color: var(--accent-red);
  font-size: 18px;
  flex-shrink: 0;
  line-height: 1.4;
}
.warning-box__message {
  line-height: 1.4;
}

.info-box {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  background: rgba(120, 180, 255, 0.06);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  margin: 0 0 14px;
}
.info-box__icon { flex-shrink: 0; }
.info-box__title { font-size: 12px; font-weight: 600; color: var(--text-primary); margin-bottom: 3px; }
.info-box__text { font-size: 11.5px; color: var(--text-muted); line-height: 1.5; }

/* --- Techtree Sprint 2: Detail-Panel --- */
.detail-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  position: sticky;
  top: 16px;
}
.detail-panel--empty {
  color: var(--text-dim);
  font-size: 12px;
  text-align: center;
  padding: 40px 18px;
}
.detail-panel__head { display: flex; gap: 12px; align-items: center; margin-bottom: 10px; }
.detail-panel__name { font-family: var(--font-heading); font-weight: 600; font-size: 15px; color: var(--text-primary); }
.detail-panel__sub { font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-dim); margin-top: 3px; }
.detail-panel__desc { font-size: 11.5px; color: var(--text-muted); line-height: 1.5; margin-bottom: 10px; }
.detail-panel__label { font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-dim); margin: 12px 0 6px; }
.detail-panel__time { font-size: 11px; color: var(--text-dim); margin-top: 4px; }
.detail-panel__maxed { font-size: 11px; color: var(--accent-gold); margin-top: 8px; }
.detail-panel__chip { display: inline-block; font-size: 10.5px; padding: 3px 8px; border-radius: var(--radius-sm); background: rgba(120,180,255,0.08); color: var(--text-muted); margin: 0 4px 4px 0; }
.detail-panel__action {
  display: block; width: 100%; margin-top: 12px; padding: 9px;
  border-radius: var(--radius-sm); border: 1px solid var(--accent);
  background: rgba(70, 217, 208, 0.12); color: var(--accent);
  font-size: 12px; cursor: pointer;
}
.detail-panel__action:disabled { border-color: var(--border); background: transparent; color: var(--text-dim); cursor: not-allowed; }

/* Erweiterte Bauplanung im Forschungsmodal - bewusst zurueckgenommen
   gegenueber "Jetzt erforschen", weil der Knopf nichts sofort startet. */
.detail-panel__action--queue { color: var(--text-dim); border-style: dashed; }
.detail-panel__action--queue:hover:not(:disabled) {
  color: var(--accent); border-color: var(--accent); border-style: solid;
}
.detail-panel__action--queued {
  color: var(--warning, #e0a44a);
  border-color: color-mix(in srgb, var(--warning, #e0a44a) 45%, transparent);
  border-style: dashed;
}
.detail-panel__action--queued:hover:not(:disabled) {
  border-color: var(--warning, #e0a44a); border-style: solid;
}

/* --- Techtree Sprint 2: Forschungs-Layout --- */
/* Baum: 4 Spalten je Reihe (8 Kategorien = 2 Reihen), feste Spaltenbreite und
   linksbuendig - skaliert NICHT auf die volle Seitenbreite, rechts bleibt Platz.
   Das Detail erscheint als zentriertes Modal beim Klick auf eine Technologie. */
.research-filters {
  display: flex; flex-wrap: wrap; gap: 14px;
  align-items: center;
  margin: 0 0 14px;
}

/* "7 von 19 Gebaeuden" neben den Haken (2026-09-05). Sie steht nur da, wenn
   ein Filter wirklich etwas wegnimmt - sonst waere sie eine Zahl ohne Anlass. */
.research-filters__count {
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.research-tree { display: grid; grid-template-columns: repeat(4, 330px); gap: 16px; justify-content: start; }
.tech-col { background: var(--surface-2, rgba(13, 21, 36, 0.5)); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 14px; }
.tech-col__head { display: flex; align-items: center; gap: 6px; margin-bottom: 12px; }
.tech-col__title { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--col-color, var(--accent)); flex: 1; }
.tech-col__count { font-size: 9.5px; color: var(--text-dim); border: 1px solid var(--border); border-radius: 20px; padding: 1px 8px; }
.tech-col__arrow { text-align: center; color: var(--text-dim); font-size: 12px; margin: 3px 0; }
/* Nutzeranfrage 2026-08-01: der Knoten traegt jetzt den Forschungsfortschritt
   und bei forschbaren Technologien die Kostenliste. Deshalb SPALTE statt Zeile -
   Name und Status bleiben in .tech-node__row zusammen, darunter die Kosten.
   position/overflow tragen die Fuellschicht: sie liegt hinter dem Inhalt und
   darf nicht ueber die abgerundeten Ecken hinauslaufen. */
.tech-node {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 6px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 10px 12px; cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.tech-node:hover { background: rgba(70, 217, 208, 0.06); }
.tech-node__row { display: flex; align-items: center; gap: 8px; position: relative; z-index: 1; }
.tech-node__name { font-size: 12.5px; color: var(--text-primary); }
.tech-node__tag { font-size: 9px; color: var(--text-dim); margin-left: auto; white-space: nowrap; }
/* Der laufende Knoten behaelt die normale Hoehe seiner Nachbarn: der
   Abbrechen-Knopf ist absolut positioniert und treibt die Zeilenhoehe deshalb
   nicht mehr mit. --tech-cancel-w haelt Knopfbreite und Balkenbahn zusammen,
   damit beide nicht auseinanderlaufen, wenn die Breite spaeter angepasst wird. */
.tech-node--running {
  border-color: rgba(143, 224, 160, 0.7); cursor: default;
  --tech-cancel-w: 32px;
}
/* Bahn des Fortschrittsbalkens (Nutzervorgabe 2026-08-01): volle Hoehe bis an
   den Rand, waagerecht aber nur bis 2px vor den Abbrechen-Knopf. Der Knopf
   selbst haelt 2px Abstand zum Rahmen, macht zusammen die 4px im right-Wert.
   Die Bahn ist noetig, damit sich der Prozentwert auf die SICHTBARE Strecke
   bezieht - ohne sie liefe der Balken unter dem Knopf hindurch und die letzten
   Prozent waeren verdeckt. */
.tech-node__track {
  position: absolute; left: 0; top: 0; bottom: 0;
  right: calc(var(--tech-cancel-w, 32px) + 4px);
  overflow: hidden;
}
.tech-node__fill {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, rgba(143, 224, 160, 0.28), rgba(70, 217, 208, 0.28));
  transition: width 0.9s linear;
}
.tech-node__tag--running {
  color: var(--accent-green); font-size: 10px;
  font-variant-numeric: tabular-nums;
}
/* Platz fuer den absolut positionierten Knopf freihalten - ohne das rutschte
   die Restzeit darunter, weil sie per margin-left: auto nach rechts geht. */
.tech-node--running .tech-node__row {
  padding-right: calc(var(--tech-cancel-w, 32px) + 8px);
}
/* Nutzervorgabe 2026-08-01: je 2px Abstand zum Rahmen oben, rechts und unten.
   Absolut positioniert statt in der Zeile - dadurch bestimmt der Knopf die
   Knotenhoehe nicht mehr mit (der laufende Knoten bleibt so hoch wie seine
   Nachbarn) und seine Hoehe ergibt sich umgekehrt aus dem Knoten. */
.tech-node__cancel {
  position: absolute; top: 2px; right: 2px; bottom: 2px;
  width: var(--tech-cancel-w, 32px); padding: 0;
  /* PFLICHT, nicht Kosmetik: der Knopf traegt zusaetzlich die Klasse
     progress-box__cancel-btn (fuer attachProgressBoxCancelHandlers), und die
     bringt margin-top: 12px mit. Bei einem absolut positionierten Element mit
     top UND bottom geht dieser Aussenabstand in die Hoehengleichung ein - der
     Knopf sass dadurch 14px unter dem Rand und war nur 18px statt 30px hoch. */
  margin: 0;
  z-index: 2;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm);
  border: 1px solid rgba(224, 90, 74, 0.4);
  background: rgba(224, 90, 74, 0.12);
  color: #e08a7a; font-size: 14px; cursor: pointer; line-height: 1;
}
.tech-node__cancel:hover { border-color: var(--accent-red); }
/* Aktionsknopf direkt im Baumknoten (Nutzerwunsch 2026-09-02). Volle Breite
   unter den Kosten - der Knoten ist schmal, ein rechtsbuendiger Knopf haette
   dort zu wenig Platz fuer seine Beschriftung. */
.tech-node__action {
  display: block;
  width: 100%;
  margin-top: 8px;
  padding: 6px 8px;
  font-family: var(--font-body);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-bright);
  background: rgba(127, 233, 255, 0.08);
  border: 1px solid rgba(127, 233, 255, 0.35);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.tech-node__action:hover:not(:disabled) {
  background: rgba(127, 233, 255, 0.16);
  border-color: var(--accent-bright);
}
.tech-node__action:disabled { opacity: 0.5; cursor: default; }
/* Vorgemerkt und Einreihen in Gold statt Cyan: die Warteschlange ist eine
   andere Zusage als "jetzt sofort". */
.tech-node__action--queue,
.tech-node__action--queued {
  color: var(--accent-gold);
  background: rgba(255, 215, 106, 0.08);
  border-color: rgba(255, 215, 106, 0.35);
}
.tech-node__action--queue:hover:not(:disabled),
.tech-node__action--queued:hover:not(:disabled) {
  background: rgba(255, 215, 106, 0.16);
  border-color: var(--accent-gold);
}
/* Kostenliste im Knoten: dieselbe Darstellung wie in den Gebaeudekacheln,
   nur ohne die aeusseren Trennlinien - im schmalen Knoten wirkten sie wie ein
   zweiter Rahmen im Rahmen. */
.tech-node .build-cost-list {
  position: relative; z-index: 1;
  border: none; padding: 0; margin: 0;
}
.tech-node--done { border-color: rgba(95, 216, 138, 0.5); }
.tech-node--avail { border-color: rgba(74, 144, 226, 0.6); }
.tech-node--lock { opacity: 0.55; }
.tech-node--selected { box-shadow: 0 0 0 2px var(--accent) inset; }
/* Nutzerwunsch 2026-08-25: fuenf Spalten - aber nur, wo sie wirklich
   hinpassen. Seit dem Alien-Zweig gibt es neun Kategorien; bei vier Spalten
   sind das drei Reihen, bei fuenf nur noch zwei.

   Die Schwelle ist gerechnet, nicht geschaetzt: 5 x 330 px Spalten plus 4 x 16
   px Abstand sind 1714 px. Dazu kommen 76 px Sidebar (--sidebar-width) und
   72 px Innenabstand von .app-main, macht 1862 px - plus Scrollbalken. Unter
   1880 px Fensterbreite wuerde die fuenfte Spalte den Inhalt seitlich
   herausschieben, deshalb bleibt es dort bei vier. Die Kaertchenbreite
   aendert sich bewusst NICHT. */
@media (min-width: 1880px) {
  .research-tree { grid-template-columns: repeat(5, 330px); }
}
@media (max-width: 1480px) {
  .research-tree { grid-template-columns: repeat(3, 330px); }
}
@media (max-width: 1130px) {
  .research-tree { grid-template-columns: repeat(2, 330px); }
}
@media (max-width: 740px) {
  .research-tree { grid-template-columns: 1fr; }
}

/* --- Techtree Sprint 2: Forschungs-Detail-Modal --- */
/* --- Stapelreihenfolge der Modale ---------------------------------------
   Nutzermeldung 2026-08-25: "generell sind alle Modale immer im Hintergrund,
   wenn das Systemview offen ist."

   Die Vollbild-Systemansicht (#starmap-sysmodal-wrapper, game.js) rendert als
   eigenstaendiges Body-Kind mit inline z-index:100. Jedes Modal darunter wird
   von ihrem opaken Overlay verdeckt - es ist da, reagiert auf ESC, ist aber
   unsichtbar. Genau das liess den Flug-Fehler erst beim Schliessen der
   Systemansicht auftauchen.

   Die Leiter, absteigend geordnet und bewusst hier gebuendelt dokumentiert:

     1200  Kampfoperation (.combat-operation-backdrop)
      205  Bestaetigen/Fehler, Backdrop (.action-modal-backdrop)
      210  Bestaetigen/Fehler (.action-modal)          - immer ganz oben
      180  Schiffsinfo (.ship-info-modal)
      170  Flotteneditor (.fleet-editor-modal)
      160  Detail-Modal (.detail-modal) - Forschung, Gebaeude, Versteck
      150  Warp-Blitz (.system-zoom-warp-flash)
      140  Artefaktfund (.starmap-artifact-alert)
      100  Vollbild-Systemansicht

   Die relative Ordnung der Modale untereinander bleibt wie zuvor (Detail <
   Flotteneditor < Schiffsinfo < Bestaetigen), nur liegt jetzt die ganze Gruppe
   ueber der Systemansicht. Wer hier eine Ebene ergaenzt, traegt sie in diese
   Liste ein.
   ---------------------------------------------------------------------- */
.detail-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(2, 3, 8, 0.62);
  backdrop-filter: blur(2px);
  z-index: 159;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}
.detail-modal-backdrop--visible {
  opacity: 1;
  pointer-events: auto;
}
.detail-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.96);
  width: 420px;
  max-width: 92vw;
  max-height: 88vh;
  overflow-y: auto;
  z-index: 160;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.detail-modal--open {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}
/* Deutlicher als das blosse Kreuz (Nutzerwunsch 2026-09-07: "[X] Schliessen
   ein bisschen eindeutiger anzeigen"). Ein 30 Pixel grosses Kreuz in der Ecke
   eines 1240 Pixel breiten Modals findet man erst, wenn man es sucht.

   Kraeftigerer Rahmen und heller Text von Anfang an - nicht erst beim
   Ueberfahren: Wer den Ausweg sucht, hat die Maus noch woanders. */
.detail-modal__close {
  position: absolute;
  top: 12px;
  right: 12px;
  min-width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: rgba(20, 25, 44, 0.96);
  color: var(--text-primary);
  font-family: var(--font-heading, inherit);
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
  z-index: 1;
}
.detail-modal__close-label { text-transform: uppercase; }
.detail-modal__close:hover {
  color: #ffb3a4;
  border-color: rgba(224, 90, 74, 0.7);
  background: rgba(44, 18, 16, 0.96);
}
.detail-modal__close:focus-visible { outline: 2px solid #7fe9ff; outline-offset: 2px; }

/* Auf schmalen Schirmen bleibt nur das Kreuz - das Wort wuerde dort mit dem
   Inhalt konkurrieren, und im schmalen Modal ist die Ecke ohnehin nah. */
@media (max-width: 560px) {
  .detail-modal__close-label { display: none; }
  .detail-modal__close { padding: 0; width: 30px; }
}

/* Effektknopf neben dem Schliessen-Kreuz (Nutzerwunsch 2026-09-01, Large
   Collider). Gleiche Groesse und Hoehe wie das Kreuz, eine Knopfbreite plus
   Abstand weiter links - so bleibt die Ecke ruhig. */
.detail-modal__effect {
  position: absolute;
  top: 12px;
  right: 50px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(199, 146, 234, 0.55);
  border-radius: var(--radius-sm);
  background: rgba(14, 17, 32, 0.9);
  color: #c792ea;
  cursor: pointer;
  transition: color .15s, border-color .15s, opacity .15s;
}
.detail-modal__effect:hover:not(:disabled) {
  color: #e4c8ff;
  border-color: #c792ea;
  box-shadow: 0 0 12px rgba(199, 146, 234, 0.35);
}
.detail-modal__effect:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Nutzervorgabe 2026-07-26: Bestaetigen/Fehler-Dialoge muessen immer ueber
   jedem anderen Modal erscheinen koennen, auch ueber dem neuen verschachtelten
   ship-info-modal - deshalb hier auf den hoechsten Wert angehoben.
   Bugfix 2026-07-28: 90/95 lag unter dem Vollbild-Systemansicht-Modal
   (#starmap-sysmodal-wrapper, inline z-index:100) - Fehlermeldungen (z.B.
   "Scan nicht moeglich") wurden dort unsichtbar hinter dem opaken Overlay
   gerendert, wirkten wie ein kompletter Nicht-Reaktion des Buttons. Jetzt
   ueber dem hoechsten sonst im CSS verwendeten Wert (200). */
.action-modal-backdrop { z-index: 205; }
.action-modal { z-index: 210; }

/* Fundmeldung nach einem Planetenscan: ueber der Systemansicht (100), aber
   unter Warp-Flash (150) und Toast-/Aktionsmeldungen. */
.starmap-artifact-alert {
  position: fixed;
  inset: 0;
  z-index: 140;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.starmap-artifact-alert__backdrop {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, rgba(28, 103, 129, 0.2), rgba(2, 3, 9, 0.72) 55%);
  backdrop-filter: blur(3px);
}
.starmap-artifact-alert__panel {
  --artifact-alert-color: #7fe9ff;
  position: relative;
  width: min(500px, 92vw);
  overflow: hidden;
  border: 1px solid var(--artifact-alert-color);
  border-radius: 14px;
  padding: 34px 38px 30px;
  background: linear-gradient(145deg, rgba(12, 19, 35, 0.99), rgba(4, 7, 17, 0.99));
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.04), 0 0 42px rgba(127, 233, 255, 0.3), inset 0 0 48px rgba(127, 233, 255, 0.05);
  text-align: center;
  animation: modalRise 0.32s cubic-bezier(.2, .7, .3, 1) both;
}
.starmap-artifact-alert--unknown .starmap-artifact-alert__panel {
  --artifact-alert-color: #e0c07a;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.04), 0 0 42px rgba(224, 192, 122, 0.24), inset 0 0 48px rgba(224, 192, 122, 0.05);
}
.starmap-artifact-alert__signal {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.28;
}
.starmap-artifact-alert__signal span,
.starmap-artifact-alert__signal b,
.starmap-artifact-alert__signal i {
  position: absolute;
  left: 50%;
  top: 62px;
  border: 1px solid var(--artifact-alert-color);
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.starmap-artifact-alert__signal span { width: 92px; height: 92px; }
.starmap-artifact-alert__signal b { width: 124px; height: 124px; opacity: 0.55; }
.starmap-artifact-alert__signal i { width: 158px; height: 158px; opacity: 0.25; }
.starmap-artifact-alert__glyph {
  position: relative;
  color: var(--artifact-alert-color);
  font-family: 'Chakra Petch', sans-serif;
  font-size: 40px;
  line-height: 56px;
  text-shadow: 0 0 18px var(--artifact-alert-color);
}
.starmap-artifact-alert__eyebrow {
  position: relative;
  margin-top: 14px;
  color: var(--artifact-alert-color);
  font-family: 'Chakra Petch', sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.24em;
}
.starmap-artifact-alert__title {
  margin: 9px 0 0;
  color: #f1f5ff;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 25px;
  letter-spacing: 0.06em;
}
.starmap-artifact-alert__planet {
  margin-top: 7px;
  color: #8b96ba;
  font-size: 11px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}
.starmap-artifact-alert__message {
  max-width: 390px;
  margin: 22px auto 0;
  color: #cfd7f5;
  font-size: 13px;
  line-height: 1.65;
}
.starmap-artifact-alert__close {
  margin-top: 24px;
  border: 1px solid var(--artifact-alert-color);
  border-radius: 7px;
  padding: 10px 18px;
  background: rgba(127, 233, 255, 0.09);
  color: var(--artifact-alert-color);
  font-family: 'Chakra Petch', sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  cursor: pointer;
}
.starmap-artifact-alert__close:hover,
.starmap-artifact-alert__close:focus-visible {
  background: rgba(127, 233, 255, 0.17);
  box-shadow: 0 0 14px rgba(127, 233, 255, 0.25);
  outline: none;
}

/* Artefaktmarker am Planeten (Nutzerwunsch 2026-08-21: orange und pulsierend).
   Gepulst wird der Schein, nicht die Groesse: der Marker sitzt mit festem
   top/right am Planetenrand, eine Skalierung wuerde ihn dort verrutschen
   lassen. --artifact-color setzt das Markup je Zustand. */
/* Marker fuer eine geortete, noch nicht geborgene Lebensform
   (Nutzerwunsch 2026-08-22). Aufbau wie der Artefaktmarker, aber LINKS am
   Planeten: beide koennen gleichzeitig auftreten und duerfen sich nicht
   ueberdecken. Gepulst wird der Schein, nicht die Groesse - der Marker
   sitzt mit festem top/left am Rand und wuerde beim Wachsen verrutschen. */
/* Exemplare an Bord: seit dem 2026-08-22 offen statt in einem <details>.
   Uebernimmt die Optik der frueheren summary-Zeile, damit der Block sich
   im Panel nicht anders anfuehlt als seine Nachbarn. */
.starmap-shippanel__creatures {
  margin-top: 10px;
}
.starmap-shippanel__creatures-head {
  font-size: 10px;
  letter-spacing: 0.1em;
  color: #63709a;
  margin-bottom: 6px;
}

/* Ressourcen an Bord (2026-09-17). Derselbe Aufbau wie die Exemplare darunter -
   Ueberschrift, Zeilen, eine Handlung; der Spieler soll nicht lernen muessen,
   dass "an Bord" hier anders aussieht als dort. */
.starmap-shippanel__cargo {
  margin-top: 10px;
}

/* Der Abliefern-Knopf teilt sich die Form mit dem Abbrechen-Knopf, traegt aber
   Gruen statt Orange: Abbrechen nimmt etwas zurueck, Abliefern bringt etwas
   ein. Dieselbe Form, weil beide an derselben Stelle im Panel sitzen. */
.starmap-shippanel__unload {
  color: var(--accent-green);
  border-color: rgba(95, 216, 138, 0.4);
}
.starmap-shippanel__unload:hover {
  background: rgba(95, 216, 138, 0.1);
}

.starmap-creature-marker {
  position: absolute;
  top: -7px;
  left: -9px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: rgba(6, 9, 20, 0.92);
  border: 1px solid;
  font-size: 10px;
  line-height: 1;
  z-index: 7;
  animation: creaturePulse 1.8s ease-in-out infinite;
}
@keyframes creaturePulse {
  0%, 100% { box-shadow: 0 0 3px var(--creature-color); }
  50% { box-shadow: 0 0 11px var(--creature-color), 0 0 3px var(--creature-color); }
}

/* Erfasste Anomalie an einem Planeten (Nutzerwunsch 2026-09-02). Aufbau wie
   der Lebensform- und der Artefaktmarker, nur unten rechts: oben links sitzt
   die Lebensform, oben rechts das Artefakt, ueber dem Planeten das
   Missionsziel. Alle vier koennen gleichzeitig auftreten und duerfen sich
   nicht ueberdecken. */
.starmap-anomaly-marker {
  position: absolute;
  bottom: -7px;
  right: -9px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: rgba(6, 9, 20, 0.92);
  border: 1px solid #c792ea;
  color: #c792ea;
  font-size: 9px;
  line-height: 1;
  z-index: 7;
  animation: anomalyMarkerPulse 2.1s ease-in-out infinite;
}
/* Untersucht: der Marker bleibt als Gedaechtnis stehen, hoert aber auf zu
   pulsen. Ein Puls ist eine Aufforderung, und hier ist nichts mehr zu tun. */
.starmap-anomaly-marker--done {
  animation: none;
  border-color: #6f5b86;
  color: #6f5b86;
}

/* Die FREIE Anomalie im Systemmodal (Nutzerbefund 2026-09-12, viermal "ich
   sehe nichts"). Das Modal ist die Ansicht, die man beim Spielen benutzt -
   Doppelklick auf den Stern und der Knopf "System oeffnen" fuehren beide
   hierher. Objektgebundene Anomalien trugen dort laengst ihr Zeichen am
   Traeger; es fehlten genau die freien.

   Bewusst auffaelliger als der Planetenmarker: Der haengt an einem Planeten,
   den man ohnehin sieht. Dieser hier IST das Objekt. */
/* DER CONTAINER FAENGT NICHTS AB (Nutzerbefund 2026-09-12: "wenn ich es
   anklicke oder einen Planeten anklicke passiert nix").

   Das Namensschild ist `white-space: nowrap` und damit rund 150 px breit -
   in einem 34 px schmalen Container ragt es weit nach links und rechts
   heraus. Mit `pointer-events: auto` am Container fing dieser unsichtbare
   Streifen die Klicks der Planeten ab, ueber denen er gerade lag. Klickbar
   ist deshalb NUR das Zeichen. */
.sysmodal-anomaly {
  position: relative;
  width: 34px;
  pointer-events: none;
  text-align: center;
  margin: 0 auto;
}
/* Ein unsichtbarer Ring um das Zeichen vergroessert die Trefferflaeche auf
   46 px. Ein kreisendes Ziel von 26 px trifft man sonst nur mit Glueck. */
.sysmodal-anomaly__sign::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 50%;
}
.sysmodal-anomaly__ring {
  position: absolute;
  left: 50%;
  top: 17px;
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border-radius: 50%;
  border: 1px solid var(--sysmodal-anomaly-color, #8b96ba);
  opacity: .5;
  animation: sysmodalAnomalyPulse 2.2s ease-in-out infinite;
  pointer-events: none;
}
.sysmodal-anomaly__sign {
  position: relative;
  width: 26px;
  height: 26px;
  margin: 4px auto;
  pointer-events: auto;
  cursor: pointer;
  /* Der Trefferbereich ist groesser als das Zeichen: ein kreisendes Ziel von
     26 Pixeln trifft man sonst nur mit Glueck. Der Rahmen bleibt am Zeichen,
     die Flaeche waechst nach aussen. */
  outline-offset: 0;
  box-sizing: border-box;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  line-height: 1;
  color: var(--sysmodal-anomaly-color, #8b96ba);
  background: rgba(6, 9, 20, .92);
  border: 1px solid var(--sysmodal-anomaly-color, #8b96ba);
  box-shadow: 0 0 12px var(--sysmodal-anomaly-color, #8b96ba);
}
/* Hell, nicht in der Anomaliefarbe: Die gestaffelte Enthuellung steckt im
   INHALT des Schildes ("Unbekanntes Phaenomen" verraet nichts), nicht in
   seiner Lesbarkeit. */
.sysmodal-anomaly__label {
  /* Nicht klickbar: siehe Kommentar am Container. */
  pointer-events: none;
  margin-top: 6px;
  font-size: 10px;
  letter-spacing: .05em;
  white-space: nowrap;
  color: #dce3f7;
  text-shadow: 0 0 4px rgba(8, 10, 20, .95), 0 0 2px rgba(8, 10, 20, .95);
}
.sysmodal-anomaly:hover .sysmodal-anomaly__sign {
  border-color: #7fe9ff;
  color: #7fe9ff;
}
@keyframes sysmodalAnomalyPulse {
  0%, 100% { transform: scale(1); opacity: .5; }
  50% { transform: scale(1.35); opacity: .12; }
}

/* Die aufgeschlagene Anomalie im Systemmodal.
   Gestaltung 1:1 nach der Vorlage des Nutzers
   `_Design-Vorlage/weltraumspiel-starcontrol/project/Anomalie Fancy.dc.html`
   (uebernommen 2026-09-13, loest den eigenen Entwurf "Fenster ins Unbekannte"
   vom Vortag ab).

   DER KERN DER VORLAGE SIND ZWEI SVG-FILTER: feTurbulence plus
   feDisplacementMap verbiegen Gitter, Halo und Kern. Das ist die
   Raumverzerrung, die man nicht malen kann - sie entsteht aus dem Rauschen.
   Die Filter stehen im Markup der Ansicht, nicht hier.

   Die violette Grundstimmung kommt aus der Vorlage und bleibt in allen
   Kategorien; die Kategoriefarbe sitzt als --anofancy-accent an Ringen und
   Werten. Eine Anomalie ist ein Phaenomen, keine Farbtafel - welche Kategorie
   sie hat, steht als Wert daneben. */
.anofancy {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 40;
  background: radial-gradient(circle at 50% 50%, rgba(30, 10, 50, .5), #050208 70%);
  font-family: var(--font-heading);
  color: #e9e4fb;
  animation: anofancyIn .4s cubic-bezier(.2, .8, .2, 1);
}
.anofancy__defs { position: absolute; width: 0; height: 0; }

.anofancy__backdrop {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, rgba(30, 10, 50, .5), #050208 70%);
}
/* Das verzerrte Gitter - der auffaelligste Teil der Vorlage. */
.anofancy__warpgrid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, .03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .03) 1px, transparent 1px);
  background-size: 46px 46px;
  filter: url(#anofancyWarp);
  opacity: .8;
}
.anofancy__hatch {
  position: absolute;
  top: -20%;
  left: -10%;
  width: 70%;
  height: 70%;
  background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, .025) 0 2px, transparent 2px 26px);
  filter: url(#anofancyWarpSoft);
}
.anofancy__scanline {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(197, 158, 255, .5), transparent);
  animation: anofancyScan 5.5s linear infinite;
  opacity: .5;
}

.anofancy__head {
  position: absolute;
  top: 22px;
  left: 28px;
  max-width: calc(100% - 380px);
}
.anofancy__eyebrow {
  font-family: var(--font-body);
  font-size: 10px;
  letter-spacing: .22em;
  color: #a68be0;
}
.anofancy__name {
  font-weight: 600;
  font-size: 29px;
  letter-spacing: .005em;
  margin-top: 6px;
  animation: anofancyFlicker 6s ease-in-out infinite;
}
.anofancy__class {
  font-family: var(--font-body);
  font-size: 11.5px;
  color: #9d92c4;
  margin-top: 4px;
}
.anofancy__unknown { color: #6b5f92; }

/* --- das Phaenomen ---------------------------------------------------- */
.anofancy__stage {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}
.anofancy__haloWarp {
  position: absolute;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  filter: url(#anofancyWarpSoft);
}
.anofancy__halo {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid rgba(197, 158, 255, .22);
}
.anofancy__ring {
  position: absolute;
  border-radius: 50%;
}
.anofancy__ring--dashed {
  width: 360px;
  height: 360px;
  border: 1px dashed rgba(197, 158, 255, .28);
  animation: anofancySpin 24s linear infinite;
}
.anofancy__ring--rose {
  width: 300px;
  height: 300px;
  border: 1px solid var(--anofancy-accent, rgba(255, 140, 200, .24));
  opacity: .45;
  animation: anofancySpinRev 17s linear infinite;
}

.anofancy__core { position: relative; width: 192px; height: 192px; }
.anofancy__coreWarm,
.anofancy__coreCold,
.anofancy__coreWarp,
.anofancy__coreShade { position: absolute; inset: 0; border-radius: 50%; }
/* Zwei gegenlaeufige Schichten im Screen-Modus: daher das Schillern. */
.anofancy__coreWarm {
  background: radial-gradient(circle at 38% 32%, #ffe9c2, #ff9d5c 30%, #c85fce 58%, #4a1a72 82%, #160a24 100%);
  mix-blend-mode: screen;
  opacity: .85;
  animation: anofancyCoreShift 5s ease-in-out infinite, anofancyAberrate .4s steps(4) infinite;
  filter: hue-rotate(6deg);
}
.anofancy__coreCold {
  background: radial-gradient(circle at 38% 32%, #c2fff0, #5cf0ff 30%, #5f8fce 58%, #1a3a72 82%, #0a1424 100%);
  mix-blend-mode: screen;
  opacity: .4;
  animation: anofancyCoreShift 5s ease-in-out infinite reverse;
  filter: hue-rotate(-6deg);
}
.anofancy__coreWarp { filter: url(#anofancyWarp); }
.anofancy__coreBody {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 34%, #fff3d6 0%, #ffb35c 34%, #b8632f 62%, #2a1208 100%);
  box-shadow: 0 0 70px 14px rgba(255, 150, 90, .5), 0 0 150px 46px rgba(160, 90, 220, .28);
}
.anofancy__coreShade { box-shadow: inset -20px -16px 44px rgba(0, 0, 0, .6); }

/* --- Messwerte -------------------------------------------------------- */
.anofancy__reads {
  position: absolute;
  top: 150px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.anofancy__reads--left { left: 30px; }
.anofancy__reads--right { right: 30px; }
.anofancy__read {
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(197, 158, 255, .16);
  border-radius: 10px;
  padding: 10px 14px;
  min-width: 150px;
}
.anofancy__reads--left .anofancy__read { min-width: 120px; }
.anofancy__readLabel {
  font-family: var(--font-body);
  font-size: 8.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #8a7fb8;
}
.anofancy__readValue {
  font-family: var(--font-body);
  font-size: 15px;
  color: #e9e4fb;
  margin-top: 4px;
}
.anofancy__readValue--big {
  font-size: 17px;
  animation: anofancyPulseVal 2.6s ease-in-out infinite;
}

/* --- Fusszeile -------------------------------------------------------- */
.anofancy__foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 26px;
  border-top: 1px solid rgba(197, 158, 255, .16);
  background: rgba(10, 7, 18, .6);
}
.anofancy__note { flex: 1; min-width: 0; font-size: 12px; color: #9d92c4; }
.anofancy__actions {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.anofancy__hint { font-size: 11.5px; color: #9d92c4; max-width: 260px; line-height: 1.5; }

/* Der laufende Anomaliescan (Nutzerbefund 2026-09-14: "ich druecke ihn, es
   passiert augenscheinlich nichts"). Bis dahin kannte das Panel nur zwei
   Zustaende - "nicht klassifiziert" und "erfasst" -, also zeichnete es nach
   dem Start unveraendert denselben Knopf. */
.anofancy__scanbar {
  margin-top: 8px;
  height: 4px;
  border-radius: 2px;
  background: rgba(127, 233, 255, .12);
  overflow: hidden;
}
.anofancy__scanbar-fill {
  height: 100%;
  background: linear-gradient(90deg, #46b4d9, #7fe9ff);
  box-shadow: 0 0 8px rgba(127, 233, 255, .5);
  transition: width .4s linear;
}
.anofancy__scaneta {
  margin-top: 5px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  color: #7fe9ff;
  font-variant-numeric: tabular-nums;
}
.anofancy__preview {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-family: var(--font-body);
  font-size: 11.5px;
  color: #9d92c4;
}
.anofancy__preview b { color: #cbb9ef; font-weight: 500; }
.anofancy__blocked { color: #ff8f78; }

.anofancy__btn {
  border: 1px solid rgba(197, 158, 255, .28);
  background: transparent;
  color: #cbb9ef;
  font-size: 12px;
  letter-spacing: .06em;
  padding: 9px 18px;
  border-radius: 8px;
  cursor: pointer;
  white-space: nowrap;
}
.anofancy__btn:hover { background: rgba(255, 255, 255, .05); }
.anofancy__btn--primary {
  border-color: rgba(255, 157, 92, .5);
  background: linear-gradient(160deg, rgba(255, 157, 92, .22), rgba(200, 95, 206, .16));
  color: #ffe1c4;
  font-weight: 500;
  padding: 9px 20px;
}
.anofancy__btn--primary:hover {
  background: linear-gradient(160deg, rgba(255, 157, 92, .32), rgba(200, 95, 206, .24));
}
.anofancy__btn--danger { border-color: rgba(255, 143, 120, .45); color: #ff8f78; }

/* Die laufende Untersuchung ist DIESELBE Schau wie im Seitenpanel und in der
   Planetenansicht (Nutzerwunsch 2026-09-13: "die untersuchen-animation darfst
   du von dir gern uebernehmen da rein"). Sie bekommt hier nur den Rahmen der
   Vorlage. */
.anofancy__running {
  display: grid;
  gap: 8px;
  min-width: 250px;
}
.anofancy__running .invshow { margin: 0; }

@keyframes anofancyIn {
  from { opacity: 0; transform: scale(.96); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes anofancyCoreShift {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33% { transform: translate(-2px, 1px) scale(1.02); }
  66% { transform: translate(2px, -1px) scale(.985); }
}
@keyframes anofancySpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes anofancySpinRev { from { transform: rotate(360deg); } to { transform: rotate(0deg); } }
@keyframes anofancyFlicker {
  0%, 100% { opacity: .95; }
  45% { opacity: .95; }
  47% { opacity: .5; }
  49% { opacity: .95; }
  72% { opacity: .95; }
  74% { opacity: .6; }
  76% { opacity: .95; }
}
@keyframes anofancyAberrate {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(1.4px, -0.6px); }
  40% { transform: translate(-1.2px, 0.4px); }
  60% { transform: translate(0.8px, 0.8px); }
  80% { transform: translate(-0.6px, -1px); }
}
@keyframes anofancyPulseVal { 0%, 100% { opacity: .75; } 50% { opacity: 1; } }
@keyframes anofancyScan { from { transform: translateY(-100%); } to { transform: translateY(100%); } }

/* Die Verzerrungsfilter sind das Teuerste an dieser Ansicht: feTurbulence
   rechnet je Bild neu. Wer Bewegung abbestellt hat, bekommt das ruhige Bild -
   und der Rechner seine Leistung zurueck. */
@media (prefers-reduced-motion: reduce) {
  .anofancy,
  .anofancy__name,
  .anofancy__scanline,
  .anofancy__ring,
  .anofancy__coreWarm,
  .anofancy__coreCold,
  .anofancy__readValue--big { animation: none; }
  .anofancy__warpgrid,
  .anofancy__hatch,
  .anofancy__coreWarp { filter: none; }
}

/* Schmale Fenster: die Messwerte wandern unter das Phaenomen. */
@media (max-width: 1000px) {
  .anofancy__reads {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
  }
  .anofancy__head { max-width: calc(100% - 56px); }
  .anofancy__foot { flex-wrap: wrap; }
}

@keyframes anomalyMarkerPulse {
  0%, 100% { box-shadow: 0 0 3px #c792ea; }
  50% { box-shadow: 0 0 11px #c792ea, 0 0 3px #c792ea; }
}

.starmap-artifact-marker {
  position: absolute;
  top: -7px;
  right: -9px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: rgba(6, 9, 20, 0.92);
  border: 1px solid;
  font-family: 'Chakra Petch', sans-serif;
  font-weight: 700;
  font-size: 9px;
  line-height: 1;
  z-index: 7;
  animation: artifactPulse 1.8s ease-in-out infinite;
}
@keyframes artifactPulse {
  0%, 100% { box-shadow: 0 0 3px var(--artifact-color); }
  50% { box-shadow: 0 0 11px var(--artifact-color), 0 0 3px var(--artifact-color); }
}

/* Seltenheits-Badge (Nutzerwunsch 2026-08-22, Vorbild Diablo): die Stufe ist
   ab dem Fund bekannt, das steigert die Vorfreude. Farben nach Nutzervorgabe -
   grau, gruen, blau, rosa, orange - eine Skala fuer Fundstuecke UND
   Lebensformen (Nutzerentscheidung 2026-08-22).

   LEGENDARY hat noch kein einziges Artefakt im Katalog. Die Stufe steht
   trotzdem hier: sie ist fuer spaeter vorgesehen, und die Farbe soll jetzt
   schon feststehen statt irgendwann beilaeufig vergeben zu werden. */
/* Die Wirkungszeile traegt jetzt zwei Ebenen: Beschriftung mit Wert oben,
   darunter der Satz, wo der Bonus einschlaegt (Nutzerwunsch 2026-08-22).
   Deshalb bekommt .artifact-effect eine Spaltenrichtung - vorher lagen
   Label und Wert direkt darin nebeneinander. */
/* Katalogdauer neben der tatsaechlichen (Nutzerwunsch 2026-08-22).
   Bewusst gedaempft: es ist eine Balancing-Hilfe, keine Spielinformation. */
/* Fiktive Balancing-Uhr in der Admin-Topbar (Nutzerwunsch 2026-08-22).
   Bewusst zurueckhaltend: ein Werkzeug, kein Spielelement. */
.topbar-clock {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 3px 10px;
  border-radius: 6px;
  border: 1px solid rgba(120, 180, 255, 0.18);
  background: rgba(255, 255, 255, 0.03);
  cursor: help;
}
.topbar-clock__time {
  font-family: 'Chakra Petch', sans-serif;
  font-size: 13px;
  letter-spacing: 0.08em;
  color: #ffd76a;
  line-height: 1.1;
}
.topbar-clock__tracks {
  font-size: 9px;
  letter-spacing: 0.03em;
  color: #63709a;
  white-space: nowrap;
}

/* Ausblenden der Balancing-Uhr (Nutzerwunsch 2026-09-01). Sie ist ein reines
   Testwerkzeug und steht sonst dauerhaft in der Leiste. */
.topbar-clock {
  position: relative;
}
.topbar-clock__hide {
  position: absolute;
  top: 1px;
  right: 1px;
  width: 14px;
  height: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: none;
  color: #47527a;
  font-size: 9px;
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s, color .15s;
}
/* Erst beim Darueberfahren sichtbar: die Uhr ist eng, ein dauerhaftes Kreuz
   wuerde neben der Uhrzeit staendig um Aufmerksamkeit buhlen. */
.topbar-clock:hover .topbar-clock__hide { opacity: 1; }
.topbar-clock__hide:hover { color: #ffd76a; }

.topbar-clock-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border-radius: 6px;
  border: 1px solid rgba(120, 180, 255, 0.18);
  background: rgba(255, 255, 255, 0.03);
  color: #63709a;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}
.topbar-clock-toggle:hover {
  color: #ffd76a;
  border-color: rgba(255, 215, 106, 0.45);
}

.progress-box__tempo {
  margin-left: 8px;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: #63709a;
}

.artifact-effect__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.artifact-effect__where {
  margin-top: 3px;
  font-size: 10.5px;
  line-height: 1.45;
  color: #8b96ba;
}

/* Markiert einen Wert, der seine Obergrenze erreicht hat (2026-08-22).
   Bewusst unauffaellig: es ist eine Fussnote am Wert, keine Warnung. */
.artifact-effect__capped {
  margin-left: 5px;
  font-size: 9px;
  letter-spacing: 0.06em;
  color: #8b96ba;
  text-transform: uppercase;
}

.artifact-card__badges {
  display: flex;
  gap: 6px;
  margin-top: 6px;
}
.artifact-card__badges:empty {
  display: none;
}
.artifact-rarity {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 4px;
  border: 1px solid;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 1.4;
  white-space: nowrap;
}
.artifact-rarity--common {
  color: #8b96ba;
  border-color: rgba(139, 150, 186, 0.5);
  background: rgba(139, 150, 186, 0.1);
}
.artifact-rarity--uncommon {
  color: #8fe0a0;
  border-color: rgba(143, 224, 160, 0.5);
  background: rgba(143, 224, 160, 0.1);
}
.artifact-rarity--rare {
  color: #7fb0ff;
  border-color: rgba(127, 176, 255, 0.5);
  background: rgba(127, 176, 255, 0.1);
}
.artifact-rarity--exotic {
  color: #f0a8f4;
  border-color: rgba(240, 168, 244, 0.5);
  background: rgba(240, 168, 244, 0.1);
}
.artifact-rarity--legendary {
  color: #e8963c;
  border-color: rgba(232, 150, 60, 0.55);
  background: rgba(232, 150, 60, 0.12);
}

/* Fortschrittsbalken der Identifikation, ueber die volle Kachelbreite
   (Nutzervorgabe 2026-08-22). Bewusst ohne Abbrechen-Knopf: die Identifikation
   kostet nichts, es gaebe nichts zurueckzuerstatten. */
.artifact-card__progress {
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.07);
  overflow: hidden;
  margin-top: 10px;
}
.artifact-card__progress-bar {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, #8a4f12, #e8963c);
  transition: width 0.4s linear;
}

/* Fundmarker auf der Planetenoberflaeche (Nutzerwunsch 2026-08-21): Zeichen im
   Kern, darum ein pulsierender orangener Kreis. Hier darf der Kreis in der
   GROESSE pulsieren - anders als beim Marker am Planeten im Orbitbild, der mit
   festem top/right am Rand klebt: dieser hier ist ueber seinen Mittelpunkt
   positioniert (translate(-50%,-50%)) und bleibt beim Wachsen an Ort. */
.starmap-surface-artifact {
  position: absolute;
  width: 18px;
  height: 18px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.25s ease;
  z-index: 6;
}
.starmap-surface-artifact::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px solid var(--artifact-color);
  box-shadow: 0 0 8px var(--artifact-color);
  animation: surfaceArtifactPulse 1.8s ease-out infinite;
}
.starmap-surface-artifact__glyph {
  position: relative;
  z-index: 1;
  font-family: 'Chakra Petch', sans-serif;
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
  color: var(--artifact-color);
  text-shadow: 0 0 6px var(--artifact-color), 0 0 2px #05060f;
}
@keyframes surfaceArtifactPulse {
  0% { transform: scale(0.75); opacity: 0.95; }
  70% { transform: scale(1.7); opacity: 0; }
  100% { transform: scale(1.7); opacity: 0; }
}

/* Legende der Systemansicht (Nutzerwunsch 2026-08-21). Sitzt im rechten Panel,
   solange dort kein Detail-Scan steht. Die Symbolgroessen sind bewusst klein
   und einheitlich: die Legende erklaert die FORM und FARBE eines Zeichens,
   nicht seine Groesse im Orbitbild (die haengt dort am Planetendurchmesser). */
.starmap-legend__title {
  font-size: 11px;
  letter-spacing: 0.14em;
  color: #63709a;
  margin-bottom: 12px;
}
.starmap-legend__row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}
.starmap-legend__symbol {
  position: relative;
  flex: 0 0 18px;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.starmap-legend__label {
  font-size: 11px;
  line-height: 1.35;
  color: #aab4d4;
}
.starmap-legend__ring {
  width: 16px;
  height: 16px;
  border-radius: 50%;
}
.starmap-legend__dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
}
.starmap-legend__badge {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid;
  background: rgba(6, 9, 20, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Chakra Petch', sans-serif;
  font-weight: 700;
  font-size: 9px;
  line-height: 1;
}
.starmap-legend__diamond {
  width: 7px;
  height: 7px;
  transform: rotate(45deg);
}
.starmap-legend__moon {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}
.starmap-legend__fleet-icon {
  font-size: 17px;
  filter: drop-shadow(0 0 4px currentColor);
}
/* Warndreieck der Anomalien (Nutzerwunsch 2026-09-04). Als CSS-Dreieck aus
   Rahmen gebaut, weil das Orbitbild dieselbe Form zeichnet: Spitze nach oben,
   Breite 9, Hoehe 8,5 - dort per Canvas-Pfad, hier per border-Trick. Die
   Farbe kommt ueber border-bottom-color aus dem Symbol selbst. */
.starmap-legend__triangle {
  width: 0;
  height: 0;
  background: none;
  border-left: 4.5px solid transparent;
  border-right: 4.5px solid transparent;
  border-bottom: 8px solid currentColor;
  filter: drop-shadow(0 0 4px currentColor);
}

/* Ring fuer bereits gescannte Planeten (Nutzervorgabe 2026-08-21: gepunktet,
   sichtbarer Abstand). Der Abstand ist nicht -2px, sondern -5px: die
   Planetenkugel traegt einen box-shadow, der ueber ihren Container hinausragt
   - beim angeflogenen Planeten ein SOLIDER 2px-Ring (innerRing in
   renderStarmapSystemModalSystemView). Bei -3px sass der Scanring direkt auf
   diesem Ring auf, also ohne sichtbaren Abstand. -5px laesst die 2px Ring
   plus 2px Luft frei, bevor die 1px-Punktlinie beginnt. */
.starmap-sysmodal-planet-scan-ring {
  position: absolute;
  inset: -5px;
  z-index: 6;
  border: 1px dotted #7fe9ff;
  border-radius: 50%;
  box-shadow: 0 0 5px rgba(127, 233, 255, 0.35);
  pointer-events: none;
}

.starmap-sysmodal-zoom-moon-orbit {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 1;
  transform: translate(-50%, -50%);
  animation-name: orbit;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.starmap-sysmodal-zoom-moon {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #f2f5ff, #a8b1c7 62%, #606b84);
  box-shadow: 0 0 7px rgba(201, 208, 224, 0.8);
}

.fleet-editor-modal-backdrop {
  position: fixed; inset: 0; background: rgba(2, 3, 8, 0.62); backdrop-filter: blur(2px);
  z-index: 169; opacity: 0; pointer-events: none; transition: opacity 0.15s ease;
}
.fleet-editor-modal-backdrop--visible { opacity: 1; pointer-events: auto; }
.fleet-editor-modal {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.96);
  width: calc(100vw - 48px); height: calc(100vh - 48px); max-width: none; max-height: none; overflow-y: auto;
  background: rgba(14, 17, 32, 0.99); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  padding: 24px; z-index: 170; opacity: 0; pointer-events: none; transition: opacity 0.15s ease, transform 0.15s ease;
}
.fleet-editor-modal--open { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); }
.fleet-editor-modal__close {
  position: absolute; top: 12px; right: 12px; width: 30px; height: 30px; display: flex;
  align-items: center; justify-content: center; background: var(--surface-active); border: 1px solid var(--border);
  border-radius: var(--radius-sm); color: var(--text-muted); cursor: pointer;
}

.ship-info-modal-backdrop {
  position: fixed; inset: 0; background: rgba(2, 3, 8, 0.66); backdrop-filter: blur(2px);
  z-index: 179; opacity: 0; pointer-events: none; transition: opacity 0.15s ease;
}
.ship-info-modal-backdrop--visible { opacity: 1; pointer-events: auto; }
.ship-info-modal {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.96);
  width: 420px; max-width: 92vw; max-height: 88vh; overflow-y: auto;
  background: rgba(14, 17, 32, 0.99); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  padding: 20px; z-index: 180; opacity: 0; pointer-events: none; transition: opacity 0.15s ease, transform 0.15s ease;
}
.ship-info-modal--open { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); }
.ship-info-modal__close {
  position: absolute; top: 12px; right: 12px; width: 30px; height: 30px; display: flex;
  align-items: center; justify-content: center; background: var(--surface-active); border: 1px solid var(--border);
  border-radius: var(--radius-sm); color: var(--text-muted); cursor: pointer;
}

/* Panel im Modal-Kontext: kein sticky, staerkerer Rahmen/Hintergrund. */
.detail-modal .detail-panel {
  position: static;
  border-color: var(--border-strong);
  background: rgba(14, 17, 32, 0.99);
  padding: 20px 22px;
}

.detail-panel__milestone {
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-gold);
  margin-left: 6px;
}

/* --- Techtree Sprint 3: Bau-Ansicht --- */
/* Nutzeranfrage 2026-08-01: die Kategorieblocke stehen NEBENEINANDER statt
   gestapelt - Administration dreispaltig (Kacheln brechen darunter um),
   Energie, Produktion und Lager je einspaltig daneben, getrennt durch
   vertikale Linien.

   align-items: stretch ist hier die tragende Eigenschaft: nur dadurch laufen
   die Trennlinien ueber die Hoehe des HOECHSTEN Blocks statt jeweils nur ueber
   die eigenen Kacheln - sonst haetten die kurzen Bloecke rechts Stummel-Linien.
   flex-wrap sorgt dafuer, dass auf schmalen Fenstern die hinteren Bloecke
   umbrechen statt die Seite waagerecht scrollen zu lassen. */
.building-columns {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: 0;
}
.building-group {
  margin-bottom: 18px;
  padding: 0 18px;
}
.building-group:first-child {
  padding-left: 0;
}
.building-group + .building-group {
  border-left: 1px solid var(--border);
}
.building-group__head {
  font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-dim); margin-bottom: 10px;
}
/* Einspaltig ist der Standard; die Breitenspanne haelt die Kacheln in allen
   Bloecken gleich breit, egal wie viel Platz der Block insgesamt hat. */
.building-group__tiles {
  display: grid;
  grid-template-columns: minmax(210px, 250px);
  gap: 12px;
  justify-content: start;
}
.building-group--wide .building-group__tiles {
  grid-template-columns: repeat(3, minmax(210px, 250px));
}
/* Vier Bloecke nebeneinander brauchen rund 1500 px. Darunter zuerst die
   Administration schmaler machen, erst danach umbrechen lassen. */
@media (max-width: 1600px) {
  .building-group--wide .building-group__tiles { grid-template-columns: repeat(2, minmax(210px, 250px)); }
}
@media (max-width: 1200px) {
  .building-group { padding: 0 12px; }
}
.building-tile {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 12px 14px; cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.building-tile:hover { background: rgba(70, 217, 208, 0.06); border-color: rgba(70,217,208,0.4); }
.building-tile--maxed { border-color: rgba(95, 216, 138, 0.5); }
.building-tile--avail { border-color: rgba(74, 144, 226, 0.6); }
.building-tile--damage-light {
  border-color: rgba(255, 215, 106, 0.72);
  background: linear-gradient(145deg, rgba(255, 215, 106, 0.07), var(--surface) 48%);
}
.building-tile--damage-damaged {
  border-color: rgba(224, 131, 74, 0.82);
  background: linear-gradient(145deg, rgba(224, 131, 74, 0.11), var(--surface) 52%);
}
.building-tile--damage-destroyed {
  border-color: rgba(224, 90, 74, 0.95);
  background: linear-gradient(145deg, rgba(224, 90, 74, 0.17), rgba(28, 16, 22, 0.96) 58%);
  box-shadow: inset 3px 0 0 rgba(224, 90, 74, 0.72);
}
.building-tile__head { display: flex; align-items: center; gap: 10px; }
.building-tile__body { flex: 1; min-width: 0; }
.building-tile__name { font-size: 12.5px; color: var(--text-primary); }
.building-tile__level { font-size: 10.5px; color: var(--accent); margin-top: 3px; }
.building-tile__milestone { color: var(--accent-gold); font-size: 10px; margin-left: 6px; }
/* Ausbauzeile (Nutzerwunsch 2026-09-22): trennt sichtbar, was man BESITZT
   (Name und Stufe darueber) von dem, was der Preis darunter meint - die
   naechste Stufe. Ohne sie las sich die Kachel als ein einziger Block. */
.building-tile__upgrade {
  font-size: 10.5px; color: var(--accent-gold); margin: 7px 0 5px;
  padding-top: 6px; border-top: 1px solid var(--border);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.building-tile__structure { margin-top: 8px; }
.building-tile__structure-head {
  display: flex;
  justify-content: space-between;
  color: var(--accent-red);
  font-size: 10px;
}
.building-tile__structure--light .building-tile__structure-head { color: #ffd76a; }
.building-tile__structure--damaged .building-tile__structure-head { color: #e0834a; }
.building-tile__structure--destroyed .building-tile__structure-head { color: #ff7468; font-weight: 700; }
.starmap-debris-field {
  position: absolute;
  width: 34px;
  height: 34px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 2;
  filter: drop-shadow(0 0 7px rgba(214, 142, 74, 0.62));
}
.starmap-debris-field__hull {
  position: absolute;
  left: 8px;
  top: 10px;
  width: 18px;
  height: 11px;
  border: 1px solid rgba(224, 168, 104, 0.9);
  background: linear-gradient(135deg, #69513d 0%, #252936 62%, #a85f32 100%);
  clip-path: polygon(0 22%, 72% 0, 100% 48%, 68% 100%, 12% 78%);
  transform: rotate(-18deg);
}
.starmap-debris-field__shard {
  position: absolute;
  width: 7px;
  height: 4px;
  background: #9d8064;
  clip-path: polygon(0 50%, 100% 0, 72% 100%);
}
.starmap-debris-field__shard--a {
  left: 3px;
  top: 5px;
  transform: rotate(24deg);
}
.starmap-debris-field__shard--b {
  right: 2px;
  bottom: 4px;
  transform: rotate(-32deg) scale(0.8);
}
.building-tile__structure-track {
  height: 5px;
  margin-top: 4px;
  overflow: hidden;
  border-radius: 3px;
  background: rgba(224, 90, 74, 0.18);
}
.building-tile__structure-track span {
  display: block;
  height: 100%;
  background: var(--accent-red);
}
.building-tile__structure--light .building-tile__structure-track { background: rgba(255, 215, 106, 0.18); }
.building-tile__structure--light .building-tile__structure-track span { background: #ffd76a; }
.building-tile__structure--damaged .building-tile__structure-track { background: rgba(224, 131, 74, 0.2); }
.building-tile__structure--damaged .building-tile__structure-track span { background: #e0834a; }
.building-tile__structure--destroyed .building-tile__structure-track { background: rgba(224, 90, 74, 0.25); }
.building-tile__structure--destroyed .building-tile__structure-track span { background: #e05a4a; }

/* K4d: Reparatur ist ein eigener Vorgang neben dem Ausbau. Der Rahmen trennt
   Reparaturkosten und -aktion von den darunter weiterhin sichtbaren
   Ausbaukosten. */
.building-repair {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 2px;
  padding: 8px;
  border: 1px solid rgba(224, 131, 74, 0.35);
  border-radius: var(--radius-sm);
  background: rgba(224, 131, 74, 0.07);
}
.building-repair--active { border-color: rgba(95, 216, 138, 0.45); }
.building-repair__title {
  color: #f0b26c;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.building-repair__progress,
.building-repair__start {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.building-repair__time { color: var(--accent-green); font-variant-numeric: tabular-nums; }
.building-repair__start,
.building-repair__cancel {
  border: 1px solid rgba(224, 131, 74, 0.55);
  border-radius: var(--radius-sm);
  background: rgba(224, 131, 74, 0.13);
  color: #f0b26c;
  font: inherit;
  font-size: 11px;
  padding: 5px 8px;
  cursor: pointer;
}
.building-repair__start { justify-content: center; width: 100%; }
.building-repair__start:disabled {
  border-color: var(--border);
  background: rgba(139, 150, 186, 0.07);
  color: var(--text-dim);
  cursor: not-allowed;
}
.building-repair__cancel { color: var(--accent-red); border-color: rgba(224, 90, 74, 0.45); }
.building-repair__reason { color: var(--text-dim); font-size: 10px; line-height: 1.35; }

/* K4d: Die Hüllenstufe muss auch ohne Lesen erkennbar sein. Die exakten
   Prozentwerte bleiben daneben stehen; Farbe und linke Markierung tragen die
   schnelle Einordnung. */
.ships-bar--hull {
  padding: 3px 5px;
  border-left: 3px solid transparent;
  border-radius: 3px;
}
.ships-bar--light { border-left-color: #ffd76a; background: rgba(255, 215, 106, 0.07); }
.ships-bar--damaged { border-left-color: #e0834a; background: rgba(224, 131, 74, 0.1); }
.ships-bar--destroyed { border-left-color: #e05a4a; background: rgba(224, 90, 74, 0.16); }
/* Genau zwei Zeilen statt "mindestens zwei" (Nutzeranfrage 2026-08-01: alle
   Kacheln gleich gross). Laengere Beschreibungen werden abgeschnitten - der
   vollstaendige Text steht im Detail-Fenster hinter dem Info-Knopf. */
.building-tile__desc {
  font-size: 11px; color: var(--text-dim); line-height: 1.4;
  height: 2.8em;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
/* Kostenliste in der Kachel (Nutzeranfrage 2026-08-01): eine Zeile je
   Ressource ueber die ganze Kachelbreite, rechts Haekchen oder "fehlt". */
.build-cost-list {
  display: flex; flex-direction: column; gap: 3px;
  margin: 2px 0;
  border-top: 1px solid rgba(120, 180, 255, 0.1);
  border-bottom: 1px solid rgba(120, 180, 255, 0.1);
  padding: 6px 0;
}
.build-cost-row {
  display: flex; align-items: center; gap: 7px;
  font-size: 11px; line-height: 1.3;
}
.build-cost-row__icon { font-size: 13px; flex: none; }
.build-cost-row__name { color: var(--text-muted); flex: 1; min-width: 0; }
/* Tabellarisch rechtsbuendig, damit die Mengen untereinander stehen. */
.build-cost-row__need {
  color: var(--text-primary); font-variant-numeric: tabular-nums;
  text-align: right; flex: none;
}
.build-cost-row__flag { flex: none; width: 34px; text-align: right; }
.build-cost-row__flag--ok { color: var(--accent-green); font-size: 12px; }
.build-cost-row__flag--missing {
  color: var(--accent-red); font-size: 9.5px;
  letter-spacing: 0.06em; text-transform: uppercase;
}
.build-cost-row--missing .build-cost-row__need { color: var(--accent-red); }

/* Bau-/Forschungsdauer unter der Kostenliste (Nutzeranfrage 2026-08-01):
   praesenter als die frueheren 11px Fliesstext, deshalb 12.5px und in
   Akzentfarbe. Dieselbe Klasse in Baumknoten und beiden Modalen. */
.cost-time-row {
  display: flex; align-items: center; gap: 7px;
  font-size: 12.5px; margin-top: 5px;
  color: var(--accent);
}
.cost-time-row__icon { font-size: 14px; flex: none; }
.cost-time-row__label { color: var(--text-muted); flex: 1; min-width: 0; }
.cost-time-row__value {
  font-family: var(--font-heading); font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Platzhalterzeile: haelt die Hoehe, zeigt nichts. Siehe padTo in
   renderBuildingCostRows() - alle Kacheln reservieren gleich viele Zeilen. */
.build-cost-row--filler { visibility: hidden; }
.build-cost-list--empty { border-color: transparent; }

/* margin-top: auto schiebt die Knopfzeile an den unteren Rand. Zusammen mit
   den Platzhalterzeilen und der festen Beschreibungshoehe sitzen die Knoepfe
   damit ueberall auf derselben Hoehe - auch wenn ein Gebaeudename umbricht. */
.building-tile__actions { display: flex; gap: 6px; margin-top: auto; padding-top: 2px; }
.building-tile__actions .building-tile__action { margin-top: 0; flex: 1; min-width: 0; }
/* Sich fuellender Ausbauen-Knopf waehrend des Baus. Die Fuellung ist eine
   absolut positionierte Schicht UNTER dem Label - deshalb hier position
   relative und das Label auf z-index 1, sonst verdeckt die Fuellung den Text. */
.building-tile__action--progress {
  position: relative; overflow: hidden;
  border-color: rgba(74, 144, 226, 0.6);
  cursor: default;
  display: flex; align-items: center; justify-content: center;
}
.building-tile__action-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: linear-gradient(90deg, rgba(74, 144, 226, 0.35), rgba(70, 217, 208, 0.35));
  transition: width 0.9s linear;
}
.building-tile__action-label {
  position: relative; z-index: 1;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 5px;
  max-width: 100%; overflow: hidden;
}
/* Uhr statt des Wortes "Wird gebaut": der fuellende Balken sagt das schon, und
   der Text sprengte zusammen mit langen Zeiten ("12d 07h") den schmalen Knopf
   (Nutzerbericht 2026-08-18). */
.building-tile__action-icon { font-size: 12px; opacity: 0.85; flex: none; }
.building-tile__action-time { overflow: hidden; text-overflow: ellipsis; }
/* Bauzeit unter den Kosten (Nutzeranfrage 2026-08-18): zweite Haelfte des
   Preises, bewusst dezenter als die Ressourcenzeilen. */
.building-tile__buildtime {
  display: flex; align-items: center; gap: 5px;
  font-size: 10.5px; color: var(--text-dim);
  margin-top: 4px; font-variant-numeric: tabular-nums;
}
.building-tile__bonuses,
.tech-node__bonuses,
.detail-panel__bonus-summary {
  margin-top: 7px;
  color: var(--success);
  font-size: 11px;
  line-height: 1.45;
}

.building-bonus-list {
  display: inline-grid;
  gap: 1px;
  margin-left: 4px;
  vertical-align: top;
}

.building-bonus-line {
  display: block;
}

.building-tile__bonuses .building-bonus-list,
.tech-node__bonuses .building-bonus-list {
  margin-left: 0;
}

.detail-panel__bonus-sources {
  display: grid;
  gap: 5px;
}

.detail-panel__bonus-source {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  color: var(--text-dim);
  font-size: 11px;
}

.detail-panel__bonus-source span:last-child {
  color: var(--success);
  text-align: right;
}

.research-modifier--bonus,
.detail-panel__bonus-source span.research-modifier--bonus {
  color: var(--accent-green);
}

.research-modifier--malus,
.detail-panel__bonus-source span.research-modifier--malus {
  color: var(--accent-red);
}
.building-tile__action {
  margin-top: 2px; padding: 7px 10px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-2, rgba(13,21,36,0.6));
  color: var(--accent); font-size: 11px; cursor: pointer; text-align: center;
}
.building-tile__action:hover:not(:disabled) { border-color: var(--accent); }
.building-tile__action:disabled { color: var(--text-dim); cursor: not-allowed; opacity: 0.6; }
.building-tile__action--maxed { color: var(--text-dim); cursor: default; }

/* Erweiterte Bauplanung: Einreihen und der bereits vorgemerkte Ausbau.
   Bewusst zurueckgenommen gegenueber "Ausbauen" - der Knopf startet nichts
   sofort, und das soll man ihm ansehen. */
.building-tile__action--queue {
  color: var(--text-dim);
  border-style: dashed;
}
.building-tile__action--queue:hover:not(:disabled) {
  color: var(--accent);
  border-color: var(--accent);
  border-style: solid;
}
.building-tile__action--queued {
  color: var(--warning, #e0a44a);
  border-color: color-mix(in srgb, var(--warning, #e0a44a) 45%, transparent);
  border-style: dashed;
}
.building-tile__action--queued:hover:not(:disabled) {
  border-color: var(--warning, #e0a44a);
  border-style: solid;
}
/* Info und Abbrechen sind formgleich (Nutzeranfrage 2026-08-01) - gleiche
   Polsterung und Mindestbreite, Unterschied nur in der Farbe. Die Mindestbreite
   traegt die Angleichung: "Info" ist vier Zeichen breit, das X nur eines, ohne
   sie bliebe der Abbrechen-Knopf deutlich schmaler. Die HOEHE gleicht schon das
   Flex-Layout der Knopfzeile an (align-items: stretch ist der Standard). */
.building-tile__info,
.building-tile__cancel {
  flex: none;
  min-width: 46px;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  font-size: 11px;
  cursor: pointer;
  text-align: center;
  /* Ebenfalls Pflicht: der Abbrechen-Knopf traegt zusaetzlich
     progress-box__cancel-btn mit margin-top: 12px und saesse sonst 12px tiefer
     als der Info-Knopf daneben - siehe .tech-node__cancel. */
  margin: 0;
}
.building-tile__info {
  border: 1px solid var(--border); background: var(--surface-2, rgba(13,21,36,0.6));
  color: var(--text-dim);
}
.building-tile__info:hover { border-color: var(--accent); color: var(--accent); }
/* Abbrechen: gleiche Form wie Info (Regel oben), nur in Warnfarbe. Ersetzt den
   Abbrechen-Knopf aus dem entfallenen Kasten "Aktueller Bauauftrag" - ohne ihn
   waere ein laufender Bauauftrag gar nicht mehr abzubrechen. */
.building-tile__cancel {
  border: 1px solid rgba(224, 90, 74, 0.4);
  background: rgba(224, 90, 74, 0.12);
  color: #e08a7a;
}
.building-tile__cancel:hover { border-color: var(--accent-red); }
.building-tile { position: relative; }
.building-tile__badge {
  position: absolute; top: 6px; right: 6px;
  background: #e05a4a; color: #fff; font-size: 8px; font-weight: 700;
  letter-spacing: .04em; padding: 2px 4px; border-radius: 4px;
  line-height: 1.3; pointer-events: none;
}

/* Large Collider: rein kosmetische, kurze Monitorinterferenz. Die Animation
   liegt als Overlay ueber dem Spiel und veraendert keinerlei Eingaben oder
   serverseitige Werte. */
.null-interference {
  position: fixed;
  inset: 0;
  z-index: 10000;
  overflow: hidden;
  pointer-events: none;
  background: rgba(0, 0, 0, 0.14);
  animation: null-interference-fade 1.6s steps(2, end) both;
}
.null-interference__noise,
.null-interference__scan {
  position: absolute;
  inset: -12%;
}
.null-interference__noise {
  opacity: 0.28;
  background-image:
    repeating-radial-gradient(circle at 17% 31%, rgba(255,255,255,0.7) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(97deg, transparent 0 7px, rgba(126,233,255,0.22) 8px 9px, transparent 10px 16px);
  background-size: 11px 13px, 23px 17px;
  animation: null-interference-noise 0.12s steps(2, end) infinite;
}
.null-interference__scan {
  background: repeating-linear-gradient(
    to bottom,
    transparent 0 3px,
    rgba(240, 168, 244, 0.2) 4px,
    rgba(0, 0, 0, 0.28) 5px 7px
  );
  animation: null-interference-scan 0.18s linear infinite;
}
.null-interference__label {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: 7px 12px;
  border: 1px solid rgba(240, 168, 244, 0.65);
  background: rgba(0, 0, 0, 0.78);
  color: #f0a8f4;
  font-family: var(--font-heading);
  font-size: 11px;
  letter-spacing: 0.1em;
  white-space: nowrap;
}
.null-interference-active .app-main,
.null-interference-active .app-topbar,
.null-interference-active .app-sidebar {
  animation: null-interference-screen 0.16s steps(2, end) 9;
}
@keyframes null-interference-fade {
  0%, 100% { opacity: 0; }
  8%, 86% { opacity: 1; }
}
@keyframes null-interference-noise {
  0% { transform: translate(-2%, 1%); }
  50% { transform: translate(3%, -2%); }
  100% { transform: translate(-1%, 3%); }
}
@keyframes null-interference-scan {
  from { transform: translateY(-7px); }
  to { transform: translateY(7px); }
}
@keyframes null-interference-screen {
  0%, 100% { transform: translateX(0); filter: none; }
  35% { transform: translateX(-2px); filter: contrast(1.3) hue-rotate(12deg); }
  70% { transform: translateX(2px); filter: contrast(0.8) hue-rotate(-10deg); }
}
@media (prefers-reduced-motion: reduce) {
  .null-interference,
  .null-interference__noise,
  .null-interference__scan,
  .null-interference-active .app-main,
  .null-interference-active .app-topbar,
  .null-interference-active .app-sidebar {
    animation: none;
  }
  .null-interference { opacity: 1; background: rgba(0, 0, 0, 0.08); }
  .null-interference__noise,
  .null-interference__scan { display: none; }
}

/* --- Techtree Sprint 4: Werft --- */
/* 44 -> 64 px (Nutzerwunsch 2026-09-04: "ein bisschen groesser als bisher
   duerfen sie sein"). Die Grafiken liegen mit 192 px laengster Kante vor,
   also dreifach - das reicht auch fuer Bildschirme mit doppelter Dichte. */
.detail-panel__ship-fig { width: 64px; display: flex; align-items: center; justify-content: center; }
.detail-panel__ship-fig .ship-figure { width: 58px; height: 68px; }
/* Die gezeichnete Grafik passt sich ein, ohne ihr Seitenverhaeltnis zu
   verlieren: die Modelle sind unterschiedlich breit (Hopper 192x128, Firefly
   189x192), und ein fester Rahmen wuerde sie stauchen. */
.ship-figure-img {
  max-width: 64px;
  max-height: 68px;
  width: auto;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .55));
  transition: transform .12s ease, filter .12s ease;
}

/* DIE LUPE NUR, WO DER KLICK AUCH ETWAS TUT (Nutzerbefund 2026-09-11:
   "Lupe im Flottenmenue auf der Schiffsgrafik... aktuell passiert nix").
   Vorher trug JEDE Schiffsgrafik `cursor: zoom-in` - auch die, die nur
   Beiwerk in einer Tabelle war. Der Zeiger versprach etwas, das es nicht
   gab. Jetzt haengt er am selben Merkmal wie der Zuhoerer. */
.ship-figure-img[data-ship-image] { cursor: zoom-in; }
.ship-figure-img[data-ship-image]:hover,
.ship-figure-img[data-ship-image]:focus-visible {
  transform: scale(1.08);
  filter: drop-shadow(0 0 7px rgba(127, 233, 255, .55));
  outline: none;
}

/* Die grosse Ansicht (Nutzerwunsch 2026-09-04). Sie zeigt nur das Schiff -
   Werte und Knoepfe stehen auf der Karte, von der aus man herkommt. */
.ship-image-modal { text-align: center; }
.ship-image-modal__title { margin: 4px 0 16px; font-size: 20px; }
.ship-image-modal__img {
  max-width: 100%;
  /* Bis zur Hoehe des Sichtfensters, damit ein hochformatiges Modell wie der
     Firefly nicht ueber den unteren Rand hinauslaeuft. */
  max-height: 62vh;
  object-fit: contain;
  filter: drop-shadow(0 6px 24px rgba(0, 0, 0, .6));
}
.detail-panel__build-row { display: flex; gap: 8px; margin-top: 12px; }
.detail-panel__quantity {
  width: 64px; padding: 9px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-2, rgba(13,21,36,0.6));
  color: var(--text-primary); font-size: 12px; text-align: center;
}
.detail-panel__build-row .detail-panel__action { margin-top: 0; flex: 1; }

.ship-group { margin-bottom: 22px; }
.ship-group__head {
  font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-dim); margin-bottom: 10px;
}
/* Grosse Vollinfo-Kacheln: max 4 nebeneinander, Block ~70% der Breite
   (nicht full width), linksbuendig. Responsive stufenweise reduziert. */
.ship-fullcard-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  max-width: 70%;
}
.ship-fullcard {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
}
.ship-fullcard .detail-panel__head { margin-bottom: 10px; }
/* Nutzerentscheidung 2026-07-28: Platz fuer zwei Zeilen reservieren, damit
   Werte/Kosten/Button unabhaengig von ein- oder zweizeiliger Beschreibung
   auf gleicher Hoehe sitzen (analog .building-tile__desc). */
.ship-fullcard .detail-panel__desc { min-height: 3em; }
/* Der [Details]-Aufklapper (Nutzerwunsch 2026-09-10). Die Balken machten die
   Werftseite unuebersichtlich; Icon, Name, Beschreibung, Kosten und die
   Bauzeile bleiben sichtbar, die Werte klappen auf Wunsch auf. */
.ship-fullcard__details { margin: 4px 0 2px; }
.ship-fullcard__details-toggle {
  cursor: pointer;
  list-style: none;
  display: inline-block;
  padding: 2px 0;
  font-size: 12px;
  color: var(--accent);
  user-select: none;
}
.ship-fullcard__details-toggle::-webkit-details-marker { display: none; }
.ship-fullcard__details-toggle::before {
  content: '[+] ';
  font-family: monospace;
}
.ship-fullcard__details[open] > .ship-fullcard__details-toggle::before { content: '[2] '; }
.ship-fullcard__details-toggle:hover { text-decoration: underline; }

.ship-fullcard__build-row { display: flex; gap: 8px; margin-top: 12px; }
.ship-fullcard__quantity {
  width: 60px; padding: 9px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-2, rgba(13,21,36,0.6));
  color: var(--text-primary); font-size: 12px; text-align: center;
}
.ship-fullcard__build-row .detail-panel__action { margin-top: 0; flex: 1; }
/* Der Fortschrittsknopf steht allein in der Zeile (kein Mengenfeld daneben)
   und traegt nicht .detail-panel__action, bekam das flex:1 der Zeile darueber
   also nicht ab - er blieb schmal, waehrend der Bauen-Knopf sich streckt.
   Nutzerwunsch 2026-08-19: volle Kachelbreite. */
.ship-fullcard__build-row .building-tile__action { margin-top: 0; flex: 1; }
@media (max-width: 1500px) { .ship-fullcard-grid { max-width: 100%; } }
@media (max-width: 1200px) { .ship-fullcard-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 900px) { .ship-fullcard-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .ship-fullcard-grid { grid-template-columns: 1fr; } }

/* Xenobiologie Sub-Projekt D: Sammlungskarten, Vorbild .ship-fullcard-grid */
.creature-card-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  max-width: 70%;
}
.creature-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  text-align: center;
  position: relative;
}
.creature-card--known { cursor: pointer; }
.creature-card--unknown { opacity: 0.55; }
.creature-card--identifying { opacity: 1; }
.creature-card--identifying { opacity: 1; }
.creature-card__fig { display: flex; justify-content: center; margin-bottom: 8px; }
.creature-card__name { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.creature-card__meta { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; margin-top: 2px; }
.creature-card__status { font-size: 11px; color: var(--text-dim); margin-top: 8px; }
.creature-card__badge {
  position: absolute; top: 8px; right: 8px; font-size: 9px; letter-spacing: 0.08em;
  padding: 2px 6px; border-radius: 999px; background: rgba(95, 216, 138, 0.15);
  color: #5fd88a; border: 1px solid rgba(95, 216, 138, 0.4);
}
/* Frisch bestimmt (Nutzerwunsch 2026-09-06). LINKS oben, weil "GESAMMELT"
   rechts oben sitzt - beide absolut an derselben Ecke haetten einander
   verdeckt, und zwar ausgerechnet im haeufigsten Fall: Eine gerade bestimmte
   Art ist immer auch gesammelt.

   Blau statt gruen: Gruen heisst hier "gehoert dir", blau heisst "sieh hier
   hin" - dieselbe Farbe wie die uebrigen Neuheiten-Hinweise im Spiel. */
.creature-card__badge--new {
  right: auto;
  left: 8px;
  background: rgba(74, 144, 226, 0.16);
  color: #7fb4ff;
  border-color: rgba(74, 144, 226, 0.45);
}
@media (max-width: 1500px) { .creature-card-grid { max-width: 100%; } }
@media (max-width: 1200px) { .creature-card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 900px) { .creature-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .creature-card-grid { grid-template-columns: 1fr; } }
.creature-card--analyzing { opacity: 1; cursor: default; }
.creature-card__pending-status { font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; margin-top: 8px; }
.creature-card__pending-status--ready { color: #8fe0a0; }
.creature-card__pending-status--transit { color: #8b96ba; }
.creature-card__pending-action {
  margin-top: 6px; font-family: var(--font-heading); font-size: 11px; letter-spacing: 0.04em;
  color: #0a0c18; background: linear-gradient(135deg, #7fe98f, #46d9a0);
  border: none; border-radius: 5px; padding: 6px 12px; cursor: pointer;
}

/* Labor-Modal: einfache Label/Wert-Zeilen ohne Balken (kein Vorbild in kit.js
   fuer nicht-numerische Werte). */
.creature-info-row {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 6px 0; border-bottom: 1px solid var(--border); font-size: 12px;
}
.creature-info-row__label { color: var(--text-dim); }
.creature-info-row__value { color: var(--text-primary); text-align: right; }

/* --- Flotten-Management Sprint 5: Flottenansicht --- */
.fleet-group__tiles {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 280px));
  gap: 12px; justify-content: start; margin-bottom: 8px;
}
.fleet-tile {
  position: relative;
  display: flex; align-items: stretch;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 12px 14px; cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.fleet-tile__color-dot {
  position: absolute; top: 10px; right: 10px;
  width: 12px; height: 12px; border-radius: 50%;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.4);
}
.fleet-tile:hover { background: rgba(70, 217, 208, 0.06); border-color: rgba(70,217,208,0.4); }
.fleet-tile__body { flex: 1; min-width: 0; }
.fleet-tile__name { font-family: var(--font-heading); font-size: 13.5px; color: var(--text-primary); }
.fleet-tile__location { font-size: 10.5px; color: var(--text-muted); margin-top: 3px; }
.fleet-tile__meta { font-size: 10.5px; color: var(--accent); margin-top: 4px; }
/* Fortschritt des laufenden Auftrags (Nutzerwunsch 2026-08-19): derselbe Balken
   wie in der Abbau-Uebersicht, nur schmaler fuer die kleinere Kachel. */
.fleet-tile__bar { margin-top: 6px; height: 4px; }
.fleet-tile__eta { margin-top: 4px; font-size: 9.5px; color: var(--text-dim); }
.fleet-tile__stats {
  display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 8px;
  font-size: 9.5px; color: var(--text-dim);
}
.fleet-create-btn {
  display: inline-block; margin-top: 12px; padding: 9px 16px;
  border-radius: var(--radius-sm); border: 1px solid var(--accent);
  background: rgba(70, 217, 208, 0.12); color: var(--accent);
  font-size: 12px; cursor: pointer;
}

/* "Alle nachhause kommen" (Spec 2026-09-18, Paket A).
   Gedaempfter als der Erstellen-Knopf daneben: Der Rueckruf bricht Auftraege
   ab, er soll nicht der auffaelligste Knopf der Seite sein. */
.fleet-recall-all-btn {
  display: inline-block; margin-top: 12px; margin-left: 8px; padding: 9px 16px;
  border-radius: var(--radius-sm); border: 1px solid var(--text-muted);
  background: transparent; color: var(--text-muted);
  font-size: 12px; cursor: pointer;
}
.fleet-recall-all-btn:hover {
  border-color: var(--accent-gold); color: var(--accent-gold);
}
.fleet-recall-all-btn i { margin-right: 4px; }

/* Der Knopf IN der Kachel. Die Kachel selbst ist klickbar und oeffnet den
   Flotteneditor - deshalb muss dieser Knopf sichtbar ein eigenes Ziel sein
   und nicht wie Text aussehen. */
.fleet-tile__recall {
  margin-top: 10px; padding: 5px 10px;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.03); color: var(--text-muted);
  font-size: 11px; cursor: pointer;
}
.fleet-tile__recall:hover {
  border-color: var(--accent-gold); color: var(--accent-gold);
}
.fleet-tile__recall i { margin-right: 4px; }

.fleet-unassigned-group { margin-top: 18px; }
.fleet-unassigned-group__head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-dim); margin-bottom: 8px;
}
.fleet-unassigned-group__total { color: var(--text-muted); letter-spacing: 0.04em; }

/* TABELLE STATT KACHELN (Nutzerwunsch 2026-09-05): Hier stand ein
   `fleet-roster-grid` mit einer `fleet-roster-card` je EINZELNEM Schiff. Bei
   hundert unzugewiesenen Schiffen waren das hundert Kaesten. Jetzt eine Zeile
   je Typ. Die alten Kachelregeln sind mit der letzten Verwendung im JS
   entfallen. */
.fleet-unassigned-table {
  width: 100%; max-width: 520px; border-collapse: collapse;
  background: var(--surface-active); border: 1px solid var(--border);
  border-radius: var(--radius-sm); overflow: hidden;
}
.fleet-unassigned-table th {
  padding: 7px 12px; text-align: left;
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-dim); background: rgba(120, 150, 220, .07);
  border-bottom: 1px solid var(--border);
}
.fleet-unassigned-table td {
  padding: 6px 12px; font-size: 12px; color: var(--text-primary);
  border-bottom: 1px solid rgba(120, 150, 220, .10);
}
.fleet-unassigned-table tr:last-child td { border-bottom: none; }
.fleet-unassigned-table__type { display: flex; align-items: center; gap: 8px; }
/* Platzhalter in Bildgroesse: ohne ihn ruecken Namen ohne Grafik nach links
   und die Spalte franst aus. */
.fleet-unassigned-table__nopic { display: inline-block; width: 28px; height: 20px; }
.fleet-unassigned-table__count {
  text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.fleet-unassigned-table__damaged {
  display: block; font-size: 10px; color: var(--warning, #e0a458);
}
.fleet-stats-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px; margin: 10px 0 4px;
}
.fleet-form { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.fleet-form__field { display: flex; flex-direction: column; gap: 4px; }
.fleet-form__label { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dim); }
.fleet-form__input, .fleet-form__select {
  padding: 9px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface-2, rgba(13,21,36,0.6)); color: var(--text-primary); font-size: 12px;
}
.fleet-color-picker { display: flex; flex-wrap: wrap; gap: 8px; }
.fleet-color-swatch {
  width: 24px; height: 24px; border-radius: 50%; cursor: pointer;
  border: 2px solid transparent; padding: 0;
}
.fleet-color-swatch:hover { border-color: rgba(255, 255, 255, 0.35); }
.fleet-color-swatch--selected { border-color: #fff; box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.25); }
.fleet-editor__appearance { display: flex; flex-direction: column; gap: 10px; }
.fleet-icon-picker { display: flex; flex-wrap: wrap; gap: 8px; }
.fleet-icon-choice {
  width: 30px; height: 30px; padding: 0; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid transparent; background: var(--surface-active);
  color: var(--accent); cursor: pointer; font-size: 17px;
}
.fleet-icon-choice:hover { border-color: rgba(255, 255, 255, 0.35); }
.fleet-icon-choice--selected { border-color: #fff; box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.25); }
.fleet-icon-choice--automatic { width: auto; padding: 0 9px; gap: 6px; font-size: 15px; }
.fleet-icon-choice--automatic span { color: var(--text-secondary); font-size: 10px; }
.fleet-detail__rename { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.fleet-detail__rename .fleet-form__input { flex: 1; }
.fleet-detail__rename .detail-panel__action { width: auto; margin-top: 0; padding: 9px 14px; }
.fleet-detail__disband-btn { border-color: var(--accent-red) !important; color: var(--accent-red) !important; }
@media (max-width: 900px) { .fleet-group__tiles { grid-template-columns: repeat(2, 1fr); } }

.org-color-picker-row { display: flex; align-items: center; gap: 8px; }
.org-color-input {
  width: 44px; height: 34px; padding: 2px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: none; cursor: pointer;
}
.org-color-preview {
  padding: 6px 10px; border-radius: var(--radius-sm); font-size: 12px; font-family: monospace;
  color: #0a1f10; text-shadow: 0 0 2px rgba(255,255,255,0.4);
}

.fleet-editor { display: flex; flex-direction: column; gap: 14px; min-height: calc(100% - 82px); }
.fleet-editor__settings { display: grid; grid-template-columns: minmax(220px, 2fr) minmax(220px, 1fr) minmax(220px, 1fr); gap: 14px; }
.fleet-editor__feedback { padding: 10px 12px; border: 1px solid var(--accent); border-radius: var(--radius-sm); color: var(--text-primary); background: rgba(127, 233, 255, 0.08); }
.fleet-editor__hint { margin: 0; color: var(--text-muted); font-size: 12px; }
.fleet-editor__info-btn {
  background: none; border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text-muted); font-size: 10px; padding: 2px 6px; cursor: pointer; margin-left: 6px;
}
.fleet-manifest { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; min-height: 0; flex: 1; }
.fleet-manifest__side { min-width: 0; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 12px; overflow-y: auto; }
.fleet-manifest__group { display: grid; grid-template-columns: minmax(0, 1fr) auto; border-top: 1px solid var(--border); }
.fleet-manifest__group:first-of-type { border-top: 0; }
.fleet-manifest__group-toggle { display: grid; grid-template-columns: 18px minmax(100px, 1fr) 48px 92px; align-items: center; gap: 8px; padding: 10px 8px; border: 0; background: none; color: var(--text-body); text-align: left; cursor: pointer; }
.fleet-manifest__type { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fleet-manifest__count, .fleet-manifest__hull, .fleet-manifest__ship-hull { color: var(--text-muted); font-variant-numeric: tabular-nums; font-size: 12px; }
.fleet-manifest__bulk { display: flex; align-items: center; gap: 6px; padding: 6px 8px; }
.fleet-manifest__bulk input { width: 68px; padding: 6px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); color: var(--text-body); }
.fleet-manifest__bulk button, .fleet-manifest__arrow { padding: 6px 9px; border: 1px solid var(--border-strong); border-radius: 4px; background: var(--surface-active); color: var(--accent-bright); cursor: pointer; }
.fleet-manifest__bulk button:disabled, .fleet-manifest__arrow:disabled { opacity: 0.45; cursor: default; }
.fleet-manifest__ships { grid-column: 1 / -1; padding: 0 8px 8px 34px; }
.fleet-manifest__ship { display: grid; grid-template-columns: minmax(100px, 1fr) 76px auto auto; align-items: center; gap: 6px; padding: 6px 0; border-top: 1px solid rgba(255,255,255,0.04); font-size: 12px; }
.fleet-manifest__ship-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 850px) {
  .fleet-editor-modal { width: calc(100vw - 16px); height: calc(100vh - 16px); padding: 16px; }
  .fleet-editor__settings, .fleet-manifest { grid-template-columns: 1fr; }
  .fleet-manifest__side { max-height: none; overflow: visible; }
}

.ship-stat-bar { margin-bottom: 4px; }
.ship-stat-bar__label { font-size: 10px; color: var(--text-dim); display: block; margin-bottom: 2px; text-align: left; }
.ship-stat-bar__track { position: relative; height: 18px; border-radius: 4px; background: rgba(120, 180, 255, 0.08); overflow: hidden; }
.ship-stat-bar__fill { position: absolute; inset: 0; height: 100%; }
.ship-stat-bar__value {
  position: relative; text-align: center; line-height: 18px; font-size: 10.5px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* --- Automatisierter Abbau Sprint 6: Abbau-Uebersichtsseite --- */
.mining-order-tiles {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 320px));
  gap: 12px; justify-content: start; margin-bottom: 8px;
}
.mining-order-tile {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 14px 16px;
}
.mining-order-tile__target { font-family: var(--font-heading); font-size: 13.5px; color: var(--text-primary); }
.mining-order-tile__system { color: var(--text-muted); font-weight: normal; }
.mining-order-tile__fleet { font-size: 10.5px; color: var(--text-muted); margin-top: 3px; }
.mining-order-tile__meta { font-size: 10.5px; color: var(--accent); margin-top: 4px; }
.mining-order-tile__bar { margin-top: 8px; }

/* Flottenauswahl in der Systemansicht (Bugreport 2026-08-18): gebundene
   Flotten bleiben waehlbar - nur so erreicht man ihren Abbrechen-Knopf -,
   sind aber sichtbar als beschaeftigt gekennzeichnet. */
.system-fleet-pick { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.system-fleet-pick__btn {
  background: var(--surface-active); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); color: var(--text-primary);
  font-size: 11px; padding: 6px 10px; cursor: pointer;
}
.system-fleet-pick__btn--active { border-color: var(--accent); color: var(--accent); }
.system-fleet-pick__btn--busy { opacity: 0.55; font-style: italic; }

/* Fernglas in der Flottenuebersicht + Markierung auf der Karte
   (Nutzerentscheidung 2026-08-18). Gebundene Flotten kreisen nicht mehr auf der
   Karte; die Liste ist dann der Weg, sie zu finden. */
.starmap-fleet-selector__find {
  background: none; border: none; cursor: pointer; padding: 2px 4px;
  color: var(--text-muted); font-size: 13px; line-height: 1;
}
.starmap-fleet-selector__find:hover { color: var(--accent); }
.starmap-fleet-selector__item-ort { color: var(--text-dim); }

.starmap-find-marker {
  position: absolute; width: 46px; height: 46px; margin: -23px 0 0 -23px;
  border: 2px solid var(--accent); border-radius: 50%;
  pointer-events: none; z-index: 7;
  animation: starmapFindPulse 1.4s ease-out infinite;
}
@keyframes starmapFindPulse {
  0%   { transform: scale(0.55); opacity: 1; }
  100% { transform: scale(1.5);  opacity: 0; }
}

/* Anomalien im freien Raum (Paket 2026-09-03). Sie haengen an keinem Stern und
   bekommen deshalb einen eigenen Punkt in rohen Weltkoordinaten.

   EINE RAUTE, kein Kreis: runde Marker sind auf dieser Karte durchweg Sterne,
   Flotten oder Suchgebiete. Eine Form, die es sonst nicht gibt, laesst sich
   ohne Legende einordnen - und der Spieler soll auf den ersten Blick sehen,
   dass dort NICHTS ist ausser der Signatur.

   z-index 6: ueber der Unbekannt-Kulisse (5), unter Flottenmarkern (7). Der
   Fund ist Umgebung, kein eigener Akteur. */
.starmap-deep-anomaly {
  position: absolute;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  z-index: 6;
  cursor: pointer;
}
.starmap-deep-anomaly__mark {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 9px;
  height: 9px;
  margin: -4.5px 0 0 -4.5px;
  transform: rotate(45deg);
  background: var(--anomaly-color, #c792ea);
  box-shadow: 0 0 8px var(--anomaly-color, #c792ea);
  opacity: 0.85;
}
.starmap-deep-anomaly:hover .starmap-deep-anomaly__mark { opacity: 1; }
/* Der Ring markiert die Auswahl - dieselbe Sprache wie beim gewaehlten Stern,
   nur eckig, damit die Form durchgehalten bleibt. */
.starmap-deep-anomaly--selected::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  transform: rotate(45deg);
  border: 1px dashed var(--anomaly-color, #c792ea);
}

.starmap-cta--anomaly {
  border-color: rgba(199, 146, 234, 0.45);
  color: #c792ea;
}
/* Der Grund steht UNTER dem gesperrten Knopf, nicht nur im title: ein Hinweis,
   den man erst beim Darueberfahren findet, ist fuer den Spieler keiner
   (Nutzervorgabe 2026-09-03). */
.starmap-info-panel__hint {
  margin-top: 6px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-muted);
}
.starmap-info-panel__row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 0;
  font-size: 11.5px;
  color: var(--text-dim);
}
.starmap-info-panel__row span:last-child { color: var(--text-primary); }
/* Questhilfe (Nutzerwunsch 2026-08-19): Suchgebiet einer aktiven Mission. Das
   Zielsystem liegt irgendwo in diesem Kreis - nicht in der Mitte, moeglicherweise
   am Rand.

   z-index 6 wie die Sichtradius-Grenzlinie und damit UEBER der schwarzen
   "Unbekanntes Universum"-Kulisse (starmap-unknown-veil, z5). Das ist Absicht:
   Missionsziele liegen regelmaessig jenseits des eigenen Sichtradius, und dann
   ist der Kreis die Aufforderung, Reichweite auszubauen. */
.starmap-mission-hint {
  position: absolute;
  transform: translate(-50%, -50%);
  border: 2px dashed rgba(74, 144, 226, 0.75);
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(74, 144, 226, 0.13) 0%,
    rgba(74, 144, 226, 0.05) 65%,
    transparent 100%);
  box-shadow: 0 0 24px rgba(74, 144, 226, 0.22), inset 0 0 50px rgba(74, 144, 226, 0.07);
  pointer-events: none;
  z-index: 6;
  /* Das Suchgebiet engt sich beim Absuchen ein (Nutzerwunsch 2026-09-18) und
     soll dabei sichtbar zusammenfahren, statt veraendert dazustehen. Die
     Dauer ist absichtlich lang: Der Kreis wandert gleichzeitig zum Ziel hin,
     und diese Bewegung ist die eigentliche Auskunft - sie soll man sehen. */
  transition: left .9s ease-out, top .9s ease-out, width .9s ease-out, height .9s ease-out;
}
/* Waehrend des Zusammenfahrens kurz kraeftiger, damit der Blick hinfindet -
   auf einer Karte mit tausend Sternen geht eine stille Bewegung unter. */
.starmap-mission-hint--narrowing {
  border-color: rgba(120, 190, 255, 0.95);
  box-shadow: 0 0 34px rgba(74, 144, 226, 0.4), inset 0 0 50px rgba(74, 144, 226, 0.1);
  transition: left .9s ease-out, top .9s ease-out, width .9s ease-out, height .9s ease-out,
              border-color 1.6s ease-out, box-shadow 1.6s ease-out;
}
.starmap-mission-hint__label {
  position: absolute; left: 50%; top: 0; transform: translate(-50%, -160%);
  white-space: nowrap;
  font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase;
  color: #9fc6f2; text-shadow: 0 0 6px #000, 0 0 6px #000;
}

/* Suchgebiet aus einem Anomaliehinweis (Paket I-1b). Gruen statt blau und
   feiner gepunktet - ein Hinweis ist Information, kein Auftrag, und soll
   nicht wie ein Missionsziel aussehen. */
.starmap-anomaly-hint {
  position: absolute;
  transform: translate(-50%, -50%);
  border: 2px dotted rgba(143, 224, 160, 0.7);
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(143, 224, 160, 0.10) 0%,
    rgba(143, 224, 160, 0.04) 65%,
    transparent 100%);
  box-shadow: 0 0 22px rgba(143, 224, 160, 0.18), inset 0 0 46px rgba(143, 224, 160, 0.06);
  pointer-events: none;
  z-index: 6;
}
.starmap-anomaly-hint__label {
  position: absolute; left: 50%; top: 0; transform: translate(-50%, -160%);
  white-space: nowrap;
  font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase;
  color: #8fe0a0; text-shadow: 0 0 6px #000, 0 0 6px #000;
}
/* Ziel entdeckt: der Suchkreis weicht dem exakten Marker. */
.starmap-mission-target {
  position: absolute; width: 32px; height: 32px; margin: -16px 0 0 -16px;
  border: 2px solid var(--accent-blue); border-radius: 50%;
  box-shadow: 0 0 14px rgba(74, 144, 226, 0.55);
  pointer-events: none; z-index: 7;
}
.starmap-mission-target__pulse {
  position: absolute; left: 50%; top: 50%; width: 32px; height: 32px;
  margin: -16px 0 0 -16px;
  border: 2px solid var(--accent-blue); border-radius: 50%;
  animation: starmapFindPulse 1.8s ease-out infinite;
}
.starmap-mission-target__label {
  position: absolute; left: 50%; top: 100%; transform: translate(-50%, 6px);
  white-space: nowrap;
  font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase;
  color: #9fc6f2; text-shadow: 0 0 6px #000, 0 0 6px #000;
}
.mining-order-tile__stats {
  display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 8px;
  font-size: 9.5px; color: var(--text-dim);
}
/* (i) neben der Gesamtzahl: oeffnet die Aufschluesselung nach Ressourcen
   (Nutzerwunsch 2026-08-30). Sitzt IN der Zahlen-Zeile, damit klar ist, worauf
   es sich bezieht - ein eigener Knopf in der Aktionsleiste haette wie eine
   dritte Auftragsaktion neben Anzeigen und Abbrechen ausgesehen. */
.mining-order-tile__info {
  border: none; background: none; padding: 0 0 0 4px; cursor: pointer;
  color: var(--text-dim); font-size: 11px; line-height: 1; vertical-align: -1px;
}
.mining-order-tile__info:hover { color: var(--accent-blue); }
.mining-yield-list { display: flex; flex-direction: column; gap: 6px; }
.mining-yield-row {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px; border-radius: var(--radius-sm);
  background: rgba(255,255,255,.03); border: 1px solid var(--border);
}
.mining-yield-row__icon { font-size: 14px; flex: none; }
.mining-yield-row__name { flex: 1; font-size: 11.5px; color: var(--text-muted); }
.mining-yield-row__amount {
  font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.mining-order-tile__actions { display: flex; gap: 8px; margin-top: 12px; }
.mining-order-tile__btn {
  flex: 1; padding: 7px 10px; font-size: 10.5px; letter-spacing: .04em;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: rgba(255,255,255,.04); color: var(--text-primary); cursor: pointer;
}
.mining-order-tile__btn--danger { border-color: rgba(224,90,74,.4); color: #e08a7a; background: rgba(224,90,74,.08); }
/* Abbruch angefordert: der Auftrag laeuft noch bis zum Zyklusende, ein zweiter
   Klick waere wirkungslos - deshalb ersetzt dieser Zustand den Abbrechen-Knopf. */
.mining-order-tile__btn--stopping {
  border-color: rgba(255,215,106,.35); color: var(--accent-gold);
  background: rgba(255,215,106,.07); cursor: default;
  display: inline-flex; align-items: center; gap: 5px;
}
.mining-order-tile__btn--stopping:disabled { opacity: 1; }
@media (max-width: 620px) { .fleet-group__tiles { grid-template-columns: 1fr; } .fleet-stats-grid { grid-template-columns: repeat(2, 1fr); } }

.starmap-territory-ring {
  position: absolute; border: 2px dashed; border-radius: 50%;
  pointer-events: none; z-index: 6; opacity: 0.65;
}
.starmap-territory-ring__label {
  position: absolute; top: -18px; left: 50%; transform: translateX(-50%);
  font-size: 11px; letter-spacing: 0.04em; white-space: nowrap;
  text-shadow: 0 0 4px rgba(0,0,0,0.8);
}

.creature-capture-show {
  margin-top: 6px; padding: 8px; border-radius: 6px;
  background: rgba(95,216,138,.06); border: 1px solid rgba(95,216,138,.3);
}
.creature-capture-show__wave { display: block; width: 100%; height: 40px; }
.creature-capture-show__vitals { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
.creature-capture-show__heartbeat {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  animation: creature-capture-heartbeat 1.1s ease-in-out infinite;
}
@keyframes creature-capture-heartbeat {
  0%, 100% { transform: scale(.7); opacity: .6; }
  15% { transform: scale(1.15); opacity: 1; }
  30% { transform: scale(.85); opacity: .8; }
  45% { transform: scale(1); opacity: 1; }
  60% { transform: scale(.7); opacity: .6; }
}
.creature-capture-show__telemetry {
  font-size: 9.5px; letter-spacing: .05em; color: #8b96ba; font-variant-numeric: tabular-nums;
}
.creature-capture-show__progress-track {
  margin-top: 6px; height: 3px; border-radius: 2px; background: rgba(255,255,255,.08); overflow: hidden;
}
.creature-capture-show__progress-bar { height: 100%; transition: width .1s linear; }
.creature-capture-show__log { margin-top: 8px; display: flex; flex-direction: column; gap: 3px; }
.creature-capture-show__log-line {
  font-size: 10px; letter-spacing: .03em; color: #cfd7f5;
  animation: creature-capture-log-in .3s ease-out;
}
@keyframes creature-capture-log-in {
  from { opacity: 0; transform: translateY(-3px); }
  to { opacity: 1; transform: translateY(0); }
}

/* --- Missionssystem Sprint 7: Missionsuebersicht --- */
/* Missionsfilter (Nutzerwunsch 2026-08-28): standardmaessig stehen nur die
   offenen Auftraege da, Abgeschlossene und Abgelaufene sind zuschaltbar. */
.mission-filter {
  display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px;
}
.mission-filter__btn {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 7px 12px;
  color: #8b96ba; font-size: 13px; cursor: pointer;
}
.mission-filter__btn:hover { border-color: rgba(127, 233, 255, 0.35); color: #c9d4f0; }
.mission-filter__btn--on { color: #7fe9ff; border-color: rgba(127, 233, 255, 0.5); }
.mission-filter__count {
  background: rgba(127, 233, 255, 0.12); border-radius: 999px;
  padding: 1px 7px; font-size: 12px;
}
/* Erledigte Auftraege als Zweizeiler - handeln kann man dort nicht mehr,
   eine volle Karte waere verschenkter Platz. */
.mission-rows { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.mission-row {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 9px 14px;
}
.mission-row__head {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
}
.mission-row__title {
  font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mission-row__sub {
  color: #8b96ba; font-size: 12px; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mission-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 320px));
  gap: 12px; justify-content: start; margin-bottom: 8px;
}
.mission-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 14px 16px;
}
/* Die Zivilisationsgeschichte als Kettenmission (2026-09-05).
 *
 * Sie soll sich abheben, ohne zu schreien: ein zweifarbiger Rand, ein
 * leichter Schein und ein Glied als Zeichen. Kein durchgefaerbter Kasten -
 * sie steht zwischen gewoehnlichen Auftraegen, und ein voll gefaerbter Block
 * naehme ihnen die Lesbarkeit.
 *
 * position: relative traegt das Kettenglied am linken Rand. */
.mission-card--chain {
  position: relative;
  border-color: rgba(240, 168, 244, .42);
  background:
    linear-gradient(160deg, rgba(240, 168, 244, .07), rgba(0, 0, 0, 0) 55%),
    var(--surface);
  box-shadow: 0 0 0 1px rgba(240, 168, 244, .12), 0 0 18px -6px rgba(240, 168, 244, .45);
}

/* Der farbige Streifen an der linken Kante - dieselbe Sprache wie die
   Warnstufen im DEFCON-Reiter: die Kante traegt die Bedeutung. */
.mission-card__chain-mark {
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: linear-gradient(180deg, #f0a8f4, rgba(240, 168, 244, .25));
}

.mission-card--chain .mission-card__type { color: #f0a8f4; }
.mission-card--chain .mission-card__title { color: #f6dcff; }

.mission-card__header { display: flex; justify-content: space-between; align-items: center; }
.mission-card__type { font-size: 9.5px; letter-spacing: .05em; color: var(--text-muted); text-transform: uppercase; }
.mission-card__status { font-size: 9.5px; letter-spacing: .05em; padding: 2px 6px; border-radius: var(--radius-sm); }
.mission-card__status--available { color: var(--accent); background: rgba(255,255,255,.06); }
.mission-card__status--active { color: #f0c674; background: rgba(240,198,116,.1); }
.mission-card__status--completed { color: #5fd88a; background: rgba(95,216,138,.1); }
.mission-card__status--failed, .mission-card__status--expired { color: #e08a7a; background: rgba(224,90,74,.08); }
.mission-card__title { font-family: var(--font-heading); font-size: 13.5px; color: var(--text-primary); margin-top: 6px; }
.mission-card__description { font-size: 10.5px; color: var(--text-muted); margin-top: 3px; }
.mission-card__meta {
  display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 8px;
  font-size: 9.5px; color: var(--text-dim);
}
.mission-card__reward {
  flex-basis: 100%; display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
}
.mission-card__reward-label { display: block; }
.mission-card__reward-values { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; }
.mission-card__reward-kind { color: var(--text-muted); }
.mission-card__steps { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }

/* Geborgene Fundstuecke (Zivilisationsketten, 2026-09-04). Abgesetzt wie ein
   Zitat: was hier steht, hat der Spieler gefunden, nicht das Spiel gesagt. */
.mission-card__finds { margin-top: 10px; display: grid; gap: 7px; }
.mission-card__finds-head {
  color: #8b96ba;
  font-size: 10px;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.mission-card__find {
  border-left: 2px solid rgba(224, 192, 122, .55);
  padding: 2px 0 2px 10px;
}
.mission-card__find-name {
  color: #e0c07a;
  font-size: 11.5px;
  font-weight: 600;
}
.mission-card__find-text {
  margin-top: 2px;
  color: var(--text-muted);
  font-size: 11.5px;
  line-height: 1.5;
  font-style: italic;
}
.mission-card__step { font-size: 9.5px; color: var(--text-dim); display: flex; align-items: center; gap: 5px; }
.mission-card__step--done { color: #5fd88a; }
.mission-card__hint {
  margin-top: 8px; font-size: 9.5px; letter-spacing: 0.04em;
  color: var(--accent-blue); display: flex; align-items: center; gap: 5px;
}
.mission-card__guidance {
  margin-top: 8px; padding: 7px 9px; border-left: 2px solid var(--accent-gold);
  background: rgba(255, 215, 106, .06); color: var(--text-muted);
  font-size: 10px; line-height: 1.45;
}
.mission-card__guidance i { color: var(--accent-gold); margin-right: 6px; }
.mission-card__actions { display: flex; gap: 8px; margin-top: 12px; }
.mission-card__btn {
  flex: 1; padding: 7px 10px; font-size: 10.5px; letter-spacing: .04em;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: rgba(255,255,255,.04); color: var(--text-primary); cursor: pointer;
}
/* Kein Platz mehr frei (Nutzerentscheidung 2026-09-14). Der Knopf bleibt
   STEHEN statt zu verschwinden: Ein Angebot ohne Knopf sieht aus, als waere
   es abgelaufen - hier ist es nur gerade nicht annehmbar. */
.mission-card__btn:disabled {
  opacity: .45;
  cursor: not-allowed;
  border-style: dashed;
}

/* Der Platzstand ueber der Liste (2026-09-14). Er steht auch dann da, wenn
   noch Platz ist - sonst erschiene die Grenze erst in dem Moment, in dem sie
   stoert, und wirkte wie ein Fehler. */
.mission-slots {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  margin: -4px 0 14px;
  padding: 7px 11px;
  border: 1px solid rgba(120, 180, 255, .16);
  border-radius: var(--radius-sm);
  background: rgba(12, 18, 34, .55);
  font-size: 11px;
  color: var(--text-muted);
}
.mission-slots .ph { color: #8fd8ff; }
.mission-slots__count {
  font-family: 'Share Tech Mono', monospace;
  font-size: 13px;
  color: var(--text-primary);
}
.mission-slots__note {
  margin-left: auto;
  font-size: 9.5px;
  opacity: .7;
}
.mission-slots--full {
  border-color: rgba(232, 162, 74, .4);
  background: rgba(232, 162, 74, .08);
}
.mission-slots--full .ph,
.mission-slots--full .mission-slots__count { color: #e8a24a; }
@media (max-width: 620px) {
  .mission-slots__note { margin-left: 0; width: 100%; }
}

/* EINE WARTENDE BELOHNUNG FAELLT INS AUGE (Nutzerwunsch 2026-09-13:
   "Belohnung abholen prominenter anzeigen - gruener rahmen, gruener knopf,
   leichter glow am button"). Bis dahin sah die fertige Mission aus wie jede
   andere; der Knopf war zu suchen statt zu sehen. */
.mission-card--claimable {
  border-color: rgba(95, 216, 138, .55);
  box-shadow: 0 0 0 1px rgba(95, 216, 138, .18), 0 0 22px rgba(95, 216, 138, .1);
}
.mission-card__btn--claim {
  flex: 1.4;
  border-color: var(--accent-green);
  background: var(--accent-green);
  color: #061309;
  font-weight: 600;
  letter-spacing: .06em;
  box-shadow: 0 0 14px rgba(95, 216, 138, .38);
  animation: missionClaimGlow 2.6s ease-in-out infinite;
}
.mission-card__btn--claim:hover { background: #79e7a1; border-color: #79e7a1; }
@keyframes missionClaimGlow {
  0%, 100% { box-shadow: 0 0 10px rgba(95, 216, 138, .3); }
  50% { box-shadow: 0 0 20px rgba(95, 216, 138, .55); }
}
@media (prefers-reduced-motion: reduce) {
  .mission-card__btn--claim { animation: none; }
}

/* Modularer Raumschiffbau, Sub-Projekt 3: Entwurfsliste + Editor. */
.ship-design-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  max-width: 1400px;
}
@media (max-width: 1200px) { .ship-design-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 900px) { .ship-design-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .ship-design-grid { grid-template-columns: 1fr; } }

.ship-design-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 14px;
}
.ship-design-tile__head { display: flex; justify-content: space-between; align-items: center; }
.ship-design-tile__name { font-size: 15px; font-weight: 600; color: var(--text-primary); }
.ship-design-tile__badge { font-size: 11px; padding: 2px 8px; border-radius: 999px; }
.ship-design-tile__badge--valid { background: rgba(95,216,138,.18); color: var(--accent-green); }
.ship-design-tile__badge--invalid { background: rgba(224,90,74,.18); color: var(--accent-red); }
.ship-design-tile__hull { font-size: 12px; color: var(--text-muted); margin: 4px 0; }
.ship-design-tile__stats { display: flex; gap: 10px; font-size: 11.5px; color: var(--text-muted); flex-wrap: wrap; }
.ship-design-tile__actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }

.ship-hull-picker__card { cursor: pointer; }
.ship-hull-picker__card--locked { opacity: .5; cursor: not-allowed; }
.ship-hull-picker__locked-hint { font-size: 11px; color: var(--accent-red); }

.ship-editor { display: flex; gap: 20px; align-items: flex-start; }
.ship-editor__col { flex: 1; min-width: 0; }
.ship-editor__col--grid { flex: 1.4; }

.ship-editor__palette-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 12px; }
.ship-editor__palette-tab {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: rgba(255,255,255,.03);
  color: var(--text-muted);
  font-size: 10.5px;
  padding: 6px 10px;
  cursor: pointer;
}
.ship-editor__palette-tab--active {
  border-color: var(--accent);
  color: var(--text-primary);
  background: rgba(70,217,208,.15);
}

.ship-editor__palette-group { display: flex; flex-direction: row; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.ship-editor__palette-card {
  position: relative;
  border: 2px solid var(--border);
  border-radius: 6px;
  cursor: grab;
  background: rgba(255,255,255,.03);
  overflow: hidden;
  flex-shrink: 0;
}
.ship-editor__palette-subgrid {
  position: absolute;
  inset: 0;
  display: grid;
}
.ship-editor__palette-subcell {
  border: 1px dashed rgba(255,255,255,.25);
}
.ship-editor__palette-card-label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 9px;
  line-height: 1.15;
  padding: 4px;
  color: var(--text-primary);
  pointer-events: none;
}

.ship-editor__grid {
  display: grid;
  gap: 4px;
  background: rgba(255,255,255,.02);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  width: max-content;
  position: relative;
}
.ship-editor__cell {
  border: 1px dashed rgba(255,255,255,.12);
  border-radius: 4px;
}
.ship-editor__cell--valid { background: rgba(95,216,138,.25); border-color: var(--accent-green); }
.ship-editor__cell--invalid { background: rgba(224,90,74,.25); border-color: var(--accent-red); }
.ship-editor__placed {
  background: rgba(70,217,208,.18);
  border: 1px solid var(--accent);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  font-size: 11px;
  text-align: center;
  cursor: grab;
  padding: 2px;
}
.ship-editor__placed-remove {
  position: absolute;
  top: 2px;
  right: 2px;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 12px;
}

.ship-editor__meta-row { font-size: 12.5px; color: var(--text-muted); margin-bottom: 4px; }

@media (max-width: 1100px) { .ship-editor { flex-direction: column; } }

/* ------------------------------------------------------------------
 * Schiffe-Ansicht (Spec 2026-08-01-schiffe-ansicht-design.md):
 * aggregierte Typzeile, aufklappbar zu den Einzelschiffen.
 * ------------------------------------------------------------------ */

.ships-readiness { display: grid; grid-template-columns: repeat(3, minmax(150px, 240px)); gap: 10px; margin: 4px 0 16px; }
.ships-readiness__card { display: flex; flex-direction: column; gap: 3px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text-muted); text-align: left; }
.ships-readiness__card strong { color: var(--text-primary); font-family: 'Chakra Petch', sans-serif; font-size: 18px; }
.ships-readiness__card--action { cursor: pointer; }
.ships-readiness__card--action:hover, .ships-readiness__card--action:focus-visible { border-color: var(--accent); background: rgba(127, 233, 255, 0.06); }

.ships-toolbar {
  display: flex;
  gap: 16px;
  align-items: center;
  margin: 12px 0 16px;
  flex-wrap: wrap;
}

.ships-search {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-body);
  font-family: inherit;
  font-size: 13px;
  padding: 7px 10px;
  min-width: 220px;
}

.ships-search:focus {
  outline: none;
  border-color: var(--border-strong);
}

@media (max-width: 650px) { .ships-readiness { grid-template-columns: 1fr; } }

.ships-toolbar label {
  display: flex;
  gap: 6px;
  align-items: center;
  color: var(--text-muted);
  font-size: 13px;
  cursor: pointer;
}

.ships-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.ships-table th {
  text-align: left;
  color: var(--text-muted);
  font-family: 'Chakra Petch', sans-serif;
  font-weight: 500;
  letter-spacing: 0.03em;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}

.ships-table td {
  padding: 8px 10px;
  border-top: 1px solid var(--border);
  color: var(--text-body);
  vertical-align: middle;
}

.ships-table__group {
  cursor: pointer;
  font-weight: 600;
}

.ships-table__group td:first-child {
  font-family: 'Chakra Petch', sans-serif;
  letter-spacing: 0.02em;
}

.ships-table__group:hover td,
.ships-table__group:focus-visible td {
  background: var(--surface-active);
}

/* Die Modellgrafik am Zeilenanfang (2026-09-05). Sie ERSETZT den frueheren
   Aufklappfeil: dass die Zeile aufklappt, sagt jetzt der Zeigerwechsel und
   die geoeffnete Zeile selbst. */
.ships-table__group-name {
  display: flex;
  align-items: center;
  gap: 9px;
}

.ship-figure-img--sm {
  width: 34px;
  height: 34px;
  object-fit: contain;
  flex: none;
  /* Ohne festen Platz springt die Spalte, sobald ein Modell keine Grafik hat
     - die Namen stuenden dann zeilenweise verschoben. */
  margin: -4px 0;
}

/* Ein Modell ohne Grafik behaelt trotzdem seinen Platz. */
.ships-table__group-name > span { min-width: 0; }

.ships-table__group.is-open td { background: var(--surface-active); }

/* Die beiden Baender: "Ohne Aufgabe" und "Im Einsatz" (2026-09-05). Sie
   trennen die Liste in die zwei Fragen, die man an sie stellt - was kann ich
   einteilen, und was laeuft gerade. */
.ships-table__band td {
  padding: 16px 14px 7px;
  border-bottom: 1px solid var(--border);
  background: transparent;
  font-family: var(--font-heading);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent-bright);
}

/* Das erste Band braucht oben keinen Abstand - darueber steht die Kopfzeile. */
.ships-table__band:first-child td { padding-top: 7px; }

.ships-table__band i { margin-right: 6px; }

.ships-table__band-count {
  float: right;
  letter-spacing: .04em;
  text-transform: none;
  color: var(--text-muted);
}

.ships-table__subhead th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 10px 10px 2px 26px;
  border-bottom: none;
  color: var(--text-dim);
}

.ships-table__ship {
  cursor: pointer;
}

.ships-table__ship td:first-child {
  padding-left: 26px;
}

.ships-table__ship:hover td,
.ships-table__ship:focus-visible td {
  background: rgba(127, 233, 255, 0.05);
}

.ships-table__muted {
  color: var(--text-dim);
}

/* Schiffsrecycling (Spec 2026-08-19): Aktionsspalte der Schiffsliste. */
.ships-table__recycle {
  font-family: inherit;
  font-size: 11px;
  padding: 4px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid rgba(224, 164, 74, 0.45);
  background: rgba(224, 164, 74, 0.10);
  color: #e0a44a;
  cursor: pointer;
  white-space: nowrap;
}
.ships-table__recycle:hover {
  background: rgba(224, 164, 74, 0.18);
}
.ships-repair {
  min-width: 190px;
  margin-top: 7px;
  padding-top: 6px;
  border-top: 1px solid rgba(224, 131, 74, 0.28);
  font-size: 10.5px;
}
.ships-repair__costs { display: flex; flex-direction: column; gap: 2px; }
.ships-repair__cost { color: var(--text-muted); white-space: nowrap; }
.ships-repair__footer,
.ships-repair--active {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 7px;
}
.ships-repair__footer > span,
.ships-repair--active > span { color: #f0b26c; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ships-repair__start,
.ships-repair__cancel {
  border: 1px solid rgba(224, 131, 74, 0.5);
  border-radius: var(--radius-sm);
  background: rgba(224, 131, 74, 0.12);
  color: #f0b26c;
  font: inherit;
  font-size: 10.5px;
  padding: 4px 7px;
  cursor: pointer;
}
.ships-repair__start:disabled {
  border-color: var(--border);
  background: rgba(139, 150, 186, 0.07);
  color: var(--text-dim);
  cursor: not-allowed;
}
.ships-repair__cancel { color: var(--accent-red); border-color: rgba(224, 90, 74, 0.45); }
.ships-repair__reason { margin-top: 4px; color: var(--text-dim); line-height: 1.3; }
/* Der Fortschrittsknopf sitzt in einer schmalen Tabellenzelle - ohne feste
   Mindestbreite springt die Spalte beim Wechsel von Knopf zu Balken. */
.ships-table__ship .building-tile__action--progress {
  min-width: 96px;
  margin: 0;
  padding: 4px 8px;
  font-size: 11px;
}
/* Ertragsliste im Bestaetigungsdialog. */
.ships-recycle-list {
  margin-top: 10px;
  border-top: 1px solid var(--border);
  padding-top: 8px;
}
.ships-recycle-row {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}
.ships-recycle-warn {
  margin-top: 8px;
  font-size: 11.5px;
  color: #e05a4a;
}

.ships-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 110px;
}

.ships-bar .progress-bar {
  flex: 1;
}

.ships-bar__value {
  font-variant-numeric: tabular-nums;
  min-width: 44px;
  text-align: right;
  color: var(--text-muted);
}

.ships-fleet-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
}

.ships-footnote {
  color: var(--text-dim);
  font-size: 12px;
  margin-top: 18px;
  max-width: 70ch;
}

@media (max-width: 1100px) {
  .ships-table { font-size: 12px; }
  .ships-table th,
  .ships-table td { padding: 6px 6px; }
  .ships-bar { min-width: 80px; }
  .ships-bar__value { min-width: 36px; }
}

/* ------------------------------------------------------------------
 * Werft-Editor: Entwurfsname als Eingabefeld statt Überschrift
 * (Nutzerhinweis 2026-08-01 - vorher ein window.prompt).
 * ------------------------------------------------------------------ */

.ship-editor__name {
  display: block;
  width: 100%;
  max-width: 520px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 2px 8px;
  margin: 0 0 2px -8px;
  color: var(--text-primary);
  font-family: 'Chakra Petch', sans-serif;
  font-size: 28px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.ship-editor__name:hover {
  border-color: var(--border);
}

.ship-editor__name:focus {
  outline: none;
  border-color: var(--border-strong);
  background: var(--surface);
}

.ship-editor__name-hint {
  min-height: 16px;
  margin-bottom: 8px;
  font-size: 12px;
  color: var(--text-dim);
}

.ship-editor__name-hint--error {
  color: #e05a4a;
}

/* ------------------------------------------------------------------
 * Huellenformen im Werft-Editor
 * (Spec 2026-08-01-raumschiff-editor-huellenformen-design.md).
 * ------------------------------------------------------------------ */

.ship-hull-picker {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 70%;
}

.ship-hull-picker__card {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  padding: 12px 14px;
}

.ship-hull-picker__card--locked {
  opacity: 0.55;
}

.ship-hull-picker__head {
  margin-bottom: 10px;
}

.ship-shape-thumb-row {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  align-items: flex-end;
}

.ship-shape-thumb {
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  text-align: center;
}

.ship-shape-thumb.clickable {
  cursor: pointer;
}

.ship-shape-thumb.clickable:hover,
.ship-shape-thumb.clickable:focus-visible {
  border-color: var(--border-strong);
  background: var(--surface-active);
  outline: none;
}

.ship-shape-thumb--current {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.ship-shape-thumb--locked {
  cursor: default;
}

.ship-shape-thumb__grid {
  display: grid;
  gap: 1px;
  justify-content: center;
  margin-bottom: 6px;
}

.ship-shape-thumb__cell {
  background: var(--accent);
  border-radius: 1px;
  opacity: 0.75;
}

.ship-shape-thumb__cell--hole {
  background: transparent;
}

.ship-shape-thumb__label {
  font-size: 11px;
  color: var(--text-muted);
  font-family: 'Chakra Petch', sans-serif;
  letter-spacing: 0.02em;
}

/* Kompakte Kostenzeile: farbiger Punkt plus Menge. */
.ship-cost-line {
  display: inline-flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

.ship-cost-line__item {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 10.5px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.ship-cost-line__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  display: inline-block;
}

.ship-editor__palette-card-cost {
  position: absolute;
  left: 4px;
  right: 4px;
  bottom: 3px;
  display: flex;
  justify-content: center;
  pointer-events: none;
}

/* Das Label ist per inset:0 ueber die ganze Karte zentriert - ohne diesen
   Freiraum liefe es in die Kostenzeile am unteren Rand. */
.ship-editor__palette-card-label {
  padding-bottom: 14px;
}

/* Startsignal (Spec 2026-08-20): Wartephase vor Rundenbeginn. */
.round-countdown {
  margin: 48px auto;
  max-width: 640px;
  padding: 40px 32px;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
}
.round-countdown__eyebrow {
  font-size: 12px;
  letter-spacing: 0.18em;
  color: var(--text-dim);
}
.round-countdown__clock {
  margin: 12px 0;
  font-size: 56px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}
.round-countdown__date { color: var(--text-dim); font-size: 14px; }
.round-countdown__hint {
  margin-top: 20px;
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.5;
}

/* Startsignal (Spec 2026-08-20): Rundenstart in der Universumsauswahl. */
.picker-card__round {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--text-dim);
}
.picker-card__round strong {
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.picker-card__round--live { color: var(--accent-green); }
.picker-card__round-date { width: 100%; color: var(--text-dimmer); }

/* ==========================================================================
   Kachel-Statistik in der Universumsauswahl (Nutzerwunsch 2026-09-21):
   Laufzeit, Platz eins und die Bevoelkerungsaufteilung.

   Alle drei Zeilen bleiben ZURUECKHALTEND. Die Kachel ist ein Knopf, kein
   Bericht - wer sie ansieht, will wissen, welche Runde er anklickt. Deshalb
   kleine Schrift, gedaempfte Farben, und die Auszeichnung nur dort, wo sie
   etwas unterscheidet (die drei Gruppen, die Krone).
   ========================================================================== */
.picker-card__uptime {
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-dim);
}

.picker-card__uptime strong {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.picker-card__leader {
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-dim);
  min-width: 0;
}

.picker-card__leader i {
  color: var(--accent-gold, #ffd76a);
  flex: none;
}

/* Der Name darf die Kachel nicht sprengen - Bots und Zivilisationen tragen
   teils lange Namen. */
.picker-card__leader-name {
  color: var(--text-primary);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.picker-card__leader-bot {
  flex: none;
  font-size: 9.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 3px;
  background: rgba(110, 160, 255, .14);
  color: #9ec2ff;
}

.picker-card__leader-score {
  flex: none;
  margin-left: auto;
  color: var(--accent-gold, #ffd76a);
  font-variant-numeric: tabular-nums;
}

.picker-card__pop {
  margin-top: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.picker-pop {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
}

/* Grün = Mensch, Blau = Bot, Rot = Pirat. Dieselbe Zuordnung wie in
   Rangliste, Verwaltung und auf der Karte - eine vierte Gruppe holt sich
   ihre Farbe von dort, wo sie sonst vorkommt. */
.picker-pop.is-human {
  background: rgba(70, 217, 160, .10);
  border-color: rgba(70, 217, 160, .28);
  color: #6fe0b4;
}

.picker-pop.is-bot {
  background: rgba(110, 160, 255, .10);
  border-color: rgba(110, 160, 255, .28);
  color: #9ec2ff;
}

.picker-pop.is-pirate {
  background: rgba(255, 106, 106, .10);
  border-color: rgba(255, 106, 106, .28);
  color: #ff9a9a;
}

/* Abbau-Log (Nutzerwunsch 2026-08-20): Tabelle der Rueckkehren. */
/* Nutzerwunsch 2026-09-03: auf drei Viertel der Seite verbreitert. Die
   Untergrenze bleibt die alte Breite - auf einem schmalen Fenster waeren
   75 % weniger als die bisherigen 1100 px, das Log wuerde also enger statt
   breiter. */
.mining-log { max-width: max(1100px, 75%); }
.mining-log-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  font-size: 13px;
}
.mining-log-table th {
  text-align: left;
  padding: 10px 14px;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: rgba(120, 180, 255, 0.05);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.mining-log-table td {
  padding: 10px 14px;
  border-bottom: 1px solid rgba(120, 180, 255, 0.08);
  color: var(--text-body);
  vertical-align: top;
}
.mining-log-table tr:last-child td { border-bottom: none; }
.mining-log__time { white-space: nowrap; color: var(--text-muted); }
.mining-log__total { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--accent); }
.mining-log__cargo { display: flex; flex-wrap: wrap; gap: 6px; }
.mining-log__chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(120, 180, 255, 0.08);
  font-size: 12px;
  white-space: nowrap;
}
.mining-log__pager {
  display: flex; align-items: center; gap: 12px;
  margin-top: 10px;
}
.mining-log__pagebtn {
  padding: 6px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-active);
  color: var(--text-primary);
  font-size: 12px;
  cursor: pointer;
  user-select: none;
}
.mining-log__pagebtn:hover { border-color: var(--accent); }
.mining-log__pagebtn--off { opacity: 0.35; cursor: default; }
.mining-log__pagebtn--off:hover { border-color: var(--border-strong); }
.mining-log__pageinfo { font-size: 12px; color: var(--text-dim); }

/* Schmale Fenster: die Tabelle darf scrollen statt die Seite zu sprengen. */
@media (max-width: 900px) {
  .mining-log { overflow-x: auto; }
  .mining-log-table { min-width: 720px; }
}

/* ══════════════════════════════════════════════════════════════════
   Spezieswahl im Beitritt (Konzept: konzept-spielbare-spezies.md)
   Dropdown mit Kurzfassung darunter, dazu ein Detail-Modal mit einem
   Tab je Spezies. Nutzerentscheidung 2026-08-21.
   ══════════════════════════════════════════════════════════════════ */

.field select {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 11px 12px;
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--text-primary);
}
.field select:focus {
  outline: none;
  border-color: rgba(70, 217, 208, 0.6);
}

.species-detail-link {
  margin-left: 10px;
  color: var(--accent-bright);
  cursor: pointer;
  letter-spacing: 0.08em;
}
.species-detail-link:hover { text-decoration: underline; }

.species-hint { margin-top: 8px; }
.species-teaser {
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
  line-height: 1.5;
}
.species-bonus-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 7px;
}
.species-bonus, .species-malus {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
  white-space: nowrap;
}
.species-bonus {
  background: rgba(143, 224, 160, 0.12);
  color: var(--accent-green);
}
.species-malus {
  background: rgba(224, 90, 74, 0.12);
  color: var(--accent-red);
}
.species-inactive {
  margin-top: 8px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--accent-orange, #ffd76a);
}

/* Die Zivilisationswahl war bis 2026-08-21 ein Modal ueber dem
   Grunddatenformular, erreichbar nur ueber einen [Details]-Link neben einer
   Auswahlliste - der wurde uebersehen, und damit sah kaum jemand die
   Spezieskarten. Sie ist jetzt ein eigener Beitrittsschritt; die Modal-Huelle
   (fixed, Backdrop, Box, Kopf, Schliesskreuz, Fuss) ist deshalb entfallen.
   Geblieben sind die Reiter und der Kartenbereich. */
.species-step__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 14px 0 16px;
}
.species-tab {
  cursor: pointer;
  font-size: 11.5px;
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
}
.species-tab:hover { border-color: var(--border-strong); color: var(--text-primary); }
.species-tab--active {
  border-color: var(--accent);
  color: var(--accent-bright);
  background: rgba(70, 217, 208, 0.08);
}
.species-step__body {
  display: block;
}
/* Die Spezieskarte traegt Name, Zitat und Werte selbst - sie steht deshalb
   allein und ueber die volle Breite, ohne Textspalte daneben. Kein eigener
   Rahmen: die Karte bringt ihren gezeichneten Rahmen mit, ein zweiter
   daneben wirkt wie ein Fehler. */
.species-karte {
  position: relative;
  border-radius: var(--radius-md);
  overflow: hidden;
}
.species-karte img { width: 100%; display: block; }
/* Unsichtbare Knoepfe auf der gezeichneten Auswahlleiste am unteren Kartenrand.
   Alle Werte in Prozent, damit sie mitskalieren - das Bild ist width: 100 %.
   Die Masse stammen aus einer Messung an allen sechs Karten (siehe join.js);
   'left' setzt das JS je Slot. */
.species-karte__slot,
.species-karte__pfeil {
  position: absolute;
  top: 80.65%;
  height: 14.65%;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease;
}
.species-karte__slot { width: 9.61%; }
.species-karte__pfeil { width: 7.6%; }
.species-karte__pfeil--links { left: 6.5%; }
.species-karte__pfeil--rechts { left: 85.8%; }
/* Die Karte zeigt die aktive Auswahl schon selbst (farbig umrandetes Symbol),
   deshalb hebt sich hier nur der Zeigerkontakt hervor - eine zweite
   Dauermarkierung wuerde mit der gezeichneten konkurrieren. */
.species-karte__slot:hover,
.species-karte__pfeil:hover {
  background: rgba(120, 180, 255, 0.18);
  border-color: rgba(160, 210, 255, 0.55);
}
.species-karte__slot:focus-visible,
.species-karte__pfeil:focus-visible {
  outline: none;
  border-color: var(--accent, #7fe9ff);
  background: rgba(120, 180, 255, 0.12);
}
/* Rueckfallebene, wenn das Bild fehlt (siehe join.js). */
.species-detail--ersatz[hidden] { display: none; }
.species-detail { flex: 1; min-width: 0; }
.species-detail__title {
  font-family: var(--font-heading);
  font-size: 17px;
  color: var(--text-primary);
}
.species-detail__role {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-bright);
  margin-top: 3px;
}
.species-detail__teaser {
  font-size: 12.5px;
  font-style: italic;
  color: var(--text-muted);
  margin-top: 10px;
  line-height: 1.6;
}
.species-detail__label {
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--text-dim);
  margin-top: 14px;
}
.species-detail ul {
  margin: 6px 0 0;
  padding-left: 18px;
  font-size: 12.5px;
  color: var(--text-body);
  line-height: 1.7;
}
.species-detail__note {
  margin-top: 16px;
  font-size: 11px;
  color: var(--text-dim);
}

/* --- Beitrittsschritte (2026-08-21) ------------------------------------- */

.species-step {
  margin-top: 18px;
}

/* Zurueck und Weiter an den Aussenkanten: der zurueckfuehrende Weg links, der
   voranfuehrende rechts - wie in den uebrigen Assistenten des Spiels. */
.join-actions {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 20px;
}
.join-actions .btn-primary { margin-left: auto; }

.join-summary {
  margin-top: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.join-summary__row {
  display: flex;
  gap: 14px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
}
.join-summary__row:last-child { border-bottom: 0; }
.join-summary__label {
  flex: 0 0 40%;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.join-summary__value {
  flex: 1;
  min-width: 0;
  color: var(--text-primary);
  word-break: break-word;
}
.join-summary__deko {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 20px;
}
.join-summary__swatch {
  width: 18px;
  height: 18px;
  border-radius: 4px;
  border: 1px solid var(--border-strong);
}

/* Der Beitritt ist unumkehrbar. Der Hinweis steht deshalb direkt ueber dem
   Knopf und nicht im Kleingedruckten. */
.join-warning {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 16px;
  padding: 11px 13px;
  border: 1px solid rgba(255, 190, 90, 0.45);
  border-radius: var(--radius-sm);
  background: rgba(255, 190, 90, 0.08);
  font-size: 12px;
  line-height: 1.5;
  color: #ffd79a;
}
.join-warning i { flex: 0 0 auto; font-size: 15px; }

/* Die Karte skaliert von sich aus mit der Breite (width: 100 %), deshalb
   braucht die schmale Ansicht keine eigene Regel mehr - die frueheren
   Umbrueche galten der Zweispaltigkeit aus Bild und Text. */

/* --- Xeno-Archiv (Artefakte), 2026-08-21 ------------------------------------
   Etappe 3 des Artefakt-Systems. Die Karten sind absichtlich schmaler als die
   Schiffskarten der Werft: ein unidentifiziertes Fundstueck hat fast keinen
   Inhalt, breite Kacheln waeren dann grosse leere Flaechen. */

.artifact-counters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 18px;
}
.artifact-counter {
  flex: 1 1 120px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.artifact-counter__value {
  font-family: var(--font-heading);
  font-size: 20px;
  color: var(--text-primary);
}
.artifact-counter__label {
  margin-top: 2px;
  font-size: 10.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.artifact-effects {
  margin-bottom: 20px;
  padding: 14px 16px;
  border: 1px solid rgba(70, 217, 208, 0.3);
  border-radius: var(--radius-md);
  background: rgba(70, 217, 208, 0.05);
}
.artifact-effects__head {
  font-family: var(--font-heading);
  font-size: 12.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent-bright);
  margin-bottom: 10px;
}
/* Breitere Spalten und mehr Zeilenabstand seit dem 2026-08-22: jede Wirkung
   traegt jetzt einen Erklaerungssatz unter sich, und in 210 px wurde der zum
   Absatz. */
.artifact-effects__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px 18px;
}
/* Seit dem 2026-08-22 zweizeilig: Beschriftung mit Wert oben (.__row),
   darunter der Satz, wo der Bonus einschlaegt. Vorher lagen Label und Wert
   direkt hier drin nebeneinander - deshalb column statt der fruehen
   Standardrichtung, sonst stuende die Erklaerung daneben statt darunter. */
/* Jede Wirkung eine eigene Kachel (Nutzerbefund 2026-09-11: "Wirkung der
   Sammlung ist etwas unaufgeraeumt, bitte eine sichtbare Trennung"). Die
   farbige Kante links sagt auf einen Blick, ob die Zeile ein Vorteil ist -
   die Sortierung setzt Vorteile ohnehin nach oben. */
.artifact-effect {
  display: flex;
  flex-direction: column;
  font-size: 12.5px;
  padding: 9px 11px;
  border: 1px solid rgba(120, 180, 255, 0.12);
  border-left-width: 3px;
  border-radius: var(--radius-sm, 6px);
  background: rgba(9, 12, 24, 0.35);
}
.artifact-effect--good { border-left-color: #8fe0a0; }
.artifact-effect--bad { border-left-color: #ff9a8f; }
/* Der Begriff hell, die Erklaerung darunter grau (Nutzervorgabe
   2026-08-22): so traegt die Zeile ihre Ueberschrift und der Satz bleibt
   nachgeordnet. Vorher war beides gedaempft und die Zeile las sich flach. */
.artifact-effect__label { color: var(--text-primary); }
.artifact-effect__value--good { color: #8fe0a0; }
.artifact-effect__value--bad { color: #ff9a8f; }
.artifact-effects__note {
  margin-top: 10px;
  font-size: 10.5px;
  color: var(--text-dim);
}

.artifact-section { margin-bottom: 24px; }
.artifact-section__head {
  font-family: var(--font-heading);
  font-size: 13px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}

.artifact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 12px;
}
.artifact-card {
  position: relative;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.artifact-card__glyph {
  font-size: 26px;
  line-height: 1;
  margin-bottom: 4px;
}
/* Die NEU-Marke am frisch identifizierten Artefakt (2026-09-10). Sie sitzt in
   der oberen rechten Ecke der Karte - dieselbe Stelle wie das NEU am
   Menuepunkt, damit der Blick sie dort sucht, wo er sie kennt. */
.artifact-card--new { cursor: pointer; box-shadow: 0 0 0 1px rgba(255,215,106,.35); }
.artifact-card--new:hover { box-shadow: 0 0 0 1px rgba(255,215,106,.6); }
.artifact-card__new {
  position: absolute; top: 8px; right: 8px;
  font-family: var(--font-heading); font-size: 9px; font-weight: 700; letter-spacing: .14em;
  color: #05060f; background: var(--accent-gold); border-radius: 4px; padding: 2px 6px;
}
.artifact-card__name {
  font-family: var(--font-heading);
  font-size: 14px;
  color: var(--text-primary);
}
.artifact-card__meta {
  font-size: 11px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.artifact-card__status {
  font-size: 11px;
  color: var(--text-dim);
}
.artifact-card__desc {
  margin-top: 8px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}
.artifact-card__effects {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 12px;
}
.artifact-card__effect {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  color: var(--text-muted);
}
/* Aktion und Hinweis nach unten druecken, damit die Knoepfe in einer Reihe
   stehen, auch wenn die Karten unterschiedlich viel Text tragen. */
.artifact-card__action {
  margin-top: auto;
  padding-top: 12px;
  display: flex;
  gap: 8px;
  align-items: center;
}
.artifact-card__action select {
  flex: 1;
  min-width: 0;
}
.artifact-card__action .btn-primary {
  padding: 7px 12px;
  font-size: 11px;
}
.artifact-card__hint {
  margin-top: auto;
  padding-top: 10px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-dim);
}

/* --- Zivilisation und Boni in der Dashboard-Kopfzeile, 2026-08-21 ---------- */

/* Das (i) neben dem Zivilisationsnamen. Klein und ruhig: es soll auffindbar
   sein, ohne mit dem Namen zu konkurrieren. */
.meta-info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-left: 5px;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  font-family: var(--font-heading);
  font-size: 10px;
  font-style: italic;
  line-height: 1;
  color: var(--text-dim);
  cursor: pointer;
  vertical-align: middle;
  transition: color 120ms ease, border-color 120ms ease;
}
.meta-info-btn:hover,
.meta-info-btn:focus-visible {
  outline: none;
  color: var(--accent-bright);
  border-color: var(--accent);
}

.meta-bonus-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 6px;
}
.meta-bonus {
  font-size: 11px;
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: default;
}
.meta-bonus--good {
  color: #8fe0a0;
  border-color: rgba(143, 224, 160, 0.35);
  background: rgba(143, 224, 160, 0.08);
}
.meta-bonus--bad {
  color: #ff9a8f;
  border-color: rgba(255, 154, 143, 0.35);
  background: rgba(255, 154, 143, 0.08);
}
.meta-bonus--more {
  color: var(--text-dim);
  border-color: var(--border);
}

/* Das Modal hinter dem (i). Die Karte ist das Herzstueck - im Spiel gibt es sie
   sonst nirgends zu sehen, nach dem Beitritt war sie bisher unerreichbar. */
.species-info__card {
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: 14px;
}
.species-info__card img {
  width: 100%;
  display: block;
}
.species-info__title {
  font-family: var(--font-heading);
  font-size: 17px;
  color: var(--text-primary);
}
.species-info__role {
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent-bright);
  margin-top: 2px;
}
.species-info__teaser {
  margin-top: 10px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-muted);
}
.species-info__head {
  margin-top: 16px;
  margin-bottom: 8px;
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.species-info__bonus {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
  border-bottom: 1px solid var(--border);
  font-size: 12.5px;
}
.species-info__bonus:last-child { border-bottom: 0; }
.species-info__source {
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
}

/* Bonushinweis in den Fortschrittsboxen (2026-08-21). Steht neben der
   Restzeit und nennt im Titel die volle Erklaerung - die Zahl allein
   ("-5 min") liesse offen, worauf sie sich bezieht. */
.progress-box__bonus {
  margin-left: 8px;
  font-size: 10.5px;
  padding: 1px 5px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: help;
  white-space: nowrap;
}
.progress-box__bonus--good {
  color: #8fe0a0;
  border-color: rgba(143, 224, 160, 0.3);
  background: rgba(143, 224, 160, 0.07);
}
.progress-box__bonus--bad {
  color: #ff9a8f;
  border-color: rgba(255, 154, 143, 0.3);
  background: rgba(255, 154, 143, 0.07);
}

/* Breite Fassung des Detail-Modals (2026-08-21). Gebraucht fuer Inhalte, deren
   Text IM BILD steht - die Spezieskarten. Bei den ueblichen 420 px werden sie
   auf ein Drittel gestaucht und die gezeichnete Schrift unlesbar; dieselbe
   Ueberlegung wie bei .join-panel--wide im Beitritt. */
/* Lagerkachel: "Leeren" und der Entsorgungsdialog dahinter (Nutzerwunsch
   2026-08-24). Der Knopf sitzt bewusst unauffaellig am Fuss der Kachel - er
   vernichtet ohne Gegenwert und soll nicht wie eine Hauptaktion aussehen. */
/* Ein Quadrat in der rechten oberen Ecke der Kachel (Nutzerwunsch
   2026-09-06). Vorher lief der Knopf ueber die volle Breite unter der
   Produktionszeile und machte jede Kachel um seine Hoehe laenger - genau das
   war der Grund, warum das Lager bei zwoelf Ressourcen scrollte.

   Absolut positioniert, damit er dem Inhalt keinen Platz wegnimmt; die Kachel
   traegt dafuer position: relative. */
.resource-card__discard {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-size: 13px;
  line-height: 1;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color .15s, border-color .15s;
}
.resource-card__discard:hover {
  color: var(--accent-red);
  border-color: rgba(224, 90, 74, .45);
}
/* NEU-Label auf der Werftkarte (Nutzerwunsch 2026-08-25). Der Rahmen greift
   dieselbe Farbe auf wie die frisch freigeschalteten Gebaeudekacheln, damit
   das Label ueberall dasselbe bedeutet. */
/* Missionslog: Checkbox neben dem Eintrag (Nutzerwunsch 2026-08-25). Sie
   schaltet das blaue Suchgebiet der Mission auf der Karte an und aus. */
.starmap-questlog__row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.starmap-questlog__row .starmap-questlog__item {
  flex: 1;
  min-width: 0;
}

/* KLASSENQUEST UND FINALQUEST BEKOMMEN EINEN RAHMEN (Nutzerwunsch
   2026-09-18). Beide sind keine gewoehnlichen Auftraege: Man nimmt sie nicht
   an und legt sie nicht weg, sie laufen ueber die ganze Runde und bauen
   aufeinander auf.

   NUR DIESE ZWEI. Scan- und Bergungsauftraege bleiben schlicht - wer alles
   hervorhebt, hebt nichts hervor.

   ZWEI FARBEN, NICHT EINE (Nutzerentscheidung 2026-09-18): Die
   Zivilisationsgeschichte laeuft die ganze Runde und traegt den ruhigen
   Akzentton der Kettenmissionen; das Finale laeuft nur die letzte Woche und
   bekommt das dringlichere Gold. Gleiche Faerbung liesse beide gleich
   wichtig aussehen.

   Der Balken sitzt links als inset-Schatten statt als border-left: Ein echter
   Rahmen verschoebe den Inhalt um seine Breite, und die Zeilen staenden dann
   nicht mehr buendig unter den uebrigen. */
.starmap-questlog__row--chain,
.starmap-questlog__row--endgame {
  border-radius: 4px;
  padding: 4px 6px 4px 8px;
  margin: 2px 0;
}

.starmap-questlog__row--chain {
  border: 1px solid rgba(159, 168, 240, .38);
  background: rgba(159, 168, 240, .06);
  box-shadow: inset 2px 0 0 rgba(159, 168, 240, .55);
}

.starmap-questlog__row--endgame {
  border: 1px solid rgba(255, 215, 106, .45);
  background: rgba(255, 215, 106, .07);
  box-shadow: inset 2px 0 0 rgba(255, 215, 106, .65);
}

/* Eine abgeschlossene Kette behaelt ihren Rahmen, verliert aber den
   Nachdruck - sonst leuchtet Erledigtes staerker als das, was noch aussteht. */
.starmap-questlog__row--completed.starmap-questlog__row--chain,
.starmap-questlog__row--completed.starmap-questlog__row--endgame {
  background: transparent;
  box-shadow: none;
}

/* Die Knopfspalte (Nutzerwunsch 2026-09-15: "bitte im missionslog die buttons
   sauber untereinander anzeigen, die schwimmen gerade bissel rum, je nachdem
   wie lang der text ist").

   VORHER lagen Zeigen, Mehr und Aufgeben als Geschwister in derselben
   Flex-Zeile wie der Missionseintrag. Der waechst mit seinem Titel, also
   verschob jede laengere Mission die Knoepfe an eine andere Stelle - von
   Zeile zu Zeile.

   `flex: 0 0 74px` ist der Kern: eine feste Breite, die den Text nicht kennt.
   Alles darin liegt untereinander und ist gleich breit. */
.starmap-questlog__actions {
  flex: 0 0 74px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-self: stretch;
}
.starmap-questlog__action {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 4px;
  width: 100%;
  padding: 3px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .03);
  color: var(--text-muted);
  font-family: inherit;
  font-size: 9.5px;
  letter-spacing: .06em;
  line-height: 1.4;
  white-space: nowrap;
  cursor: pointer;
}
.starmap-questlog__action i { font-size: 11px; flex: none; }
.starmap-questlog__action:hover { color: var(--accent-bright); border-color: var(--border-strong); }
.starmap-questlog__check {
  margin-top: 10px;
  flex: none;
  cursor: pointer;
  accent-color: #7fe9ff;
}
.ship-fullcard--new {
  border-color: rgba(120, 180, 255, .45);
}
.ship-fullcard__badge {
  margin-left: 8px;
  vertical-align: middle;
}
.discard-modal__eyebrow {
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--text-dim);
}
.discard-modal__title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 16px;
  color: var(--text-primary);
  margin: 6px 0 14px;
}
.discard-modal__stock {
  font-size: 12.5px;
  color: var(--text-muted);
  margin-bottom: 14px;
}
.discard-modal__label {
  display: block;
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  margin-bottom: 6px;
}
.discard-modal__input {
  width: 100%;
  padding: 8px 10px;
  font-size: 14px;
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.discard-modal__quick {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}
.discard-modal__quick button {
  flex: 1;
  padding: 5px 8px;
  font-size: 11px;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.discard-modal__quick button:hover {
  color: var(--text-primary);
  border-color: var(--border-strong);
}
.discard-modal__warn {
  margin: 16px 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}
.discard-modal__warn i {
  color: var(--accent-red);
}
.discard-modal__submit {
  width: 100%;
  padding: 10px;
  font-size: 12.5px;
  font-weight: 600;
  color: #fff;
  background: var(--accent-red);
  border: 1px solid var(--accent-red);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.discard-modal__submit:hover {
  background: #f0715f;
}
.detail-modal--wide {
  width: 1240px;
}

/* Eine MITTLERE Stufe zwischen 420 und 1240 (Nutzerbefund 2026-09-17:
   "Materie-Konverter Modal zu schmal, die Infos sind abgeschnitten").

   420 px reichen fuer ein Formular mit zwei Knoepfen; der Konverter zeigt
   zwoelf Ressourcenkacheln zu 92 px, eine Mengeneingabe mit Einheit und drei
   Bilanzzeilen nebeneinander. Bei 420 px standen davon drei Kacheln je Zeile
   und die Zeile "Grundstoffe · 70 % Ausbeute" brach mitten im Wort.

   1240 px waeren das andere Extrem - das ist die Breite fuer Tabellen und
   Archive, nicht fuer ein Formular. 760 px fassen sieben Kacheln je Zeile und
   lassen die Bilanz atmen. `max-width: 92vw` von `.detail-modal` gilt weiter,
   auf dem Telefon aendert sich also nichts. */
.detail-modal--medium {
  width: 760px;
}

/* MODALINHALTE OHNE EIGENEN RAHMEN (2026-09-07).

   `.detail-modal` ist bewusst eine reine Huelle - Position und
   Schliessknopf, sonst nichts (siehe Kommentar dort). Rahmen und Grund
   liefert der INHALT, ueblicherweise ueber `.detail-panel`.

   Diese vier Wrapper taten das nicht: Sie schwebten frei ueber der Seite.
   Aufgefallen ist es an den Organisationsmodalen (Nutzerbefund 2026-09-06:
   "die Modale haben keinen Rahmen"); ein Durchgang durch alle
   openDetailModal-Aufrufe fand diese hier.

   Sie bekommen die Werte HIER und nicht in `.detail-modal`: Ein Rahmen an
   der Huelle haette jedem Modal mit `.detail-panel` einen zweiten gegeben.

   Zwei weitere Faelle liessen sich so NICHT loesen -
   `.starmap-info-panel__row` und `.state-block` kommen auch ausserhalb von
   Modalen vor, ein Rahmen dort haette die Sternenkarte und jede Ladeanzeige
   getroffen. Die beiden Stellen sind stattdessen im JS gewickelt. */
.favorite-editor,
.species-info,
.discard-modal,
.ship-image-modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
}

/* Laborbericht einer Kreaturenart (Nutzerlieferung 2026-09-07).

   Die Grafik ist 1672x941 und traegt Text. Sie skaliert auf die Modalbreite
   herunter, aber NICHT hinauf: Ueber ihre eigene Auflaesung gezogen wuerde
   der Text weich, und genau den soll man lesen koennen. */

/* Die Huelle bekam ihren Rahmen erst am 2026-09-21 (gefunden beim Schaerfen
   von modal-rahmen.test.mjs): `.lab-report` hatte gar keine eigene Regel -
   nur `__sheet` und `__img`. Das BILD trug damit seinen Rahmen selbst, der
   Rand darum blieb durchsichtig. Dieselben Werte wie bei den uebrigen
   Modalhuellen, damit der Laborbericht sich nicht als Sonderfall liest. */
.lab-report {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
}

.lab-report__sheet {
  margin-top: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #05070e;
  overflow: hidden;
  /* Das Seitenverhaeltnis der Vorlage - so springt das Modal beim Laden des
     Bildes nicht in der Hoehe. */
  aspect-ratio: 1672 / 941;
}
.lab-report__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Das Artportrait im Steckbrief (2026-09-11).

   GROESSER ALS DIE KOPFFIGUR DANEBEN (64 px): Die Sprites sind quadratisch
   und freigestellt, in 64 Pixeln waere davon nichts zu erkennen. 128 px
   bleiben weit unter den 512 der Vorlage, das Bild wird also nicht weich.

   Der Kopf bricht dafuer um: Name und Untertitel stehen UNTER dem Bild statt
   daneben - bei 128 px Bildbreite blieben im 420 Pixel breiten Modal sonst
   keine 260 fuer einen langen wissenschaftlichen Namen. */
.detail-panel__head--portrait {
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
.detail-panel__portrait {
  width: 128px;
  height: 128px;
  flex: 0 0 auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: radial-gradient(ellipse at 50% 34%, rgba(70, 217, 208, .1), #05080f 76%);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.detail-panel__portrait-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* Derselbe Schlagschatten wie an den Schiffsgrafiken - ohne ihn schwebt das
     freigestellte Wesen vor dem Verlauf, statt darin zu sitzen. */
  filter: drop-shadow(0 3px 7px rgba(0, 0, 0, .6));
}

.highscore-table-wrap { overflow-x: auto; }
.highscore-table { width: 100%; border-collapse: collapse; background: var(--surface); border: 1px solid var(--border); }
.highscore-table th { padding: 10px 12px; text-align: left; color: var(--text-muted); font-size: 11px; letter-spacing: .08em; border-bottom: 1px solid var(--border); }
.highscore-table td { padding: 11px 12px; border-bottom: 1px solid var(--border); }
.highscore-table__self { background: rgba(255, 215, 106, .09); }
.highscore-table__rank, .highscore-table__points { color: var(--accent-gold); font-weight: 700; }
.highscore-table__military-points { color: var(--accent-red); font-weight: 700; }

/* Bestandszahlen (2026-09-05): LINKSbuendig, Kopf wie Werte - Nutzerwunsch
   vom selben Tag. Sie stehen damit bewusst anders als Punkte und Ruf: das
   sind Wertungen, die man untereinander vergleicht, waehrend Schiffe,
   Flotten und Basen blosse Auskunft sind. Die Ziffernbreite bleibt fest,
   damit die Spalte trotzdem ruhig steht. */
.highscore-table__assets {
  text-align: left;
  font-variant-numeric: tabular-nums;
}
.highscore-table__assets--hidden { color: var(--text-muted); }
/* Ruf und Rufpunkte (Nutzerwunsch 2026-08-31). Dieselben drei Farben, die
   core/reputation.js fuer die Flottenrahmen auf der Sternenkarte benutzt -
   eine vierte Skala fuer dieselbe Sache waere ein zweites Vokabular. */
.highscore-table__reputation--good { color: #4a90e2; }
.highscore-table__reputation--neutral { color: #8b96ba; }
.highscore-table__reputation--evil { color: #e05a4a; }
.highscore-table__reputation { white-space: nowrap; }
/* Nutzerbefund 2026-08-31: die Werte standen rechtsbuendig, die Ueberschrift
   aber links - beides jetzt links. tabular-nums bleibt, damit die Ziffern
   trotzdem untereinander stehen. */
.highscore-table__reputation-value { text-align: left; font-variant-numeric: tabular-nums; font-weight: 700; }

/* Organisations-Rangliste (Nutzerwunsch 2026-09-06). Sie teilt sich die
   Tabellenklassen mit der Spielerliste - eigen sind nur der Farbpunkt der
   Organisation und ihr Kuerzel. Die Reiter darueber nutzen .admin-player-tabs. */
.highscore-table__orgdot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 8px;
  vertical-align: baseline;
}
.highscore-table__orgtag { color: var(--text-muted); font-size: 11.5px; }

.menu-intro-story {
  display: grid;
  gap: 10px;
  text-align: left;
}
.menu-intro-story p {
  margin: 0;
  color: var(--text-body);
  line-height: 1.65;
}
.menu-intro-story p:first-child {
  color: var(--text-primary);
}

/* ---------------------------------------------------------------------------
   Werft: Schiffskarten des Modellkatalogs (2026-08-23)

   Ersetzt das Editor-Layout des modularen Baukastens. Karten und Raster nutzen
   weiter .ship-fullcard / .ship-fullcard-grid - deren Layout (max 4 Spalten,
   70 % Breite, responsiv) war schon durchdacht und brauchte keine Kopie.
   Neu sind nur die Sternezeilen, die Spezialfaehigkeit, der Fortschrittsknopf
   und die Werftplatzliste.
   --------------------------------------------------------------------------- */

/* Die Sternezeilen (.ship-stars-row, .ship-stars) entfielen am 2026-08-23:
   die Werftkarten nutzen jetzt SCKit.statRow, dasselbe Bauteil wie Gebaeude-
   und Forschungsansicht. Sterne rundeten den Wert weg - zwei Modelle mit
   demselben Sternebild konnten weit auseinanderliegen. */

.ship-card__ability {
  margin-top: 10px;
  padding: 9px 11px;
  border: 1px solid rgba(127, 233, 255, 0.22);
  border-radius: var(--radius-sm);
  background: rgba(127, 233, 255, 0.05);
}
.ship-card__ability-head {
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  display: flex;
  align-items: center;
  gap: 5px;
}
.ship-card__ability-text {
  font-size: 10.5px;
  color: var(--text-muted);
  line-height: 1.5;
  margin-top: 5px;
}

/* Der Fortschrittsknopf ersetzt Mengenfeld und Bauen-Knopf, solange dieses
   Modell gebaut wird - er steht deshalb allein und nimmt die volle Breite. */
.ship-card__progress-btn {
  position: relative;
  overflow: hidden;
  margin-top: 12px;
  padding: 9px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font-size: 11px;
  color: var(--text-primary);
  text-align: center;
}
.ship-card__progress-fill {
  position: absolute;
  inset: 0 auto 0 0;
  background: linear-gradient(90deg, rgba(70, 217, 208, 0.35), rgba(127, 233, 255, 0.22));
  transition: width 1s linear;
}
.ship-card__progress-btn span { position: relative; }
.ship-card__cancel {
  margin-top: 6px;
  text-align: center;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--accent-red);
  cursor: pointer;
}
.ship-card__cancel:hover { text-decoration: underline; }
.ship-fullcard__buildable {
  margin-top: 6px;
  color: var(--text-muted);
  font-size: 9.5px;
}
.ship-fullcard__buildable b { color: var(--accent-green); }
.ship-build-confirm__label {
  margin: 12px 0 6px;
  color: var(--text-dim);
  font-size: 9px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.shipyard-queue {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  margin-bottom: 22px;
  max-width: 70%;
}
.shipyard-queue__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 8px;
}
.shipyard-queue__head b {
  color: var(--text-primary);
  font-size: 10.5px;
  letter-spacing: 0;
  text-transform: none;
}
.shipyard-progress { display: grid; gap: 5px; margin: 10px 0 12px; }
.shipyard-progress__track {
  display: grid;
  grid-template-columns: repeat(var(--ship-segments), minmax(8px, 1fr));
  gap: 3px;
  min-height: 12px;
}
.shipyard-progress__segment {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--border-strong);
  border-radius: 3px;
  background: color-mix(in srgb, var(--surface) 75%, transparent);
}
.shipyard-progress__segment i {
  position: absolute;
  inset: 0 auto 0 0;
  display: block;
  background: linear-gradient(90deg, var(--accent), var(--accent-bright));
}
.shipyard-progress__segment--done i { background: var(--accent-green); }
.shipyard-progress__segment--active i::after {
  content: '';
  position: absolute;
  inset: 0;
  width: 55%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.5), transparent);
  animation: shipyard-progress-scan 1.15s linear infinite;
}
@keyframes shipyard-progress-scan {
  from { transform: translateX(-130%); }
  to { transform: translateX(230%); }
}
.shipyard-queue__details > summary {
  color: var(--accent);
  cursor: pointer;
  font-size: 10.5px;
  user-select: none;
}
.shipyard-queue__details[open] > summary { margin-bottom: 6px; }
.shipyard-queue__row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 7px 0;
  border-top: 1px solid var(--border);
}
.shipyard-queue__name {
  font-size: 11.5px;
  color: var(--text-primary);
}
.shipyard-queue__state {
  font-size: 10.5px;
  color: var(--text-muted);
}
.shipyard-queue__cancel {
  padding: 4px 7px;
  border: 1px solid color-mix(in srgb, var(--accent-red) 38%, transparent);
  border-radius: var(--radius-sm);
  background: transparent;
  font-size: 9px;
  color: var(--accent-red);
  cursor: pointer;
}
.shipyard-queue__cancel:hover { background: color-mix(in srgb, var(--accent-red) 10%, transparent); }
.shipyard-queue__running { color: var(--accent-green); font-size: 9px; }
.ship-group__count {
  margin-left: 8px;
  color: var(--text-dim);
}
@media (max-width: 1500px) { .shipyard-queue { max-width: 100%; } }

@media (max-width: 600px) {
  .shipyard-queue__head { align-items: flex-start; flex-direction: column; }
  .shipyard-queue__row { grid-template-columns: 1fr auto; gap: 6px 10px; }
  .shipyard-queue__state { grid-column: 1; }
  .shipyard-queue__cancel,
  .shipyard-queue__running { grid-column: 2; grid-row: 1 / span 2; }
}

@media (prefers-reduced-motion: reduce) {
  .shipyard-progress__segment--active i::after { animation: none; }
}

/* ---------------------------------------------------------------------------
   Auswahlbildschirm: kein Spielmenue (2026-08-23)

   Auf dem Universums-Auswahlbildschirm gibt es kein Universum, also auch keine
   Uebersicht, keine Gebaeude, keine Flotten. Sichtbar bleiben nur Admin und
   Abmelden.

   Die Klasse setzt game.php anhand von ?universe= - im Markup, nicht per
   JavaScript. Vorher versteckte setSidebarPickerMode() die Punkte erst nach dem
   ersten Zeichnen, das Menue blitzte also kurz auf (Nutzermeldung 2026-08-23).
   setSidebarGameMode() nimmt die Klasse wieder ab, bevor die Freischaltregeln
   greifen - erst dann duerfen die inline gesetzten display-Werte wirken.
   --------------------------------------------------------------------------- */

/* Auswahlbildschirm: nur Admin und Abmelden.
 *
 * `:not(#admin-sidebar-item)` IST DER GANZE PUNKT DIESER REGEL (Befund
 * 2026-09-21). Ohne die Ausnahme greift `[data-route]` auch auf den
 * Admin-Eintrag - der traegt `data-route="admin"` -, und dann ist der
 * Administrationsbereich auf dem Auswahlbildschirm unerreichbar.
 *
 * WARUM DAS EIN BLOCKER IST UND KEINE SCHOENHEITSFRAGE: Auf einer frischen
 * Installation gibt es noch kein Universum. Wer sich anmeldet, landet genau
 * hier - und braucht den Admin-Bereich, um das erste Universum anzulegen. Ohne
 * die Ausnahme sieht er nur "Abmelden" und kommt nicht weiter. Gefunden beim
 * ersten Onlinegang, an einer Installation ohne Universum.
 *
 * Fuer Nicht-Administratoren bleibt der Punkt trotzdem verborgen: game.php
 * setzt ihn auf `display:none`, und game.js nimmt das nur weg, wenn die Rolle
 * passt. Diese Regel entscheidet nichts ueber Rechte, sie darf nur nicht
 * dazwischenfunken.
 */
.app-sidebar--picker .app-sidebar__item[data-route]:not(#admin-sidebar-item) {
  display: none;
}

/* Punktespalte in der Dashboard-Kopfzeile (2026-08-23). Der Stern greift die
   Anzeige aus der Topbar auf, damit beide Stellen als dieselbe Zahl lesbar
   sind. */
.dashboard-meta__value.meta-points {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--accent-gold, #ffd76a);
  font-variant-numeric: tabular-nums;
}

/* Kampfbericht K5a: Archivliste, Abschlussbilanz und ein fuer bis zu vierzig
   Runden kompaktes, einzeln aufklappbares Gruppenprotokoll. */
.combat-report-subtitle { margin-bottom: 18px; }
.combat-report-filters {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: end;
  padding: 12px; margin-bottom: 14px; border: 1px solid var(--border-subtle);
  background: rgba(12, 18, 34, 0.72);
}
.combat-report-filter { display: grid; gap: 5px; color: var(--text-muted); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
.combat-report-filter select { min-width: 150px; }
.combat-report-filter--check { display: flex; flex-direction: row; align-items: center; min-height: 34px; text-transform: none; }
.combat-report-list { display: grid; gap: 8px; }
.combat-report-row {
  position: relative; display: grid; grid-template-columns: 5px minmax(210px, 1fr) 110px 110px 110px auto;
  gap: 12px; align-items: center; width: 100%; padding: 12px 14px; text-align: left; color: var(--text-primary);
  border: 1px solid var(--border-subtle); background: rgba(10, 15, 29, .72); cursor: pointer;
}
.combat-report-row:hover { border-color: rgba(127, 233, 255, .5); background: rgba(18, 29, 48, .85); }
.combat-report-row--unseen { border-color: rgba(240, 192, 90, .55); box-shadow: inset 0 0 20px rgba(240, 192, 90, .05); }
.combat-report-row__signal { align-self: stretch; border-radius: 2px; }
.combat-report-row__signal--won { background: #5fd88a; }.combat-report-row__signal--lost { background: #e05a4a; }.combat-report-row__signal--draw { background: #aab4d4; }
.combat-report-row__main { display: grid; gap: 3px; }.combat-report-row__main small { color: var(--text-muted); }
.combat-report-row__role, .combat-report-row__losses { color: var(--text-muted); font-size: 12px; }
.combat-report-row__result { font-family: var(--font-heading); letter-spacing: .06em; }
.combat-report-row__result--won { color: #5fd88a; }.combat-report-row__result--lost { color: #ff7468; }.combat-report-row__result--draw { color: #aab4d4; }
.combat-report-row__new { color: #f0c05a; font-size: 10px; font-weight: 700; letter-spacing: .12em; }
.combat-report-back { margin-bottom: 14px; color: var(--accent-bright); border: 0; background: none; cursor: pointer; }
.combat-report-head { display: flex; justify-content: space-between; gap: 20px; align-items: start; }
.combat-report-outcome { padding: 9px 14px; border: 1px solid currentColor; font-family: var(--font-heading); letter-spacing: .08em; }
.combat-report-outcome--won { color: #5fd88a; }.combat-report-outcome--lost { color: #ff7468; }.combat-report-outcome--draw { color: #aab4d4; }
.combat-report-facts { display: flex; flex-wrap: wrap; gap: 10px; margin: 18px 0; }
.combat-report-facts span { padding: 8px 11px; border: 1px solid var(--border-subtle); color: var(--text-muted); }.combat-report-facts b { color: var(--text-primary); }
.combat-report-parties { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
.combat-report-party { display: grid; gap: 3px; padding: 11px; border-left: 3px solid #7383aa; background: rgba(14, 20, 36, .72); }
.combat-report-party span, .combat-report-party small { color: var(--text-muted); }.combat-report-party span { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; }
.combat-report-section { margin-top: 24px; }.combat-report-section h2 { margin-bottom: 10px; }.combat-report-section > p { color: var(--text-muted); font-size: 12px; }
.combat-report-table-wrap { overflow-x: auto; }.combat-report-table { width: 100%; border-collapse: collapse; }
.combat-report-table th, .combat-report-table td { padding: 9px 11px; border-bottom: 1px solid var(--border-subtle); text-align: right; }
.combat-report-table th:first-child, .combat-report-table td:first-child { text-align: left; }.combat-report-number--bad { color: #ff7468; }.combat-report-number--good { color: #5fd88a; }
.combat-report-rounds { display: grid; gap: 7px; max-height: min(64vh, 760px); overflow-y: auto; padding-right: 5px; }
/* Trümmerfeld: Vollbild-Inszenierung nach der Design-Vorlage
   `_Design-Vorlage/weltraumspiel-starcontrol/project/Truemmerfeld.dc.html`
   (2026-09-10). Links das treibende Feld, rechts die Seitenspalte; die
   frühere Kartenliste ist entfallen - sie zeigte dasselbe ein zweites Mal. */
.app-main--debris { padding: 0; overflow: hidden; }
.debris-view { position: absolute; inset: 0; display: flex; flex-direction: column; background: #04050c; }

.debris-view__head {
  flex: none; display: flex; justify-content: space-between; align-items: center; gap: 18px;
  padding: 12px 22px; border-bottom: 1px solid rgba(120,180,255,.12); background: rgba(9,12,24,.9);
}
.debris-head__left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.debris-head__back {
  flex: none; width: 30px; height: 30px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--border); background: transparent; color: var(--text-muted); font-size: 15px;
}
.debris-head__back:hover { color: var(--accent); border-color: var(--accent); }
.debris-head__title {
  font-family: var(--font-heading); font-weight: 700; font-size: 17px;
  letter-spacing: .06em; color: var(--text-primary);
}
.debris-head__sub { font-size: 10px; letter-spacing: .12em; color: #e0a44a; margin-top: 2px; }
.debris-head__sub b { color: var(--text-primary); font-weight: 600; }
.debris-head__sub[data-field-state="depleted"] { color: #d38b7c; }
.debris-head__right { display: flex; align-items: center; gap: 16px; flex: none; }

.debris-tally { display: flex; gap: 14px; font-size: 10px; letter-spacing: .08em; }
.debris-tally__item { color: var(--text-dim); display: flex; gap: 5px; }
.debris-tally__item b { font-weight: 600; }
.debris-tally__item--unknown b { color: #e0a44a; }

.debris-fleet-select { display: flex; align-items: center; gap: 7px; color: var(--text-dim); font-size: 10px; letter-spacing: .1em; }
/* Dasselbe durchsichtige --surface-active wie beim Signal-Dropdown, und
   damit derselbe unlesbare Aufklapper (2026-09-15 mitgefunden). Die uebrigen
   Auswahlfelder im Spiel setzen einen echten dunklen Ton und sind nicht
   betroffen. */
.debris-fleet-select select {
  border: 1px solid var(--border); background: var(--surface-active); color: var(--text-primary);
  padding: 7px 9px; border-radius: 7px; font-family: var(--font-body); font-size: 11.5px;
  color-scheme: dark;
}
.debris-fleet-select select option {
  background: #101827;
  color: #e6ecff;
}
.debris-no-fleet {
  border: 1px solid rgba(255,188,72,.38); background: rgba(255,188,72,.08); color: var(--accent-gold);
  padding: 7px 10px; border-radius: 7px; font-size: 11px;
}

.debris-view__body { flex: 1; display: flex; min-height: 0; }
.debris-scene {
  flex: 1; position: relative; overflow: hidden;
  background: radial-gradient(ellipse at 50% 45%, rgba(60,48,36,.28), #04050c 72%);
}
.debris-stars {
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    radial-gradient(circle at 18% 24%, rgba(255,255,255,.5) 0 1px, transparent 1px),
    radial-gradient(circle at 72% 62%, rgba(255,255,255,.4) 0 1px, transparent 1px),
    radial-gradient(circle at 44% 82%, rgba(255,255,255,.35) 0 1px, transparent 1px);
}
.debris-cable {
  position: absolute; height: 1px; transform-origin: 0 50%; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(180,160,130,.45), transparent);
  animation-name: dbSway; animation-timing-function: ease-in-out; animation-iteration-count: infinite;
}
.debris-frag {
  position: absolute; pointer-events: none;
  animation-timing-function: ease-in-out; animation-iteration-count: infinite;
}
.debris-frag i {
  display: block; border-radius: 1px; box-shadow: 0 0 5px rgba(0,0,0,.6);
  animation-name: dbSpin; animation-timing-function: linear; animation-iteration-count: infinite;
}
.debris-spark {
  position: absolute; width: 3px; height: 3px; border-radius: 50%; pointer-events: none;
  background: #ffd76a; box-shadow: 0 0 8px #ffb84a;
  animation-name: dbSpark; animation-timing-function: linear; animation-iteration-count: infinite;
}

.debris-wreck { position: absolute; transform: translate(-50%,-50%); cursor: pointer; z-index: 4; outline: none; }
.debris-wreck__spin {
  animation-name: dbSpin; animation-timing-function: linear; animation-iteration-count: infinite;
  filter: drop-shadow(0 0 10px rgba(224,164,74,.35));
}
.debris-wreck__spin svg { width: 100%; height: 100%; overflow: visible; }
.debris-wreck__label {
  position: absolute; left: 50%; top: calc(100% + 5px); transform: translateX(-50%); white-space: nowrap;
  font-size: 9.5px; letter-spacing: .08em; color: #e0a44a; text-shadow: 0 0 6px rgba(0,0,0,.9);
}
.debris-wreck--unknown .debris-wreck__label { color: #c9a06a; }
.debris-wreck--salvaged .debris-wreck__spin { opacity: .45; filter: none; }
.debris-wreck--salvaged .debris-wreck__label { color: #5fd88a; }
.debris-wreck--running-scan .debris-wreck__label { color: #d3b8ef; }
.debris-wreck--running-salvage .debris-wreck__label { color: #f4daa0; }
.debris-wreck--selected .debris-wreck__spin { filter: drop-shadow(0 0 12px rgba(127,233,255,.75)); }
.debris-wreck--selected .debris-wreck__label { color: #7fe9ff; }
.debris-wreck:hover .debris-wreck__spin,
.debris-wreck:focus-visible .debris-wreck__spin { filter: drop-shadow(0 0 12px rgba(127,233,255,.6)); }

.debris-view__side {
  flex: none; width: 340px; border-left: 1px solid rgba(120,180,255,.12);
  background: rgba(9,12,24,.96); overflow-y: auto; padding: 20px 22px;
}
.debris-side__label { font-size: 10px; letter-spacing: .12em; color: var(--text-dim); margin-bottom: 9px; }
.debris-side__lore { font-size: 12px; color: #aab4d4; line-height: 1.6; margin: 0 0 4px; }
.debris-side__rule { height: 1px; background: rgba(120,180,255,.12); margin: 18px 0; }
.debris-side__head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 12px; }
.debris-side__name { font-family: var(--font-heading); font-weight: 700; font-size: 15.5px; color: var(--text-primary); }
.debris-side__kind { font-size: 9.5px; letter-spacing: .1em; color: #e0a44a; margin-top: 2px; }
.debris-side__close { border: 0; background: transparent; color: var(--text-dim); font-size: 12px; cursor: pointer; }
.debris-side__close:hover { color: var(--text-primary); }
.debris-side__res { margin-top: 4px; }
.debris-side__res-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 0; border-bottom: 1px solid rgba(120,180,255,.08); font-size: 12px; color: #cdd6f0;
}
.debris-side__res-row span { display: flex; gap: 8px; align-items: center; }
.debris-side__dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; }
.debris-side__unknown { font-size: 12px; color: var(--text-muted); padding: 8px 0; }
.debris-side__warn {
  margin-top: 12px; border: 1px solid rgba(255,188,72,.38); background: rgba(255,188,72,.08);
  color: var(--accent-gold); padding: 9px 11px; border-radius: 7px; font-size: 11.5px;
}
.debris-side__done {
  margin-top: 16px; text-align: center; font-size: 11px; letter-spacing: .1em; color: #5fd88a;
  border: 1px solid rgba(95,216,138,.35); border-radius: 8px; padding: 11px;
}
.debris-side__action {
  display: block; width: 100%; margin-top: 16px; padding: 12px; cursor: pointer;
  font-family: var(--font-heading); font-weight: 600; letter-spacing: .12em; font-size: 12px;
  border-radius: 8px; border: 1px solid rgba(70,217,208,.6);
  background: linear-gradient(90deg,#0e6b6b,#12908a); color: #eafffe;
}
.debris-side__action:disabled { background: transparent; border-color: var(--border); color: var(--text-dim); cursor: not-allowed; }
.debris-side__note { font-size: 9.5px; color: var(--text-dim); margin-top: 8px; text-align: center; }

.debris-side__note--warn { color: var(--accent-gold); text-align: left; line-height: 1.5; }
.debris-job { display: grid; gap: 6px; margin-top: 16px; color: var(--accent); font-size: 12px; }
.debris-job > div:first-child { display: flex; justify-content: space-between; }
.debris-job__track { height: 5px; background: rgba(255,255,255,.08); border-radius: 3px; overflow: hidden; }
.debris-job__track span { display: block; height: 100%; background: var(--accent); }

@keyframes dbDrift1 { 0%{transform:translate(0,0)} 25%{transform:translate(38px,-22px)} 50%{transform:translate(12px,30px)} 75%{transform:translate(-30px,8px)} 100%{transform:translate(0,0)} }
@keyframes dbDrift2 { 0%{transform:translate(0,0)} 33%{transform:translate(-44px,18px)} 66%{transform:translate(20px,34px)} 100%{transform:translate(0,0)} }
@keyframes dbDrift3 { 0%{transform:translate(0,0)} 20%{transform:translate(26px,26px)} 55%{transform:translate(-18px,-32px)} 80%{transform:translate(34px,-6px)} 100%{transform:translate(0,0)} }
@keyframes dbDrift4 { 0%{transform:translate(0,0)} 40%{transform:translate(-28px,-28px)} 70%{transform:translate(-8px,26px)} 100%{transform:translate(0,0)} }
@keyframes dbSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes dbSpark { 0%,100%{opacity:0;transform:scale(.4)} 8%{opacity:1;transform:scale(1.3)} 22%{opacity:0;transform:scale(.5)} }
@keyframes dbSway { 0%,100%{transform:rotate(var(--r)) translateY(0)} 50%{transform:rotate(calc(var(--r) + 6deg)) translateY(8px)} }

/* Ruhiges Feld für alle, die keine Bewegung wollen. Die Wracks bleiben
   sichtbar und anklickbar - nur das Treiben hört auf. */
@media (prefers-reduced-motion: reduce) {
  .debris-cable, .debris-frag, .debris-frag i, .debris-spark, .debris-wreck__spin { animation: none; }
  .debris-spark { opacity: .8; }
}

.starmap-debris-field { border:0; padding:0; background:transparent; cursor:pointer; pointer-events:auto; }

@media (max-width: 900px) {
  .debris-view__body { flex-direction: column; }
  .debris-view__side { width: auto; border-left: 0; border-top: 1px solid rgba(120,180,255,.12); max-height: 45%; }
  .debris-view__head { flex-wrap: wrap; }
  .debris-tally { flex-wrap: wrap; }
}
.combat-report-round { border: 1px solid var(--border-subtle); background: rgba(10, 15, 29, .66); }
.combat-report-round > summary { display: grid; grid-template-columns: 100px 150px 1fr; gap: 12px; align-items: center; padding: 11px 13px; cursor: pointer; }
.combat-report-round > summary span:last-child { color: var(--text-muted); text-align: right; font-size: 11px; }
.combat-report-phase { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; }.combat-report-phase--opening { color: #f0c05a; }.combat-report-phase--escape { color: #e8963c; }
.combat-report-round__events { display: grid; gap: 7px; padding: 0 10px 10px; }
.combat-report-event { padding: 10px; border-left: 3px solid; background: rgba(18, 25, 42, .8); }
.combat-report-event--own { border-color: #7fe9ff; }.combat-report-event--foreign { border-color: #e05a4a; }
.combat-report-event__match { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }.combat-report-event__match span { color: var(--text-muted); }
.combat-report-unit--defense {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: #f0c05a;
}
.combat-report-unit--defense > i { font-size: 14px; }
.combat-report-unit--defense > span { color: inherit; }
.combat-report-unit--defense > small {
  padding: 1px 4px;
  border: 1px solid rgba(240, 192, 90, .42);
  border-radius: 2px;
  color: #f0c05a;
  font-size: 8px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.combat-report-event__stats { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 7px; color: var(--text-muted); font-size: 11px; }.combat-report-event__stats b { color: var(--text-primary); }
.combat-report-event__ability { margin-top: 7px; color: #f0c05a; font-size: 10px; letter-spacing: .08em; }.combat-report-round__empty { color: var(--text-muted); padding: 8px; }
@media (max-width: 850px) {
  .combat-report-row { grid-template-columns: 5px 1fr auto; }.combat-report-row__role, .combat-report-row__losses { display: none; }
  .combat-report-head { align-items: stretch; flex-direction: column; }.combat-report-outcome { align-self: start; }
  .combat-report-round > summary { grid-template-columns: 80px 1fr; }.combat-report-round > summary span:last-child { display: none; }
}

/* K5d: DEFCON-Lagezentrum und Live-Gefecht. */
.defcon-page { display: grid; gap: 22px; max-width: 1280px; margin: 0 auto; }

/* DER LIVE-KAMPF NIMMT DAS GANZE FENSTER (Nutzerwunsch 2026-09-05: "Bitte
   ganzes Fenster nutzen, so gut es geht").

   Die 1280 px oben sind fuer die Lageuebersicht richtig - Fliesstext ueber
   die volle Breite eines 34-Zoll-Schirms liest sich schlecht. Der taktische
   Bericht ist aber kein Text, sondern eine Karte mit zwei Seitenspalten: dort
   ist jeder zusaetzliche Pixel Spielfeld. Deshalb hier, und nur hier, der
   Deckel weg. */
.defcon-live--tactical { max-width: none; }
.defcon-page__head, .defcon-live__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}
.defcon-page__head p, .defcon-live__head p { margin: 5px 0 0; color: var(--text-muted); }
.defcon-page__actions { display: flex; flex-wrap: wrap; gap: 8px; }
.defcon-page__actions button, .defcon-operation__actions button, .defcon-operation__timing button {
  padding: 8px 11px;
  border: 1px solid rgba(127, 233, 255, .4);
  border-radius: 3px;
  background: rgba(127, 233, 255, .07);
  color: var(--accent-bright);
  cursor: pointer;
  font: 600 10px var(--font-heading);
  letter-spacing: .07em;
  text-transform: uppercase;
}
.defcon-page__actions button:hover, .defcon-operation__actions button:hover { background: rgba(127, 233, 255, .14); }
.defcon-alarm {
  display: flex;
  align-items: center;
  gap: 20px;
  min-height: 142px;
  padding: 24px 28px;
  border: 1px solid rgba(95, 216, 138, .35);
  background: linear-gradient(115deg, rgba(95, 216, 138, .1), rgba(8, 14, 27, .88) 58%);
  box-shadow: inset 4px 0 #5fd88a;
}
.defcon-alarm__radar {
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  flex: 0 0 76px;
  border: 1px solid currentColor;
  border-radius: 50%;
  color: #5fd88a;
  box-shadow: 0 0 28px rgba(95, 216, 138, .18);
}
.defcon-alarm__radar i { font-size: 34px; }
.defcon-alarm span, .defcon-kicker { color: var(--text-muted); font-size: 9px; letter-spacing: .13em; }
.defcon-alarm h1 { margin: 4px 0; color: #5fd88a; font: 700 clamp(24px, 4vw, 46px) var(--font-heading); letter-spacing: .06em; }
.defcon-alarm p { margin: 0; color: var(--text-muted); }
/* Manuelle Lagebeurteilung (Nutzerwunsch 2026-08-28). Steht rechts im
   Alarmblock, damit die gewaehlte Stufe und die von der Sensorik gemeldete
   nebeneinander lesbar sind. */
.defcon-alarm__picker { margin-left: auto; display: grid; gap: 5px; justify-items: end; text-align: right; }
.defcon-alarm__picker label { display: grid; gap: 4px; justify-items: end; }
.defcon-alarm__picker label span { color: var(--text-muted); font-size: 9px; letter-spacing: .13em; }
.defcon-alarm__picker select {
  min-width: 190px; padding: 7px 9px; border: 1px solid var(--border-subtle);
  background: rgba(8, 14, 27, .9); color: var(--text-primary); font: inherit; font-size: 12px;
}
.defcon-alarm__picker select:disabled { opacity: .55; }
.defcon-alarm__picker small { color: var(--text-muted); font-size: 10px; }
@media (max-width: 720px) {
  .defcon-alarm { flex-wrap: wrap; }
  .defcon-alarm__picker { margin-left: 0; justify-items: start; text-align: left; }
  .defcon-alarm__picker label { justify-items: start; }
  .defcon-alarm__picker select { min-width: 0; width: 100%; }
}
/* Nutzerwunsch 2026-08-28: "Wenn fremde Flotten in Sensorreichweite sind -
   dann ist das mind. Vorsichtige Lage ... Die Ueberschrift darf dann auch
   orange sein." Bewusst exakt das Orange des Menuepunkts
   (.app-sidebar__item--contacts, #e8a24a): Menue und Ansicht melden dasselbe
   Ereignis und sollen dieselbe Farbe dafuer tragen. Vorher stand hier Blau -
   die beiden Stufen waren ohnehin unerreichbar. */
.defcon-alarm--info, .defcon-alarm--notice { border-color: rgba(232, 162, 74, .45); box-shadow: inset 4px 0 #e8a24a; background: linear-gradient(115deg, rgba(232, 162, 74, .11), rgba(8, 14, 27, .88) 58%); }
.defcon-alarm--info h1, .defcon-alarm--info .defcon-alarm__radar,
.defcon-alarm--notice h1, .defcon-alarm--notice .defcon-alarm__radar { color: #e8a24a; }
.defcon-alarm--warning { border-color: rgba(255, 215, 106, .5); box-shadow: inset 4px 0 #ffd76a; background: linear-gradient(115deg, rgba(255, 215, 106, .12), rgba(8, 14, 27, .88) 58%); }
.defcon-alarm--warning h1, .defcon-alarm--warning .defcon-alarm__radar { color: #ffd76a; }
.defcon-alarm--alert, .defcon-alarm--critical { border-color: rgba(224, 90, 74, .62); box-shadow: inset 4px 0 #e05a4a; background: linear-gradient(115deg, rgba(224, 90, 74, .16), rgba(8, 14, 27, .9) 60%); }
.defcon-alarm--alert h1, .defcon-alarm--alert .defcon-alarm__radar,
.defcon-alarm--critical h1, .defcon-alarm--critical .defcon-alarm__radar { color: #ff7468; }
.defcon-alarm--critical .defcon-alarm__radar { animation: defcon-critical-pulse 1.8s ease-in-out infinite; }
.defcon-section {
  padding: 18px;
  border: 1px solid var(--border-subtle);
  background: rgba(8, 14, 27, .68);
}
.defcon-section__head { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 13px; }
.defcon-section__head h2 { margin: 4px 0 0; font: 600 18px var(--font-heading); }
.defcon-empty { display: flex; align-items: center; gap: 9px; min-height: 58px; color: var(--text-muted); font-size: 12px; }
.defcon-empty i { color: #5fd88a; font-size: 22px; }
.defcon-threat-list, .defcon-operation-list { display: grid; gap: 8px; }
.defcon-threat {
  display: grid;
  grid-template-columns: 105px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 12px;
  border: 1px solid rgba(255, 215, 106, .26);
  border-left: 3px solid #ffd76a;
  background: rgba(255, 215, 106, .035);
}
.defcon-threat--alert, .defcon-threat--critical { border-color: rgba(224, 90, 74, .32); border-left-color: #e05a4a; background: rgba(224, 90, 74, .05); }
.defcon-threat__level { color: #ffd76a; font: 700 9px var(--font-heading); letter-spacing: .08em; }
.defcon-threat--alert .defcon-threat__level, .defcon-threat--critical .defcon-threat__level { color: #ff7468; }
.defcon-threat h3, .defcon-operation h3, .defcon-defense h3, .defcon-live-party h3 { margin: 0; font-size: 14px; }
.defcon-threat p, .defcon-operation p, .defcon-defense p, .defcon-live-party p { margin: 3px 0 0; color: var(--text-muted); font-size: 11px; }
.defcon-threat__eta, .defcon-operation__timing { display: grid; justify-items: end; gap: 3px; }
.defcon-threat__eta small, .defcon-operation__timing small, .defcon-live__round small { color: var(--text-muted); font-size: 8px; letter-spacing: .12em; }
.defcon-threat__eta b, .defcon-operation__timing > b { color: var(--text-primary); font-family: var(--font-heading); }
.defcon-operation {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  padding: 13px;
  border: 1px solid rgba(127, 233, 255, .2);
  border-left: 3px solid #7fe9ff;
  background: rgba(127, 233, 255, .035);
}
.defcon-operation--combat { border-color: rgba(224, 90, 74, .34); border-left-color: #e05a4a; background: rgba(224, 90, 74, .055); }
.defcon-operation__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 7px; }
.defcon-operation__timing button { margin-top: 5px; border-color: rgba(224, 164, 74, .5); color: #e8bd77; background: rgba(224, 164, 74, .07); }
.defcon-operation .combat-operation-status { grid-template-columns: repeat(3, max-content); gap: 5px 14px; }
.defcon-operation .combat-operation-status b { grid-column: 1 / -1; }
.defcon-defense-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); gap: 10px; }
.defcon-defense { padding: 13px; border: 1px solid rgba(120, 180, 255, .18); background: rgba(12, 20, 36, .72); }
.defcon-defense__summary { display: flex; gap: 14px; margin: 8px 0; color: var(--text-muted); font-size: 10px; }
.defcon-defense__summary b { color: var(--text-primary); }
.defcon-defense__fleets, .defcon-defense__buildings { display: grid; gap: 5px; margin-top: 9px; }
.defcon-defense__fleets span { color: var(--text-muted); font-size: 10px; }
.defcon-defense .defcon-defense__unavailable { color: #e8bd77; }
.defcon-defense-building { display: grid; gap: 4px; }
.defcon-defense-building > div:first-child { display: flex; justify-content: space-between; gap: 8px; color: var(--text-muted); font-size: 10px; }
.defcon-defense-building > div:first-child b { color: #5fd88a; }
.defcon-defense-building__track { height: 4px; overflow: hidden; background: rgba(255, 255, 255, .08); }
.defcon-defense-building__track span { display: block; height: 100%; background: #5fd88a; }
.defcon-defense-building--light > div:first-child b, .defcon-defense-building--light .defcon-defense-building__track span { color: #ffd76a; background: #ffd76a; }
.defcon-defense-building--damaged > div:first-child b, .defcon-defense-building--damaged .defcon-defense-building__track span,
.defcon-defense-building--destroyed > div:first-child b, .defcon-defense-building--destroyed .defcon-defense-building__track span { color: #e05a4a; background: #e05a4a; }
.defcon-live__round { display: grid; justify-items: end; gap: 3px; min-width: 130px; }
.defcon-live__round > b { color: var(--accent-bright); font: 700 28px var(--font-heading); }
.defcon-live__round span { color: var(--text-muted); font-size: 10px; }
.defcon-live__progress { height: 5px; overflow: hidden; background: rgba(255, 255, 255, .08); }
.defcon-live__progress span { display: block; height: 100%; background: linear-gradient(90deg, #4a90e2, #7fe9ff); box-shadow: 0 0 10px rgba(127, 233, 255, .5); }
.defcon-live-parties { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 9px; }
.defcon-live-party { padding: 12px; border: 1px solid rgba(224, 90, 74, .28); border-left: 3px solid #e05a4a; background: rgba(224, 90, 74, .04); }
.defcon-live-party--own { border-color: rgba(127, 233, 255, .28); border-left-color: #7fe9ff; background: rgba(127, 233, 255, .04); }
.defcon-live-party > span { color: var(--text-muted); font-size: 9px; letter-spacing: .09em; }
.defcon-live-party > b { display: block; margin-top: 8px; color: #ff8a7f; font-size: 10px; }
.defcon-live-party--own > b { color: var(--accent-bright); }
/* Live-Gefecht: Fortschritt sichtbar machen (Nutzerbefund 2026-08-28, "man
   weiss nicht, ob hier noch was passiert"). Der Pulsschlag laeuft nur, solange
   der Kampf RUNNING ist - ein beendetes Gefecht darf nicht weiterblinken. */
.defcon-live__status { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 9px; color: var(--text-muted); font-size: 11px; }
.defcon-live__status b { color: var(--text-primary); }
.defcon-live__pulse {
  width: 9px; height: 9px; border-radius: 50%; background: #7fe9ff;
  box-shadow: 0 0 0 0 rgba(127, 233, 255, .6); animation: defcon-live-pulse 1.6s ease-out infinite;
}
@keyframes defcon-live-pulse {
  0% { box-shadow: 0 0 0 0 rgba(127, 233, 255, .55); }
  70% { box-shadow: 0 0 0 9px rgba(127, 233, 255, 0); }
  100% { box-shadow: 0 0 0 0 rgba(127, 233, 255, 0); }
}
.defcon-live__progress--running span { animation: defcon-live-sheen 2.4s linear infinite; background-size: 200% 100%; }
@keyframes defcon-live-sheen { from { background-position: 0 0; } to { background-position: -200% 0; } }

/* Bestand beider Seiten. Eigene Gruppen tragen einen Huellenbalken, fremde
   nicht - der Server liefert deren Huellenwerte gar nicht erst aus. */
.defcon-live-units { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 9px; }
.defcon-live-units__party { padding: 12px; border: 1px solid rgba(224, 90, 74, .28); border-left: 3px solid #e05a4a; background: rgba(224, 90, 74, .04); }
.defcon-live-units__party--own { border-color: rgba(127, 233, 255, .28); border-left-color: #7fe9ff; background: rgba(127, 233, 255, .04); }
.defcon-live-units__party h3 { margin: 0 0 9px; font-size: 13px; }
.defcon-live-units__party h3 small { color: var(--accent-bright); font-size: 8px; letter-spacing: .12em; }
.defcon-unit { padding: 7px 0; border-top: 1px solid var(--border-subtle); }
.defcon-unit:first-of-type { border-top: 0; }
.defcon-unit--lost { opacity: .5; }
.defcon-unit__head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: 12px; }
.defcon-unit__head strong { font-weight: 600; }
.defcon-unit__head small { color: var(--text-muted); font-size: 9px; letter-spacing: .08em; }
.defcon-unit__head span { color: var(--text-muted); font-family: var(--font-heading); font-size: 11px; white-space: nowrap; }
.defcon-unit__hull { height: 4px; margin: 5px 0 4px; overflow: hidden; background: rgba(255, 255, 255, .08); }
.defcon-unit__hull span { display: block; height: 100%; background: linear-gradient(90deg, #e05a4a, #ffd76a 55%, #5fd88a); }
.defcon-unit__losses { display: block; color: #ff8a7f; font-size: 10px; }
.defcon-unit__initiative { display: block; color: var(--text-muted); font-size: 9px; letter-spacing: .06em; }

/* Begriffslegende (Nutzerbefund 2026-08-28: "Swarm Attack, Intercept sind
   nicht bekannt so richtig"). Zugeklappt, damit sie das Protokoll nicht
   verdraengt. */
.combat-legend { margin-top: 12px; border: 1px solid var(--border-subtle); background: rgba(10, 15, 29, .5); }
.combat-legend > summary { padding: 9px 12px; color: var(--text-muted); font-size: 11px; letter-spacing: .06em; cursor: pointer; }
.combat-legend__body { display: grid; gap: 14px; padding: 4px 12px 12px; }
.combat-legend__group h4 { margin: 0 0 6px; color: var(--text-primary); font-size: 11px; letter-spacing: .08em; }
.combat-legend__group dl { display: grid; grid-template-columns: minmax(120px, auto) minmax(0, 1fr); gap: 4px 12px; margin: 0; }
.combat-legend__group dt { color: var(--accent-bright); font-size: 11px; }
.combat-legend__group dd { margin: 0; color: var(--text-muted); font-size: 11px; }

/* Wer da auf wen schiesst (Nutzerwunsch 2026-08-28). */
.combat-report-event__actor { margin-bottom: 5px; color: var(--text-muted); font-size: 10px; letter-spacing: .05em; }
.combat-report-event__actor span { opacity: .7; }

@keyframes defcon-critical-pulse { 0%,100% { box-shadow: 0 0 10px rgba(224,90,74,.15); } 50% { box-shadow: 0 0 36px rgba(224,90,74,.55); } }
@media (prefers-reduced-motion: reduce) {
  .defcon-alarm--critical .defcon-alarm__radar { animation: none; }
  .defcon-live__pulse, .defcon-live__progress--running span { animation: none; }
}
@media (max-width: 720px) {
  .combat-legend__group dl { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .combat-legend__group dd { margin-bottom: 7px; }
}
@media (max-width: 720px) {
  .defcon-page__head, .defcon-live__head { flex-direction: column; }
  .defcon-alarm { align-items: flex-start; padding: 18px; }
  .defcon-alarm__radar { width: 54px; height: 54px; flex-basis: 54px; }
  .defcon-threat, .defcon-operation { grid-template-columns: 1fr; }
  .defcon-threat__eta, .defcon-operation__timing { justify-items: start; }
  .defcon-operation__actions { justify-content: flex-start; }
  .defcon-operation .combat-operation-status { grid-template-columns: 1fr; }
}

/* K5c: Angriff aus Systemansicht und Sternenkarte. */
.combat-targets {
  display: grid;
  gap: 7px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border-subtle);
}
.combat-targets__heading {
  color: #e05a4a;
  font: 600 10px var(--font-heading);
  letter-spacing: .12em;
}
.combat-target {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px;
  border: 1px solid rgba(224, 90, 74, .25);
  background: rgba(224, 90, 74, .05);
}
.combat-target > div { min-width: 0; }
.combat-target b, .combat-target small { display: block; }
.combat-target b { overflow: hidden; color: var(--text-primary); text-overflow: ellipsis; white-space: nowrap; }
.combat-target small, .combat-targets__hint { margin-top: 3px; color: var(--text-muted); font-size: 10px; }
.combat-target__attack, .combat-operation__submit {
  border: 1px solid rgba(224, 90, 74, .72);
  border-radius: 3px;
  background: rgba(224, 90, 74, .12);
  color: #ff8a7f;
  cursor: pointer;
  font: 600 10px var(--font-heading);
  letter-spacing: .07em;
  text-transform: uppercase;
}
.combat-target__attack { flex: 0 0 auto; padding: 7px 9px; }
.combat-target__attack:hover, .combat-operation__submit:hover { background: rgba(224, 90, 74, .22); }
.combat-target__attack:disabled { cursor: not-allowed; opacity: .42; }
.combat-operation-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(2, 5, 12, .82);
}
.combat-operation {
  position: relative;
  width: min(540px, 100%);
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  padding: 24px;
  border: 1px solid rgba(224, 90, 74, .58);
  background: #0b1120;
  box-shadow: 0 20px 70px rgba(0, 0, 0, .62);
}
.combat-operation h2 { margin: 5px 32px 18px 0; }

/* Der Kraeftevergleich im Angriffsdialog (Nutzerwunsch 2026-09-05).
   Zwei Spalten mit einem "gegen" dazwischen - die eigene Seite vollstaendig,
   die gegnerische so weit, wie die Aufklaerung reicht. */
.combat-forces {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: 12px;
  margin: 0 0 18px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, .02);
}

.combat-forces__side { min-width: 0; }

.combat-forces__side h3 {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 12px;
  letter-spacing: .04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.combat-forces__side--own h3 { color: var(--accent-bright); }
.combat-forces__side--enemy h3 { color: var(--accent-red); }

.combat-forces__side > small {
  display: block;
  margin-top: 1px;
  font-size: 9.5px;
  letter-spacing: .06em;
  color: var(--text-muted);
}

.combat-forces__side ul {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  /* Eine grosse Flotte darf den Dialog nicht sprengen - der Rest scrollt. */
  max-height: 132px;
  overflow-y: auto;
}

.combat-forces__side li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 8px;
  padding: 3px 0;
  font-size: 10.5px;
  border-bottom: 1px solid rgba(120, 180, 255, .07);
}

.combat-forces__side li span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-body);
}

.combat-forces__side li b { font-family: var(--font-mono); color: var(--text-primary); }

.combat-forces__side li u {
  grid-column: 1 / -1;
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--text-muted);
}

.combat-forces__empty { color: var(--text-muted); font-style: italic; border-bottom: 0 !important; }

.combat-forces__note {
  display: block;
  margin-top: 6px;
  font-size: 9px;
  letter-spacing: .05em;
  color: var(--text-dimmer);
}

/* Wohin der Angriff fuehrt - ueber die volle Breite unter beiden Seiten
   (2026-09-05). Der Kartenmarker steht auf der letzten Ortung, die Flotte
   fliegt zum System; wer das nicht weiss, haelt die Reiselinie fuer falsch. */
.combat-forces__target {
  grid-column: 1 / -1;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--text-body);
}

.combat-forces__target i { color: var(--accent-gold); margin-right: 4px; }
.combat-forces__target b { color: var(--accent-gold); }

.combat-forces__target small {
  display: block;
  margin-top: 2px;
  font-size: 9.5px;
  color: var(--text-muted);
}

.combat-forces__versus {
  align-self: center;
  font-family: var(--font-heading);
  font-size: 10px;
  letter-spacing: .16em;
  color: var(--text-dim);
}

@media (max-width: 560px) {
  .combat-forces { grid-template-columns: 1fr; }
  .combat-forces__versus { justify-self: center; }
}
.combat-operation label { display: grid; gap: 5px; margin-top: 12px; color: var(--text-muted); font-size: 11px; }
.combat-operation select, .combat-operation input {
  width: 100%;
  padding: 9px;
  border: 1px solid var(--border-subtle);
  background: #070d19;
  color: var(--text-primary);
}
.combat-operation__close {
  position: absolute;
  top: 12px;
  right: 14px;
  border: 0;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 25px;
}
.combat-operation__help { display: grid; gap: 5px; padding-left: 18px; color: var(--text-muted); font-size: 11px; }
.combat-operation__help b { color: var(--text-primary); }
.combat-operation__warning {
  margin: 16px 0;
  padding: 10px;
  border-left: 3px solid #e0a44a;
  background: rgba(224, 164, 74, .08);
  color: #e8bd77;
  font-size: 11px;
  line-height: 1.5;
}
/* Die Abfangauskunft im Angriffsdialog (Spec 2026-09-18). Steht direkt ueber
   dem Knopf, weil sie die Entscheidung tragen soll. */
.combat-operation__intercept {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  margin: 0 0 12px;
  padding: 10px;
  border-left: 3px solid #6fd3ff;
  background: rgba(111, 211, 255, .08);
  color: #a9e2ff;
  font-size: 11px;
  line-height: 1.5;
}
.combat-operation__intercept--blocked {
  border-left-color: #ff8b70;
  background: rgba(255, 139, 112, .08);
  color: #ffb9a6;
}
.combat-operation__submit:disabled { opacity: .45; cursor: not-allowed; }
.combat-operation__submit { width: 100%; padding: 11px; }
.combat-operation-status { display: grid; gap: 2px; margin: 7px 0; font-size: 10px; }
.combat-operation-status b { color: #ff8a7f; }
.combat-operation-status span { color: var(--text-muted); }
.combat-retreat {
  display: grid;
  gap: 6px;
  margin-top: 12px;
  padding: 10px;
  border: 1px solid rgba(224, 90, 74, .42);
  background: rgba(224, 90, 74, .07);
}
.combat-retreat b { color: #ff8a7f; font-size: 11px; }
.combat-retreat span { color: var(--text-muted); font-size: 10px; line-height: 1.45; }
.combat-retreat__action {
  padding: 8px 10px;
  border: 1px solid rgba(224, 90, 74, .72);
  background: rgba(224, 90, 74, .14);
  color: #ff8a7f;
  cursor: pointer;
  font: 600 10px var(--font-heading);
  letter-spacing: .07em;
  text-transform: uppercase;
}
.combat-retreat__action:hover { background: rgba(224, 90, 74, .24); }
.combat-retreat__action:disabled { cursor: wait; opacity: .5; }
.combat-retreat--running { border-color: rgba(224, 164, 74, .5); background: rgba(224, 164, 74, .07); }
.combat-retreat--running b { color: #e8bd77; }
.combat-retreat--resolved { border-color: var(--border-subtle); background: rgba(255, 255, 255, .025); }
.combat-retreat--resolved b { color: var(--text-muted); }

/* --- Das Versteck: Bildbuehne mit deckungsgleichen Prozent-Hotspots --- */
.app-main--hideout {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  overflow: auto;
  background: #05040a;
}
.hideout-stage {
  position: relative;
  flex: 0 0 auto;
  aspect-ratio: 1456 / 1092;
  width: min(100%, calc((100vh - var(--topbar-height)) * 1456 / 1092));
  width: min(100%, calc((100dvh - var(--topbar-height)) * 1456 / 1092));
  margin: auto;
  background-image: url('/assets/img/hideout/das-versteck-neu.png');
  background-size: 100% 100%;
  background-repeat: no-repeat;
  image-rendering: auto;
}
.hideout-hotspot {
  position: absolute;
  left: var(--hideout-left);
  top: var(--hideout-top);
  width: var(--hideout-width);
  height: var(--hideout-height);
  padding: 0;
  border: 0;
  border-radius: 16px;
  background: transparent;
  color: var(--text-primary);
  cursor: pointer;
  transition: background-color .16s ease, box-shadow .16s ease, filter .16s ease;
}
.hideout-hotspot:hover,
.hideout-hotspot:focus-visible {
  outline: none;
  background: rgba(91, 213, 255, .035);
  box-shadow: 0 0 26px 5px rgba(91, 213, 255, .2), inset 0 0 24px rgba(255, 255, 255, .035);
  filter: brightness(1.08);
}
.hideout-hotspot__label {
  position: absolute;
  z-index: 1;
  display: block;
  padding: 5px 8px;
  border: 1px solid rgba(91, 213, 255, .42);
  border-radius: var(--radius-sm);
  background: rgba(5, 7, 15, .9);
  box-shadow: 0 4px 18px rgba(0, 0, 0, .55);
  color: #d8f7ff;
  font: 600 10px var(--font-heading);
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .14s ease, transform .14s ease;
}
.hideout-hotspot:hover .hideout-hotspot__label,
.hideout-hotspot:focus-visible .hideout-hotspot__label { opacity: 1; }
.hideout-hotspot--missions .hideout-hotspot__label,
.hideout-hotspot--intro .hideout-hotspot__label {
  top: calc(100% + 7px);
  left: 50%;
  transform: translate(-50%, -3px);
}
.hideout-hotspot--missions:hover .hideout-hotspot__label,
.hideout-hotspot--missions:focus-visible .hideout-hotspot__label,
.hideout-hotspot--intro:hover .hideout-hotspot__label,
.hideout-hotspot--intro:focus-visible .hideout-hotspot__label { transform: translate(-50%, 0); }
.hideout-hotspot--lottery .hideout-hotspot__label {
  bottom: calc(100% + 7px);
  right: 8%;
  transform: translateY(3px);
}
.hideout-hotspot--story .hideout-hotspot__label,
.hideout-hotspot--bounties .hideout-hotspot__label,
.hideout-hotspot--jukebox .hideout-hotspot__label {
  top: 50%;
  left: calc(100% + 7px);
  transform: translate(-3px, -50%);
}
.hideout-hotspot--lottery:hover .hideout-hotspot__label,
.hideout-hotspot--lottery:focus-visible .hideout-hotspot__label { transform: translateY(0); }
.hideout-hotspot--story:hover .hideout-hotspot__label,
.hideout-hotspot--story:focus-visible .hideout-hotspot__label,
.hideout-hotspot--bounties:hover .hideout-hotspot__label,
.hideout-hotspot--bounties:focus-visible .hideout-hotspot__label,
.hideout-hotspot--jukebox:hover .hideout-hotspot__label,
.hideout-hotspot--jukebox:focus-visible .hideout-hotspot__label { transform: translate(0, -50%); }
.hideout-modal {
  padding: 26px 28px;
  background: linear-gradient(145deg, rgba(14, 12, 24, .99), rgba(6, 7, 15, .99));
  border: 1px solid rgba(91, 213, 255, .2);
  color: var(--text-muted);
}
.hideout-modal__title {
  margin: 4px 38px 16px 0;
  color: var(--text-primary);
  font: 600 21px var(--font-heading);
  letter-spacing: .06em;
}
.hideout-modal p { margin: 0 0 13px; font-size: 11px; line-height: 1.65; }
/* Kopfgeldbrett (Nutzerentscheidung 2026-08-28): zwei Abschnitte - wer gesucht
   wird, und wer schon kassiert hat. */
.bounty-section {
  margin: 18px 0 8px;
  color: var(--accent);
  font: 600 12px var(--font-heading);
  letter-spacing: .12em;
  text-transform: uppercase;
}
.bounty-section:first-of-type { margin-top: 4px; }
.bounty-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.bounty-table th {
  padding: 0 10px 6px 0;
  color: #8b96ba;
  font: 600 10px var(--font-heading);
  letter-spacing: .1em;
  text-transform: uppercase;
  text-align: left;
  border-bottom: 1px solid rgba(120, 180, 255, 0.16);
}
.bounty-table td {
  padding: 7px 10px 7px 0;
  border-bottom: 1px solid rgba(120, 180, 255, 0.07);
  line-height: 1.4;
}
.bounty-table tr:last-child td { border-bottom: none; }
/* Zahlen rechtsbuendig und mit gleichen Ziffernbreiten - sonst tanzen die
   Betraege in der Spalte. */
.bounty-table__num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bounty-table__unknown { color: #8b96ba; font-style: italic; }
.bounty-amount { color: #ffd479; font-weight: 600; }
.hideout-modal__action {
  width: 100%;
  margin-top: 8px;
  padding: 10px 14px;
  border: 1px solid rgba(91, 213, 255, .45);
  border-radius: var(--radius-sm);
  background: rgba(91, 213, 255, .08);
  color: #d8f7ff;
  cursor: pointer;
  font: 600 11px var(--font-heading);
  letter-spacing: .07em;
  text-transform: uppercase;
}
.hideout-modal__action:hover { background: rgba(91, 213, 255, .15); }
.hideout-modal__action:disabled { cursor: wait; opacity: .55; }
.hideout-modal--missions { min-height: 180px; }
.hideout-modal--missions .mission-cards { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.hideout-modal--story-archive { min-height: 180px; }
.story-archive__chapter {
  margin: -8px 0 14px;
  color: var(--accent-gold);
  font: 600 11px var(--font-heading);
  letter-spacing: .08em;
}
.hideout-modal--story-archive > .stat-row { margin-bottom: 22px; }
.story-archive__section {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid rgba(120, 180, 255, .13);
}
.story-archive__section > h3 {
  margin: 0 0 11px;
  color: var(--accent);
  font: 600 10px var(--font-heading);
  letter-spacing: .14em;
}
.story-archive__clue-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px;
}
.story-archive__clue-group {
  padding: 12px 14px;
  border: 1px solid rgba(120, 180, 255, .13);
  border-radius: var(--radius-sm);
  background: rgba(91, 213, 255, .035);
}
.story-archive__clue-group h4 {
  margin: 0 0 9px;
  color: var(--text-primary);
  font: 600 10px var(--font-heading);
  letter-spacing: .08em;
  text-transform: uppercase;
}
.story-archive__clue-group ul,
.story-archive__open-steps {
  display: grid;
  gap: 9px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.story-archive__clue-group li { display: grid; gap: 3px; font-size: 10px; line-height: 1.5; }
.story-archive__clue-group li strong { color: var(--accent-bright); font-weight: 600; }
.story-archive__open-steps li { display: flex; align-items: center; gap: 8px; font-size: 10px; }
.story-archive__open-steps i { color: var(--accent-gold); }

/* Storyentscheidung (Paket Z6, Baustein C). Bewusst anders als der
   Raetselblock: kein Zaehler, keine Stufe, und die Optionen stehen als
   gleichwertige Knoepfe untereinander - es gibt keine falsche Antwort, nur
   eine, die bleibt. */
.story-archive__choice {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid rgba(255, 215, 106, .28);
  border-left: 3px solid var(--accent-gold);
  border-radius: 6px;
  background: rgba(255, 215, 106, .05);
}
.story-archive__choice-prompt { margin: 0 0 10px; font-size: 12.5px; line-height: 1.5; color: var(--text-body); }
.story-archive__choice-options { display: grid; gap: 8px; margin-top: 12px; }
.story-archive__choice-options .hideout-modal__action { width: 100%; margin: 0; }
/* Getroffen: der Rahmen beruhigt sich. Eine Entscheidung, die feststeht,
   soll nicht mehr zum Handeln auffordern. */
.story-archive__choice--done {
  border-color: var(--border-strong);
  border-left-color: var(--text-muted);
  background: rgba(255, 255, 255, .02);
}
.story-archive__choice-chosen { margin: 0 0 6px; font-size: 12.5px; color: var(--accent-gold); }

/* Das siebte Signal (Konzept Abschnitt 14). Es steht am FUSS des Archivs und
   bewusst gedaempft: solange es verschlossen ist, ist es eine Fussnote ueber
   andere Spieler, kein Auftrag. Offen bekommt es den goldenen Rand, den auch
   die Entscheidung traegt - dann ist es beides. */
.story-archive__seventh {
  margin-top: 18px;
  padding: 12px 14px;
  border: 1px dashed var(--border-strong);
  border-radius: 6px;
  background: rgba(255, 255, 255, .015);
}
.story-archive__seventh--open {
  border-style: solid;
  border-color: rgba(255, 215, 106, .28);
  border-left: 3px solid var(--accent-gold);
  background: rgba(255, 215, 106, .05);
}
.story-archive__seventh-text {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}

/* Titel in der Kopfzeile (Paket Z6, Baustein C). Golden wie eine
   Auszeichnung, aber ohne Gut/Schlecht-Faerbung - ein Titel wirkt nicht, er
   erzaehlt. */
.meta-title {
  padding: 1px 6px;
  border: 1px solid rgba(255, 215, 106, .35);
  border-radius: 4px;
  background: rgba(255, 215, 106, .08);
  color: var(--accent-gold);
  font-size: 10px;
  white-space: nowrap;
}
.meta-title--more { border-color: var(--border-strong); background: none; color: var(--text-muted); }
.story-archive__choice--done p:last-child { margin: 0; font-size: 11.5px; color: var(--text-muted); line-height: 1.5; }
.hideout-modal--lottery { min-height: 360px; }
.lottery-jackpot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 22px;
  padding: 14px 17px;
  border: 1px solid color-mix(in srgb, var(--accent-gold) 42%, transparent);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--accent-gold) 7%, transparent);
  box-shadow: inset 0 0 22px color-mix(in srgb, var(--accent-gold) 7%, transparent);
}
.lottery-jackpot span,
.lottery-ticket h3,
.lottery-result h3,
.lottery-yesterday h3 {
  color: var(--text-muted);
  font: 600 10px var(--font-heading);
  letter-spacing: .14em;
}
.lottery-jackpot strong {
  color: var(--accent-gold);
  font: 700 clamp(22px, 5vw, 34px) var(--font-heading);
  letter-spacing: .06em;
  text-shadow: var(--glow-sm) color-mix(in srgb, var(--accent-gold) 65%, transparent);
}
.lottery-ticket__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.lottery-randomize {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 10px;
  border: 1px solid color-mix(in srgb, var(--accent-gold) 48%, transparent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent-gold) 8%, transparent);
  color: var(--accent-gold);
  cursor: pointer;
  font: 600 9px var(--font-heading);
  letter-spacing: .08em;
  text-transform: uppercase;
}
.lottery-randomize:hover { background: color-mix(in srgb, var(--accent-gold) 15%, transparent); }
.lottery-randomize:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.lottery-randomize:disabled { cursor: wait; opacity: .55; }
.lottery-randomize i { font-size: 16px; }
.lottery-code {
  display: grid;
  grid-template-columns: repeat(8, minmax(42px, 1fr));
  gap: 7px;
  margin: 10px 0 16px;
}
.lottery-code__choice { min-width: 0; }
.lottery-code__choice > span {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}
.lottery-code__choice select,
.lottery-code__cell {
  width: 100%;
  min-height: 58px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-primary);
  text-align: center;
  font: 700 21px var(--font-heading);
}
.lottery-code__choice select { padding: 8px 2px; cursor: pointer; }
.lottery-code__choice--spinning select {
  border-color: var(--accent-bright);
  box-shadow: inset 0 0 18px color-mix(in srgb, var(--accent-bright) 18%, transparent);
  animation: lottery-reel-spin .11s linear infinite;
}
.lottery-code__choice--slowing select {
  border-color: var(--accent-gold);
  box-shadow: inset 0 0 16px color-mix(in srgb, var(--accent-gold) 16%, transparent);
  animation: lottery-reel-slow .24s ease-out infinite;
}
.lottery-code__choice--locked select { animation: lottery-reel-lock .22s ease-out; }
@keyframes lottery-reel-spin {
  0% { transform: translateY(-2px); filter: brightness(.75); }
  50% { transform: translateY(2px); filter: brightness(1.35); }
  100% { transform: translateY(-2px); filter: brightness(.75); }
}
@keyframes lottery-reel-slow {
  0% { transform: translateY(-1px); }
  50% { transform: translateY(1px); }
  100% { transform: translateY(-1px); }
}
@keyframes lottery-reel-lock {
  0% { transform: scale(.9); }
  65% { transform: scale(1.08); }
  100% { transform: scale(1); }
}
.lottery-code__choice select:focus-visible {
  outline: 2px solid var(--accent-bright);
  outline-offset: 2px;
}
.lottery-code__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  transition: color .18s ease, background-color .18s ease, border-color .18s ease, transform .18s ease;
}
.lottery-code__cell > span { color: var(--text-dim); font-size: 13px; opacity: 0; }
.lottery-code__cell small { color: var(--text-muted); font: 500 7px var(--font-body); line-height: 1.1; opacity: 0; }
.lottery-code__cell--revealed { transform: translateY(-2px); }
.lottery-code__cell--revealed > span,
.lottery-code__cell--revealed small { opacity: 1; }
.lottery-code__cell--exact {
  border-color: var(--accent-green);
  background: color-mix(in srgb, var(--accent-green) 17%, var(--surface));
}
.lottery-code__cell--exact > span { color: var(--accent-green); }
.lottery-code__cell--misplaced {
  border-color: var(--accent-gold);
  background: color-mix(in srgb, var(--accent-gold) 15%, var(--surface));
}
.lottery-code__cell--misplaced > span { color: var(--accent-gold); }
.lottery-code__cell--none {
  border-color: var(--text-dim);
  background: color-mix(in srgb, var(--text-dim) 12%, var(--surface));
}
.lottery-ticket__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
.lottery-ticket__footer .hideout-modal__action { width: auto; min-width: 180px; margin: 0; }
.lottery-ticket__error { min-height: 18px; margin: 8px 0 0 !important; color: var(--accent-red); }
.lottery-result { padding: 12px; border: 1px solid var(--border); border-radius: var(--radius-md); }
.lottery-result--near-jackpot {
  border-color: var(--accent-gold);
  box-shadow: var(--glow-sm) color-mix(in srgb, var(--accent-gold) 35%, transparent);
}
.lottery-result--jackpot {
  border-color: var(--accent-green);
  box-shadow: var(--glow-md) color-mix(in srgb, var(--accent-green) 45%, transparent);
}
.lottery-yesterday { margin-top: 22px; padding-top: 17px; border-top: 1px solid var(--border); }
.lottery-yesterday__code { margin: 9px 0; color: var(--accent-bright); font: 600 17px var(--font-heading); letter-spacing: .15em; }
.lottery-yesterday__stats { display: flex; flex-wrap: wrap; gap: 8px 18px; color: var(--text-muted); font-size: 9px; }
.lottery-yesterday__stats b { color: var(--text-body); }

@media (max-width: 600px) {
  .hideout-modal--lottery { padding: 22px 16px; }
  .lottery-code { grid-template-columns: repeat(4, minmax(42px, 1fr)); }
  .lottery-ticket__footer { align-items: stretch; flex-direction: column; }
  .lottery-ticket__footer .hideout-modal__action { width: 100%; }
  .combat-operation-backdrop { padding: 8px; }
  .combat-operation { max-height: calc(100vh - 16px); padding: 18px; }
  .combat-target { align-items: stretch; flex-direction: column; }
  .combat-target__attack { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .lottery-code__choice select { animation: none; }
}

/* DEFCON: fremde Flotten in Sensorreichweite (2026-08-25). Eigene Liste statt
   einer weiteren Bedrohungszeile - was hier steht, ist beobachtet, nicht
   bewertet. */
.defcon-contact-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.defcon-contact {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border-radius: var(--radius-lg);
  background: rgba(232, 162, 74, .07);
  border: 1px solid rgba(232, 162, 74, .34);
  border-left: 3px solid #e8a24a;
}
.defcon-contact__icon {
  font-size: 20px;
  color: #e8a24a;
}
.defcon-contact__body h3 {
  margin: 0;
  font-size: 14px;
  color: #ffd9a3;
}
.defcon-contact__body p {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--text-dim);
}
.defcon-contact__composition {
  opacity: .85;
}
.defcon-contact__stale {
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  margin-left: 6px;
  vertical-align: middle;
}
.defcon-contact__level {
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #e8a24a;
  white-space: nowrap;
}
@media (max-width: 640px) {
  .defcon-contact {
    grid-template-columns: auto 1fr;
  }
  .defcon-contact__level {
    grid-column: 2;
  }
}
.defcon-situation-selector {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 1rem;
  padding: 0.85rem 1rem;
  border: 1px solid rgba(74, 222, 128, 0.24);
  background: rgba(8, 27, 34, 0.82);
}

.defcon-situation-selector label {
  color: var(--text-muted);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.defcon-situation-selector select {
  min-width: min(26rem, 70vw);
}
.favorite-star {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: 8px;
  padding: 0;
  border: 1px solid rgba(127, 233, 255, .28);
  border-radius: 7px;
  background: rgba(8, 13, 28, .8);
  color: #8b96ba;
  cursor: pointer;
  vertical-align: middle;
}

.favorite-star:hover,
.favorite-star--active {
  border-color: rgba(255, 215, 106, .65);
  color: #ffd76a;
  box-shadow: 0 0 12px rgba(255, 215, 106, .16);
}
.favorite-star span { font-size: 19px; line-height: 1; }
.starmap-moon-favorite-anchor .favorite-star { width: 19px; height: 19px; margin-left: 1px; border: 0; background: transparent; }
.starmap-moon-favorite-anchor .favorite-star span { font-size: 14px; }

/* Nutzerbefund 2026-08-31: der Knopf lag auf dem Navigatorkasten.
   Er steht jetzt RECHTS DANEBEN, als eigene Ueberlagerung der Karte - wie die
   uebrigen Panels (.starmap-navigator).

   Die 350px sind nicht frei gewaehlt: der Navigator sitzt bei left:16px und
   ist 322px breit, endet also bei 338. Wer eine der beiden Zahlen aendert,
   muss diese mitziehen.

   Entfernt wurde hier ein `.starmap-navigator { position: relative; }` - es
   stand NACH der Regel in Zeile 1992 und ueberschrieb damit deren
   `position: absolute`. Der Navigator ist eine Ueberlagerung der Karte (z-index
   5, top/left 16, Schlagschatten) und fiel dadurch in den normalen Fluss.
   Gebraucht wurde die Regel ohnehin nicht: ein absolut positioniertes Element
   ist fuer absolute Kinder bereits der Bezugsrahmen. */
/* .starmap-favorites-open ist am 2026-09-04 entfallen: die Favoriten haben
   einen eigenen Reiter in der rechten Leiste und brauchen keinen Knopf, der
   ein Modal ueber die Karte legt. */

.favorite-editor label { display: grid; gap: 7px; color: var(--text-muted); }
.favorite-editor textarea,
.favorites-table textarea {
  box-sizing: border-box;
  width: 100%;
  resize: vertical;
  border: 1px solid rgba(120, 180, 255, .25);
  border-radius: 6px;
  padding: 9px;
  background: rgba(4, 7, 17, .9);
  color: var(--text-primary);
  font: inherit;
}
.favorite-editor__actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.favorite-editor__actions button,
.favorites-table__actions button,
.favorites-modal__head button {
  border: 1px solid rgba(120, 180, 255, .3);
  border-radius: 6px;
  padding: 7px 10px;
  background: rgba(20, 31, 58, .85);
  color: var(--text-primary);
  cursor: pointer;
}
.favorite-editor__actions .favorites-remove,
.favorites-table__actions .favorites-remove { border-color: rgba(224, 90, 74, .45); color: #ef8f84; }

.favorites-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 219;
  pointer-events: none;
  opacity: 0;
  background: rgba(1, 3, 10, .82);
  transition: opacity .18s ease;
}
.favorites-modal-backdrop--visible { pointer-events: auto; opacity: 1; }
.favorites-modal {
  position: fixed;
  inset: 24px;
  z-index: 220;
  display: none;
  overflow: auto;
  border: 1px solid rgba(120, 180, 255, .28);
  border-radius: 12px;
  padding: 24px;
  background: #080d1c;
  color: var(--text-primary);
  box-shadow: 0 28px 90px rgba(0, 0, 0, .62);
}
.favorites-modal--open { display: block; }
.favorites-modal__head { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 20px; }
.favorites-modal__head h1 { margin: 2px 0 0; }
.favorites-table-wrap { overflow-x: auto; }
.favorites-table { width: 100%; border-collapse: collapse; min-width: 980px; }
.favorites-table th,
.favorites-table td { border-bottom: 1px solid rgba(120, 180, 255, .14); padding: 10px; text-align: left; vertical-align: top; }
.favorites-table th { color: #8b96ba; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; }

/* FAVORITEN IM REITER DER STERNENKARTE (Nutzerwunsch 2026-09-04).

   Zweizeilig je Favorit: oben Name und Knoepfe, darunter die Notiz hinter
   einem [mehr]. Das Markup dafuer kommt aus favoritesPanelMarkup() - die
   siebenspaltige Modal-Tabelle in diese Leiste zu stauchen hiess entweder
   waagerecht scrollen oder die halben Spalten verstecken. */
.favorites-panel { width: 100%; border-collapse: collapse; }
.favorites-panel__row > td {
  padding: 7px 0 0;
  vertical-align: middle;
}
.favorites-panel__name {
  color: #e6ebff;
  font-size: 12px;
  display: flex;
  align-items: baseline;
  gap: 6px;
  overflow: hidden;
}
.favorites-panel__name > i { color: var(--accent); flex: none; }
.favorites-panel__starname {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.favorites-panel__system {
  color: #8b96ba;
  font-size: 10px;
  white-space: nowrap;
}
.favorites-panel__actions {
  width: 1%;
  white-space: nowrap;
  text-align: right;
}
.favorites-panel__actions button {
  border: 1px solid rgba(120, 180, 255, .22);
  border-radius: 5px;
  background: rgba(10, 14, 28, .7);
  color: #c9d0e0;
  cursor: pointer;
  padding: 4px 6px;
  margin-left: 3px;
  font-size: 12px;
  line-height: 1;
}
.favorites-panel__actions button:hover { border-color: rgba(127, 233, 255, .45); color: #7fe9ff; }
.favorites-panel__actions .favorites-remove:hover { border-color: rgba(224, 90, 74, .5); color: #ef8f84; }

/* Die Notizzeile schliesst den Eintrag ab - deshalb traegt SIE die Trennlinie
   und nicht die Namenszeile darueber. */
.favorites-panel__noterow > td {
  padding: 2px 0 7px;
  border-bottom: 1px solid rgba(120, 180, 255, .14);
}
.favorites-panel__more {
  display: flex;
  width: 100%;
  gap: 8px;
  align-items: baseline;
  border: none;
  background: none;
  padding: 0;
  color: #8b96ba;
  cursor: pointer;
  font-size: 11px;
  text-align: left;
}
.favorites-panel__preview {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.favorites-panel__morelabel { flex: none; color: #7fe9ff; }
.favorites-panel__note[hidden] { display: none; }
.favorites-panel__note {
  display: flex;
  gap: 6px;
  align-items: flex-end;
  margin-top: 5px;
}
.favorites-panel__note textarea {
  flex: 1;
  border: 1px solid rgba(120, 180, 255, .22);
  border-radius: 5px;
  background: rgba(6, 9, 20, .8);
  color: var(--text);
  padding: 5px 7px;
  font: inherit;
  font-size: 11px;
  resize: vertical;
}
.favorites-panel__note button {
  flex: none;
  border: 1px solid rgba(127, 233, 255, .35);
  border-radius: 5px;
  background: rgba(127, 233, 255, .10);
  color: #7fe9ff;
  cursor: pointer;
  padding: 5px 9px;
  font-size: 11px;
}
.favorites-table__type { color: #ffd76a; white-space: nowrap; }
.favorites-table__type i { margin-right: 6px; }
.favorites-table__actions { display: grid; gap: 6px; min-width: 126px; }
.favorites-empty { display: grid; place-items: center; min-height: 45vh; color: #8b96ba; }
.favorites-empty i { color: #ffd76a; font-size: 40px; }

@media (max-width: 800px) {
  .favorites-modal { inset: 8px; padding: 14px; }
}

/* Mission aufgeben (Nutzerwunsch 2026-09-01). Bewusst zurueckgenommen
   gegenueber "Annehmen" und "Bergen" - es ist die abraeumende Handlung, nicht
   die vorantreibende. */
.mission-card__btn--abandon {
  border-color: color-mix(in srgb, var(--accent-red, #e06c75) 40%, transparent);
  color: var(--text-dim);
}
.mission-card__btn--abandon:hover:not(:disabled) {
  border-color: var(--accent-red, #e06c75);
  color: var(--accent-red, #e06c75);
}

/* Derselbe Abbruch im Missionslog der Sternenkarte. Seit dem 2026-09-15
   steht er als dritter Knopf in der Spalte statt als nacktes Symbol daneben -
   Form und Groesse kommen von .starmap-questlog__action, hier bleibt nur der
   gedaempfte Ausgangston: Er raeumt ab, er treibt nichts voran. */
.starmap-questlog__abandon {
  color: var(--text-dim);
  border-color: transparent;
  background: transparent;
}
.starmap-questlog__abandon:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--accent-red, #e06c75) 45%, transparent);
  color: var(--accent-red, #e06c75);
}
.starmap-questlog__abandon:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ---------------------------------------------------------------------------
   Anomalie-Schimmer am Stern (Nutzerwunsch 2026-09-01).

   Kein eigener Marker neben dem System: Anomalien liegen IN einem System, und
   ein Punkt daneben haette eine Position im freien Raum vorgetaeuscht, die es
   nicht gibt.

   WICHTIG: pointer-events bleibt aus. Der Stern muss anklickbar bleiben - der
   Schimmer liegt hinter ihm und faengt keine Klicks ab.
   --------------------------------------------------------------------------- */
.starmap-anomaly-glow {
  position: absolute;
  left: 50%;
  top: 50%;
  /* 46 -> 68 px (Nutzerbefund 2026-09-02: "kann uebersehen werden"). Der
     Schimmer liegt hinter dem Sternpunkt und faengt keine Klicks - er darf
     deshalb deutlich ueber den Stern hinausragen. */
  width: 68px;
  height: 68px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 0;
}

/* Die Verzerrungszone: die darunterliegende Karte verbiegt sich leicht.
   backdrop-filter ist pro Element teuer, deshalb nur ein weicher Schleier -
   die Sternenkarte ist schon einmal an Speicher gescheitert. */
.starmap-anomaly-glow__haze {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--anomaly-color) 34%, transparent) 0%,
    transparent 70%
  );
  backdrop-filter: blur(0.7px) saturate(1.25);
}

.starmap-anomaly-glow__spark {
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--anomaly-color);
  box-shadow: 0 0 7px var(--anomaly-color), 0 0 12px var(--anomaly-color);
}
.starmap-anomaly-glow__spark--a { left: 20%; top: 30%; }
.starmap-anomaly-glow__spark--b { right: 22%; top: 58%; }
.starmap-anomaly-glow__spark--c { left: 52%; bottom: 18%; }

/* HINTED: unregelmaessiges Aussetzen. Die Keyframes stehen bewusst in
   ungleichen Abstaenden - ein gleichmaessiger Puls sieht nach Herzschlag aus,
   dies nach Stoersignal. */
/* Spitzen 2026-09-02 angehoben (0.55/0.62/0.48 -> 0.95/1.0/0.85) und die
   Blitze verbreitert: der Wert entscheidet, ob man den Stern im
   Vorbeiscrollen bemerkt. Die Taeler bleiben tief - das Aussetzen ist das
   Signal, ein durchgehend heller Ring waere nur ein weiterer Marker. */
@keyframes anomalyFlicker {
  0%   { opacity: 0.06; }
  6%   { opacity: 0.95; }
  13%  { opacity: 0.10; }
  33%  { opacity: 0.14; }
  38%  { opacity: 1; }
  45%  { opacity: 0.12; }
  72%  { opacity: 0.16; }
  77%  { opacity: 0.85; }
  83%  { opacity: 0.08; }
  100% { opacity: 0.06; }
}
@keyframes anomalyBreathe {
  0%   { opacity: 0.55; transform: translate(-50%, -50%) scale(0.90); }
  50%  { opacity: 1; transform: translate(-50%, -50%) scale(1.12); }
  100% { opacity: 0.55; transform: translate(-50%, -50%) scale(0.90); }
}

/* Zwei harte Schlaege, dann lange Ruhe - der Takt eines Notrufs. */
@keyframes anomalyDoubleBeat {
  0%   { opacity: 0.10; }
  4%   { opacity: 1; }
  9%   { opacity: 0.18; }
  14%  { opacity: 0.92; }
  20%  { opacity: 0.10; }
  100% { opacity: 0.08; }
}

/* Langsame Drehung: die drei Funken wandern um den Stern, statt zu blinken. */
@keyframes anomalyDrift {
  0%   { opacity: 0.45; transform: translate(-50%, -50%) rotate(0deg) scale(1); }
  50%  { opacity: 0.95; transform: translate(-50%, -50%) rotate(180deg) scale(1.06); }
  100% { opacity: 0.45; transform: translate(-50%, -50%) rotate(360deg) scale(1); }
}

/* Langer Aufbau, ploetzlicher Einbruch - etwas laedt sich auf und faellt. */
@keyframes anomalyCollapse {
  0%   { opacity: 0.12; transform: translate(-50%, -50%) scale(0.86); }
  78%  { opacity: 1; transform: translate(-50%, -50%) scale(1.18); }
  84%  { opacity: 0.06; transform: translate(-50%, -50%) scale(0.80); }
  100% { opacity: 0.12; transform: translate(-50%, -50%) scale(0.86); }
}

/* FUENF CHARAKTERE STATT EINEM (Nutzerbefund 2026-09-03: "sieht bei jeder
   anomalie immer gleich aus ... nicht alle im gleichen takt").

   Die Variante haengt an der Anomalie-ID (glowVariante), der Startversatz
   ebenfalls (glowVersatz, als --anomaly-delay). Beides zusammen sorgt dafuer,
   dass selbst zwei Sterne mit demselben Charakter nie synchron laufen.

   Die Dauern sind bewusst teilerfremd gewaehlt: 4.3 / 5.7 / 6.9 / 8.1 / 7.3.
   Runde Werte wie 4 und 8 liefen alle paar Sekunden wieder im Gleichschritt,
   und genau dieser Gleichschritt ist es, der generisch aussieht.

   :not(--analyzed) statt Reihenfolge-Ueberschreibung: eine analysierte
   Anomalie bleibt ruhig, und diese Regel gilt unabhaengig davon, wo im
   Stylesheet sie steht. */
.starmap-anomaly-glow--v1:not(.starmap-anomaly-glow--analyzed) {
  animation: anomalyFlicker 4.3s steps(1, end) infinite;
  animation-delay: var(--anomaly-delay, 0s);
}
.starmap-anomaly-glow--v2:not(.starmap-anomaly-glow--analyzed) {
  animation: anomalyBreathe 5.7s ease-in-out infinite;
  animation-delay: var(--anomaly-delay, 0s);
}
.starmap-anomaly-glow--v3:not(.starmap-anomaly-glow--analyzed) {
  animation: anomalyDoubleBeat 6.9s ease-out infinite;
  animation-delay: var(--anomaly-delay, 0s);
}
.starmap-anomaly-glow--v4:not(.starmap-anomaly-glow--analyzed) {
  animation: anomalyDrift 8.1s linear infinite;
  animation-delay: var(--anomaly-delay, 0s);
}
.starmap-anomaly-glow--v5:not(.starmap-anomaly-glow--analyzed) {
  animation: anomalyCollapse 7.3s ease-in infinite;
  animation-delay: var(--anomaly-delay, 0s);
}

/* Der Zustand faerbt nicht mehr den Takt, sondern die Deutlichkeit: solange
   nur geahnt, verzerrt nichts und die Funken bleiben schwach. */
.starmap-anomaly-glow--hinted .starmap-anomaly-glow__haze {
  backdrop-filter: none;
}
.starmap-anomaly-glow--hinted .starmap-anomaly-glow__spark {
  opacity: 0.7;
  box-shadow: 0 0 4px var(--anomaly-color), 0 0 8px var(--anomaly-color);
}

.starmap-anomaly-glow--analyzed {
  opacity: 0.9;
}
.starmap-anomaly-glow--analyzed .starmap-anomaly-glow__haze {
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--anomaly-color) 32%, transparent) 0%,
    transparent 72%
  );
}

@media (prefers-reduced-motion: reduce) {
  /* Seit den fuenf Charakteren traegt die Variante die Animation, nicht mehr
     der Zustand - hier muessen deshalb alle fuenf stehen. */
  .starmap-anomaly-glow--v1,
  .starmap-anomaly-glow--v2,
  .starmap-anomaly-glow--v3,
  .starmap-anomaly-glow--v4,
  .starmap-anomaly-glow--v5 {
    animation: none;
    opacity: 0.6;
  }
}

/* Noch nicht bekannte Anomaliewerte. Bewusst gedaempft und ohne Farbe: ein
   Fragezeichen soll nicht wichtiger aussehen als eine echte Angabe. */
.starmap-info-panel__unknown {
  color: var(--text-dim);
  letter-spacing: 0.12em;
  opacity: 0.7;
}

/* Admin-Universumsansicht: Spieler und Piraten getrennt (Nutzerwunsch
   2026-09-01). Gleiches Muster wie .message-drawer__tab, aber linksbuendig
   statt gestreckt - zwei Reiter ueber einer breiten Tabelle sollen nicht die
   halbe Seite fuellen. */
.admin-player-tabs {
  display: flex;
  gap: 4px;
  margin: 18px 0 0;
  border-bottom: 1px solid var(--border);
}
.admin-player-tab {
  padding: 9px 16px;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
}
.admin-player-tab:hover {
  color: var(--text-primary);
}
.admin-player-tab.is-active {
  color: var(--accent-bright);
  border-bottom-color: var(--accent-bright);
}
.admin-player-pane {
  margin-top: 12px;
}

/* Warteschlange unter dem laufenden Auftrag (Nutzerbefund 2026-09-01: "Wie
   kann ich diese Reihenfolge sehen und ggf. das eine wieder rausnehmen?").
   Bewusst schmaler und blasser als die Fortschrittsbox darueber - was laeuft,
   ist wichtiger als was wartet. */
.queued-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  padding: 8px 12px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
}
.queued-row__icon {
  font-size: 15px;
  color: var(--text-muted);
  flex-shrink: 0;
}
.queued-row__body {
  flex: 1;
  min-width: 0;
}
.queued-row__label {
  display: block;
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.queued-row__name {
  display: block;
  font-size: 12.5px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Ein gescheiterter Anlauf ist die wichtigste Information in dieser Zeile:
   der Auftrag steht still und wartet auf etwas, das der Spieler tun muss. */
.queued-row__hint {
  margin-top: 2px;
  font-size: 10.5px;
  line-height: 1.35;
  color: var(--accent-gold);
}
.queued-row__remove {
  flex-shrink: 0;
  padding: 5px 11px;
  font-size: 10.5px;
  letter-spacing: 0.03em;
  color: var(--text-dim);
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color .15s, border-color .15s;
}
.queued-row__remove:hover {
  color: var(--accent-bright);
  border-color: var(--accent-bright);
}
.queued-row__remove:disabled {
  opacity: 0.5;
  cursor: default;
}

/* X-Labor: Uebersicht ueber die gefundenen Anomalien (Nutzerwunsch
   2026-09-01). Karten statt Tabelle, weil die meisten Felder je nach
   Wissensstufe fehlen - eine Tabelle waere ueberwiegend leer. */
.xlab-hint {
  margin: 6px 0 4px;
  font-size: 11px;
  color: var(--text-muted);
}

/* Anleitung im X-Labor (Nutzerwunsch 2026-09-02). Dauerhaft sichtbar, aber
   ruhig gehalten: sie soll die Funde darunter nicht ueberstrahlen. */
.xlab-howto {
  margin: 10px 0 16px;
  padding: 10px 14px;
  border: 1px solid rgba(199, 146, 234, 0.28);
  border-left: 3px solid #c792ea;
  border-radius: 6px;
  background: rgba(199, 146, 234, 0.06);
}
.xlab-howto__title {
  font-family: var(--font-heading);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #c792ea;
  margin-bottom: 6px;
}
/* Frueher eine nummerierte Anleitung, seit dem 2026-09-03 ein Absatz. Die
   Listenregel bleibt stehen, falls dort je wieder Schritte stehen sollen. */
.xlab-howto__list {
  margin: 0;
  padding-left: 18px;
  display: grid;
  gap: 4px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-body);
}
.xlab-howto__text {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--text-body);
}

/* Kopfleiste des X-Labors (Nutzerwunsch 2026-09-03: „sieht alles so
   auseinandergezogen aus"). Vorher standen laufende Untersuchungen,
   Kennzahlen und Anomaliedaten als drei lose Stapel untereinander, jeder mit
   einem `section-heading` - und der traegt 36 px Abstand nach oben. Drei davon
   sind allein 108 px Luft, bevor der erste Wert zu sehen ist.

   Jetzt: umrahmte Panels. Der Rahmen ersetzt den Abstand - er grenzt ab, ohne
   zu schieben. Stand und Anomaliedaten sind beide reine Zahlenleisten und
   stehen deshalb nebeneinander. */
/* JUKEBOX IM VERSTECK (Nutzerwunsch 2026-09-04): ein Tracker-Player mit
   Equalizer. Die Optik folgt dem Rest des Verstecks - dunkel, Cyan, eckig. */
.jukebox__eq {
  display: block;
  width: 100%;
  height: 112px;
  margin: 12px 0;
  border: 1px solid rgba(120, 180, 255, .18);
  border-radius: 6px;
  background: rgba(4, 7, 16, .92);
  /* Das Canvas ist nur 192x98 gross und wird hochgezogen. Ohne pixelated
     glaettet der Browser die Segmente zu Matsch - genau das soll es nicht
     sein (Nutzerwunsch: "pixlig, wie alte LEDs"). */
  image-rendering: pixelated;
}
.jukebox__intro {
  margin: 6px 0 4px;
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.55;
}

/* Fortschritt: klickbar, zeigt die POSITION im Stueck (Tracker haben keine
   Zeitachse - siehe songProgress() in jukebox.js). */
.jukebox__seek {
  height: 10px;
  border: 1px solid rgba(120, 180, 255, .22);
  border-radius: 5px;
  background: rgba(6, 9, 20, .8);
  cursor: pointer;
  overflow: hidden;
}
.jukebox__seek:hover { border-color: rgba(127, 233, 255, .45); }
.jukebox__seek:focus-visible { outline: 1px solid rgba(127, 233, 255, .6); outline-offset: 2px; }
.jukebox__seek-fill {
  width: 0;
  height: 100%;
  background: linear-gradient(90deg, #1f6f88, #7fe9ff);
  /* Kurz genug, dass der Sprung sofort wirkt, lang genug, dass der Balken
     zwischen zwei Zeilen nicht ruckelt. */
  transition: width .12s linear;
}
.jukebox__position {
  margin: 5px 0 10px;
  color: #8b96ba;
  font-size: 10.5px;
  letter-spacing: .05em;
}

.jukebox__controls { display: flex; gap: 8px; align-items: stretch; }
.jukebox__play,
.jukebox__open {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid rgba(127, 233, 255, .35);
  border-radius: 6px;
  background: rgba(127, 233, 255, .10);
  color: #7fe9ff;
  cursor: pointer;
  padding: 8px 14px;
  font: inherit;
  font-size: 12px;
}
.jukebox__play { flex: 1; justify-content: center; }
.jukebox__play:disabled { opacity: .45; cursor: default; }
.jukebox__play:not(:disabled):hover,
.jukebox__open:hover { background: rgba(127, 233, 255, .18); }
/* Der Dateiknopf ist ein Label um ein verstecktes input - er muss sich
   deshalb selbst wie ein Knopf verhalten. */
.jukebox__open { flex: none; }

.jukebox__status { margin-top: 8px; min-height: 16px; color: #8b96ba; font-size: 11px; }
.jukebox__empty {
  margin-top: 12px;
  padding: 14px;
  border: 1px dashed rgba(120, 180, 255, .22);
  border-radius: 6px;
  color: #8b96ba;
  font-size: 11.5px;
  text-align: center;
}
.jukebox__list { margin-top: 12px; display: grid; gap: 4px; max-height: 220px; overflow-y: auto; }
.jukebox__track {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  border: 1px solid rgba(120, 180, 255, .14);
  border-radius: 5px;
  background: rgba(10, 14, 28, .6);
  color: var(--text);
  cursor: pointer;
  padding: 7px 10px;
  font: inherit;
  font-size: 12px;
  text-align: left;
}
.jukebox__track:hover { border-color: rgba(127, 233, 255, .4); color: #7fe9ff; }
.jukebox__track-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jukebox__track-format { flex: none; color: #8b96ba; font-size: 10px; letter-spacing: .06em; }
/* Erkannt, aber nicht abspielbar: sichtbar und offensichtlich tot. Kein
   Zeiger, kein Hover - der Eintrag ist eine Auskunft, kein Angebot. */
.jukebox__track--dead { opacity: .45; cursor: default; }
.jukebox__track--dead:hover { border-color: rgba(127, 233, 255, .18); color: inherit; }

/* Hinweise im Labor (Paket I-1b). Gruen wie ihr Suchkreis auf der Karte -
   dieselbe Sache, zweimal gezeigt. */
.xlab-hints { display: grid; gap: 8px; margin-bottom: 6px; }
.xlab-hint {
  border: 1px solid rgba(143, 224, 160, .28);
  border-left: 3px solid rgba(143, 224, 160, .65);
  border-radius: 8px;
  background: rgba(143, 224, 160, .06);
  padding: 10px 12px;
}
.xlab-hint__head { display: flex; align-items: baseline; gap: 10px; }
.xlab-hint__title { flex: 1; color: #8fe0a0; font-size: 12.5px; font-weight: 600; }
.xlab-hint__rest { flex: none; color: #8b96ba; font-size: 10.5px; white-space: nowrap; }
.xlab-hint__body { margin-top: 4px; color: var(--text-muted); font-size: 11.5px; }
.xlab-hint__dismiss {
  margin-top: 8px;
  border: 1px solid rgba(120, 180, 255, .22);
  border-radius: 5px;
  background: rgba(10, 14, 28, .7);
  color: #8b96ba;
  cursor: pointer;
  padding: 4px 9px;
  font-size: 10.5px;
}
.xlab-hint__dismiss:hover { border-color: rgba(224, 90, 74, .45); color: #ef8f84; }

.xlab-topbar {
  display: grid;
  gap: 10px;
  margin-bottom: 4px;
}
.xlab-topbar__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 10px;
}

.xlab-panel {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.xlab-panel__title {
  font-family: var(--font-heading);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 8px;
}
/* Laufende Untersuchungen tragen die Laborfarbe: sie binden Zeit und sind das
   Einzige in der Kopfleiste, an dem der Spieler etwas tun kann. */
.xlab-panel--running {
  border-color: rgba(199, 146, 234, 0.28);
  background: rgba(199, 146, 234, 0.05);
}
.xlab-panel--running .xlab-panel__title { color: #c792ea; }

/* Enger als .admin-stat-grid (140 px / 10 px Abstand): die Werte im Labor sind
   kurze Zahlen, keine Beträge. */
.xlab-statgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: 6px 4px;
}
.xlab-statgrid .hud-stat { padding: 0 8px; }
.xlab-statgrid .hud-stat:last-child { border-right: none; }

.xlab-running-list {
  display: grid;
  gap: 8px;
}

.xlab-running {
  padding: 10px 12px;
  border: 1px solid rgba(199, 146, 234, 0.22);
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.16);
}

.xlab-running__head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: var(--text-primary);
  font-weight: 600;
}

.xlab-running__meta {
  margin-top: 3px;
  color: var(--text-muted);
  font-size: 12px;
}
.xlab-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}
/* FUSSZEILE IMMER AM BODEN (Nutzerbefund 2026-09-03: „das Sternname -
   Untersuchen haengt aber manchmal etwas hoeher"). Die Karten sind im Grid
   schon gleich hoch, ihr Inhalt floss aber von oben: eine Karte ohne die
   Zeile „Untersuchungen" endete eine Zeile weiter oben, und mit ihr die
   Trennlinie. Flex-Spalte plus `margin-top: auto` an der Fusszeile schiebt
   sie in jeder Karte auf dieselbe Hoehe. */
.xlab-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.xlab-card__rows { display: block; }
/* Die NEU-Marke am frisch untersuchten Fund (2026-09-10) - dieselbe Form wie
   am Artefakt, damit der Blick sie an beiden Stellen wiedererkennt. */
.xlab-card--new { cursor: pointer; box-shadow: 0 0 0 1px rgba(255,215,106,.35); }
.xlab-card--new:hover { box-shadow: 0 0 0 1px rgba(255,215,106,.6); }
.xlab-card__new {
  position: absolute; top: 8px; right: 8px;
  font-family: var(--font-heading); font-size: 9px; font-weight: 700; letter-spacing: .14em;
  color: #05060f; background: var(--accent-gold); border-radius: 4px; padding: 2px 6px;
}
.xlab-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}
.xlab-card__title {
  font-family: var(--font-heading);
  font-size: 14px;
  color: var(--text-primary);
}
.xlab-card__level {
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}
.xlab-card__row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 0;
  font-size: 11.5px;
  color: var(--text-dim);
}
.xlab-card__row span:last-child { color: var(--text-primary); }
/* Was der Spieler nicht weiss, bleibt sichtbar leer - nicht weggelassen.
   Dieselbe Konvention wie im Anomaliepanel der Systemansicht: "unbekannt"
   und "bekanntlich leer" muessen unterscheidbar bleiben. */
.xlab-card__unknown { color: var(--text-muted); }
.xlab-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  /* auto statt eines festen Werts: das ist die ganze Korrektur. */
  margin-top: auto;
  padding-top: 9px;
  border-top: 1px solid var(--border);
  font-size: 11px;
}
.xlab-card__system {
  color: var(--accent-bright);
  cursor: pointer;
}
.xlab-card__system:hover { text-decoration: underline; }
.xlab-card__next {
  color: var(--text-muted);
  letter-spacing: 0.03em;
}

.xlab-report {
  margin-bottom: 10px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-left: 3px solid #c792ea;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
}
.xlab-report__head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 6px;
}
.xlab-report__type {
  font-family: var(--font-heading);
  font-size: 12.5px;
  color: var(--text-primary);
}
.xlab-report__outcome {
  font-size: 11px;
  color: #c792ea;
}
.xlab-report__list {
  margin: 0;
  padding-left: 18px;
}
.xlab-report__list li {
  margin-bottom: 4px;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--text-dim);
}

/* Bericht einer Anomalieuntersuchung (Paket C2). Er kommt als Modal, weil eine
   Untersuchung die Flotte versetzen oder Schiffe beschaedigen kann - das darf
   niemand uebersehen. */
.anomaly-report__outcome {
  font-size: 13px;
  letter-spacing: 0.03em;
  color: var(--accent-bright);
  margin-bottom: 10px;
}
.anomaly-report__list {
  margin: 0;
  padding-left: 18px;
  text-align: left;
}
.anomaly-report__list li {
  margin-bottom: 6px;
  color: var(--text-primary);
  line-height: 1.45;
}

/* --- Anomalien Paket E: globale, aber stets bedienbare Stoerungen -------- */
/*
 * OBEN MITTIG, NICHT RECHTS (Nutzerwunsch 2026-09-13: "Das fenster
 * 'Sensorrauschen Stufe 1 xx:xx' sollte oben mittig in der Starmap sichtbar
 * sein").
 *
 * Rechts oben lag es unter der Glocke und dem Geschwindigkeitsregler - auf
 * der Sternenkarte, wo die Stoerung am ehesten auffaellt, sah man es kaum.
 * Mittig steht es ueber der Karte, wo ohnehin niemand etwas anklickt (das
 * Feld traegt pointer-events: none, es faengt keinen Klick ab).
 *
 * Die Verschiebung laeuft ueber `translateX`, nicht ueber `margin`: Die
 * Breite richtet sich nach dem Text - bei zwei gleichzeitigen Stoerungen ist
 * er doppelt so lang -, und eine feste Breite waere bei einer kurzen Meldung
 * ein halbleerer Kasten.
 */
.anomaly-fx-status {
  position: fixed;
  top: 62px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 320;
  text-align: center;
  max-width: min(620px, calc(100vw - 90px));
  padding: 8px 12px;
  border: 1px solid rgba(127, 233, 255, .55);
  border-left: 3px solid #f0a8f4;
  border-radius: var(--radius-sm);
  background: rgba(8, 13, 29, .94);
  box-shadow: 0 0 18px rgba(127, 233, 255, .2);
  color: #d9f9ff;
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: .04em;
  line-height: 1.35;
  pointer-events: none;
}
.anomaly-fx-status[hidden] { display: none; }

/* Die beiden Vollbildschichten sind rein visuell. pointer-events:none ist die
   wichtigste Bedienbarkeitsgarantie: keine Stoerung kann einen Klick fangen. */
html.anomaly-fx--sensor-noise body::before,
html.anomaly-fx--static-sensor-noise body::before,
html.anomaly-fx--space-warp body::after,
html.anomaly-fx--static-space-warp body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 300;
  pointer-events: none;
}
html.anomaly-fx--sensor-noise body::before {
  opacity: var(--anomaly-fx-sensor-noise-opacity, .032);
  background-image:
    repeating-radial-gradient(circle at 23% 37%, #d9fbff 0 1px, transparent 1px 4px),
    repeating-linear-gradient(0deg, transparent 0 3px, rgba(127, 233, 255, .65) 4px);
  background-size: 9px 11px, 100% 5px;
  animation: anomaly-sensor-noise .28s steps(3, end) infinite;
}
html.anomaly-fx--space-warp body::after {
  opacity: var(--anomaly-fx-space-warp-opacity, .075);
  background:
    radial-gradient(ellipse at 15% 35%, transparent 0 28%, rgba(240, 168, 244, .7) 30%, transparent 33%),
    radial-gradient(ellipse at 82% 65%, transparent 0 22%, rgba(127, 233, 255, .65) 24%, transparent 27%);
  background-size: 115% 105%;
  mix-blend-mode: screen;
  animation: anomaly-space-warp 5.5s ease-in-out infinite alternate;
}

/* Zahlen bleiben wahr und am selben Ort. Nur ihr Lichtsaum zittert; dadurch
   springen weder Layout noch Trefferflaechen. */
html.anomaly-fx--number-jitter :is(
  .hud-stat__value, .stat-row__value, .resource-value, .storage-amount,
  .countdown, time, [data-countdown]
) {
  animation: anomaly-number-jitter .42s steps(2, end) infinite;
}

/* Der Text bleibt durchgehend lesbar. Der farbige Nachhall ist das Glitch-
   Signal; keine Zeichen werden ersetzt oder verborgen. */
html.anomaly-fx--text-glitch .app-main :is(p, li, td, th, label, .section-title, .card-title) {
  animation: anomaly-text-glitch .85s steps(2, end) infinite;
}

/* Signalverlust dimmt nur Informationsflaechen und nie unter 68 Prozent.
   Schaltflaechen verschwinden nicht und behalten ihre Trefferflaeche. */
html.anomaly-fx--signal-loss :is(
  .sensor-stat-grid, .sensor-contact-row, .starmap-info-panel,
  .hud-stat, .stat-row
) {
  animation: anomaly-signal-loss 2.4s ease-in-out infinite;
}

@keyframes anomaly-sensor-noise {
  0% { background-position: 0 0, 0 0; }
  33% { background-position: 3px -2px, 0 1px; }
  66% { background-position: -2px 4px, 0 -1px; }
  100% { background-position: 1px 1px, 0 0; }
}
@keyframes anomaly-space-warp {
  from { transform: scale(1) skewX(-.15deg); filter: hue-rotate(-5deg); }
  to { transform: scale(1.018) skewX(.18deg); filter: hue-rotate(9deg); }
}
@keyframes anomaly-number-jitter {
  0%, 100% { text-shadow: 0 0 0 transparent; }
  45% { text-shadow: var(--anomaly-fx-number-jitter-offset, 1px) 0 #7fe9ff; }
  55% { text-shadow: var(--anomaly-fx-number-jitter-offset-negative, -1px) 0 #f0a8f4; }
}
@keyframes anomaly-text-glitch {
  0%, 78%, 100% { text-shadow: none; }
  82% { text-shadow: 1px 0 #7fe9ff, -1px 0 #f0a8f4; }
  88% { text-shadow: -1px 0 #7fe9ff, 1px 0 #f0a8f4; }
}
@keyframes anomaly-signal-loss {
  0%, 72%, 100% { opacity: 1; }
  78% { opacity: var(--anomaly-fx-signal-loss-opacity, .8); }
  84% { opacity: .94; }
}

/* Stille Kennzeichnungen fuer prefers-reduced-motion. Sie zeigen weiterhin,
   welche Art Stoerung aktiv ist, bewegen oder flackern aber nichts. */
html.anomaly-fx--static-sensor-noise body::before {
  opacity: var(--anomaly-fx-static-sensor-opacity, .037);
  background: repeating-linear-gradient(0deg, transparent 0 5px, rgba(127, 233, 255, .65) 6px);
}
html.anomaly-fx--static-space-warp body::after {
  inset: 5px;
  border: var(--anomaly-fx-static-warp-border, 2px) solid rgba(240, 168, 244, .45);
  box-shadow: inset 0 0 24px rgba(127, 233, 255, .13);
}
html.anomaly-fx--static-number-jitter :is(.hud-stat__value, .stat-row__value, .resource-value, time) {
  text-decoration: underline dotted rgba(127, 233, 255, .8);
  text-underline-offset: 3px;
}
html.anomaly-fx--static-text-glitch .app-main {
  border-top: 2px solid rgba(240, 168, 244, .55);
}
html.anomaly-fx--static-signal-loss :is(.sensor-stat-grid, .starmap-info-panel, .hud-stat) {
  outline: 1px dashed rgba(127, 233, 255, .48);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  html.anomaly-fx--sensor-noise body::before,
  html.anomaly-fx--space-warp body::after,
  html.anomaly-fx--number-jitter :is(.hud-stat__value, .stat-row__value, .resource-value, .storage-amount, .countdown, time, [data-countdown]),
  html.anomaly-fx--text-glitch .app-main :is(p, li, td, th, label, .section-title, .card-title),
  html.anomaly-fx--signal-loss :is(.sensor-stat-grid, .sensor-contact-row, .starmap-info-panel, .hud-stat, .stat-row) {
    animation: none !important;
  }
}

@media (max-width: 700px) {
  .anomaly-fx-status {
    top: 54px;
    right: 8px;
    max-width: calc(100vw - 72px);
    font-size: 10px;
  }
}

/* ============================================================
   Live-Kampfbericht — taktische Lageuebersicht

   Aufbau 1:1 nach der Gestaltungsvorlage des Nutzers
   (_Design-Vorlage/weltraumspiel-starcontrol/project/Kampfbericht.dc.html),
   umgesetzt 2026-09-04.

   Bewusst dicht: 8,5-11 px in den Beschriftungen. Es soll nach
   Kommandobruecke aussehen, nicht nach Formular. Angreifer cyan,
   Verteidiger rot — dieselbe Bildsprache wie im abgeschlossenen Bericht.

   Die Karte arbeitet mit absolut positionierten Elementen in Prozent, nicht
   mit SVG: die Buehne zeichnet sie im Sekundentakt neu, und einzelne
   HTML-Knoten mit eigenen CSS-Animationen laufen dabei fluessiger als ein
   jedes Mal komplett ersetztes SVG.
   ============================================================ */

.defcon-live--tactical { max-width: none; }

.clive {
  --clive-attacker: var(--accent-bright);
  --clive-defender: var(--accent-red);
  --clive-line: rgba(120, 180, 255, 0.16);
  --clive-panel: rgba(11, 14, 27, 0.72);
  --clive-label: #63709a;
  --clive-dim: #4d5878;
  --clive-good: #46d9d0;
  --clive-warn: #e0a44a;
  --clive-bad: #e05a4a;
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: #cdd6f0;
}

.clive b,
.clive u,
.clive s,
.clive em { font-style: normal; text-decoration: none; }

/* ------------------------------------------------------------- Kopfzeile */

.clive-head {
  display: flex;
  align-items: center;
  gap: 20px;
  padding-bottom: 11px;
  border-bottom: 1px solid var(--clive-line);
}

.clive-head__title { display: flex; align-items: baseline; gap: 12px; }

.clive-head__title b {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 21px;
  letter-spacing: 0.06em;
  color: #e9edfb;
}

.clive-head__id {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--clive-dim);
}

.clive-head__center {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 22px;
  min-width: 0;
}

.clive-head__pair { display: flex; align-items: baseline; gap: 9px; }

.clive-head__pair small {
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--clive-label);
}

.clive-head__clock,
.clive-head__round {
  font-family: var(--font-mono);
  font-size: 16px;
  color: var(--clive-attacker);
}

.clive-head__pair u {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--clive-dim);
}

.clive-head__sep { width: 1px; height: 16px; background: rgba(120, 180, 255, 0.2); }

.clive-head__phase {
  font-size: 10px;
  letter-spacing: 0.1em;
  margin-left: 4px;
}

.clive-head__phase--opening { color: var(--clive-warn); }
.clive-head__phase--regular { color: var(--clive-good); }
.clive-head__phase--escape { color: #f0a8f4; }

.clive-pips {
  display: flex;
  gap: 2px;
  width: 160px;
  height: 7px;
  padding: 1px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(120, 180, 255, 0.14);
  overflow: hidden;
}

.clive-pip {
  flex: 1;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.06);
  transition: background 0.4s ease;
}

.clive-pip--done { background: #2a86f0; }
.clive-pip--now { box-shadow: 0 0 8px #2a86f0; }

.clive-head__state {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: #8b96ba;
}

.clive-head__state--running { color: var(--clive-good); }

.clive-head__pulse {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--clive-good);
  box-shadow: 0 0 7px var(--clive-good);
  animation: clivePulse 1.8s ease-in-out infinite;
}

/* ------------------------------------------------------------ Grundraster */

.clive-body {
  display: grid;
  grid-template-columns: 284px minmax(0, 1fr) 284px;
  gap: 10px;
  align-items: stretch;
}

.clive-col { display: flex; flex-direction: column; gap: 9px; min-width: 0; }

.clive-box {
  border: 1px solid rgba(120, 180, 255, 0.14);
  border-radius: 9px;
  background: var(--clive-panel);
  padding: 11px 13px;
}

.clive-box h3 {
  margin: 0 0 9px;
  font-family: var(--font-heading);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.11em;
  color: var(--clive-label);
}

.clive-box h4 {
  margin: 13px 0 6px;
  font-family: var(--font-heading);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.11em;
  color: var(--clive-label);
}

.clive-empty {
  margin: 0;
  font-size: 10.5px;
  color: var(--clive-dim);
}

/* ---------------------------------------------------------- Parteispalten */

.clive-party { display: flex; flex-direction: column; gap: 9px; min-width: 0; }

.clive-party__head {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 14px;
  border-radius: 9px;
}

.clive-party--attacker .clive-party__head {
  border: 1px solid rgba(224, 90, 74, 0.32);
  background: linear-gradient(160deg, rgba(60, 16, 16, 0.5), rgba(12, 14, 26, 0.7));
}

.clive-party--defender .clive-party__head {
  border: 1px solid rgba(70, 180, 255, 0.3);
  background: linear-gradient(160deg, rgba(14, 38, 72, 0.55), rgba(12, 14, 26, 0.7));
}

.clive-emblem { width: 28px; height: 28px; flex: none; }
.clive-party--attacker .clive-emblem { color: var(--clive-defender); animation: cliveSpin 44s linear infinite; }
.clive-party--defender .clive-emblem { color: #4aa8f0; animation: cliveSpin 52s linear infinite reverse; }

.clive-party__ident { flex: 1; min-width: 0; }

.clive-party__ident b {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.08em;
}

.clive-party--attacker .clive-party__ident b { color: #ffd0c8; }
.clive-party--defender .clive-party__ident b { color: #cfe6ff; }

.clive-party__ident small {
  display: block;
  margin-top: 1px;
  font-size: 10px;
  letter-spacing: 0.1em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.clive-party--attacker .clive-party__ident small { color: #c98a80; }
.clive-party--defender .clive-party__ident small { color: #7fa8cd; }

.clive-party__power { text-align: right; flex: none; }

.clive-party__power small {
  display: block;
  font-size: 8.5px;
  letter-spacing: 0.11em;
  color: #a0788f;
}

.clive-party--defender .clive-party__power small { color: #78889f; }

.clive-party__power b {
  display: block;
  margin-top: 1px;
  font-family: var(--font-mono);
  font-size: 16px;
}

.clive-party--attacker .clive-party__power b { color: #ff6b58; }
.clive-party--defender .clive-party__power b { color: #4aa8f0; }

/* --------------------------------------------------------- Einsatzübersicht */

.clive-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.clive-table th,
.clive-table td { text-align: right; }

.clive-table thead th {
  padding-bottom: 7px;
  border-bottom: 1px solid rgba(120, 180, 255, 0.1);
  font-family: var(--font-heading);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  color: var(--clive-label);
  white-space: nowrap;
}

.clive-table thead th:first-child { text-align: left; }
.clive-table thead th:not(:first-child) { width: 34px; }

.clive-table tbody th {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5.5px 0;
  min-width: 0;
  font-weight: 400;
  text-align: left;
}

.clive-table tbody th svg {
  width: 22px;
  height: 12px;
  flex: none;
  fill: none;
  stroke: #8fa6d8;
  stroke-width: 1.1;
  opacity: 0.85;
}

.clive-table tbody th span {
  font-size: 10.5px;
  letter-spacing: 0.05em;
  color: #cdd6f0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.clive-table tbody tr { border-bottom: 1px solid rgba(120, 180, 255, 0.05); }

.clive-table tbody td {
  padding: 5.5px 0 5.5px 7px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: #e9edfb;
}

.clive-table tbody td + td { font-size: 11px; }

.clive-row--lost th svg { opacity: 0.25; }
.clive-row--lost th span { color: #5a6588; }

.clive-num--bad { color: #ff6b58; }
.clive-num--warn { color: var(--clive-warn); }
.clive-num--none { color: #3f4a68; }

/* ------------------------------------------------------------ Statusbalken */

.clive-bars { display: flex; flex-direction: column; gap: 9px; }

.clive-bar {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 8px;
}

.clive-bar span { font-size: 10px; color: #8b96ba; }

.clive-bar b {
  font-family: var(--font-mono);
  font-size: 10px;
  text-align: right;
}

.clive-bar i {
  grid-column: 1 / -1;
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.05);
  overflow: hidden;
}

.clive-bar u,
.clive-spot__bar em {
  display: block;
  height: 100%;
  border-radius: 3px;
  transition: width 0.6s ease;
}

.clive-fill--good { background: var(--clive-good); box-shadow: 0 0 6px var(--clive-good); }
.clive-fill--warn { background: var(--clive-warn); box-shadow: 0 0 6px var(--clive-warn); }
.clive-fill--bad { background: var(--clive-bad); box-shadow: 0 0 6px var(--clive-bad); }

.clive-text--good { color: var(--clive-good); }
.clive-text--warn { color: var(--clive-warn); }
.clive-text--bad { color: var(--clive-bad); }

.clive-bar--hidden b { color: var(--clive-dim); font-size: 9px; letter-spacing: 0.04em; }
.clive-bar--hidden i { background: repeating-linear-gradient(105deg, rgba(255, 255, 255, 0.05) 0 4px, transparent 4px 8px); }

/* --------------------------------------------------------- Spezialfähigkeiten */

.clive-abilities { list-style: none; margin: 0; padding: 0; }

.clive-abilities li {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 3.5px 0;
  min-width: 0;
}

.clive-abilities i {
  width: 6px;
  height: 6px;
  flex: none;
  transform: rotate(45deg);
  background: #3f4a68;
}

.clive-abilities li.is-active i {
  background: var(--clive-attacker);
  animation: cliveBlink 1.6s ease-in-out infinite;
}

.clive-abilities span {
  flex: 1;
  min-width: 0;
  font-size: 10px;
  letter-spacing: 0.03em;
  color: #5a6588;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.clive-abilities li.is-active span { color: #cdd6f0; }

.clive-abilities b {
  flex: none;
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--clive-dim);
}

.clive-abilities li.is-active b { color: var(--clive-attacker); }

/* ------------------------------------------------------- Ausgewählte Einheit */

.clive-box--spot { flex: 1; display: flex; flex-direction: column; }

.clive-spot__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 11px;
}

.clive-spot__head b {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.04em;
  color: #e9edfb;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.clive-spot__head small {
  flex: none;
  font-size: 8.5px;
  letter-spacing: 0.08em;
}

.clive-party--attacker .clive-spot__head small { color: #c98a80; }
.clive-party--defender .clive-spot__head small { color: #7fa8cd; }

.clive-spot__bars { display: flex; flex-direction: column; gap: 6px; }

.clive-spot__bar {
  display: grid;
  grid-template-columns: 38px 32px 1fr auto;
  align-items: center;
  gap: 8px;
}

.clive-spot__bar span { font-size: 9.5px; color: var(--clive-label); }

.clive-spot__bar b {
  font-family: var(--font-mono);
  font-size: 11px;
}

.clive-spot__bar i {
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.05);
  overflow: hidden;
}

.clive-spot__bar u {
  font-family: var(--font-mono);
  font-size: 9px;
  color: #5a6588;
  white-space: nowrap;
}

.clive-spot__bar--hidden u { font-family: var(--font-body); font-size: 8.5px; }

.clive-systems { list-style: none; margin: 0; padding: 0; }

.clive-systems li {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 2px 0;
  min-width: 0;
}

.clive-systems i {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--clive-good);
  display: flex;
  align-items: center;
  justify-content: center;
}

.clive-systems u {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--clive-good);
  animation: clivePulse 2.6s ease-in-out infinite;
}

.clive-systems li.is-hit i { border-color: var(--clive-bad); }
.clive-systems li.is-hit u { background: var(--clive-bad); animation: cliveBlink 0.8s steps(1) infinite; }

.clive-systems span {
  flex: 1;
  min-width: 0;
  font-size: 8.5px;
  letter-spacing: 0.03em;
  color: #8b96ba;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.clive-systems b {
  flex: none;
  font-size: 8px;
  letter-spacing: 0.05em;
  color: #5fd88a;
}

.clive-systems li.is-hit b { color: var(--clive-bad); }

/* Der Kasten leitet seine Systeme aus der Huelle ab — das gehoert dazugesagt,
   sonst liest man ihn als Messwert. */
.clive-note {
  margin: 9px 0 0;
  font-size: 8px;
  letter-spacing: 0.04em;
  color: #46506e;
}

/* ------------------------------------------------------------ Kampfübersicht */

.clive-box--map {
  flex: 1;
  /* HOEHE AM FENSTER STATT AN EINER FESTEN ZAHL (Nutzerwunsch 2026-09-05:
     "der Bereich, wo der taktische Kampf sichtbar ist, ist zu schmal, darf
     gern groesser werden in der Height - ein bisschen Platz ist noch").

     Vorher standen hier 420 px. `flex: 1` half nicht, weil kein Elternteil
     eine Hoehe vorgibt: `.clive` waechst mit seinem Inhalt, also blieb die
     Karte auf ihrem Mindestmass sitzen, egal wie gross das Fenster war.

     Der Deckel von 900 px ist Absicht - auf einem sehr hohen Bildschirm
     wuerde die Buehne sonst leer wirken, weil die Verbaende in der Mitte
     bleiben und nur der Abstand waechst. */
  min-height: min(70vh, 900px);
  display: flex;
  flex-direction: column;
  border-color: var(--clive-line);
  background: rgba(8, 11, 22, 0.8);
  padding: 11px 13px 8px;
}

.clive-map__head {
  flex: none;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.clive-map__head h3 { margin: 0; }

.clive-map__head small {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.06em;
  color: #3f4a68;
}

.clive-power {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 26px;
  margin-top: 9px;
}

.clive-power__value {
  font-family: var(--font-mono);
  font-size: 14px;
  flex: none;
}

.clive-power__value--attacker { color: var(--clive-attacker); }
.clive-power__value--defender { color: #ff6b58; }

.clive-power__track {
  flex: 1;
  max-width: 420px;
  height: 13px;
  background: rgba(255, 255, 255, 0.04);
  overflow: hidden;
  display: flex;
}

.clive-power__track--attacker {
  border-radius: 3px 0 0 3px;
  border: 1px solid rgba(70, 180, 255, 0.2);
  justify-content: flex-end;
}

.clive-power__track--defender {
  border-radius: 0 3px 3px 0;
  border: 1px solid rgba(224, 90, 74, 0.25);
}

.clive-power__track span {
  height: 100%;
  animation: cliveBarFlow 1.4s linear infinite;
  transition: width 0.8s ease;
}

.clive-power__track--attacker span {
  background: repeating-linear-gradient(115deg, #1b6fd8 0 10px, #2a86f0 10px 20px);
  box-shadow: 0 0 10px rgba(42, 134, 240, 0.5);
}

.clive-power__track--defender span {
  background: repeating-linear-gradient(115deg, #a82a1e 0 10px, #d84030 10px 20px);
  box-shadow: 0 0 10px rgba(216, 64, 48, 0.5);
}

.clive-power__pivot {
  width: 22px;
  height: 22px;
  flex: none;
  margin: 0 6px;
  color: var(--clive-attacker);
  animation: cliveSpin 20s linear infinite;
}

/* ------------------------------------------------------------------ Legende */

.clive-legend {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: 5px 13px;
  justify-content: center;
  margin-top: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(120, 180, 255, 0.08);
}

.clive-legend__item {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 8.5px;
  letter-spacing: 0.08em;
  color: #7683a8;
}

.clive-legend__item svg {
  width: 11px;
  height: 11px;
  fill: none;
  stroke-width: 1.3;
}

.clive-legend__scale {
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.06em;
  color: #46d9d0;
}

/* -------------------------------------------------------------------- Karte */

.clive-map {
  flex: 1;
  min-height: 0;
  display: flex;
  margin-top: 8px;
}

.clive-map__rows {
  flex: none;
  width: 16px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
}

.clive-map__main { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.clive-map__cols {
  flex: none;
  height: 16px;
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.clive-map__rows span,
.clive-map__cols span {
  font-family: var(--font-mono);
  font-size: 9.5px;
  color: var(--clive-dim);
}

.clive-map__field {
  flex: 1;
  position: relative;
  min-height: 0;
  overflow: hidden;
  background:
    linear-gradient(rgba(76, 116, 196, 0.07) 1px, transparent 1px) 0 0 / 100% 10%,
    linear-gradient(90deg, rgba(76, 116, 196, 0.07) 1px, transparent 1px) 0 0 / 6.667% 100%,
    radial-gradient(ellipse at 30% 45%, rgba(30, 90, 190, 0.07), transparent 60%),
    radial-gradient(ellipse at 72% 52%, rgba(180, 50, 40, 0.07), transparent 60%);
}

.clive-map__scan {
  position: absolute;
  left: 0;
  right: 0;
  height: 44px;
  background: linear-gradient(rgba(127, 233, 255, 0), rgba(127, 233, 255, 0.055), rgba(127, 233, 255, 0));
  animation: cliveScan 7s linear infinite;
  pointer-events: none;
}

.clive-map__layer { position: absolute; inset: 0; pointer-events: none; }

/* Verbandsellipse: umschliesst die lebenden Symbole und wandert mit ihnen. */
.clive-formation {
  position: absolute;
  transform: translate(-50%, -50%);
  border: 1px dashed rgba(70, 180, 255, 0.32);
  border-radius: 50%;
  transition: left 1s linear, top 1s linear, width 1s linear, height 1s linear;
}

.clive-formation--def { border-color: rgba(224, 90, 74, 0.32); }

.clive-wreck {
  position: absolute;
  animation: cliveSpin linear infinite;
}

.clive-wreck svg {
  width: 9px;
  height: 9px;
  opacity: 0.5;
  fill: none;
  stroke: #6c7690;
  stroke-width: 1;
}

/* ------------------------------------------------------------- Kartensymbole */

.clive-unit {
  position: absolute;
  transform: translate(-50%, -50%);
  animation: cliveDrift ease-in-out infinite;
  transition: left 1s linear, top 1s linear;
}

.clive-unit__badge {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.clive-unit__badge svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  stroke-width: 1.4;
}

.clive-unit--att .clive-unit__badge svg { fill: rgba(20, 52, 86, 0.82); stroke: var(--clive-attacker); }
.clive-unit--def .clive-unit__badge svg { fill: rgba(74, 26, 22, 0.82); stroke: #ff6b58; }

.clive-unit--att .clive-unit__badge { filter: drop-shadow(0 0 4px var(--clive-attacker)); }
.clive-unit--def .clive-unit__badge { filter: drop-shadow(0 0 4px #ff6b58); }
.clive-unit.is-sortie .clive-unit__badge { filter: drop-shadow(0 0 9px currentColor); }

.clive-unit__badge b {
  position: relative;
  font-family: var(--font-mono);
  line-height: 1;
  letter-spacing: -0.02em;
  text-shadow: 0 0 6px rgba(3, 6, 14, 0.95);
}

.clive-unit--att .clive-unit__badge b { color: #dff4ff; }
.clive-unit--def .clive-unit__badge b { color: #ffd9d0; }

.clive-unit__ping {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border-radius: 50%;
  border: 1px solid currentColor;
  animation: cliveRing 1.6s ease-out infinite;
}

.clive-unit--att .clive-unit__ping { color: var(--clive-attacker); }
.clive-unit--def .clive-unit__ping { color: #ff6b58; }

.clive-unit__bar {
  display: block;
  margin-top: 2.5px;
  height: 2px;
  border-radius: 1px;
  background: rgba(255, 255, 255, 0.09);
  overflow: hidden;
}

.clive-unit__fill { display: block; height: 100%; background: currentColor; }
.clive-unit--att .clive-unit__fill { color: var(--clive-attacker); }
.clive-unit--def .clive-unit__fill { color: #ff6b58; }
.clive-unit__fill--warn { color: var(--clive-warn) !important; }
.clive-unit__fill--bad { color: var(--clive-bad) !important; }

/* ------------------------------------------------------------------ Effekte */

.clive-fx { position: absolute; pointer-events: none; }

.clive-fx--laser {
  height: 1.5px;
  background: linear-gradient(90deg, var(--fx-color), transparent);
  box-shadow: 0 0 6px var(--fx-color);
  transform-origin: 0 50%;
  animation-name: cliveTracer;
  animation-timing-function: linear;
}

.clive-fx--torpedo,
.clive-fx--bomb { height: 0; transform-origin: 0 50%; }

.clive-fx--torpedo b,
.clive-fx--bomb b {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 0;
  animation-name: cliveTravel;
  animation-fill-mode: forwards;
}

.clive-fx--torpedo b { animation-timing-function: linear; }
.clive-fx--bomb b { animation-timing-function: cubic-bezier(0.4, 0.08, 0.7, 1); }

.clive-fx--torpedo u {
  position: absolute;
  left: 0;
  top: 0;
  width: 30px;
  height: 2px;
  transform: translate(-100%, -50%);
  background: linear-gradient(90deg, transparent, var(--fx-color));
  opacity: 0.5;
}

.clive-fx--torpedo s {
  position: absolute;
  left: 0;
  top: 0;
  width: 10px;
  height: 3.5px;
  border-radius: 2px;
  transform: translate(-50%, -50%);
  background: var(--fx-color);
  box-shadow: 0 0 8px var(--fx-color);
}

.clive-fx--bomb u {
  position: absolute;
  left: 0;
  top: 0;
  animation-name: cliveArc;
  animation-timing-function: ease-in-out;
  animation-fill-mode: forwards;
}

.clive-fx--bomb s {
  display: block;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle at 35% 32%, #fff3cc, var(--fx-color) 58%, transparent 74%);
  box-shadow: 0 0 14px var(--fx-color);
  animation: cliveBombPulse 0.3s linear infinite;
}

.clive-fx--wave { width: 0; height: 0; }

.clive-fx--wave u {
  position: absolute;
  left: 0;
  top: 0;
  border: 1.5px solid var(--fx-color);
  border-radius: 50%;
  /* Halbmond statt vollem Ring: die Welle laeuft nach vorn, nicht nach
     hinten in die eigene Formation. */
  clip-path: polygon(50% -10%, 130% -10%, 130% 110%, 50% 110%);
  animation-name: cliveWave;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
}

.clive-fx--hit {
  border-radius: 50%;
  background: radial-gradient(circle, var(--fx-color), transparent 70%);
  animation-name: cliveFlash;
  animation-timing-function: ease-out;
}

.clive-fx--boom { width: 0; height: 0; }

.clive-fx--boom u,
.clive-fx--boom b {
  position: absolute;
  left: 0;
  top: 0;
  border-radius: 50%;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
}

.clive-fx--boom u {
  background: radial-gradient(circle, #fff8e0 8%, var(--fx-color) 42%, transparent 72%);
  animation-name: cliveBoomCore;
}

.clive-fx--boom b {
  border: 1.5px solid var(--fx-color);
  animation-name: cliveBoomRing;
}

/* --------------------------------------------------------------- Protokoll */

.clive-log {
  flex: 0 1 274px;
  min-height: 160px;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--clive-line);
  border-radius: 9px;
  background: rgba(11, 14, 27, 0.78);
  padding: 11px 13px;
}

.clive-log__head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.clive-log__head h3 {
  margin: 0;
  flex: 1;
  font-family: var(--font-heading);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.11em;
  color: var(--clive-label);
}

.clive-log__tabs { display: flex; gap: 4px; flex-wrap: wrap; }

.clive-log__tab {
  cursor: pointer;
  font-family: var(--font-heading);
  font-size: 8.5px;
  letter-spacing: 0.08em;
  padding: 4px 9px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.03);
  color: #7683a8;
  border: 1px solid rgba(120, 180, 255, 0.12);
  transition: 0.15s;
}

.clive-log__tab:hover { color: #cdd6f0; border-color: rgba(120, 180, 255, 0.3); }

.clive-log__tab.is-active {
  background: rgba(70, 217, 208, 0.14);
  color: var(--clive-good);
  border-color: rgba(70, 217, 208, 0.45);
}

.clive-log__list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  list-style: none;
  margin: 9px 0 0;
  padding: 0 5px 0 0;
}

.clive-log__row {
  display: flex;
  gap: 12px;
  padding: 4.5px 0;
  animation: cliveFadeUp 0.3s ease-out;
}

.clive-log__time {
  flex: none;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--clive-dim);
}

.clive-log__text { font-size: 11.5px; line-height: 1.45; color: #cdd6f0; }

.clive-log__row--bad .clive-log__text { color: #ff6b58; }
.clive-log__row--good .clive-log__text { color: #5fd88a; }
.clive-log__row--warn .clive-log__text { color: var(--clive-warn); }
.clive-log__row--info .clive-log__text,
.clive-log__row--special .clive-log__text { color: var(--clive-attacker); }

/* DIE SEITE SCHLAEGT DEN TON (Nutzerwunsch 2026-09-05: "ICH tuerkise Logs,
   mein Gegner rote Logs").

   Diese Regeln stehen bewusst NACH den Ton-Regeln darueber und ueberschreiben
   deren Textfarbe. Vorher richtete sich die Farbe nach dem Ergebnis - ein
   eigener Abschuss war gruen, ein fremder rot -, und man musste jede Zeile
   lesen, um zu wissen, wer schiesst. Beim Ueberfliegen ist die Partei die
   nuetzlichere Auskunft.

   Der Ton geht dabei nicht verloren: Abschuesse behalten ihr Gewicht ueber
   die Schriftstaerke und einen Randstreifen, nur eben in der Farbe der
   handelnden Seite. Zeilen ohne Seite - der Rundenwechsel - bleiben grau. */
.clive-log__row--own .clive-log__text { color: var(--clive-attacker); }
.clive-log__row--foe .clive-log__text { color: var(--clive-defender); }

.clive-log__row--own,
.clive-log__row--foe {
  padding-left: 8px;
  border-left: 2px solid transparent;
}

.clive-log__row--own { border-left-color: rgba(127, 233, 255, 0.28); }
.clive-log__row--foe { border-left-color: rgba(224, 90, 74, 0.28); }

/* Ein Abschuss ist die einzige Zeile, die den Bestand aendert - sie darf
   auffallen, ohne die Partei-Farbe aufzugeben. */
.clive-log__row--own.clive-log__row--good,
.clive-log__row--own.clive-log__row--bad { border-left-color: var(--clive-attacker); }
.clive-log__row--foe.clive-log__row--good,
.clive-log__row--foe.clive-log__row--bad { border-left-color: var(--clive-defender); }

.clive-log__row--good .clive-log__text,
.clive-log__row--bad .clive-log__text { font-weight: 600; }

/* ---------------------------------------------------------------- Bewegung */

@keyframes clivePulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
@keyframes cliveBlink { 0%, 44% { opacity: 1; } 50%, 94% { opacity: 0.15; } 100% { opacity: 1; } }
@keyframes cliveScan { 0% { transform: translateY(-100%); } 100% { transform: translateY(1100%); } }
@keyframes cliveSpin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
@keyframes cliveBarFlow { 0% { background-position: 0 0; } 100% { background-position: 24px 0; } }
@keyframes cliveFadeUp { 0% { opacity: 0; transform: translateY(6px); } 100% { opacity: 1; transform: translateY(0); } }

@keyframes cliveDrift {
  0%, 100% { transform: translate(-50%, -50%); }
  25% { transform: translate(calc(-50% + 4px), calc(-50% - 3px)); }
  50% { transform: translate(calc(-50% - 2px), calc(-50% + 4px)); }
  75% { transform: translate(calc(-50% - 4px), calc(-50% - 2px)); }
}

@keyframes cliveRing {
  0% { transform: translate(-50%, -50%) scale(0.4); opacity: 0.9; }
  100% { transform: translate(-50%, -50%) scale(2.4); opacity: 0; }
}

@keyframes cliveTracer {
  0% { opacity: 0; transform: scaleX(0); }
  12% { opacity: 1; transform: scaleX(1); }
  70% { opacity: 1; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(1); }
}

@keyframes cliveTravel { 0% { transform: translateX(0); } 100% { transform: translateX(100%); } }
@keyframes cliveArc { 0% { transform: translateY(0); } 50% { transform: translateY(-11px); } 100% { transform: translateY(0); } }
@keyframes cliveBombPulse { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.5); } }

@keyframes cliveWave {
  0% { transform: translate(-50%, -50%) scale(0.18); opacity: 0.05; }
  25% { opacity: 0.85; }
  100% { transform: translate(-50%, -50%) scale(3.6); opacity: 0; }
}

@keyframes cliveBoomRing {
  0% { transform: translate(-50%, -50%) scale(0.12); opacity: 0.95; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}

@keyframes cliveBoomCore {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); }
  18% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
}

@keyframes cliveFlash {
  0%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  20% { opacity: 1; transform: translate(-50%, -50%) scale(1.4); }
  60% { opacity: 0.3; transform: translate(-50%, -50%) scale(1); }
}

/* Wer Bewegung abgestellt hat, bekommt eine stehende Lage: die Symbole
   bleiben, nur Flug und Blitzen entfallen. Ein eingefrorenes Geschoss mitten
   im Flug waere eine Falschaussage ueber die Lage. */
@media (prefers-reduced-motion: reduce) {
  .clive-fx,
  .clive-map__scan { display: none; }

  .clive-unit,
  .clive-wreck,
  .clive-emblem,
  .clive-power__pivot,
  .clive-power__track span,
  .clive-abilities i,
  .clive-systems u,
  .clive-head__pulse { animation: none !important; }
}

/* ---------------------------------------------------------------- Umbruch */

@media (max-width: 1400px) {
  .clive-body { grid-template-columns: 246px minmax(0, 1fr) 246px; }
}

@media (max-width: 1200px) {
  /* Die Karte zuerst ueber die volle Breite, die Parteien darunter
     nebeneinander - so bleibt der Vergleich der beiden Seiten erhalten. */
  .clive-body { grid-template-columns: 1fr 1fr; }
  .clive-col--center { grid-column: 1 / -1; grid-row: 1; }
  .clive-col--left { grid-row: 2; }
  .clive-col--right { grid-row: 2; }
}

@media (max-width: 900px) {
  .clive-body { grid-template-columns: 1fr; }
  .clive-col--left,
  .clive-col--right { grid-row: auto; }
  .clive-head { flex-wrap: wrap; justify-content: center; gap: 10px; }
  .clive-head__center { flex-wrap: wrap; justify-content: center; }
}

/* ============================================================
   Abgeschlossener Kampfbericht — Nachbesprechung (2026-09-02)

   Nach der zweiten Gestaltungsvorlage des Nutzers
   (docs/agents/vorlagen/2026-09-02-kampflog.webp). Dieselbe Bildsprache wie
   der Live-Bericht: Angreifer cyan, Verteidiger rot, dichte Beschriftung.
   Der Unterschied ist der Inhalt, nicht die Form.
   ============================================================ */

.cdeb {
  --cdeb-attacker: var(--accent-bright);
  --cdeb-defender: var(--accent-red);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* ----------------------------------------------------------- Kopfzeile */

.cdeb-head {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.cdeb-head__title { display: flex; align-items: baseline; gap: var(--space-3); }
.cdeb-head__title .dashboard-eyebrow { font-size: 17px; letter-spacing: 0.16em; color: var(--text-primary); }
.cdeb-head__id { font-size: 11px; letter-spacing: 0.12em; color: var(--text-dim); }

.cdeb-head__facts { display: flex; gap: var(--space-4); justify-self: center; }
.cdeb-fact { display: inline-flex; align-items: baseline; gap: 6px; }
.cdeb-fact small { font-size: 9px; letter-spacing: 0.18em; color: var(--text-dim); }
.cdeb-fact b { font-family: var(--font-body); font-size: 13px; color: var(--text-primary); }
.cdeb-fact--clock { color: var(--accent-bright) !important; }
.cdeb-fact--good { color: var(--accent-green) !important; }
.cdeb-fact--bad { color: var(--accent-red) !important; }
.cdeb-fact--neutral { color: var(--accent-gold) !important; }

.cdeb-head__time { justify-self: end; font-size: 10px; letter-spacing: 0.12em; color: var(--text-muted); }

/* -------------------------------------------------------------- Raster */

.cdeb-body {
  display: grid;
  grid-template-columns: 330px minmax(0, 1fr) 330px;
  gap: var(--space-3);
  align-items: start;
}

.cdeb-col { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }

.cdeb-box {
  padding: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.cdeb-box .section-heading { margin: 0 0 var(--space-2); font-size: 10px; letter-spacing: 0.16em; }
.cdeb-empty { margin: 0; font-size: 11px; color: var(--text-dim); }

/* -------------------------------------------------------- Parteispalte */

.cdeb-party { display: flex; flex-direction: column; gap: var(--space-3); }

.cdeb-party__head {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2);
  align-items: center;
  padding: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.cdeb-party--attacker .cdeb-party__head { border-color: rgba(127, 233, 255, 0.34); }
.cdeb-party--defender .cdeb-party__head { border-color: rgba(224, 90, 74, 0.34); }

.cdeb-emblem {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 2px solid currentColor;
  position: relative;
}
.cdeb-emblem::after {
  content: "";
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
}
.cdeb-emblem--attacker { color: var(--cdeb-attacker); }
.cdeb-emblem--defender { color: var(--cdeb-defender); }

.cdeb-party__ident b { display: block; font-size: 13px; letter-spacing: 0.14em; color: var(--text-primary); }
.cdeb-party__ident small { display: block; font-size: 9px; letter-spacing: 0.14em; color: var(--text-dim); }

.cdeb-party__power { grid-column: 1 / -1; text-align: right; }
.cdeb-party__power small { display: block; font-size: 8px; letter-spacing: 0.18em; color: var(--text-dim); }
.cdeb-party__power b { font-family: var(--font-body); font-size: 20px; }
.cdeb-party--attacker .cdeb-party__power b { color: var(--cdeb-attacker); }
.cdeb-party--defender .cdeb-party__power b { color: var(--cdeb-defender); }

/* ------------------------------------------------- Einsatz und Formen */

.cdeb-table { width: 100%; border-collapse: collapse; font-size: 11px; }
.cdeb-table thead th {
  padding: 0 4px 3px;
  font-size: 8px;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  text-align: right;
  border-bottom: 1px solid var(--border);
  font-weight: 400;
}
.cdeb-table tbody tr + tr > * { border-top: 1px solid rgba(120, 180, 255, 0.07); }
.cdeb-table tbody th {
  padding: 4px;
  text-align: left;
  font-weight: 400;
  min-width: 0;
}
.cdeb-table tbody th b { display: block; color: var(--text-body); font-weight: 400; }
.cdeb-table tbody th small {
  display: block;
  font-size: 8.5px;
  letter-spacing: 0.08em;
  color: var(--text-dimmer);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cdeb-table__fig { width: 52px; padding: 4px 2px 4px 0; }
.cdeb-table__num { padding: 4px; text-align: right; font-family: var(--font-body); color: var(--text-primary); }

/* Die Silhouetten sind gezeichnet, nicht geladen: echte Grafiken koennen
   spaeter kommen, bis dahin ist eine erkennbare Form besser als ein leeres
   Kaestchen. */
.cdeb-glyph {
  display: block;
  width: 50px;
  height: 20px;
  /* Die Fuellung traegt die Form, nicht die Kontur: bei 20 px Hoehe
     verschwimmt eine reine Strichzeichnung zu einem Fleck. Als Flaeche
     bleibt der Umriss lesbar. */
  fill: currentColor;
  fill-opacity: 0.22;
  stroke: currentColor;
  stroke-width: 1.1;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.cdeb-party--attacker .cdeb-glyph { color: var(--accent-bright); }
.cdeb-party--defender .cdeb-glyph { color: var(--accent-red); }

.cdeb-num--bad { color: var(--accent-red); }
.cdeb-num--warn { color: var(--accent-gold); }
.cdeb-num--none { color: var(--text-dimmer); }

/* -------------------------------------------------------------- Balken */

.cdeb-bars { display: flex; flex-direction: column; gap: 9px; }

/* --------------------------------------------------------- Faehigkeiten */

.cdeb-abilities { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.cdeb-abilities li { display: grid; grid-template-columns: auto 1fr auto; gap: 6px; align-items: baseline; }
.cdeb-abilities span { color: var(--accent-bright); }
.cdeb-abilities b { font-size: 10.5px; font-weight: 400; color: var(--text-body); }
/* Runden statt Wirkungsgrad: das Kampfsystem haelt fest, WELCHE Faehigkeit in
   WELCHER Runde ausloeste, nicht wie stark. */
.cdeb-abilities em {
  font-style: normal;
  font-size: 8.5px;
  letter-spacing: 0.1em;
  color: var(--text-dimmer);
  white-space: nowrap;
}

/* ------------------------------------------------------------ Verluste */

.cdeb-loss--attacker { border-color: rgba(127, 233, 255, 0.26); }
.cdeb-loss--defender { border-color: rgba(224, 90, 74, 0.26); }

.cdeb-loss__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 3px 0;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--text-muted);
}
.cdeb-loss__row + .cdeb-loss__row { border-top: 1px solid rgba(120, 180, 255, 0.07); }
.cdeb-loss__row b { font-family: var(--font-body); font-size: 15px; color: var(--text-primary); }

/* -------------------------------------------------------- Kampfverlauf */

.cdeb-log {
  padding: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.cdeb-log__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-2);
}
.cdeb-log__head .section-heading { margin: 0; }

.cdeb-log__tabs { display: flex; gap: 3px; }
.cdeb-log__tab {
  padding: 3px 9px;
  font-family: inherit;
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--text-dim);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.cdeb-log__tab:hover { color: var(--text-body); border-color: var(--border-strong); }
.cdeb-log__tab.is-active { color: var(--bg); background: var(--accent-bright); border-color: var(--accent-bright); }

.cdeb-log__body { max-height: 460px; overflow-y: auto; }

.cdeb-round + .cdeb-round { margin-top: var(--space-2); }
.cdeb-round__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: 4px 6px;
  background: rgba(120, 180, 255, 0.05);
  border-left: 2px solid var(--border-strong);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.cdeb-round__head b { font-size: 10px; letter-spacing: 0.16em; color: var(--text-primary); }
.cdeb-round__head span {
  font-size: 8.5px;
  letter-spacing: 0.14em;
  /* Der Phasenname kommt gemischt aus dem Glossar; die Vorlage schreibt ihn
     in Versalien. Das ist Darstellung, keine Datenfrage. */
  text-transform: uppercase;
  color: var(--text-dim);
}
/* Die Uhr steht am Rundenkopf, weil combat_rounds.resolved_at der einzige
   Zeitstempel im Verlauf ist - Sekunden je Zeile waeren erfunden. */
.cdeb-round__head time {
  margin-left: auto;
  font-family: var(--font-body);
  font-size: 10px;
  color: var(--accent-bright);
}

.cdeb-round__list { list-style: none; margin: 0; padding: 2px 0 0 8px; }
.cdeb-log__row {
  padding: 2.5px 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-body);
}
.cdeb-log__row--bad { color: var(--accent-red); }
.cdeb-log__row--good { color: var(--accent-green); }
.cdeb-log__row--warn { color: var(--accent-gold); }
.cdeb-log__row--special { color: var(--accent-bright); }

/* --------------------------------------------------------- Truemmerfeld */

.cdeb-loot {
  padding: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.cdeb-loot__grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--space-4);
  align-items: start;
}

.cdeb-loot__row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 6px;
  align-items: baseline;
  padding: 3px 0;
  font-size: 11px;
  color: var(--text-body);
}
.cdeb-loot__row + .cdeb-loot__row { border-top: 1px solid rgba(120, 180, 255, 0.06); }
.cdeb-loot__row b { font-family: var(--font-body); color: var(--text-primary); }
.cdeb-loot__icon {
  width: 16px;
  height: 16px;
  align-self: center;
  fill: currentColor;
  fill-opacity: 0.2;
  stroke: currentColor;
  stroke-width: 1;
  stroke-linejoin: round;
  color: var(--accent-bright);
}
.cdeb-loot__row--unknown { color: var(--text-muted); }
.cdeb-loot__row--unknown .cdeb-loot__icon { color: var(--accent-gold); }
.cdeb-loot__row { align-items: center; }

.cdeb-loot__fig {
  width: 180px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-deep);
}
.cdeb-debris { display: block; width: 100%; height: auto; fill: rgba(180, 200, 235, 0.5); }
.cdeb-debris__glow { fill: rgba(255, 150, 90, 0.16); stroke: rgba(255, 180, 120, 0.3); stroke-width: 0.6; }

.cdeb-loot__foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: baseline;
  margin-top: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
  font-size: 9px;
  letter-spacing: 0.14em;
  color: var(--text-dim);
}
.cdeb-loot__foot b { font-family: var(--font-body); font-size: 12px; letter-spacing: 0; color: var(--text-primary); }
.cdeb-danger--low { color: var(--accent-green) !important; }
.cdeb-danger--medium { color: var(--accent-gold) !important; }
.cdeb-danger--high { color: var(--accent-red) !important; }
.cdeb-loot__done { margin-left: auto; color: var(--text-dimmer); }
.cdeb-loot__note { margin: var(--space-2) 0 0; font-size: 9.5px; color: var(--text-dimmer); }

/* -------------------------------------------------------------- Umbruch */

@media (max-width: 1200px) {
  /* Der Verlauf zuerst ueber die volle Breite, die Parteien darunter
     nebeneinander - so bleibt der Vergleich beider Seiten erhalten. */
  .cdeb-body { grid-template-columns: 1fr 1fr; }
  .cdeb-col--center { grid-column: 1 / -1; grid-row: 1; }
  .cdeb-col--left { grid-row: 2; }
  .cdeb-col--right { grid-row: 2; }
}

@media (max-width: 900px) {
  .cdeb-body { grid-template-columns: 1fr; }
  .cdeb-col--left,
  .cdeb-col--right { grid-row: auto; }
  .cdeb-head { grid-template-columns: 1fr; gap: var(--space-2); text-align: center; }
  .cdeb-head__facts { justify-self: center; flex-wrap: wrap; justify-content: center; }
  .cdeb-head__time { justify-self: center; }
  .cdeb-loot__grid { grid-template-columns: 1fr; }
  .cdeb-loot__fig { width: 100%; }
}

/* --------------------------------------- Kampflog: Angleich an die Vorlage
   Zweiter Durchgang nach genauem Abgleich (2026-09-02). Die Vorlage faerbt
   nach BEDEUTUNG, nicht nach Partei: beide Seiten tragen dieselben
   Balkenfarben, unterschieden werden sie ueber Wappen und Kampfkraft. Rot
   heisst hier "Verlust" und nicht "Gegner".
   --------------------------------------------------------------------- */

.cdeb-head__slash { color: var(--text-dimmer); font-size: 11px; }
.cdeb-head__time small { font-size: 9px; letter-spacing: 0.18em; color: var(--text-dim); }

/* Das Fraktionswappen: ein gezackter Stern im Ring statt eines Punktes. */
.cdeb-emblem {
  width: 34px;
  height: 34px;
  overflow: visible;
}
.cdeb-emblem__ring { fill: none; stroke: currentColor; stroke-width: 1; opacity: 0.4; }
.cdeb-emblem__star { fill: currentColor; }
.cdeb-emblem--attacker { color: var(--cdeb-attacker); filter: drop-shadow(0 0 6px rgba(127, 233, 255, 0.4)); }
.cdeb-emblem--defender { color: var(--cdeb-defender); filter: drop-shadow(0 0 6px rgba(224, 90, 74, 0.4)); }

/* Die Klasse in Versalien wie in der Vorlage, das Modell klein darunter. */
.cdeb-table tbody th b {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 10.5px;
  color: var(--text-primary);
}

/* ------------------------------------------------- Flottenstatus, neu */

.cdeb-bar {
  display: grid;
  grid-template-columns: 16px 1fr auto;
  grid-template-areas:
    "glyph label value"
    "track track  seg"
    ".     .      delta";
  gap: 3px var(--space-2);
  align-items: center;
}

.cdeb-bar__glyph {
  grid-area: glyph;
  width: 14px;
  height: 14px;
  fill: currentColor;
  fill-opacity: 0.25;
  stroke: currentColor;
  stroke-width: 0.9;
  color: var(--accent-bright);
}
.cdeb-bar--absent .cdeb-bar__glyph { color: var(--text-dimmer); }

/* :not(.cdeb-seg) ist Pflicht: die Segmentleiste ist ebenfalls ein span und
   direktes Kind: ohne den Ausschluss bekaeme sie grid-area:label und legte
   sich ueber die Beschriftung. Genau so ingame gesehen. */
.cdeb-bar > span:not(.cdeb-seg) {
  grid-area: label;
  font-size: 9px;
  letter-spacing: 0.1em;
  color: var(--text-muted);
}
.cdeb-bar__value {
  grid-area: value;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--text-primary);
}

.cdeb-bar__track {
  grid-area: track;
  display: block;
  height: 5px;
  border-radius: 3px;
  background: rgba(120, 180, 255, 0.12);
  overflow: hidden;
}
.cdeb-bar__track > u {
  display: block;
  height: 100%;
  text-decoration: none;
  background: var(--accent-bright);
}

/* Die Segmentleiste macht den Unterschied zwischen 58 und 72 Prozent auf
   einen Blick lesbar - ein durchgehender Balken sagt nur "zwei Drittel". */
.cdeb-seg { grid-area: seg; display: inline-flex; gap: 2px; }
.cdeb-seg > i {
  width: 6px;
  height: 5px;
  border-radius: 1px;
  background: rgba(120, 180, 255, 0.12);
}
.cdeb-seg > i.is-on { background: var(--accent-bright); }
.cdeb-seg--warn > i.is-on { background: var(--accent-gold); }
.cdeb-seg--crit > i.is-on { background: var(--accent-red); }

.cdeb-bar > em {
  grid-area: delta;
  justify-self: end;
  font-style: normal;
  font-family: var(--font-body);
  font-size: 10px;
}

.cdeb-bar--absent .cdeb-bar__track { background: none; border-bottom: 1px dashed rgba(120, 180, 255, 0.16); }
.cdeb-bar--absent .cdeb-bar__value,
.cdeb-bar--absent > em { color: var(--text-dimmer); }

/* ------------------------------------------------------ Verlustkachel */

/* Die EIGENE Kachel ist rot gerahmt, die gegnerische nicht: die Vorlage
   faerbt nach Bedeutung fuer den Betrachter. Eigene Verluste tun weh,
   fremde sind eine Zahl. */
.cdeb-loss--own {
  border-color: rgba(224, 90, 74, 0.45);
  background: linear-gradient(180deg, rgba(224, 90, 74, 0.06), transparent 60%), var(--surface);
}
.cdeb-loss--own .section-heading { color: var(--accent-red); }

.cdeb-loss__figs {
  display: flex;
  gap: 4px;
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid rgba(120, 180, 255, 0.07);
}
.cdeb-loss__fig {
  flex: 1 1 0;
  min-width: 0;
  padding: 4px 2px;
  border: 1px solid rgba(120, 180, 255, 0.1);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.25);
}
/* Gedaempft: es sind Wracks, keine Einheiten. */
.cdeb-loss__fig .cdeb-glyph {
  width: 100%;
  height: 18px;
  color: var(--text-muted);
  fill-opacity: 0.18;
}

/* ------------------------------------------- Lokalisieren aus den Favoriten
   Nutzerwunsch 2026-09-02: ein Favorit, den man nicht wiederfindet, ist nur
   eine Notiz. Der Knopf springt zur Karte, zentriert den Stern - und das
   Aufblitzen sagt, welcher gemeint ist. Der Auswahlring allein ist dezent;
   wer gerade aus einer Liste kommt, sucht ihn sonst trotzdem.
   ------------------------------------------------------------------------ */

.favorites-locate {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.favorites-locate i { font-size: 13px; }

/* Doppelter Klassenselektor mit Absicht: .starmap-system:hover::before
   belegt dasselbe Pseudoelement und haette bei geringerer Spezifitaet
   gewonnen - der Ping waere verschwunden, sobald die Maus den Stern
   beruehrt. Gleiche Spezifitaet, spaeter im Stylesheet: diese Regel gewinnt. */
.starmap-system.starmap-system--located::before,
.starmap-system.starmap-system--located::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  border: 2px solid var(--accent-gold);
  pointer-events: none;
  animation: starmap-locate-ping 1.5s ease-out 2;
}
/* Zwei Ringe versetzt: ein einzelner Puls geht auf einer belebten Karte
   unter, zwei lesen sich als gezieltes Signal. */
.starmap-system.starmap-system--located::after { animation-delay: 0.35s; }

@keyframes starmap-locate-ping {
  0% { transform: scale(0.6); opacity: 0; }
  15% { opacity: 1; }
  100% { transform: scale(6); opacity: 0; }
}

/* Dasselbe Signal fuer einen Sensorkontakt (2026-09-05). Piraten stehen fast
   immer zwischen den Sternen: dort gibt es keinen Systemmarker, auf den das
   Lokalisieren zeigen koennte - also leuchtet der Kontakt selbst auf.

   Eigener Selektor statt einer gemeinsamen Klasse: der Systemmarker traegt
   seine Ringe auf ::before/::after, und beim Kontaktmarker ist ::before
   bereits vom Rufabzeichen belegt. */
.starmap-contact-marker.starmap-contact-marker--located::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  border: 2px solid var(--accent-gold);
  pointer-events: none;
  animation: starmap-locate-ping 1.5s ease-out 2;
}

/* Wer Bewegung abgestellt hat, bekommt einen ruhenden Ring statt gar keiner
   Rueckmeldung - sonst waere der Sprung stumm. */
@media (prefers-reduced-motion: reduce) {
  .starmap-system.starmap-system--located::before {
    animation: none;
    transform: scale(2.2);
    opacity: 0.9;
  }
  .starmap-system.starmap-system--located::after { display: none; }

  .starmap-contact-marker.starmap-contact-marker--located::after {
    animation: none;
    transform: scale(2.2);
    opacity: 0.9;
  }
}

/* ==========================================================================
   ORGANISATIONSMENUE — KARTEN STATT EINER LANGEN KETTE
   Nutzerwunsch 2026-09-05: "Redesign des Organisations-Menue. Uebersichtlicher
   mit Boxen und keine so riesigen Boxen bauen."

   Vorher lief alles als Folge aus `section-heading` + Inhalt ueber die volle
   Bildschirmbreite: Mitglieder, Depot, Steuersatz, Spenden, Entnehmen,
   Historie — sechs Bloecke untereinander. Jetzt zwei Spalten aus Karten.
   ========================================================================== */

.org-head {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-start;
  justify-content: space-between;
  padding: 14px 18px;
  margin-bottom: 18px;
  background: var(--panel-bg, rgba(18, 22, 40, .72));
  border: 1px solid var(--panel-border, rgba(120, 150, 220, .18));
  /* Die Hausfarbe der Organisation steht als Kante links. Die Farbe kommt
     als Inline-Stil aus dem JS — hier nur die Breite, damit eine fehlende
     Farbe nicht zu einer 6px-Leerkante fuehrt. */
  border-left-width: 5px;
  border-radius: 10px;
}

.org-head__ident { min-width: 0; }

.org-head__name {
  margin: 2px 0 0;
  font-size: 24px;
  line-height: 1.2;
  letter-spacing: .5px;
}

.org-head__name small {
  font-size: 15px;
  color: var(--text-muted);
  letter-spacing: 1px;
}

.org-head__desc {
  margin: 6px 0 0;
  max-width: 70ch;
  font-size: 13px;
  color: var(--text-muted);
}

.org-head__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.org-head__actions .detail-panel__action { margin: 0; }

.org-head__leave {
  border-color: rgba(226, 116, 116, .4);
  color: #e59a9a;
}

/* Zwei Spalten. auto-fit statt fester Spaltenzahl: bei schmalem Fenster
   rutschen die Karten von selbst untereinander, ohne eigene Bruchstelle.
   minmax(320px, 1fr) ist die Grenze, unter der die Mitgliederzeilen
   umbrechen wuerden. */
.org-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 14px;
  align-items: start;
}

.org-grid--wide { margin-bottom: 14px; }

.org-card {
  background: var(--panel-bg, rgba(18, 22, 40, .72));
  border: 1px solid var(--panel-border, rgba(120, 150, 220, .18));
  border-radius: 10px;
  overflow: hidden;
}

.org-card__head {
  margin: 0;
  padding: 10px 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--accent, #7fb2ff);
  background: rgba(120, 150, 220, .07);
  border-bottom: 1px solid var(--panel-border, rgba(120, 150, 220, .18));
}

.org-card__body { padding: 12px 14px; }

/* "Keine so riesigen Boxen": Die Mitgliederliste war der Block, der die Seite
   in die Laenge zog — bei 30 Mitgliedern dreissig Zeilen am Stueck. Sie
   scrollt jetzt in sich, statt die Nachbarkarte nach unten zu schieben. */
.org-card--members .org-card__body {
  max-height: 420px;
  overflow-y: auto;
}

/* Das Depot fuellt EINE Karte mit mehreren Abschnitten. Der Bestand ohne die
   Knoepfe daneben waere nur eine halbe Auskunft — deshalb bleiben sie
   zusammen, getrennt nur durch eine Linie. */
.org-card__section + .org-card__section {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(120, 150, 220, .14);
}

.org-card__sub {
  margin-bottom: 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.org-card__note {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}

/* ------------------------------------------------- Kopfgeld-Meldung (Modal)
   Nutzerwunsch 2026-09-05: Nach einem gewonnenen Kampf gegen einen Piraten
   mit Kopfgeld meldet sich die Sternenwacht im Versteck. Die Credits waren
   schon vorher gutgeschrieben - nur wusste es niemand. */

.bounty-notice__text {
  margin: 0 0 14px;
  font-size: 13.5px;
  line-height: 1.55;
  font-style: italic;
  color: var(--text-primary);
}

.bounty-notice__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
  margin: 0 0 12px;
  padding: 11px 13px;
  background: rgba(120, 150, 220, .06);
  border: 1px solid rgba(120, 150, 220, .16);
  border-radius: 8px;
}

.bounty-notice__facts div { min-width: 0; }

.bounty-notice__facts dt {
  margin: 0 0 3px;
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.bounty-notice__facts dd {
  margin: 0;
  font-size: 13px;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  /* Ein Piratenname kann lang sein und wuerde die Spalte sonst sprengen. */
  overflow-wrap: anywhere;
}

.bounty-notice__credits { color: var(--accent-gold); font-weight: 600; }

.bounty-notice__footer {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-muted);
}

/* --------------------------------------------- Steuersatz-Regler (Orga)
   Nutzerwunsch 2026-09-05. Der Satz hat seit derselben Entscheidung eine
   feste Obergrenze von 50 % - ein Regler zeigt sie, statt sie erst in der
   Fehlermeldung zu verraten. Das Zahlenfeld bleibt daneben: Wer genau 12 %
   will, tippt sie schneller, als er sie trifft. */

.org-tax { display: flex; flex-direction: column; gap: 6px; }

.org-tax__slider { display: flex; align-items: center; gap: 12px; }

.org-tax__range {
  flex: 1;
  min-width: 0;
  height: 4px;
  cursor: pointer;
  accent-color: var(--accent);
}

.org-tax__value {
  flex: none;
  min-width: 56px;
  text-align: right;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 15px;
  color: var(--accent-bright);
  font-variant-numeric: tabular-nums;
}

/* Die Randbeschriftung endet buendig ueber dem Regler, nicht ueber der
   Wertanzeige daneben - deshalb der rechte Abstand in deren Breite. */
.org-tax__scale {
  display: flex;
  justify-content: space-between;
  margin-right: 68px;
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--text-dim);
}

.org-tax__actions { margin-top: 4px; }

/* Das Zahlenfeld braucht neben dem Regler keine volle Breite - drei Stellen
   reichen fuer einen Prozentwert. */
.org-tax__actions .fleet-form__input { max-width: 110px; }

/* ====================================================================
   ANOMALIE-EFFEKTE AM PLANETEN (Systemansicht)
   Nutzerwunsch 2026-09-05: "koennen wir in diesem View noch einen schoenen
   visuellen Effekt einbauen? Verzerrung am Planet, Blitze, schwarzes Loch mit
   Glow - vielleicht je nach Anomalie andere Effekte?"

   Rein kosmetisch: Der Effekt sagt nichts, was Marker und Kachel nicht schon
   sagen. Er macht nur von weitem sichtbar, DASS an diesem Planeten etwas ist.

   Alles per CSS, keine Zeitgeber in JavaScript: Die Systemansicht zeichnet
   sich bei jedem Tick neu, und ein setInterval je Planet waere genau die
   Sorte Leck, die auf der Sternenkarte schon einmal Speicher gefressen hat.

   `--fx` traegt die Kategoriefarbe und kommt als Inline-Stil vom Renderer.
   `inset: -30%` laesst den Effekt ueber den Planetenrand hinausgreifen - er
   liegt bewusst NEBEN der Kugel (die hat overflow:hidden), nicht in ihr.
   ==================================================================== */

.planet-fx {
  position: absolute;
  inset: -30%;
  border-radius: 50%;
  pointer-events: none;
  z-index: 6;
}

/* --- Raumzeit: die Linse. Ein dunkler Kern mit hellem Saum, der langsam
       kreist - das "schwarze Loch mit Glow" aus dem Wunsch. Der Kern liegt
       versetzt, damit es nach Verzerrung AN einer Stelle aussieht und nicht
       nach einem zweiten Planeten. */
.planet-fx--spacetime {
  background:
    radial-gradient(circle at 72% 28%, rgba(0, 0, 0, .85) 0 14%, transparent 15%),
    radial-gradient(circle at 72% 28%, transparent 13%, var(--fx) 15%, transparent 26%);
  filter: blur(.6px) drop-shadow(0 0 5px var(--fx));
  animation: fxLens 9s linear infinite;
}
@keyframes fxLens {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* --- Sensorik: Radarwellen, die nach aussen laufen und verblassen. Zwei
       Ringe mit versetztem Start, damit nie eine Luecke entsteht. */
.planet-fx--sensor::before,
.planet-fx--sensor::after {
  content: '';
  position: absolute;
  inset: 26%;
  border-radius: 50%;
  border: 1px solid var(--fx);
  animation: fxPing 3.2s ease-out infinite;
}
.planet-fx--sensor::after { animation-delay: 1.6s; }
@keyframes fxPing {
  0% { inset: 26%; opacity: .85; }
  100% { inset: -2%; opacity: 0; }
}

/* --- Energie: kurze Entladungen am Rand. Zwei duenne Bogen, die versetzt
       aufblitzen - laenger sichtbar als ein echter Blitz waere, sonst
       uebersieht man sie zwischen zwei Bildern. */
.planet-fx--energy::before,
.planet-fx--energy::after {
  content: '';
  position: absolute;
  inset: 20%;
  border-radius: 50%;
  border: 1.5px solid transparent;
  border-top-color: var(--fx);
  border-right-color: var(--fx);
  filter: drop-shadow(0 0 4px var(--fx));
  animation: fxArc 2.4s ease-in-out infinite;
}
.planet-fx--energy::after {
  inset: 12%;
  transform: rotate(150deg);
  animation-delay: 1.1s;
}
@keyframes fxArc {
  0%, 62%, 100% { opacity: 0; }
  68% { opacity: .95; }
  74% { opacity: .15; }
  80% { opacity: .8; }
}

/* --- Materie: ein Staubring, der sich langsam dreht. Gestrichelt statt
       durchgezogen, damit er nicht mit dem Scanring verwechselt wird. */
.planet-fx--matter::before {
  content: '';
  position: absolute;
  inset: 16%;
  border-radius: 50%;
  border: 1.5px dashed var(--fx);
  opacity: .7;
  filter: drop-shadow(0 0 3px var(--fx));
  animation: fxDust 14s linear infinite;
}
@keyframes fxDust {
  from { transform: rotate(0deg) scale(1); }
  50% { transform: rotate(180deg) scale(1.06); }
  to { transform: rotate(360deg) scale(1); }
}

/* --- Unbekannt und unbestimmt: Stoerung. Ein unregelmaessiges Flackern mit
       einem zuckenden Ring darum.

       NUR EIN GLIMMEN REICHTE NICHT (Nutzerbefund 2026-09-05: "dort gibt's
       Unbekannte Anomalie - Klasse I, ich sehe hier aber keinen Effekt").
       Der Planet traegt ohnehin schon einen eigenen box-shadow; ein zweiter,
       halbdurchsichtiger daneben ging darin unter. Ein RING hat eine Kante
       und damit eine Form, die man auch dann bemerkt, wenn die Farbe schwach
       ist.

       Die Zwischenschritte der Keyframes sind bewusst ungleichmaessig - ein
       sauberer Sinus liest sich als Technik, dieses Zucken als "da stimmt
       etwas nicht". */
.planet-fx--unknown,
.planet-fx--neutral {
  box-shadow: 0 0 14px 3px var(--fx);
  animation: fxFlicker 4.7s ease-in-out infinite;
}

.planet-fx--unknown::before,
.planet-fx--neutral::before {
  content: '';
  position: absolute;
  inset: 8%;
  border-radius: 50%;
  border: 1.5px dashed var(--fx);
  filter: drop-shadow(0 0 4px var(--fx));
  animation: fxJitter 3.1s steps(1, end) infinite;
}

/* Die unbestimmte Fassung bleibt zurueckhaltender: Solange die Kategorie
   nicht feststeht, soll der Planet nicht lauter schreien als einer, ueber den
   man schon etwas weiss. */
.planet-fx--neutral { opacity: .6; }

@keyframes fxFlicker {
  0%, 100% { opacity: .45; }
  17% { opacity: .95; }
  23% { opacity: .5; }
  46% { opacity: 1; }
  52% { opacity: .55; }
  71% { opacity: .85; }
}

/* steps(1, end) statt weicher Interpolation: Der Ring SPRINGT zwischen den
   Lagen, statt zu gleiten - so wirkt es wie eine Stoerung und nicht wie eine
   Umlaufbahn. */
@keyframes fxJitter {
  0% { transform: rotate(0deg) scale(1); opacity: .8; }
  20% { transform: rotate(14deg) scale(1.05); opacity: .35; }
  40% { transform: rotate(-9deg) scale(.97); opacity: .9; }
  60% { transform: rotate(6deg) scale(1.08); opacity: .45; }
  80% { transform: rotate(-3deg) scale(1); opacity: .75; }
  100% { transform: rotate(0deg) scale(1); opacity: .8; }
}

/* Wer Bewegung abbestellt hat, bekommt den Effekt als ruhigen Schimmer -
   nicht gar nichts: Die Auskunft "hier ist etwas" soll erhalten bleiben. */
@media (prefers-reduced-motion: reduce) {
  .planet-fx,
  .planet-fx::before,
  .planet-fx::after { animation: none; }
  .planet-fx { box-shadow: 0 0 10px 1px var(--fx); opacity: .45; }
}

/* ====================================================================
   ANOMALIE-EFFEKTE IM PLANETEN-VIEW (Nutzerbefund 2026-09-05)

   "Im System View sehe ich nun am Planeten eine Anomalie und einen Effekt.
   Ich meinte aber den Planeten View - wo sich der Planet dreht, ich die
   Oberflaeche sehe - da moechte ich einen eindeutig sichtbaren Effekt sehen.
   Auf dem Oberflaechenscan als auch am 3D-Modell was sich dreht."

   Zwei Zusaetze zu den `.planet-fx`-Regeln darueber. Sie erfinden KEINE neuen
   Effekte: Kategorie, Farbe und Bewegung bleiben dieselben, damit ein Spieler
   den Effekt aus der Systemuebersicht wiedererkennt.
   ==================================================================== */

/* --- 1) Die rotierende Kugel im Zoom -------------------------------- */

/* Verstaerkung fuer die grosse Darstellung. An einem 20-px-Planeten in der
   Systemuebersicht traegt ein 1,5-px-Ring; an einer 340-px-Kugel verschwindet
   er. Die Kaskade macht die Arbeit: `--zoom` steht NACH den Kategorieregeln
   und ueberschreibt nur Staerken, nie Form oder Bewegung. */
.planet-fx--zoom {
  inset: -22%;
  filter: drop-shadow(0 0 14px var(--fx));
}
.planet-fx--zoom.planet-fx--spacetime {
  filter: blur(1.4px) drop-shadow(0 0 18px var(--fx));
}
.planet-fx--zoom.planet-fx--sensor::before,
.planet-fx--zoom.planet-fx--sensor::after {
  border-width: 3px;
}
.planet-fx--zoom.planet-fx--energy::before,
.planet-fx--zoom.planet-fx--energy::after {
  border-width: 4px;
}
.planet-fx--zoom.planet-fx--matter::before {
  border-width: 4px;
}
.planet-fx--zoom.planet-fx--unknown,
.planet-fx--zoom.planet-fx--neutral {
  box-shadow: 0 0 34px 9px var(--fx);
}
.planet-fx--zoom.planet-fx--unknown::before,
.planet-fx--zoom.planet-fx--neutral::before {
  border-width: 3px;
}
/* Der unbestimmte Fall darf im Zoom nicht so blass bleiben wie in der
   Uebersicht - dort ist er ein Punkt unter vielen, hier fuellt er das Bild. */
.planet-fx--zoom.planet-fx--neutral { opacity: .85; }

/* Die Beschriftung unter der Kugel. In der Uebersicht reicht "da ist etwas",
   im Zoom steht der Spieler davor und will wissen, WAS blinkt - ohne den
   Planeten erst anklicken zu muessen. */
.planet-fx-label {
  position: absolute;
  left: 50%;
  bottom: -34px;
  transform: translateX(-50%);
  display: flex;
  align-items: baseline;
  gap: 7px;
  white-space: nowrap;
  padding: 4px 11px;
  border-radius: 7px;
  border: 1px solid color-mix(in srgb, var(--fx) 45%, transparent);
  background: rgba(5, 7, 16, .82);
  font-family: 'Chakra Petch', sans-serif;
  pointer-events: none;
  z-index: 7;
}
.planet-fx-label__mark { color: var(--fx); font-size: 12px; }
.planet-fx-label__text {
  color: #e6ecff;
  font-size: 11.5px;
  letter-spacing: .06em;
}
.planet-fx-label__cat {
  color: var(--fx);
  font-size: 9.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* --- 2) Die gescannte Oberflaeche ----------------------------------- */

/* Der Oberflaechen-Canvas ist ein Rechteck (900x420). Ein runder Saum um
   seinen Mittelpunkt saehe dort aus wie ein Zeichenfehler, deshalb eine
   eigene, flaechige Familie statt einer Variante von `.planet-fx`.

   Gemeinsam ist allen fuenf: Sie liegen UEBER dem Gelaende und lassen es
   durchscheinen. Eine deckende Stoerung wuerde genau das verbergen, wofuer
   der Spieler den Scan gefahren hat. */
.surface-fx {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  mix-blend-mode: screen;
}

/* Raumzeit: eine Linse, die ueber das Gelaende wandert - dunkler Kern,
   heller Saum. Dieselbe Erzaehlung wie an der Kugel, nur laeuft sie hier
   quer durchs Bild statt um den Planeten. */
.surface-fx--spacetime {
  background:
    radial-gradient(circle at 30% 50%, rgba(0, 0, 0, .8) 0 5%, transparent 6%),
    radial-gradient(circle at 30% 50%, transparent 5%, var(--fx) 7.5%, transparent 15%);
  filter: blur(1px);
  animation: sfxDrift 14s ease-in-out infinite alternate;
}
@keyframes sfxDrift {
  from { transform: translateX(-14%) scale(1); }
  to { transform: translateX(14%) scale(1.12); }
}

/* Sensorik: Scanbaender, die von oben nach unten durchlaufen - dasselbe
   Motiv wie die Radarwellen an der Kugel, auf ein Rechteck uebersetzt. */
.surface-fx--sensor {
  background: repeating-linear-gradient(
    180deg,
    transparent 0 22px,
    color-mix(in srgb, var(--fx) 38%, transparent) 22px 24px
  );
  opacity: .5;
  animation: sfxSweep 3.4s linear infinite;
}
@keyframes sfxSweep {
  from { background-position-y: 0; }
  to { background-position-y: 24px; }
}

/* Energie: kurze Entladungen. Zwei versetzt aufblitzende Schleier statt
   eines echten Blitzes - ein einzelner Blitz ist zu kurz, um ihn zu sehen. */
.surface-fx--energy::before,
.surface-fx--energy::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    102deg,
    transparent 0 38%,
    color-mix(in srgb, var(--fx) 75%, transparent) 46%,
    transparent 54% 100%
  );
  animation: sfxArc 2.9s ease-in-out infinite;
}
.surface-fx--energy::after {
  background: linear-gradient(
    -114deg,
    transparent 0 44%,
    color-mix(in srgb, var(--fx) 60%, transparent) 51%,
    transparent 58% 100%
  );
  animation-delay: 1.45s;
}
@keyframes sfxArc {
  0%, 74%, 100% { opacity: 0; }
  78% { opacity: .9; }
  84% { opacity: .25; }
  89% { opacity: .75; }
}

/* Materie: treibender Staub. Gepunktet, damit er nicht mit den
   Ressourcenpunkten verwechselt wird - die sind einzeln und stehen still. */
.surface-fx--matter {
  background:
    radial-gradient(circle at 20% 30%, color-mix(in srgb, var(--fx) 55%, transparent) 0 1.5px, transparent 2px),
    radial-gradient(circle at 62% 68%, color-mix(in srgb, var(--fx) 45%, transparent) 0 1.5px, transparent 2px),
    radial-gradient(circle at 84% 22%, color-mix(in srgb, var(--fx) 50%, transparent) 0 1.5px, transparent 2px);
  background-size: 120px 90px, 90px 120px, 150px 110px;
  opacity: .75;
  animation: sfxDust 9s linear infinite;
}
@keyframes sfxDust {
  from { background-position: 0 0, 0 0, 0 0; }
  to { background-position: 120px 90px, -90px 120px, 150px -110px; }
}

/* Unbekannt: unregelmaessiges Flackern ueber der ganzen Flaeche, ohne Form.
   Genau das ist die Aussage - es laesst sich nicht einordnen. */
.surface-fx--unknown,
.surface-fx--neutral {
  background: radial-gradient(ellipse at 50% 50%, color-mix(in srgb, var(--fx) 30%, transparent), transparent 72%);
  animation: sfxFlicker 4.7s ease-in-out infinite;
}
.surface-fx--neutral { opacity: .55; }
@keyframes sfxFlicker {
  0%, 100% { opacity: .3; }
  17% { opacity: .8; }
  23% { opacity: .35; }
  46% { opacity: .95; }
  52% { opacity: .4; }
  71% { opacity: .7; }
}

/* Beschriftung oben links, gegenueber der Scan-Prozentanzeige oben rechts -
   so ueberdecken sich die beiden nie. */
.surface-fx-label {
  position: absolute;
  top: 8px;
  left: 12px;
  display: flex;
  align-items: baseline;
  gap: 7px;
  max-width: calc(100% - 120px);
  padding: 4px 10px;
  border-radius: 7px;
  border: 1px solid color-mix(in srgb, var(--fx) 45%, transparent);
  background: rgba(5, 7, 16, .8);
  font-family: 'Chakra Petch', sans-serif;
  font-size: 11px;
  letter-spacing: .06em;
  color: #e6ecff;
  pointer-events: none;
  z-index: 5;
}
.surface-fx-label__mark { color: var(--fx); }
.surface-fx-label__cat {
  color: var(--fx);
  font-size: 9.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* Wer Bewegung abbestellt hat, bekommt auch hier einen ruhigen Schimmer
   statt gar nichts - dieselbe Regel wie bei `.planet-fx`. */
@media (prefers-reduced-motion: reduce) {
  .surface-fx,
  .surface-fx::before,
  .surface-fx::after { animation: none; }
  .surface-fx { opacity: .35; }
  .surface-fx--energy::before,
  .surface-fx--energy::after { opacity: .5; }
}

/* ====================================================================
   ORGANISATIONS-BUERO (Nutzervorgabe 2026-09-05, Vorlage
   _Design-Vorlage/weltraumspiel-starcontrol/project/Organisationsbuero.dc.html)

   Farben, Abstaende und Rasterbreiten sind aus der Vorlage uebernommen; sie
   arbeitet mit Inline-Stilen, hier stehen Klassen (Projektkonvention).

   Praefix `orgb-`, damit die aelteren `org-`-Klassen der Nichtmitglieder-
   Ansicht (Suche, Gruenden, offene Einladungen) unberuehrt bleiben - die
   Vorlage sagt zu jenem Zustand nichts.
   ==================================================================== */

.orgb {
  display: flex;
  flex-direction: column;
  gap: 9px;
  color: #cdd6f0;
  font-family: 'Chakra Petch', sans-serif;
}

/* --- Kopfzeile ------------------------------------------------------ */

.orgb-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 16px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(120, 180, 255, .16);
}
.orgb-head__title {
  flex: none;
  font-weight: 700;
  font-size: 20px;
  letter-spacing: .06em;
  color: #e9edfb;
}
.orgb-head__meta {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 14px;
  min-width: 0;
}
.orgb-head__key { font-size: 10.5px; letter-spacing: .13em; color: #63709a; }
.orgb-head__val { font-weight: 600; font-size: 13.5px; letter-spacing: .07em; }
.orgb-head__sep { font-family: 'Share Tech Mono', monospace; font-size: 12px; color: #39415e; }

/* --- Karten und Reihen ---------------------------------------------- */

.orgb-row1,
.orgb-row2 {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
}
/* Die Vorlage gibt beiden Spalten dieselbe Mindestbreite und laesst sie ab
   etwa 780 px umbrechen - das ist der Punkt, an dem eine Tabelle mit vier
   Spalten nebeneinander nicht mehr lesbar waere. */
.orgb-row1 > * { flex: 1 1 380px; min-width: 0; }
.orgb-row2 > * { flex: 1 1 340px; min-width: 0; }
.orgb-col { display: flex; flex-direction: column; gap: 9px; }

.orgb-card {
  border: 1px solid rgba(120, 180, 255, .14);
  border-radius: 9px;
  background: rgba(11, 14, 27, .72);
  padding: 11px 13px;
  box-sizing: border-box;
}
/* Die Identitaetskarte ist die einzige mit eigener Faerbung - sie traegt den
   Namen der Organisation und soll als erstes ins Auge fallen. */
.orgb-card--ident {
  align-self: flex-start;
  border-color: rgba(127, 233, 255, .3);
  border-radius: 11px;
  background: linear-gradient(155deg, rgba(22, 44, 80, .72), rgba(11, 14, 27, .8));
  box-shadow: 0 0 28px rgba(30, 80, 140, .14);
  padding: 15px 17px;
}
.orgb-card--depot {
  border-color: rgba(120, 180, 255, .2);
  background: linear-gradient(170deg, rgba(16, 30, 56, .6), rgba(11, 14, 27, .75));
}
.orgb-card--table {
  display: flex;
  flex-direction: column;
  min-height: 560px;
}

.orgb-card__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  padding-bottom: 9px;
  border-bottom: 1px solid rgba(120, 180, 255, .1);
}
.orgb-card__head--stacked { flex-direction: column; align-items: stretch; gap: 7px; }
.orgb-card__headline { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.orgb-card__title {
  flex: 1;
  font-weight: 600;
  font-size: 11.5px;
  letter-spacing: .11em;
  color: #dbe3f7;
  min-width: 0;
}
.orgb-card__hint {
  font-family: 'Share Tech Mono', monospace;
  font-size: 9px;
  color: #4d5878;
  white-space: nowrap;
}

/* --- Identitaetskarte ----------------------------------------------- */

.orgb-ident { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.orgb-emblem {
  width: 46px;
  height: 46px;
  flex: none;
  animation: orgbSpin 80s linear infinite;
}
@keyframes orgbSpin { from { transform: rotate(0); } to { transform: rotate(360deg); } }

.orgb-ident__text { flex: 1; min-width: 0; }
.orgb-ident__name {
  font-weight: 700;
  font-size: 24px;
  letter-spacing: .05em;
  color: #eaf6ff;
  line-height: 1.1;
}
.orgb-ident__tag { font-size: 15px; color: #7fa8d8; }
.orgb-ident__sub {
  display: flex;
  align-items: baseline;
  gap: 9px;
  flex-wrap: wrap;
  margin-top: 4px;
}
/* Steht an der Stelle, an der die Vorlage die "Doktrin" zeigt - das Spiel
   kennt kein solches Feld, wohl aber eine frei gewaehlte Beschreibung. */
.orgb-ident__doctrine { font-size: 11px; letter-spacing: .1em; color: #8fb6d8; }
.orgb-ident__founded {
  font-family: 'Share Tech Mono', monospace;
  font-size: 10px;
  color: #4d5878;
}

.orgb-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px;
  margin-top: 14px;
}
.orgb-stat {
  min-width: 0;
  border: 1px solid rgba(120, 180, 255, .16);
  border-radius: 7px;
  background: rgba(9, 13, 26, .62);
  padding: 8px 9px;
}
.orgb-stat__label {
  font-size: 8.5px;
  letter-spacing: .1em;
  color: #63709a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.orgb-stat__value {
  font-family: 'Share Tech Mono', monospace;
  font-size: 17px;
  margin-top: 3px;
}

/* --- Knoepfe --------------------------------------------------------- */

.orgb-btnrow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-top: 13px;
  padding-top: 12px;
  border-top: 1px solid rgba(120, 180, 255, .12);
}
.orgb-btnrow__right { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }

.orgb-btn {
  flex: 0 1 auto;
  white-space: nowrap;
  /* Nutzerbefund 2026-09-06: "Mitglied einladen und Anfragen haben keinen
     Rahmen". Er war da, nur mit 24 % Deckkraft - neben AUSTRETEN und
     AUFLOESEN, die farbige Rahmen tragen, las sich das wie gar keiner. */
  border: 1px solid rgba(120, 180, 255, .45);
  border-radius: 7px;
  background: rgba(16, 22, 40, .7);
  color: #a5b1cf;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 10.5px;
  letter-spacing: .1em;
  padding: 8px 14px;
  cursor: pointer;
}
.orgb-btn:hover:not(:disabled) { border-color: rgba(127, 233, 255, .5); color: #dcecff; }
.orgb-btn:focus-visible { outline: 2px solid #7fe9ff; outline-offset: 2px; }
.orgb-btn--primary {
  border-color: rgba(127, 233, 255, .55);
  background: rgba(20, 48, 80, .7);
  color: #c8f2ff;
  font-weight: 600;
  font-size: 11px;
  padding: 8px 16px;
}
.orgb-btn--good { border-color: rgba(95, 216, 138, .45); background: rgba(16, 44, 32, .6); color: #9be6b6; }
.orgb-btn--warn { border-color: rgba(224, 164, 74, .4); background: rgba(38, 26, 10, .6); color: #e8c489; }
.orgb-btn--danger { border-color: rgba(224, 90, 74, .45); background: rgba(44, 14, 12, .6); color: #ffb3a4; }
.orgb-btn--off,
.orgb-btn:disabled {
  border-color: rgba(120, 180, 255, .14);
  background: rgba(16, 20, 34, .6);
  color: #5d6786;
  cursor: not-allowed;
}
.orgb-btn__num { font-family: 'Share Tech Mono', monospace; color: #8fd8ff; }

/* Rueckmeldung der Live-Pruefung von Name und Kuerzel im Gruendungsformular
   (Nutzerwunsch 2026-09-06). Sie sitzt direkt unter dem jeweiligen Feld und
   bleibt leer, solange nichts eingetippt wurde - eine Zeile, die dauerhaft
   Platz belegt, machte das Formular ohne Gegenwert laenger. */
.org-found-check {
  min-height: 15px;
  margin-top: 5px;
  font-size: 11.5px;
  line-height: 15px;
  color: var(--text-muted);
}
.org-found-check--ok { color: #5fd88a; }
.org-found-check--error { color: #e05a4a; }
.org-found-check--pending { color: var(--text-muted); font-style: italic; }

/* --- Depot-Kachel ---------------------------------------------------- */

.orgb-flows { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }
.orgb-flow {
  flex: 1 1 130px;
  min-width: 0;
  border: 1px solid color-mix(in srgb, var(--flow) 32%, transparent);
  border-radius: 7px;
  background: color-mix(in srgb, var(--flow) 8%, rgba(11, 14, 27, .6));
  padding: 8px 9px;
}
.orgb-flow__head { display: flex; align-items: center; gap: 6px; }
.orgb-flow__head svg { width: 13px; height: 13px; flex: none; }
.orgb-flow__head span {
  flex: 1;
  font-size: 10px;
  letter-spacing: .09em;
  color: var(--flow);
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.orgb-flow__value {
  font-family: 'Share Tech Mono', monospace;
  font-size: 15px;
  color: var(--flow);
  margin-top: 5px;
}
.orgb-flow__bar { height: 3px; border-radius: 2px; margin-top: 4px; }
.orgb-flow__note { font-size: 8.5px; color: #6b7594; margin-top: 4px; text-wrap: pretty; }

/* --- Steuerkachel ----------------------------------------------------- */

/* Die grosse Prozentzahl der Vorlage ist hier zugleich das Eingabefeld -
   deshalb saemtliche Feldrahmen weg, sie soll wie reiner Text wirken. */
.orgb-tax__big {
  width: 3.2em;
  border: none;
  background: none;
  font-family: 'Share Tech Mono', monospace;
  font-size: 18px;
  text-align: right;
  padding: 0;
  -moz-appearance: textfield;
  appearance: textfield;
}
.orgb-tax__big::-webkit-outer-spin-button,
.orgb-tax__big::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.orgb-tax__big:focus-visible { outline: 1px solid #7fe9ff; outline-offset: 3px; border-radius: 3px; }
.orgb-tax__big:disabled { opacity: .6; }
.orgb-tax__pct { font-family: 'Share Tech Mono', monospace; font-size: 18px; color: #7fe9ff; }

.orgb-tax__row {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 9px;
  flex-wrap: wrap;
}
.orgb-tax__end {
  flex: none;
  font-family: 'Share Tech Mono', monospace;
  font-size: 9.5px;
  color: #4d5878;
}
.orgb-tax__range {
  flex: 1;
  min-width: 120px;
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(90deg, #7fe9ff, #2c4a72);
  outline: none;
}
.orgb-tax__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #0b0e1b;
  border: 2px solid #7fe9ff;
  box-shadow: 0 0 8px rgba(127, 233, 255, .7);
  cursor: pointer;
}
.orgb-tax__range:disabled { opacity: .45; }
.orgb-tax__range:focus-visible { outline: 2px solid #7fe9ff; outline-offset: 3px; }

.orgb-tax__presets {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 9px;
}
.orgb-tax__spacer { flex: 1; min-width: 0; }
.orgb-preset {
  flex: 0 1 auto;
  white-space: nowrap;
  border: 1px solid rgba(120, 180, 255, .16);
  border-radius: 6px;
  background: rgba(18, 24, 44, .6);
  color: #8b96ba;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 9.5px;
  letter-spacing: .09em;
  padding: 5px 11px;
  cursor: pointer;
}
.orgb-preset--on { border-color: rgba(127, 233, 255, .55); background: rgba(40, 74, 120, .65); color: #c8f2ff; }
.orgb-preset:disabled { opacity: .45; cursor: not-allowed; }
.orgb-preset:focus-visible { outline: 2px solid #7fe9ff; outline-offset: 2px; }

.orgb-tax__yield {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-top: 9px;
  font-size: 9px;
  letter-spacing: .09em;
  color: #63709a;
}
.orgb-tax__yieldval { font-family: 'Share Tech Mono', monospace; font-size: 13px; color: #5fd88a; }
.orgb-tax__hint { font-size: 9.5px; color: #6b7594; margin: 8px 0 0; text-wrap: pretty; }

/* --- Tabellen --------------------------------------------------------- */

.orgb-table {
  flex: 1;
  min-height: 200px;
  min-width: 0;
  overflow: auto;
}

.orgb-row {
  display: grid;
  gap: 0 7px;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid rgba(120, 180, 255, .05);
  animation: orgbFade .3s ease-out;
}
@keyframes orgbFade {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Die Mindestbreiten stammen aus der Vorlage. Sie sind der Grund, warum die
   Tabelle einen eigenen Scrollbereich hat: Unter dieser Breite werden die
   Zahlenspalten unlesbar, ein Umbruch waere schlechter als seitliches
   Schieben. */
/* Die letzte Spalte traegt seit dem 2026-09-06 beschriftete Rollenknoepfe
   ("Befoerdern"/"Degradieren") plus den Papierkorb. Mit den alten 44 Pixeln -
   ausgelegt auf zwei einzelne Zeichen - liefen sie in die Beitragsspalte
   hinein (Nutzerbefund: "diese ueberlappen nun die Beitraege"). Die Zeile
   bekommt die Breite deshalb wirklich zugeteilt, statt sie sich zu nehmen.

   SEIT DEM 2026-09-14 sind es 190 statt 124 Pixel: Der Umzugsknopf vom
   2026-09-12 kam dazu, ohne dass die Spalte mitwuchs (Nutzerbefund: "der
   neue umzugs button hat die spalte aber nicht mit vergroessert"). Drei
   beschriftete Knoepfe nebeneinander - Befoerdern, Umzug, Papierkorb -
   brauchen diese Breite. Die Mindestbreite der Tabelle waechst um denselben
   Betrag mit, sonst holt sich die Spalte den Platz wieder von den Zahlen.

   DIE AKTIONSSPALTE BLEIBT BEI 190. Sie war am 2026-09-14 kurzzeitig auf
   250, weil die Umzugsmarke mit ihrer Restzeit ("Unterwegs: 1T 05h") dort
   mit drinstand und die Spalte sprengte. Die Marke ist noch am selben Tag in
   eine eigene STATUS-Spalte neben dem Namen gewandert (Nutzerwunsch: "ich
   würde das unterwegs und angefragt auch aus dem action bereich rausnehmen
   und eine zusätzliche status spalte neben dem namen platzieren"), und damit
   trägt diese Spalte wieder nur Knöpfe: Befördern, Umzug, Papierkorb. */
.orgb-row--member {
  min-width: 586px;
  grid-template-columns: minmax(96px, 1fr) 120px 46px 72px 58px 190px;
}
/* Mit Lagespalte (Lagezentrum Stufe 2, 2026-09-12). Eine EIGENE Regel statt
   einer nachtraeglich eingefuegten Spalte in der Zeile darueber: Ohne
   Lagezentrum soll die Tabelle exakt so aussehen wie vorher. */
.orgb-row--member-lage {
  min-width: 658px;
  grid-template-columns: minmax(96px, 1fr) 120px 72px 46px 72px 58px 190px;
}

/* Die Statusspalte (2026-09-14). 120 Pixel tragen "Umzug in: 1T 05h" in
   einer Zeile - die Marke darf nicht umbrechen, ein Bruch mitten in der
   Restzeit sähe aus wie zwei Angaben.

   LEER IST DER NORMALFALL: Die meisten Mitglieder ziehen gerade nicht um.
   Deshalb keine Trennlinie und kein Platzhalterstrich - eine Spalte voller
   Bindestriche wäre lauter als die eine Zeile, um die es geht. */
.orgb-row__status {
  min-width: 0;
  display: flex;
  align-items: center;
}
.orgb-row__status:empty { display: block; }
.orgb-row__lage {
  justify-self: start;
  padding: 2px 6px;
  border: 1px solid rgba(120, 180, 255, .18);
  background: rgba(14, 20, 36, .7);
  font-family: 'Share Tech Mono', monospace;
  font-size: 8.5px;
  letter-spacing: .08em;
  white-space: nowrap;
  cursor: pointer;
  transition: background .15s ease, box-shadow .15s ease;
}
.orgb-row__lage:hover,
.orgb-row__lage:focus-visible { background: rgba(70, 217, 208, .12); box-shadow: 0 0 8px rgba(70, 217, 208, .25); }
/*
 * Die eigene Zeile traegt seit 2026-09-13 die WIRKLICHE Warnstufe, nicht nur
 * das Wort "EIGENE" (Nutzerbefund: "dort auch die aktuelle Lage anzeigen").
 * Farbe und Rahmen kommen deshalb aus der Stufe selbst - die Regel hier setzt
 * nur noch den Rueckfall, wenn keine Stufe geliefert wurde.
 */
.orgb-row__lage--self { color: #8fd8ff; border-color: rgba(143, 216, 255, .3); }
/* Das Woertchen daneben bleibt lesbar, tritt aber hinter die Stufe zurueck. */
.orgb-row__lage-own {
  margin-left: 5px;
  opacity: .55;
  font-size: 7.5px;
  letter-spacing: .06em;
}
/* Kein Anschluss: kein Rahmen, kein Zeiger - es gibt dort nichts zu oeffnen. */
.orgb-row__lage--off {
  border-color: transparent;
  background: none;
  color: #4d5878;
  cursor: default;
}
.orgb-row__lage--off:hover { background: none; box-shadow: none; }
.orgb-row--tx {
  min-width: 330px;
  grid-template-columns: 56px minmax(96px, 1fr) 78px 72px;
}
/* Die Freund/Feind-Tabelle (Spec 2026-09-19). Vier Spalten plus Aktionen -
   dieselbe Bauform wie die Bewegungen darueber. */
.orgb-row--standing {
  min-width: 330px;
  grid-template-columns: minmax(96px, 1fr) 84px 74px 74px 88px;
}
/* Zwei Karten teilen die rechte Spalte, also je halbe Hoehe (Nutzervorgabe:
   "Die Liste Bewegungen halbieren"). Der Deckel greift nur, wo genug Platz
   ist - auf dem Telefon stapeln die Karten ohnehin. */
@media (min-width: 900px) {
  .orgb-row2 .orgb-col > .orgb-card--table { max-height: 46vh; }
  .orgb-row2 .orgb-col > .orgb-card--table .orgb-table { overflow-y: auto; }
}
.orgb-row__home,
.orgb-row__standing,
.orgb-row__by {
  font-size: 10.5px;
  color: #8b96ba;
  align-self: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.orgb-row__standing {
  font-family: 'Chakra Petch', sans-serif;
  letter-spacing: .06em;
}
.orgb-standingbtn {
  border: 1px solid rgba(120, 180, 255, .22);
  border-radius: 5px;
  background: rgba(255, 255, 255, .03);
  padding: 3px 6px;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
}
.orgb-standingbtn:hover:not(:disabled) { background: rgba(255, 255, 255, .09); }
.orgb-standingbtn.is-on {
  border-color: currentColor;
  background: rgba(255, 255, 255, .07);
  cursor: default;
}
.orgb-standingbtn:disabled { opacity: .75; }
.orgb-row--standing .orgb-row__actions {
  display: flex;
  gap: 3px;
  justify-content: flex-end;
}
.orgb-row--head {
  position: sticky;
  top: 0;
  background: rgba(11, 14, 27, .96);
  padding: 8px 0 6px;
  border-bottom: 1px solid rgba(120, 180, 255, .1);
  font-size: 8px;
  letter-spacing: .09em;
  color: #63709a;
  animation: none;
}

.orgb-row__ident { display: flex; align-items: center; gap: 7px; min-width: 0; }
.orgb-dot {
  width: 6px;
  height: 6px;
  flex: none;
  transform: rotate(45deg);
  background: #3f4a68;
}
.orgb-dot--live { background: #5fd88a; animation: orgbPulse 3s ease-in-out infinite; }
@keyframes orgbPulse { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }

.orgb-row__names { min-width: 0; }
.orgb-row__name {
  display: block;
  font-size: 11px;
  letter-spacing: .04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.orgb-row__rank { display: block; font-size: 8.5px; letter-spacing: .08em; }

.orgb-row__num {
  text-align: right;
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  white-space: nowrap;
}
.orgb-row__tax { color: #8fd8ff; }
.orgb-row__contrib { color: #dbe3f7; }
.orgb-row__seen { color: #5d6786; font-size: 10px; }
.orgb-row__balance { color: #8b96ba; font-size: 10px; }
.orgb-row__time { font-family: 'Share Tech Mono', monospace; font-size: 10px; color: #4d5878; }

.orgb-row__who { min-width: 0; }
.orgb-row__whoname {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font-size: 10.5px;
  color: #dbe3f7;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.orgb-tick { width: 5px; height: 5px; flex: none; transform: rotate(45deg); }
.orgb-row__item {
  display: block;
  font-size: 9px;
  color: #5d6786;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-left: 11px;
}

.orgb-row__actions { display: flex; justify-content: flex-end; gap: 3px; }
.orgb-rowbtn {
  border: 1px solid rgba(120, 180, 255, .2);
  border-radius: 5px;
  background: rgba(18, 24, 44, .6);
  color: #8b96ba;
  font-size: 10px;
  line-height: 1;
  padding: 4px 6px;
  cursor: pointer;
}
.orgb-rowbtn:hover { border-color: rgba(127, 233, 255, .5); color: #dcecff; }
.orgb-rowbtn--danger:hover { border-color: rgba(224, 90, 74, .55); color: #ffb3a4; }
/* Beschriftete Zeilenknoepfe (Nutzerwunsch 2026-09-06). Die Grundregel ist
   auf ein einzelnes Zeichen zugeschnitten - ein Wort braucht mehr Luft und
   darf nicht umbrechen, sonst wird die Mitgliederzeile doppelt hoch. */
.orgb-rowbtn--label {
  padding: 4px 8px;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 9.5px;
  letter-spacing: .03em;
  white-space: nowrap;
}
/* Der Papierkorb bleibt quadratisch - er soll neben dem Wort nicht wie ein
   zweiter Textknopf wirken. */
.orgb-rowbtn .ph { font-size: 12px; display: block; }
.orgb-rowbtn--good { border-color: rgba(95, 216, 138, .4); color: #9be6b6; }
.orgb-rowbtn--good:hover { border-color: rgba(95, 216, 138, .7); color: #b8f0cd; }
.orgb-rowbtn--danger { border-color: rgba(224, 90, 74, .35); color: #d79a90; }
.orgb-rowbtn:focus-visible { outline: 2px solid #7fe9ff; outline-offset: 2px; }
/* Der offene Umzugsstand an der Stelle, an der sonst der Umzugsknopf steht
   (Nutzerwunsch 2026-09-13). BEWUSST KEIN KNOPFAUSSEHEN: Es gibt hier nichts
   zu klicken - ein ausgegrauter Knopf laedt zum Klicken ein und erzeugte nur
   eine Fehlermeldung, weil der Server nur EINEN offenen Vorgang je Mitglied
   zulaesst. Dieselben Masse wie .orgb-rowbtn--label, damit die Zeile nicht
   springt, wenn der Knopf zur Marke wird. */
.orgb-rowstate {
  padding: 4px 8px;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 9.5px;
  letter-spacing: .03em;
  line-height: 1;
  white-space: nowrap;
  color: #7f8bb0;
  border: 1px dashed rgba(120, 180, 255, .22);
  border-radius: 5px;
  cursor: default;
}

.orgb-empty { padding: 18px 0; font-size: 10.5px; color: #5d6786; text-align: center; }

/* --- Filterreiter und Blaetterung -------------------------------------- */

.orgb-tabs { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
.orgb-tab {
  flex: 0 1 auto;
  white-space: nowrap;
  border: 1px solid rgba(120, 180, 255, .16);
  border-radius: 6px;
  background: rgba(18, 24, 44, .6);
  color: #8b96ba;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 9.5px;
  letter-spacing: .1em;
  padding: 5px 11px;
  cursor: pointer;
}
.orgb-tab--on { border-color: rgba(127, 233, 255, .5); background: rgba(40, 74, 120, .6); color: #c8f2ff; }
.orgb-tab:focus-visible { outline: 2px solid #7fe9ff; outline-offset: 2px; }

.orgb-pager {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding-top: 9px;
  border-top: 1px solid rgba(120, 180, 255, .1);
}
.orgb-pager__range { font-size: 9px; letter-spacing: .09em; color: #63709a; white-space: nowrap; }
.orgb-pager__nav { display: flex; align-items: center; gap: 6px; }
.orgb-pager__label {
  font-family: 'Share Tech Mono', monospace;
  font-size: 10.5px;
  color: #8b96ba;
  white-space: nowrap;
}
.orgb-pagebtn {
  border: 1px solid rgba(127, 233, 255, .4);
  border-radius: 6px;
  background: rgba(18, 24, 44, .6);
  color: #c8f2ff;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 11px;
  padding: 4px 12px;
  cursor: pointer;
}
.orgb-pagebtn--off { border-color: rgba(120, 180, 255, .12); color: #3f4a68; cursor: not-allowed; }
.orgb-pagebtn:focus-visible { outline: 2px solid #7fe9ff; outline-offset: 2px; }

.orgb-txactions {
  flex: none;
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
  padding-top: 9px;
}
.orgb-txnote { flex: none; font-size: 9px; color: #6b7594; padding-top: 6px; margin: 0; }

/* Wer Bewegung abbestellt hat, bekommt die Karte ruhig: das kreisende
   Emblem, das Pulsieren der Online-Punkte und das Einblenden der Zeilen sind
   Schmuck, keine Auskunft. */
@media (prefers-reduced-motion: reduce) {
  .orgb-emblem,
  .orgb-dot--live,
  .orgb-row { animation: none; }
}

/* ====================================================================
   SEITENLEISTE DER STERNENKARTE: INHALTE MITWACHSEN LASSEN
   (Nutzervorgabe 2026-09-05: "Seitenleiste 20% vergroessern. Alle Inhalte
   der Tabs jeweils auch vergroessern, damit sie davon profitieren.")

   Die Leiste steht jetzt auf 562 px statt 468. Ohne diesen Block waere der
   Gewinn nur Leerraum rechts: die Schriftgroessen der Reiterinhalte sind
   ueberall fest in px gesetzt, sie wachsen nicht von selbst mit.

   ALLES HIER IST AUF `.starmap-sidepanel` GESCHACHTELT. Mehrere der
   betroffenen Klassen (`.starmap-info-panel`, `.starmap-shippanel`) werden
   auch ausserhalb der Leiste verwendet - in der Systemansicht und im
   Kartenmodal. Eine globale Erhoehung haette dort Layouts gesprengt, die
   niemand angefasst hat.

   Der Faktor ist rund 1,15 und nicht 1,2: Schrift skaliert nicht linear mit
   der Flaeche. Bei vollem 1,2 wurden die Zahlenspalten der Kontaktliste im
   Test wieder zu eng - der Gewinn an Breite waere sofort wieder aufgebraucht.
   ==================================================================== */

.starmap-sidepanel .starmap-info-panel__eyebrow { font-size: 12px; }
.starmap-sidepanel .starmap-info-panel__title { font-size: 20px; }
.starmap-sidepanel .starmap-info-panel__hint { font-size: 12.5px; }
.starmap-sidepanel .starmap-info-panel__row { font-size: 13px; }
.starmap-sidepanel .starmap-info-panel__badge { font-size: 11.5px; }
.starmap-sidepanel .starmap-info-panel__center-btn,
.starmap-sidepanel .starmap-info-panel__open-btn { font-size: 13px; }

/* Der Navigator stand hier bis zum 2026-09-14 mit drin. Seit er als
   Ueberlagerung auf der Karte sitzt, trifft ihn keine dieser Regeln mehr -
   und er soll auch nicht mitwachsen: auf der Karte ist Platz das Knappe,
   nicht in der Leiste. Seine Groessen stehen bei .starmap-navigator. */

.starmap-sidepanel .starmap-fleet-selector__btn { font-size: 13.5px; }
.starmap-sidepanel .starmap-fleet-selector__item,
.starmap-sidepanel .starmap-fleet-selector__empty { font-size: 13px; }

.starmap-sidepanel .starmap-questlog__toggle { font-size: 13.5px; }
.starmap-sidepanel .starmap-questlog__title { font-size: 13px; }
.starmap-sidepanel .starmap-questlog__meta { font-size: 11.5px; }

/* Die Reiterbeschriftungen selbst. Vier Reiter waren mit 10 px in einer
   468er-Leiste knapp; in einer 562er ist Platz fuer lesbare Schrift. */
.starmap-sidepanel__tab { font-size: 11.5px; padding: 8px 5px; }
.starmap-sidepanel__tab-badge { font-size: 10.5px; }

.starmap-sidepanel .starmap-defcon__row,
.starmap-sidepanel .starmap-defcon__empty { font-size: 12.5px; }
.starmap-sidepanel .favorites-panel__name { font-size: 13px; }
.starmap-sidepanel .favorites-panel__note,
.starmap-sidepanel .favorites-panel__morelabel { font-size: 11.5px; }
.starmap-sidepanel .favorites-empty { font-size: 12.5px; }

/* ====================================================================
   AUFGEKLAPPTE FLOTTE: DEN PLATZ AUCH NUTZEN
   (Nutzerbefund 2026-09-05: "wenn man eine Flotte aufklappt ist der Inhalt
   zu schmal, obwohl rechts noch viel Platz ist.")

   Das Panel war eine einzige schmale Spalte aus Bezeichnung-Wert-Zeilen.
   Bei 562 px Leistenbreite blieb rechts die halbe Flaeche leer, waehrend
   die Namen links umbrachen.

   Zwei Spalten statt einer - aber NICHT fuer alles: Ueberschrift,
   Fortschrittsbalken und die Reiseblocks bleiben ueber die volle Breite.
   Ein Balken in einer halben Spalte liest sich schlechter als in einer
   ganzen, und die Reisezeile traegt einen Abbruchknopf.
   ==================================================================== */

.starmap-fleet-selector__item--expanded .starmap-shippanel {
  /* Die Zeilen sind Kinder des Panels, kein eigener Wrapper - deshalb legt
     das Raster ALLE Kinder und holt die Ausnahmen per span zurueck. */
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 18px;
  align-content: start;
}

/* Ueber die volle Breite: alles, was entweder eine Ueberschrift ist oder
   waagerecht Platz braucht. */
.starmap-fleet-selector__item--expanded .starmap-shippanel > .starmap-shippanel__head,
.starmap-fleet-selector__item--expanded .starmap-shippanel > .starmap-shippanel__type,
.starmap-fleet-selector__item--expanded .starmap-shippanel > .starmap-shippanel__more,
.starmap-fleet-selector__item--expanded .starmap-shippanel > .starmap-shippanel__creatures,
.starmap-fleet-selector__item--expanded .starmap-shippanel > .starmap-shippanel__travel,
.starmap-fleet-selector__item--expanded .starmap-shippanel > .starmap-info-panel__hint {
  /* `__travel` deckt BEIDE Blocks ab: der Dauerauftrag benutzt dieselbe
     Wurzelklasse mit einem Zusatz (`--mining-order`). */
  grid-column: 1 / -1;
}

/* Ein Balken gehoert unmittelbar unter SEINE Zeile. Im Raster stuende er
   sonst daneben - Schild-Balken neben Huellen-Beschriftung. Der Griff:
   Zeile und Balken teilen sich eine Zelle, indem der Balken die Zeile
   darueber nicht verlaesst. */
.starmap-fleet-selector__item--expanded .starmap-shippanel > .starmap-shippanel__bar {
  margin-top: 5px;
  align-self: start;
}

/* Die Schriftgroessen des Panels ziehen mit der Leiste mit. */
.starmap-fleet-selector__item--expanded .starmap-shippanel__name { font-size: 18px; }
/* Das Flaggschiff unter dem Flottennamen (2026-09-17): die Klasse traegt die
   Nebenrolle und wird deshalb gedaempft - der Name der Flotte soll die Zeile
   anfuehren, die Schiffsklasse sie nur ergaenzen. */
.starmap-shippanel__flagship-type { color: var(--text-dim); }
.starmap-fleet-selector__item--expanded .starmap-shippanel__type { font-size: 11.5px; }
.starmap-fleet-selector__item--expanded .starmap-shippanel__row { font-size: 12.5px; }
.starmap-fleet-selector__item--expanded .starmap-shippanel__row--sm { font-size: 11.5px; }
.starmap-fleet-selector__item--expanded .starmap-shippanel__ship-name { font-size: 12.5px; }
.starmap-fleet-selector__item--expanded .starmap-shippanel__ship-type { font-size: 10.5px; }
.starmap-fleet-selector__item--expanded .starmap-shippanel__ship-bar-label { font-size: 10px; }
.starmap-fleet-selector__item--expanded .starmap-shippanel__creature { font-size: 12.5px; }
.starmap-fleet-selector__item--expanded .starmap-shippanel__more > summary { font-size: 12px; }

/* Die Liste der weiteren Schiffe bekommt eigene zwei Spalten. Sie ist der
   laengste Teil des Panels und der, bei dem eine einzelne Spalte am meisten
   Platz verschenkt. */
.starmap-fleet-selector__item--expanded .starmap-shippanel__more[open] {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 18px;
}
.starmap-fleet-selector__item--expanded .starmap-shippanel__more[open] > summary {
  grid-column: 1 / -1;
}

/* Unter etwa 900 px Fensterbreite belegt die Leiste zu viel vom Bild, um
   noch zwei Spalten zu tragen - dann wieder einspaltig. */
@media (max-width: 900px) {
  .starmap-fleet-selector__item--expanded .starmap-shippanel,
  .starmap-fleet-selector__item--expanded .starmap-shippanel__more[open] {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ====================================================================
   ORGA-REITER DER STERNENKARTE (Nutzerwunsch 2026-09-05)

   Aufbau bewusst wie der DEFCON-Reiter daneben: eine Zeile je Eintrag mit
   Punkt, Namen, Kennzahl und Lokalisieren-Knopf. Zwei Listen im selben
   Reiter, die verschieden aussehen, waeren ohne Gewinn verschieden.
   ==================================================================== */

.starmap-orga__empty {
  padding: 14px 0;
  font-size: 12.5px;
  color: #8b96ba;
  text-wrap: pretty;
}
.starmap-orga__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 8px;
  margin-bottom: 4px;
  border-bottom: 1px solid rgba(120, 180, 255, .12);
}
.starmap-orga__name {
  font-weight: 700;
  font-size: 14px;
  letter-spacing: .06em;
  color: #e6ecff;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.starmap-orga__count {
  flex: none;
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  color: #63709a;
}
.starmap-orga__row {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0 9px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(120, 180, 255, .05);
}
.starmap-orga__dot {
  width: 7px;
  height: 7px;
  transform: rotate(45deg);
  background: #3f4a68;
}
.starmap-orga__dot--online { background: #5fd88a; }
.starmap-orga__ident { min-width: 0; }
.starmap-orga__player {
  display: block;
  font-size: 12.5px;
  color: #dbe3f7;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.starmap-orga__meta {
  display: block;
  font-size: 10.5px;
  letter-spacing: .05em;
  color: #5d6786;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.starmap-orga__role { color: #8fd8ff; }
.starmap-orga__role--leader { color: #5fd88a; }
.starmap-orga__points {
  font-family: 'Share Tech Mono', monospace;
  font-size: 11.5px;
  color: #aab4d4;
  text-align: right;
  white-space: nowrap;
}
.starmap-orga__locate {
  border: 1px solid rgba(127, 233, 255, .35);
  border-radius: 6px;
  background: rgba(18, 24, 44, .6);
  color: #7fe9ff;
  font-size: 11px;
  line-height: 1;
  padding: 5px 8px;
  cursor: pointer;
}
.starmap-orga__locate:hover { border-color: rgba(127, 233, 255, .7); color: #c8f2ff; }
.starmap-orga__locate:focus-visible { outline: 2px solid #7fe9ff; outline-offset: 2px; }
.starmap-orga__nolocate {
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  color: #3f4a68;
  padding: 0 8px;
}
/* Die eigene Zeile hebt sich ab - in einer Liste von zwanzig Namen sucht man
   sonst den eigenen. */
.starmap-orga__row--self .starmap-orga__player { color: #7fe9ff; font-weight: 600; }

/* ====================================================================
   FRACHTBRIEF IN DER FLUGBESTAETIGUNG (Nutzerwunsch 2026-09-05)

   "Falls man sich verklickt hat, hat man hier nochmal eine Uebersicht was
   ich da wegschicken will." Der Flottenname steht deshalb oben und gross -
   er beantwortet die eigentliche Frage; die Ladung darunter praezisiert.
   ==================================================================== */

.travel-confirm__fleet {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(120, 180, 255, .14);
  font-family: 'Chakra Petch', sans-serif;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .05em;
  color: #e6ecff;
}
.travel-confirm__fleet i { color: #7fe9ff; font-size: 16px; }
.travel-confirm__line { font-size: 12.5px; color: #aab4d4; text-wrap: pretty; }
/* Der Wachhinweis in der Flugbestaetigung (2026-09-10): Der Start hebt die
   Wache auf, und das darf nicht untergehen. */
.travel-confirm__line--warn { color: var(--accent-gold); display: flex; gap: 6px; align-items: baseline; margin-top: 6px; }
.travel-confirm__head {
  margin-top: 9px;
  font-size: 10px;
  letter-spacing: .12em;
  color: #63709a;
  text-transform: uppercase;
}
.travel-confirm__hint { margin-top: 9px; font-size: 12px; color: #8b96ba; }
.travel-confirm__list {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  /* Zwei Spalten: Eine Flotte mit acht verschiedenen Schiffstypen machte das
     Modal sonst hoeher als das Fenster. */
  columns: 2;
  column-gap: 18px;
}
.travel-confirm__list li {
  font-size: 12.5px;
  color: #dbe3f7;
  padding: 2.5px 0;
  break-inside: avoid;
}
.travel-confirm__count {
  display: inline-block;
  min-width: 2.4em;
  font-family: 'Share Tech Mono', monospace;
  color: #7fe9ff;
}
/* Ladung faellt auf - sie ist der Grund, warum es diesen Frachtbrief gibt. */
.travel-confirm__cargo { color: #e8c489; }
.travel-confirm__cargo .travel-confirm__count { color: #e0a44a; }

@media (max-width: 560px) {
  .travel-confirm__list { columns: 1; }
}

/* Favoritenmarker am Planeten (Nutzerwunsch 2026-09-05: "im Stil der
   Anomalien oder Aliens oder Artefakte"). Vierte Ecke - Lebensform oben
   links, Artefakt oben rechts, Anomalie unten rechts, Favorit unten links.

   KEIN PULS, anders als bei den drei Nachbarn: Ein Puls ist eine
   Aufforderung zu handeln. Ein Favorit fordert nichts, er ist eine Notiz -
   ein ruhiger Schimmer sagt genug. */
.starmap-favorite-marker {
  position: absolute;
  bottom: -7px;
  left: -9px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: rgba(6, 9, 20, 0.92);
  border: 1px solid #ffd76a;
  color: #ffd76a;
  font-size: 9px;
  line-height: 1;
  z-index: 7;
  box-shadow: 0 0 5px rgba(255, 215, 106, .55);
}

/* ====================================================================
   KAMPFPROTOKOLL: UMSCHALTER UND DETAIL-ANALYSE
   (Vorlage _Design-Vorlage/.../Kampfprotokoll.dc.html, Z.194-197 und
   Z.172-192; nachgereicht 2026-09-05)

   Der Bericht wurde am 2026-09-02 nach einem Screenshot derselben Vorlage
   gebaut, in dem dieser Reiter nicht zu sehen war. Die Vorlagendatei zeigt
   ihn: unter dem Kampfverlauf zwei Knoepfe, rechts daneben der Zeilenzaehler.
   ==================================================================== */

.cdeb-log__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px 10px;
  padding-top: 9px;
  margin-top: 2px;
  border-top: 1px solid var(--border);
}
.cdeb-log__views { display: flex; gap: 5px; flex-wrap: wrap; min-width: 0; }
.cdeb-log__view {
  padding: 6px 16px;
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.11em;
  color: var(--text-dim);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
}
.cdeb-log__view:hover { color: var(--text-body); border-color: var(--border-strong); }
.cdeb-log__view.is-active {
  color: var(--bg);
  background: var(--accent-bright);
  border-color: var(--accent-bright);
}
.cdeb-log__count {
  font-family: 'Share Tech Mono', monospace;
  font-size: 9.5px;
  color: var(--text-dim);
  white-space: nowrap;
}

/* Die Rundentabelle. Feste erste Spalte, der Rest teilt sich gleichmaessig -
   so stehen die Zahlenkolonnen unter ihren Ueberschriften. */
.cdeb-detail {
  min-width: 480px;
  font-family: 'Share Tech Mono', monospace;
}
.cdeb-detail__row {
  display: grid;
  grid-template-columns: 64px repeat(5, minmax(0, 1fr));
  gap: 0 8px;
  align-items: center;
  padding: 7px 0;
  border-bottom: 1px solid var(--border);
}
.cdeb-detail__row > span { text-align: right; font-size: 11.5px; color: var(--text-body); }
.cdeb-detail__row > span:first-child { text-align: left; }
.cdeb-detail__row--head {
  position: sticky;
  top: 0;
  background: var(--bg);
  border-bottom-color: var(--border-strong);
}
.cdeb-detail__row--head > span {
  font-family: var(--font-body, inherit);
  font-size: 8.5px;
  letter-spacing: 0.09em;
  color: var(--text-dim);
}
.cdeb-detail__n { color: #93a4cc; font-size: 11px; }
/* Zwei Richtungen, zwei Farben - dieselbe Zuordnung wie im Protokoll
   darueber: eigenes Feuer tuerkis, fremdes rot. */
.cdeb-detail__dmg-a { color: #7fe9ff; }
.cdeb-detail__dmg-d { color: #ff8b70; }
.cdeb-detail__loss { color: #e0a44a; }

.cdeb-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  margin-top: 12px;
}
.cdeb-stat {
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 7px);
  background: rgba(16, 21, 40, 0.55);
  padding: 9px 10px;
}
.cdeb-stat__label { font-size: 8.5px; letter-spacing: 0.1em; color: var(--text-dim); }
.cdeb-stat__value {
  font-family: 'Share Tech Mono', monospace;
  font-size: 15px;
  color: var(--text-body);
  margin-top: 4px;
}
.cdeb-stat__note { font-size: 9px; color: var(--text-dim); margin-top: 2px; }
.cdeb-stat--accent .cdeb-stat__value { color: #7fe9ff; }
.cdeb-stat--warn .cdeb-stat__value { color: #e0a44a; }
.cdeb-stat--bad .cdeb-stat__value { color: #ff8b70; }

/* Vier Kacheln nebeneinander brauchen Platz; darunter zwei Reihen zu zwei. */
@media (max-width: 900px) {
  .cdeb-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Tendenz je Runde am Rundenkopf (Vorlage Kampfprotokoll.dc.html Z.156).
   Gemessen am Huellenschaden der Runde - siehe roundTide(). */
.cdeb-round__tide {
  margin-left: auto;
  font-family: 'Share Tech Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.cdeb-round__tide--attacker { color: #7fe9ff; }
.cdeb-round__tide--defender { color: #ff8b70; }
.cdeb-round__tide--even { color: var(--text-dim); }

/* ====================================================================
   ORGANISATIONS-BUERO: IDENTITAETSKARTE UEBERARBEITET
   (Nutzerwunsch 2026-09-05: "es gibt nur ein Feld fuer Ressourcen. Es
   sollten aber alle Ressourcen aufgelistet werden. Daher alle Boxen ein
   wenig kleiner und einen extra Bereich fuer alle Ress-Typen. Steuersatz
   kann ich raus. Die Schrift der Tabellen ein wenig vergroessern.")

   Die Kachelreihe steht jetzt auf DREI statt zwei Spalten und ist flacher -
   der gewonnene Platz traegt die Ressourcenliste darunter.
   ==================================================================== */

.orgb-card--ident .orgb-stats {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  margin-top: 11px;
}
.orgb-card--ident .orgb-stat { padding: 6px 8px; }
.orgb-card--ident .orgb-stat__value { font-size: 15px; margin-top: 2px; }

/* Emblem und Name etwas zurueckgenommen, damit die Karte nicht laenger
   wird als ihre Nachbarin. */
.orgb-card--ident .orgb-emblem { width: 38px; height: 38px; }
.orgb-card--ident .orgb-ident__name { font-size: 21px; }

/* --- Die Ressourcenliste -------------------------------------------- */

.orgb-resblock {
  margin-top: 11px;
  padding-top: 10px;
  border-top: 1px solid rgba(120, 180, 255, .12);
}
.orgb-resblock__head {
  font-size: 8.5px;
  letter-spacing: .11em;
  color: #63709a;
  margin-bottom: 7px;
}
/* Zwei Spalten zu sechs Zeilen: Zwoelf Posten untereinander machten die
   Karte doppelt so hoch wie die Depot- und Steuerkachel daneben, und die
   Reihe braeche um. */
.orgb-reslist {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px 14px;
}
.orgb-res {
  display: grid;
  grid-template-columns: 13px minmax(0, 1fr) auto;
  align-items: center;
  gap: 0 7px;
  padding: 3px 0;
  border-bottom: 1px solid rgba(120, 180, 255, .05);
}
.orgb-res i { font-size: 12px; line-height: 1; }
.orgb-res__label {
  font-size: 10.5px;
  letter-spacing: .03em;
  color: #b7c2de;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.orgb-res__value {
  font-family: 'Share Tech Mono', monospace;
  font-size: 11.5px;
  color: #dbe3f7;
  text-align: right;
  white-space: nowrap;
}
/* Leere Posten stehen matt - die Liste soll auf einen Blick zeigen, wo
   etwas liegt, ohne die Nullen ganz zu verschweigen. */
.orgb-res--empty i,
.orgb-res--empty .orgb-res__label { opacity: .38; }
.orgb-res--empty .orgb-res__value { color: #3f4a68; }

@media (max-width: 620px) {
  .orgb-reslist { grid-template-columns: minmax(0, 1fr); }
  .orgb-card--ident .orgb-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- Tabellenschrift ------------------------------------------------ */

/* Die beiden grossen Tabellen standen auf 8-11 px. In einer Karte, die
   ueber die halbe Breite geht, ist das unnoetig klein - der Platz ist da. */
.orgb-row--head { font-size: 9.5px; }
.orgb-row__name { font-size: 12.5px; }
.orgb-row__rank { font-size: 9.5px; }
.orgb-row__num { font-size: 12.5px; }
.orgb-row__seen,
.orgb-row__balance { font-size: 11.5px; }
.orgb-row__time { font-size: 11.5px; }
.orgb-row__whoname { font-size: 12px; }
.orgb-row__item { font-size: 10.5px; }
.orgb-card__title { font-size: 12.5px; }
.orgb-card__hint { font-size: 10px; }
.orgb-empty { font-size: 12px; }

/* Wer an einem Heimatstern sitzt (Nutzerwunsch 2026-09-06: "[SdS] - Kora
   in blauer Schrift unter oder oberhalb des Heimatsterns").

   Blau und eine Spur kleiner als der Systemname: Der Stern hat einen Namen,
   der Spieler ist die Zusatzauskunft - die Farbe trennt beide, ohne dass man
   hinsehen muss. */
.starmap-home-owner {
  position: absolute;
  left: 50%;
  white-space: nowrap;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 9.5px;
  letter-spacing: .05em;
  color: #6fb4ff;
  text-shadow: 0 0 6px #000, 0 0 6px #000;
  pointer-events: none;
}
/* Der eigene heller - in einer Organisation mit zwanzig Sternen sucht man
   sonst den eigenen. */
.starmap-home-owner--self { color: #9fd4ff; font-weight: 600; }

/* Herkunft der Zahl in der Ressourcenkachel (Nutzerwunsch 2026-09-06:
   "lass uns doch daneben 'Gebaeude' schreiben und darunter eine neue Zeile,
   was zuletzt mit der letzten Abbaufuhre reinkam").

   Sobald zwei Zahlen untereinander stehen, ist die Beschriftung zwingend -
   sonst sieht man zweimal "+500/h" und weiss nicht, was woher kommt. */
.resource-card__source {
  margin-left: 6px;
  font-size: 9px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #5d6786;
}
/* Der Abbau in der Farbe, die im Spiel ohnehin fuer Foerderung steht -
   dieselbe wie die Abbau-Menuepunkte und die Foerderziele auf der
   Planetenoberflaeche. Sie unterscheidet die Fuhre vom Gebaeudeertrag
   darueber, und das ist der ganze Zweck der zweiten Zeile. */
.resource-card__production--mining {
  margin-top: 2px;
  color: #e0a44a;
}
.resource-card__production--mining .resource-card__source { color: #8a6f45; }
/* Die Sichtgrenze eines Kameraden (Nutzerwunsch 2026-09-06: "mit
   Radiuslinien"). Gestrichelt und blau: Es ist nicht MEINE Grenze - eine
   durchgezogene Linie saehe aus wie eigenes Gebiet. */
.starmap-orgbubble {
  position: absolute;
  transform: translate(-50%, -50%);
  border: 1px dashed rgba(111, 180, 255, .38);
  border-radius: 50%;
  pointer-events: none;
  z-index: 6;
}

/* Flotten der Kameraden. Schmaler und blasser als die eigenen: fremde
   Verbaende, die man sehen, aber nicht steuern kann. */
.starmap-orgfleet {
  position: absolute;
  /* 7 px waren zu klein (Nutzerbefund 2026-09-10): Eine stehende Flotte liegt
     genau auf dem Heimatstern ihres Besitzers, und dessen Marker ist groesser
     und liegt darueber. */
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  background: #6fb4ff;
  box-shadow: 0 0 6px rgba(111, 180, 255, .8);
  transform: rotate(45deg);
  pointer-events: none;
  z-index: 7;
}
.starmap-orgfleet--moving { animation: orgFleetPulse 2.4s ease-in-out infinite; }
@keyframes orgFleetPulse {
  0%, 100% { opacity: .55; }
  50% { opacity: 1; }
}

/* Die Restzeit an der Reiselinie der Kameraden (Nutzerwunsch 2026-09-10).
   BLASS UND KLEIN: Sie soll ablesbar sein, ohne die Karte zu beherrschen -
   bei einer grossen Organisation liegen mehrere Linien uebereinander. Ihr
   z-index liegt ueber der Linie, aber unter den Systemmarkern. */
.starmap-orgtravel-eta {
  position: absolute;
  transform: translate(-50%, -50%);
  font-size: 9px;
  line-height: 1;
  padding: 1px 4px;
  border-radius: 3px;
  color: rgba(174, 210, 255, .92);
  background: rgba(6, 12, 24, .72);
  white-space: nowrap;
  pointer-events: none;
  z-index: 7;
}

.starmap-orgtravel {
  position: absolute;
  height: 1px;
  transform-origin: 0 50%;
  background: repeating-linear-gradient(
    90deg,
    rgba(111, 180, 255, .55) 0 7px,
    transparent 7px 14px
  );
  pointer-events: none;
  z-index: 6;
}

/* ══════════════════════════════════════════════════════════════════
   XENO-LABOR: VITRINE
   Port aus _Design-Vorlage/.../Xenolabor Vitrine.dc.html (2026-09-06).

   Zwei Abweichungen von der Vorlage, beide auf Nutzervorgabe:

   1. KEIN Bild-Upload. Die Vorlage nutzt <image-slot> mit Hochladefunktion;
      die Grafiken werden nachgereicht. Stattdessen steht ein Platzhalter mit
      dem Artnamen (.xl-card__slot).
   2. Das Steckbrief-MODAL bleibt unangetastet - dort soll spaeter ein Bild
      hinein, und der Umbau folgt erst mit den Grafiken.
   ══════════════════════════════════════════════════════════════════ */

@keyframes xlBlink { 0%, 44% { opacity: .15 } 50%, 94% { opacity: 1 } 100% { opacity: .15 } }
@keyframes xlBlinkSlow { 0%, 70% { opacity: .12 } 78%, 88% { opacity: .9 } 100% { opacity: .12 } }
@keyframes xlScan { 0% { transform: translateY(-100%) } 100% { transform: translateY(400%) } }
@keyframes xlNoise { 0% { background-position: 0 0, 0 0 } 100% { background-position: 0 14px, 9px -11px } }
@keyframes xlFlicker {
  0%, 100% { opacity: .5 } 12% { opacity: .85 } 24% { opacity: .35 }
  47% { opacity: .7 } 63% { opacity: .28 } 81% { opacity: .62 }
}
@keyframes xlSweep { 0% { left: -40% } 100% { left: 110% } }
@keyframes xlFade { 0% { opacity: 0; transform: translateY(6px) } 100% { opacity: 1; transform: translateY(0) } }
@keyframes xlSpin { from { transform: rotate(0) } to { transform: rotate(360deg) } }
@keyframes xlBars { 0% { transform: scaleY(.25) } 100% { transform: scaleY(1) } }

.xl-vitrine {
  font-family: 'Chakra Petch', sans-serif;
  color: #cdd6f0;
}

/* ---------------------------------------------------------- Kopfzeile */
.xl-head {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 14px 22px;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(70, 217, 208, .2);
}
.xl-head__titles { flex: 1 1 260px; min-width: 0; }
.xl-head__row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.xl-head__name { font-weight: 700; font-size: 25px; letter-spacing: .06em; color: #eafcfa; }
.xl-head__sub { font-size: 13px; letter-spacing: .14em; color: #46d9d0; }
.xl-head__hint { font-size: 11.5px; letter-spacing: .05em; color: #6b7594; margin-top: 4px; }

.xl-progress {
  flex: 1 1 300px;
  min-width: 0;
  border: 1px solid rgba(70, 217, 208, .22);
  border-radius: 9px;
  background: rgba(8, 20, 30, .66);
  padding: 10px 13px;
  box-sizing: border-box;
}
.xl-progress__top { display: flex; align-items: baseline; gap: 8px; }
.xl-progress__label { flex: 1; font-size: 9px; letter-spacing: .13em; color: #5d7d86; }
.xl-progress__count { font-family: 'Share Tech Mono', monospace; font-size: 15px; color: #46d9d0; }
.xl-progress__total { font-family: 'Share Tech Mono', monospace; font-size: 11px; color: #4d5878; }
.xl-progress__cells { display: flex; gap: 2px; margin-top: 8px; }
.xl-progress__cell { flex: 1; height: 9px; background: rgba(255, 255, 255, .07); }
.xl-progress__cell--on { background: #46d9d0; box-shadow: 0 0 7px rgba(70, 217, 208, .5); }
.xl-progress__cell--next { animation: xlBlink 1.4s steps(1, end) infinite; }
.xl-progress__foot { display: flex; justify-content: space-between; margin-top: 6px; }
.xl-progress__foot span { font-size: 9px; letter-spacing: .1em; color: #4d5878; }

/* Die Analysekammer - frei oder belegt. */
.xl-lab {
  flex: 0 1 220px;
  min-width: 0;
  border: 1px solid rgba(143, 224, 160, .3);
  border-radius: 9px;
  background: rgba(10, 28, 22, .6);
  padding: 10px 13px;
  box-sizing: border-box;
}
.xl-lab--busy { border-color: rgba(232, 150, 60, .34); background: rgba(34, 22, 8, .6); }
.xl-lab__row { display: flex; align-items: center; gap: 8px; }
.xl-lab__dot {
  width: 8px; height: 8px; flex: none; border-radius: 50%;
  background: #8fe0a0; box-shadow: 0 0 9px #8fe0a0;
  animation: xlBlinkSlow 3.6s ease-in-out infinite;
}
.xl-lab--busy .xl-lab__dot {
  background: #e8963c; box-shadow: 0 0 9px #e8963c;
  animation: xlBlink 1.2s steps(1, end) infinite;
}
.xl-lab__label { flex: 1; font-size: 9px; letter-spacing: .13em; color: #5d7d86; min-width: 0; }
.xl-lab__state { font-weight: 600; font-size: 11px; letter-spacing: .09em; color: #8fe0a0; white-space: nowrap; }
.xl-lab--busy .xl-lab__state { color: #e8963c; }
.xl-lab__note { font-size: 10px; color: #6b7594; margin-top: 6px; text-wrap: pretty; }

/* ------------------------------------------------------ Filterleiste */
.xl-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 9px; margin-top: 16px; }
.xl-bar__title { font-weight: 600; font-size: 13px; letter-spacing: .13em; color: #dbe3f7; }
.xl-bar__spacer { flex: 1; min-width: 0; }
.xl-filters { display: flex; flex-wrap: wrap; gap: 5px; }
.xl-filter {
  border: 1px solid rgba(120, 180, 255, .16);
  border-radius: 6px;
  background: rgba(14, 20, 34, .6);
  color: #8b96ba;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 9.5px;
  letter-spacing: .11em;
  padding: 6px 13px;
  cursor: pointer;
}
.xl-filter:hover { color: #cdd6f0; }
.xl-filter--on { border-color: rgba(70, 217, 208, .5); background: rgba(10, 52, 52, .7); color: #8ff0e8; }

/* ------------------------------------------------------- Leere Vitrine */
.xl-empty {
  margin-top: 18px;
  border: 1px solid rgba(70, 217, 208, .18);
  border-radius: 12px;
  background: linear-gradient(170deg, rgba(8, 22, 32, .7), rgba(6, 9, 18, .8));
  padding: 44px 26px;
  text-align: center;
}
.xl-empty__fig { position: relative; width: 118px; height: 118px; margin: 0 auto; }
.xl-empty__ring {
  position: absolute; inset: 0; border: 1px solid rgba(70, 217, 208, .3);
  border-radius: 50%; animation: xlSpin 26s linear infinite;
}
.xl-empty__ring--inner {
  inset: 18px; border: 1px dashed rgba(70, 217, 208, .22);
  animation: xlSpin 18s linear infinite reverse;
}
.xl-empty__core {
  position: absolute; inset: 40px; border-radius: 50%;
  background: radial-gradient(circle, rgba(70, 217, 208, .5), transparent 70%);
  animation: xlBlinkSlow 3.4s ease-in-out infinite;
}
.xl-empty__title { font-weight: 600; font-size: 16px; letter-spacing: .09em; color: #dbe3f7; margin-top: 20px; }
.xl-empty__text { font-size: 12px; color: #8b96ba; margin-top: 7px; }
.xl-empty__hint { font-size: 11.5px; color: #6b7594; margin-top: 3px; }

/* ------------------------------------------------------ Kartenraster */
.xl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
  gap: 13px;
  margin-top: 14px;
}

/* DIE KOMPAKTANSICHT (Nutzerwunsch 2026-09-13: "Button in Xeno-Labor, welches
   nur das Bild und die beiden Button anzeigt - die Infos dazwischen werden
   ausgeblendet").

   AM GITTER, NICHT AN DER KARTE: Die Karte wird unveraendert gebaut, das CSS
   entscheidet, was davon zu sehen ist. Ein zweiter Renderpfad in creatures.js
   waere die Stelle, an der die beiden Knoepfe oder ihre Ereignisbindungen
   verlorengingen.

   WAS BLEIBT: das Bild, der Name (Nutzerentscheidung - fuenfzig unbeschriftete
   Bilder waeren nicht auseinanderzuhalten), der laufende Fortschritt und der
   Handlungsknopf. WAS GEHT: die Seltenheits-/Gefahrenzeile und die
   Faktenliste - beides ist Information, kein Zugang.

   Der Handlungsknopf bleibt mit Absicht: Ohne ihn kaeme man in der
   Kompaktansicht an unbestimmte Arten gar nicht mehr heran, und der
   Umschalter waere eine Falle statt einer Erleichterung. Bei bereits
   bestimmten Arten liefert xlAktion() ohnehin null - dort bleiben also
   tatsaechlich nur Bild, Name und die beiden Knoepfe stehen. */
.xl-grid--kompakt .xl-card__meta,
.xl-grid--kompakt .xl-card__facts,
.xl-grid--kompakt .xl-card__sci { display: none; }

/* Die schmaleren Karten nutzen den gewonnenen Platz: Bei gleicher Gitterbreite
   passen mehr nebeneinander, statt dass jede Karte nur kuerzer wird. */
.xl-grid--kompakt { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); }

/* Der Umschalter in der Filterleiste. Abgesetzt durch einen Trennstrich: Er
   steht zwischen denselben Knoepfen, waehlt aber nichts aus - er aendert die
   Darstellung. */
.xl-filter--view { margin-left: 10px; border-left-width: 1px; }

.xl-card {
  position: relative;
  border: 1px solid rgba(120, 180, 255, .14);
  border-radius: 10px;
  background: linear-gradient(168deg, rgba(12, 18, 32, .7), rgba(6, 10, 20, .86));
  overflow: hidden;
  animation: xlFade .35s ease-out;
}

/* Der Schaukasten: 4:3, Ecken-Klammern, Rasterlinien darueber. */
.xl-card__glass {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: radial-gradient(ellipse at 50% 30%, rgba(30, 52, 74, .5), #05080f 78%);
}
.xl-card__lines {
  position: absolute; inset: 0; pointer-events: none; opacity: .55;
  background-image: repeating-linear-gradient(0deg, rgba(0, 0, 0, .34) 0 1px, transparent 1px 3px);
}
.xl-card__bracket { position: absolute; width: 13px; height: 13px; pointer-events: none; }
.xl-card__bracket--tl { left: 6px; top: 6px; border-left: 2px solid; border-top: 2px solid; }
.xl-card__bracket--tr { right: 6px; top: 6px; border-right: 2px solid; border-top: 2px solid; }
.xl-card__bracket--bl { left: 6px; bottom: 6px; border-left: 2px solid; border-bottom: 2px solid; }
.xl-card__bracket--br { right: 6px; bottom: 6px; border-right: 2px solid; border-bottom: 2px solid; }
.xl-card__leds { position: absolute; right: 8px; bottom: 8px; display: flex; gap: 3px; pointer-events: none; }
.xl-card__led { width: 4px; height: 4px; }
.xl-card__sweep {
  position: absolute; left: 0; right: 0; height: 26%; pointer-events: none;
  background: linear-gradient(180deg, transparent, rgba(70, 217, 208, .14), transparent);
}

/* Der Platzhalter statt des Bildes (siehe Kopfkommentar). */
/* Das freigestellte Wesen im Schaukasten (Nutzerlieferung 2026-09-11).
   `contain` statt `cover`: Die Sprites sind quadratisch, der Kasten ist 4:3 -
   zugeschnitten verloeren sie Fuehler und Beine, und genau die machen sie
   aus. Der Rest des Kastens bleibt sein eigener Farbverlauf. */
.xl-card__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 6px;
  filter: drop-shadow(0 3px 10px rgba(0, 0, 0, .6));
}
.xl-card__slot {
  position: absolute;
  inset: 8px;
  border: 1px dashed rgba(120, 180, 255, .2);
  border-radius: 5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px;
  box-sizing: border-box;
  text-align: center;
}
.xl-card__slot i { font-size: 26px; color: rgba(120, 180, 255, .3); }
.xl-card__slot span {
  font-family: 'Share Tech Mono', monospace;
  font-size: 8.5px;
  letter-spacing: .1em;
  color: #4d5878;
  overflow-wrap: anywhere;
}

/* Noch nicht bestimmt: Rauschen und ein flackerndes ??? */
.xl-card__mystery { position: absolute; inset: 0; }
.xl-card__noise {
  position: absolute; inset: 0;
  background-image:
    repeating-linear-gradient(0deg, rgba(120, 180, 255, .09) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(70, 217, 208, .07) 0 1px, transparent 1px 4px);
  animation: xlNoise 1.1s steps(4) infinite;
}
.xl-card__mysterybody {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px;
}
.xl-card__qm {
  font-family: 'Share Tech Mono', monospace;
  font-size: 34px; letter-spacing: .14em; color: #46d9d0;
  text-shadow: 0 0 16px rgba(70, 217, 208, .5);
  animation: xlFlicker 4.2s steps(8) infinite;
}
.xl-card__mysterylabel { font-size: 8.5px; letter-spacing: .16em; color: #4d5878; }

/* Der Fundort unter dem ??? (2026-09-12). Er steht bewusst IM Schaukasten und
   nicht im Kartenfuss: Solange die Art unbekannt ist, hat der Fuss nichts
   anzuzeigen - der Ort ist dort das einzige Wissen, das der Spieler ueberhaupt
   besitzt. */
.xl-card__origin {
  display: flex;
  align-items: center;
  gap: 4px;
  max-width: 92%;
  margin-top: 2px;
  padding: 3px 7px;
  border: 1px solid rgba(70, 217, 208, .22);
  background: rgba(8, 26, 30, .72);
  font-family: 'Share Tech Mono', monospace;
  font-size: 9px;
  letter-spacing: .06em;
  color: #7fd8d2;
}
.xl-card__origin i { font-size: 10px; flex: none; opacity: .8; }
.xl-card__originname {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.xl-card__originmore { flex: none; color: #4d5878; }

/* Ausladen laeuft: Bio-Analyse mit Balkenspiel. */
.xl-card__unloading {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 9px;
  background: radial-gradient(ellipse at 50% 45%, rgba(20, 74, 72, .62), rgba(5, 8, 15, .94) 74%);
}
.xl-card__bars { display: flex; align-items: flex-end; gap: 3px; height: 34px; }
.xl-card__bar {
  width: 5px; height: 100%; transform-origin: 50% 100%;
  background: linear-gradient(180deg, #8ff0e8, #1d6f6c);
}
.xl-card__unloading-title {
  font-family: 'Share Tech Mono', monospace; font-size: 10px;
  letter-spacing: .14em; color: #8ff0e8;
}
.xl-card__unloading-sub { font-size: 8.5px; letter-spacing: .12em; color: #5d7d86; }

/* Die zwei Banner am Schaukasten. */
.xl-card__flag {
  position: absolute; top: 12px;
  font-family: 'Share Tech Mono', monospace; font-size: 9px;
  letter-spacing: .14em; color: #06131c;
}
/* Das NEU-Faehnchen auf dem Bild ist seit dem 2026-09-13 nicht mehr in
   Gebrauch - das Zeichen sitzt jetzt am FORSCHER-LOG-Knopf, wo man es auch
   wegbekommt (siehe .xl-open--new). Die Regel bleibt fuer den Fall stehen,
   dass wieder eine Marke aufs Bild soll; das Blinken ist raus, es hat den
   Nutzer zum Suchen gebracht. */
.xl-card__flag--new {
  left: 0; background: #7fb0ff; padding: 3px 8px 3px 7px;
  box-shadow: 0 0 12px rgba(127, 176, 255, .5);
}

/* NEU am Forscher-Log (Nutzerwunsch 2026-09-13). Ruhig, nicht blinkend:
   "muss nicht blinken, einfach blau anzeigen". */
/* Was die Technologie bewirkt (Nutzerbefund 2026-09-13). Steht GANZ OBEN im
   Knoten, vor Beschreibung und Kosten: Die Wirkung ist der Grund, warum man
   forscht - die Kosten sind nur der Preis. */
.tech-node__axis {
  display: grid;
  gap: 3px;
  margin: 7px 0 2px;
}
.tech-node__axisrow {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 10.5px;
  line-height: 1.4;
  cursor: help;
}
.tech-node__axisrow .ph {
  color: var(--accent-green);
  font-size: 12px;
  flex: none;
}
.tech-node__axisval {
  font-family: var(--font-heading);
  font-size: 12.5px;
  color: var(--accent-green);
  white-space: nowrap;
  flex: none;
}
.tech-node__axistext {
  color: var(--text-body);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Der Erklaersatz im Forschungsknoten (Nutzerbefund 2026-09-13: "auch fehlt,
   was mir die tech bringt"). Zurueckgenommen gesetzt - er soll den Namen
   nicht ueberstrahlen, aber lesbar sein. */
.tech-node__desc {
  margin: 6px 0 8px;
  font-size: 10.5px;
  line-height: 1.45;
  color: var(--text-muted);
}

.xl-open--new {
  border-color: rgba(127, 176, 255, .6) !important;
  background: rgba(127, 176, 255, .1);
}
.xl-open__new {
  margin-left: 7px;
  padding: 1px 5px;
  border-radius: 4px;
  background: #7fb0ff;
  color: #04121f;
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: .06em;
  vertical-align: 1px;
}
.xl-card__flag--collected { right: 0; background: #8fe0a0; padding: 3px 7px 3px 8px; }

/* ------------------------------------------------------- Kartenfuss */
.xl-card__body { padding: 10px 11px 11px; }
.xl-card__nameline { display: flex; align-items: center; gap: 7px; }
.xl-card__gem { width: 7px; height: 7px; flex: none; transform: rotate(45deg); }
.xl-card__name {
  flex: 1; font-weight: 600; font-size: 13px; letter-spacing: .03em;
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.xl-card__sci {
  font-family: 'Share Tech Mono', monospace; font-size: 9px; letter-spacing: .06em;
  color: #5d6786; margin-top: 3px; font-style: italic;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.xl-card__meta { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.xl-card__rarity {
  flex: none; font-size: 8.5px; letter-spacing: .11em;
  border: 1px solid; border-radius: 4px; padding: 2.5px 7px; white-space: nowrap;
}
.xl-card__metaspacer { flex: 1; min-width: 0; }
.xl-card__threatlabel { flex: none; font-size: 8px; letter-spacing: .1em; color: #5d6786; }
.xl-card__threat { flex: none; display: flex; gap: 1.5px; }
.xl-card__threatcell { width: 3.5px; height: 9px; background: rgba(255, 255, 255, .08); }

.xl-card__facts {
  margin-top: 9px; padding-top: 8px;
  border-top: 1px solid rgba(120, 180, 255, .09);
  display: flex; flex-direction: column; gap: 4px;
}
.xl-card__fact { display: flex; align-items: baseline; gap: 7px; }
.xl-card__fact dt { flex: none; width: 56px; font-size: 8px; letter-spacing: .1em; color: #4d5878; }
.xl-card__fact dd {
  flex: 1; font-size: 10px; color: #b7c2de; min-width: 0; margin: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Identifikation laeuft. */
.xl-card__run { margin-top: 10px; }
.xl-card__track {
  position: relative; height: 7px; border-radius: 4px;
  background: rgba(255, 255, 255, .06); overflow: hidden;
}
.xl-card__fill { height: 100%; }
.xl-card__shine {
  position: absolute; top: 0; bottom: 0; width: 34%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .22), transparent);
  animation: xlSweep 1.9s linear infinite;
}
.xl-card__runfoot { display: flex; justify-content: space-between; align-items: baseline; margin-top: 6px; }
.xl-card__runlabel { font-size: 9.5px; letter-spacing: .06em; color: #8ff0e8; }
.xl-card__eta { font-family: 'Share Tech Mono', monospace; font-size: 9.5px; color: #5d7d86; }

/* Aktionsknopf und Steckbrief. */
.xl-card__actions { margin-top: 10px; }
.xl-action {
  width: 100%; border: 1px solid; border-radius: 7px;
  font-family: 'Chakra Petch', sans-serif; font-weight: 600;
  font-size: 10.5px; letter-spacing: .13em; padding: 8px 10px; cursor: pointer;
}
.xl-action--go { border-color: rgba(143, 224, 160, .5); background: rgba(16, 44, 32, .6); color: #9be6b6; }
.xl-action--lab { border-color: rgba(70, 217, 208, .5); background: rgba(10, 42, 44, .6); color: #8ff0e8; }
.xl-action--off {
  border-color: rgba(120, 180, 255, .14); background: rgba(14, 18, 32, .6);
  color: #5d6786; cursor: not-allowed;
}
.xl-card__actionhint { font-size: 9px; letter-spacing: .06em; margin-top: 5px; text-align: center; color: #5d7d86; }
.xl-card__actionhint--go { color: #8fe0a0; }
.xl-card__actionhint--wait { color: #4d5878; }
.xl-card__actionhint--busy { color: #e0a44a; }
.xl-open {
  width: 100%; margin-top: 10px; border: 1px solid; border-radius: 7px;
  background: rgba(12, 20, 34, .7);
  font-family: 'Chakra Petch', sans-serif; font-size: 10px;
  letter-spacing: .13em; padding: 7px 10px; cursor: pointer;
}
/* ══════════════════════════════════════════════════════════════════
   BERGUNGSSEQUENZ (Nutzerwunsch 2026-09-06: "das Bergen darf gern 15 Sekunden
   dauern und eine schöne Bergungssequenz mit Linien, Blinkeleuchten und
   schönen Elementen sci-fi-mäßig haben")

   Die Bühne zeigt links das geborgene Objekt, rechts das Schiff, dazwischen
   fünf schwingende Traktorlinien. Das Objekt wandert nach rechts, die Linien
   beruhigen sich - beides rechnet salvage-show.js, hier steht nur das
   Aussehen.

   Gold wie die Missionsbox drumherum: Es ist derselbe Vorgang.
   ══════════════════════════════════════════════════════════════════ */

@keyframes svPulse { 0%, 100% { opacity: .45 } 50% { opacity: 1 } }
@keyframes svSpin { from { transform: rotate(0) } to { transform: rotate(360deg) } }
@keyframes svDrift { 0% { background-position: 0 0 } 100% { background-position: -60px 0 } }

.salvage-show { display: flex; flex-direction: column; gap: 9px; }

.salvage-show__stage {
  position: relative;
  height: 52px;
  border: 1px solid rgba(255, 215, 106, .18);
  border-radius: 7px;
  background:
    linear-gradient(90deg, rgba(28, 22, 6, .5), rgba(8, 12, 22, .8)),
    repeating-linear-gradient(90deg, rgba(255, 215, 106, .05) 0 1px, transparent 1px 22px);
  animation: svDrift 4.5s linear infinite;
  overflow: hidden;
}
.salvage-show__beams { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Das geborgene Objekt - ein rotierender Kasten, der nach rechts wandert. */
.salvage-show__object {
  position: absolute;
  top: 50%;
  width: 9px;
  height: 9px;
  margin-top: -4.5px;
  background: #ffd76a;
  box-shadow: 0 0 10px #ffd76a;
  animation: svSpin 3.4s linear infinite;
  transition: left .25s linear;
}

/* Das aufnehmende Schiff, rechts am Rand. */
.salvage-show__ship {
  position: absolute;
  right: 6px;
  top: 50%;
  width: 0;
  height: 0;
  margin-top: -9px;
  border-top: 9px solid transparent;
  border-bottom: 9px solid transparent;
  border-right: 15px solid rgba(127, 233, 255, .85);
  filter: drop-shadow(0 0 6px rgba(127, 233, 255, .5));
}

/* Sechs Statusleuchten - eine je Sechstel der Laufzeit. */
.salvage-show__lamps { position: absolute; left: 7px; bottom: 5px; display: flex; gap: 4px; }
.salvage-show__lamp {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .12);
}
.salvage-show__lamp--on { background: #8fe0a0; box-shadow: 0 0 7px #8fe0a0; }
.salvage-show__lamp--blink {
  background: #ffd76a;
  box-shadow: 0 0 8px #ffd76a;
  animation: svPulse .7s ease-in-out infinite;
}

.salvage-show__telemetry {
  font-family: 'Share Tech Mono', monospace;
  font-size: 10px;
  letter-spacing: .05em;
  color: #8fb6d8;
}

.salvage-show__track {
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .07);
  overflow: hidden;
}
.salvage-show__bar {
  height: 100%;
  background: linear-gradient(90deg, #7a5a12, #ffd76a);
  transition: width .25s linear;
}

/* Das Protokoll. Feste Höhe mit Scroll: Ohne sie wüchse die Box mit jeder
   Zeile und schöbe den Rest der Spalte nach unten. */
.salvage-show__log {
  max-height: 62px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.salvage-show__log-line {
  font-family: 'Share Tech Mono', monospace;
  font-size: 9.5px;
  letter-spacing: .03em;
  color: #8b96ba;
}
.salvage-show__log-line:last-child { color: #f0d6ac; }

/* Sensor-Ereignisse: aufklappbar mit Filter (Nutzerwunsch 2026-09-10).
   Vorher zeigten sie nur eine Kopfzeile mit dem technischen Schluessel -
   "Sie bringen mir also nix." */
.sensor-event { cursor: pointer; }
.sensor-event__head {
  list-style: none;
  cursor: pointer;
}
.sensor-event__head::-webkit-details-marker { display: none; }
.sensor-event__body {
  padding: 8px 12px 10px 12px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-muted, #9aa4c4);
  border-top: 1px solid var(--border);
}
.sensor-event-filter {
  display: flex;
  gap: 6px;
  margin: 0 0 10px;
}
.sensor-event-filter__btn {
  padding: 4px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 4px);
  background: transparent;
  color: var(--text-muted, #9aa4c4);
  font-size: 12px;
  cursor: pointer;
}
.sensor-event-filter__btn:hover { color: var(--text, #dfe6ff); }
.sensor-event-filter__btn--active {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(70, 217, 208, .08);
}

/* --- "Das Signal" (Spec 2026-09-10 E2) ---------------------------------
   Die Boxen tragen .detail-panel und erben damit Rahmen, Flaeche und Radius
   der uebrigen Oberflaeche (Nutzervorgabe). Nur `position: sticky` muss weg -
   das braucht die Seitenspalte des Forschungsbaums, hier klebten sonst alle
   Kacheln. */
.signal-view .detail-panel { position: static; top: auto; }
/* ETWAS BREITER ALS DIE UEBRIGEN SEITEN, aber kein Vollbild (Nutzerwunsch
   2026-09-15: "Das Signal-Menue etwas breiter gestalten. Damit die 4 Boxen
   unter dem Countdown nebeneinander passen und das Material liefern auch
   richtig in eine Box reinpasst (aber nicht fullscreen, nur etwas
   vergroessern)").

   1400 statt 1100: Vier Fortschrittsboxen zu je 230 px plus drei Abstaende
   brauchen 1002 px - in 1100 blieben nach dem Seitenrand keine vier Spalten
   uebrig, und die vierte sprang in eine eigene Zeile. */
.signal-view { max-width: 1400px; }

.signal__briefing { margin: 8px 0 18px; border-left: 3px solid var(--accent); }
/* Die Tagesmarke am Lagebericht (2026-09-11). Sie steht VOR der Ueberschrift
   und nicht daneben: Der Countdown laeuft rueckwaerts, und "TAG 4" ist die
   erste Auskunft, die zaehlt. */
.signal__chapter-badge {
  display: inline-block;
  margin-right: 8px;
  padding: 1px 7px;
  border-radius: 4px;
  background: var(--accent-gold);
  color: #05060f;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  vertical-align: middle;
}
.signal__briefing-head {
  font-family: var(--font-heading); font-weight: 600; font-size: 15px;
  color: var(--text-primary); margin-bottom: 6px;
}
.signal__briefing-text { font-size: 12.5px; color: var(--text-muted); line-height: 1.6; margin: 0; }

/* Die Uhr. Gross und allein in ihrer Zeile - im Finale ist die verbleibende
   Zeit die Zahl, nach der alles andere sich richtet. */
.signal__clock { text-align: center; margin-bottom: 18px; }
.signal__clock-label {
  font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-dim);
}
.signal__clock-value {
  font-family: var(--font-heading); font-size: 38px; font-weight: 700;
  color: var(--accent-gold); line-height: 1.2; margin-top: 4px;
}
.signal__clock-note { font-size: 11px; color: var(--text-dim); margin-top: 6px; }

/* auto-fit statt einer festen Vierer-Spalte: Im breiten Fenster stehen die
   vier Zaehler nebeneinander, im schmalen brechen sie sauber um. Mehr als
   vier gibt es nicht - leere Spuren kollabieren bei auto-fit von selbst. */
.signal__bars {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px; margin-bottom: 18px;
}
.signal__bar--done { border-color: var(--accent); }
.signal__bar-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.signal__bar-name {
  font-family: var(--font-heading); font-weight: 600; font-size: 13px; color: var(--text-primary);
}
.signal__bar-percent { font-family: var(--font-body); font-size: 13px; color: var(--accent); }
.signal__bar-track {
  height: 10px; border-radius: 5px; background: rgba(255,255,255,0.06);
  overflow: hidden; margin: 8px 0 6px;
}
.signal__bar-fill {
  height: 100%; border-radius: 5px;
  background: linear-gradient(90deg, var(--accent), var(--accent-gold));
  transition: width 0.6s ease;
}
.signal__bar-numbers { font-size: 11px; color: var(--text-dim); font-family: var(--font-body); }
.signal__bar-done { color: var(--accent); }

/* Die vier Stufen der Konvergenz (Spec 2026-09-11 C2). Der Balken traegt die
   Schwellen als Marken; overflow bleibt sichtbar, damit die Marken ueber den
   Rand hinausragen duerfen. */
.signal__milestones { margin-bottom: 18px; }
.signal__milestones-percent {
  font-family: var(--font-heading); font-size: 13px; letter-spacing: 0.04em;
  color: var(--accent-gold); margin-left: 6px;
}
.signal__milestones-track {
  position: relative; height: 12px; border-radius: 6px;
  background: rgba(255,255,255,0.06); margin: 6px 0 14px;
}
.signal__milestones-fill {
  height: 100%; border-radius: 6px;
  background: linear-gradient(90deg, #7fe9ff, var(--accent-gold));
  transition: width 0.6s ease;
}
.signal__milestones-mark {
  position: absolute; top: -4px; width: 2px; height: 20px; margin-left: -1px;
  background: rgba(255,255,255,0.25);
}
.signal__milestones-mark--reached { background: var(--accent-gold); }
.signal__milestones-steps {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 8px;
}
.signal__milestone {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: 1px solid rgba(255,255,255,0.08); border-radius: 6px;
  color: var(--text-dim); font-size: 12px;
}
.signal__milestone i { margin-left: auto; font-size: 15px; }
.signal__milestone--reached { border-color: var(--accent-gold); color: var(--text-primary); }
.signal__milestone--reached i { color: var(--accent-gold); }
.signal__milestone-threshold {
  font-family: var(--font-heading); font-weight: 700; font-size: 13px; min-width: 42px;
}

.signal__columns {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px;
}
.signal__section-title {
  font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-dim); margin-bottom: 10px;
}
.signal__share-total {
  font-family: var(--font-heading); font-size: 30px; font-weight: 700; color: var(--text-primary);
}
.signal__share-unit {
  display: block; font-family: var(--font-body); font-size: 10px; font-weight: 400;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim);
}
.signal__share-rank { font-size: 12px; color: var(--accent); margin: 6px 0 12px; }
.signal__share-row {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 12px; color: var(--text-muted); padding: 5px 0;
  border-top: 1px solid var(--border);
}
.signal__share-row--zero { color: var(--text-dim); }
.signal__share-value { font-family: var(--font-body); }
.signal__share-value em { font-style: normal; color: var(--text-dim); font-size: 11px; }

.signal__supply-hint { font-size: 11.5px; color: var(--text-muted); line-height: 1.5; margin: 0 0 12px; }
/* minmax(0, 1fr) statt 1fr: Ein Auswahlfeld mit langen Eintraegen ("Metallerz
   - Faktor 1 (Bestand 12.345)") hat eine grosse Mindestbreite und sprengte
   sonst die Box nach rechts, statt sich zu kuerzen. */
.signal__supply-form { display: grid; grid-template-columns: minmax(0, 1fr) 130px; gap: 8px; align-items: center; }
.signal__supply-select,
.signal__supply-amount {
  min-width: 0;
  max-width: 100%;
  padding: 8px 10px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface-active); color: var(--text-primary);
  font-family: var(--font-body); font-size: 12px;
}

/* DAS AUFGEKLAPPTE DROPDOWN WAR NICHT ZU LESEN (Nutzerbefund 2026-09-15: "das
   dropdown im signal menü ist nicht lesbar ... eher hintergrund dunkler, damit
   es mit dem theme passt").

   --surface-active ist rgba(120,180,255,.08), also fast durchsichtig. Das
   zugeklappte Feld steht damit auf der dunklen Seite und liest sich gut - die
   aufgeklappte LISTE aber zeichnet der Browser als natives Fenster in
   Systemfarbe, hell, und erbt dazu die helle Schrift. Helles Grau auf Weiss.

   color-scheme: dark ist der eigentliche Schalter: Er sagt dem Browser, dass
   dieses Bedienelement zu einer dunklen Oberflaeche gehoert, und faerbt das
   native Fenster entsprechend. Die option-Regel darunter faengt die Browser
   ab, die sich daran nicht halten - dieselbe Farbe wie bei
   `select.admin-input option`, damit die beiden Dropdowns im Spiel gleich
   aussehen. */
.signal__supply-select {
  color-scheme: dark;
  cursor: pointer;
}
.signal__supply-select option {
  background: #101827;
  color: #e6ecff;
}
.signal__supply-button { grid-column: 1 / -1; margin-top: 4px; }
.signal__supply-msg {
  margin-top: 10px; padding: 8px 10px; border-radius: var(--radius-sm); font-size: 11.5px;
}
.signal__supply-msg--ok { border: 1px solid var(--accent); color: var(--accent); }
.signal__supply-msg--fehler { border: 1px solid var(--accent-red); color: var(--accent-red); }

/* Der Menuepunkt selbst. Er erscheint erst im Finale und soll dann auffallen,
   ohne zu blinken - eine ruhige Goldfaerbung genuegt. */
.app-sidebar__item--signal i { color: var(--accent-gold); }
.app-sidebar__item--signal .app-sidebar__label { color: var(--accent-gold); }

/* DER MENUEPUNKT NACH DEM RUNDENENDE (Nutzerwunsch 2026-09-22: "Menue Button
   'Das Signal' wird zu 'Spielende' und pulsiert").

   Er ist dann der einzige Punkt, an dem es noch etwas Neues gibt - alles
   andere ist eingefroren. Das Pulsieren sagt "hier entlang", ohne eine
   Meldung zu sein, die man wegklicken muss.

   prefers-reduced-motion respektiert: Wer Bewegung abbestellt hat, bekommt
   die Endfarbe ohne Animation. Der Punkt bleibt hervorgehoben, er zappelt
   nur nicht. */
.app-sidebar__item--ended {
  animation: sidebar-ended-pulse 2s ease-in-out infinite;
}

@keyframes sidebar-ended-pulse {
  0%, 100% {
    background: rgba(255, 199, 92, 0.08);
    box-shadow: 0 0 0 0 rgba(255, 199, 92, 0);
  }
  50% {
    background: rgba(255, 199, 92, 0.22);
    box-shadow: 0 0 10px 1px rgba(255, 199, 92, 0.35);
  }
}

@media (prefers-reduced-motion: reduce) {
  .app-sidebar__item--ended {
    animation: none;
    background: rgba(255, 199, 92, 0.18);
  }
}

@media (max-width: 720px) {
  .signal__clock-value { font-size: 28px; }
  .signal__supply-form { grid-template-columns: 1fr; }
}

/* ===================================================================
   Umzug eines Organisationsmitglieds (Spec 2026-09-12)
   =================================================================== */

/* --- Angebotsmodal ------------------------------------------------- */

.reloc-panel { max-width: 620px; }
.reloc-hint { font-size: 11px; color: #8b96ba; line-height: 1.5; margin-bottom: 12px; text-wrap: pretty; }
.reloc-label {
  display: block;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 10px;
  letter-spacing: .12em;
  color: #63709a;
  margin-bottom: 5px;
}
.reloc-input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid rgba(120, 180, 255, .22);
  background: rgba(8, 12, 24, .8);
  color: #e6ecff;
  font-family: 'Share Tech Mono', monospace;
  font-size: 12px;
}
.reloc-input:focus { outline: none; border-color: rgba(70, 217, 208, .5); }

.reloc-hits { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.reloc-hit {
  padding: 5px 10px;
  border: 1px solid rgba(120, 180, 255, .2);
  background: rgba(16, 22, 40, .8);
  color: #dbe3f7;
  font-size: 11px;
  cursor: pointer;
}
.reloc-hit:hover { border-color: rgba(70, 217, 208, .5); color: #7fe9ff; }

/* Die Planeten als Orbitreihe - die Ziffer ist die Umlaufbahn, wie überall
   sonst im Spiel. */
.reloc-planets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.reloc-planet {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 62px;
  padding: 7px 6px;
  border: 1px solid rgba(120, 180, 255, .2);
  background: rgba(16, 22, 40, .8);
  color: #dbe3f7;
  cursor: pointer;
}
.reloc-planet:hover:not(:disabled) { border-color: rgba(70, 217, 208, .5); }
.reloc-planet--on { border-color: #46d9d0; background: rgba(70, 217, 208, .14); }
.reloc-planet--off { opacity: .45; cursor: not-allowed; }
.reloc-planet__orbit { font-family: 'Share Tech Mono', monospace; font-size: 15px; color: #7fe9ff; }
.reloc-planet__tier { font-size: 8.5px; letter-spacing: .06em; color: #8b96ba; }
.reloc-planet__off { font-size: 8px; color: #e08a7a; }

.reloc-preview { margin-top: 14px; }
.reloc-block__title {
  font-family: 'Chakra Petch', sans-serif;
  font-size: 10px;
  letter-spacing: .12em;
  color: #63709a;
  margin: 12px 0 6px;
}
.reloc-row {
  display: flex;
  justify-content: space-between;
  font-size: 11.5px;
  color: #8b96ba;
  margin-top: 6px;
}
.reloc-row span:last-child { color: #e6ecff; font-family: 'Share Tech Mono', monospace; }

.reloc-assign {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  color: #dbe3f7;
  padding: 5px 0;
  border-bottom: 1px solid rgba(120, 180, 255, .07);
}
.reloc-assign__arrow { color: #46d9d0; }
.reloc-assign__to { color: #8b96ba; }
.reloc-assign__flag {
  margin-left: auto;
  font-size: 8.5px;
  letter-spacing: .08em;
  color: #ffd76a;
  border: 1px solid rgba(255, 215, 106, .35);
  padding: 1px 5px;
}

/* Die drei Warnungen. Sie stehen IMMER da, auch wenn alles möglich ist —
   keine davon lässt sich rückgängig machen. */
.reloc-warnings { margin-top: 14px; display: flex; flex-direction: column; gap: 6px; }
.reloc-warn {
  font-size: 10.5px;
  line-height: 1.45;
  color: #e0c07a;
  padding: 6px 9px;
  border-left: 2px solid rgba(224, 192, 122, .5);
  background: rgba(224, 192, 122, .07);
  text-wrap: pretty;
}
.reloc-blockers {
  margin: 12px 0 0;
  padding-left: 18px;
  font-size: 11px;
  line-height: 1.5;
  color: #e08a7a;
}

/* --- Angebot und Reise im Organisationsbüro ------------------------- */

.reloc-offer, .reloc-travel { margin-bottom: 14px; }
.reloc-offer__body { padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }
.reloc-offer__target { font-size: 12px; color: #dbe3f7; }

/* --- Das Wurmloch-Vollbild ------------------------------------------ */

.wh {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  min-height: 70vh;
  padding: 24px 16px;
  text-align: center;
}
.wh-stage {
  position: relative;
  width: 100%;
  max-width: 520px;
  height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.wh-ring {
  position: absolute;
  border-radius: 50%;
  border: 1px solid rgba(170, 120, 255, .4);
  box-shadow: 0 0 30px rgba(170, 120, 255, .25), inset 0 0 30px rgba(140, 100, 240, .2);
  animation-name: whRing;
  animation-iteration-count: infinite;
  animation-timing-function: ease-in-out;
}
@keyframes whRing {
  0%, 100% { transform: scale(1) rotate(0deg); opacity: .65; }
  50% { transform: scale(1.12) rotate(180deg); opacity: 1; }
}
.wh-core {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: radial-gradient(circle, #e6d6ff 0 18%, #a878ff 46%, #3a1a7a 78%, transparent 100%);
  box-shadow: 0 0 60px rgba(170, 120, 255, .8);
  animation: whCore 2.6s ease-in-out infinite;
}
@keyframes whCore {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.15); }
}
.wh-title {
  font-family: 'Chakra Petch', sans-serif;
  font-size: 15px;
  letter-spacing: .2em;
  color: #c8a8ff;
}
.wh-text, .wh-note {
  max-width: 460px;
  font-size: 12px;
  line-height: 1.55;
  color: #8b96ba;
  text-wrap: pretty;
}
.wh-note { font-size: 11px; color: #63709a; }
.wh-target { font-size: 12.5px; color: #dbe3f7; }
.wh-countdown {
  font-family: 'Share Tech Mono', monospace;
  font-size: 30px;
  color: #e6d6ff;
  text-shadow: 0 0 20px rgba(170, 120, 255, .6);
}

@media (prefers-reduced-motion: reduce) {
  .wh-ring, .wh-core { animation: none; }
}

/* --- Laufende Anomalieuntersuchung (2026-09-12) ---------------------- */

/* Sieben Sensorzeilen unter einem wandernden Strahl, darunter der echte
   Fortschritt aus Start- und Endzeit des Auftrags. Die Akzentfarbe kommt aus
   der Anomaliekategorie — dieselbe, die auch Marker und Panel färbt. */
.invshow { --invshow-accent: #46d9d0; }
.invshow__scope {
  position: relative;
  height: 54px;
  border: 1px solid color-mix(in srgb, var(--invshow-accent) 26%, transparent);
  background:
    radial-gradient(ellipse at 50% 120%, color-mix(in srgb, var(--invshow-accent) 14%, transparent), transparent 70%),
    rgba(6, 10, 20, .85);
  overflow: hidden;
}
.invshow__lines {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: space-evenly;
  padding: 0 10px;
}
.invshow__line {
  width: 3px;
  height: 40%;
  opacity: .75;
  transform-origin: 50% 50%;
  animation-name: invshowLine;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-timing-function: ease-in-out;
}
@keyframes invshowLine {
  from { transform: scaleY(.25); opacity: .35; }
  to { transform: scaleY(1); opacity: 1; }
}
/* Der Strahl läuft einmal quer und beginnt von vorn — er sagt „hier wird
   gemessen", ohne einen Fortschritt vorzutäuschen. Der steht darunter. */
.invshow__sweep {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in srgb, var(--invshow-accent) 22%, transparent) 45%,
    color-mix(in srgb, var(--invshow-accent) 42%, transparent) 50%,
    color-mix(in srgb, var(--invshow-accent) 22%, transparent) 55%,
    transparent 100%);
  animation: invshowSweep 2.8s linear infinite;
}
@keyframes invshowSweep {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}
.invshow__label {
  margin-top: 7px;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 9.5px;
  letter-spacing: .16em;
  color: var(--invshow-accent);
}
.invshow__track {
  margin-top: 5px;
  height: 5px;
  background: rgba(255, 255, 255, .07);
  overflow: hidden;
}
.invshow__fill {
  height: 100%;
  background: var(--invshow-accent);
  box-shadow: 0 0 8px var(--invshow-accent);
  transition: width .9s linear;
}
.invshow__foot {
  display: flex;
  justify-content: space-between;
  margin-top: 4px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 10px;
  color: #8b96ba;
}

@media (prefers-reduced-motion: reduce) {
  .invshow__line, .invshow__sweep { animation: none; }
  .invshow__fill { transition: none; }
}

/* ======================================================================
   MATERIEKONVERTER (Nutzerwunsch 2026-09-13)
   ======================================================================
   "tolles Modal erstellen, mit Auswahl Startressource und was man haben will
   ... Während der Umwandlung eine schöne unwandlungs Progress Grafik."

   KEIN EIGENER MENUEPUNKT - bedient wird er im Lager. Die Zeile dort ist der
   einzige Einstieg und erscheint nur, wenn das Gebaeude steht. */

.storage-converter {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 18px 0 6px;
  padding: 12px 16px;
  border: 1px solid rgba(240, 168, 244, .28);
  border-left: 3px solid #f0a8f4;
  border-radius: var(--radius-md);
  background: linear-gradient(100deg, rgba(240, 168, 244, .07), rgba(10, 14, 26, .6));
}
.storage-converter__text { flex: 1; min-width: 0; }
.storage-converter__title {
  font-family: var(--font-heading);
  font-size: 14px;
  letter-spacing: .04em;
  color: var(--text-primary);
}
.storage-converter__sub { font-size: 11.5px; color: var(--text-muted); margin-top: 3px; }
.storage-converter__btn {
  flex: none;
  padding: 9px 18px;
  border-radius: var(--radius-sm);
  border: 1px solid rgba(240, 168, 244, .5);
  background: rgba(240, 168, 244, .12);
  color: #f7c8fa;
  font-size: 12px;
  letter-spacing: .06em;
  cursor: pointer;
}
.storage-converter__btn:hover { background: rgba(240, 168, 244, .22); }

/* --- das Modal ------------------------------------------------------- */
.conv { min-width: min(560px, 82vw); }

/* Der Spruch oben. Zurueckgenommen gesetzt: er ist Beiwerk, kein Hinweis -
   wer ihn ueberliest, verpasst nichts. */
.conv__story {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-dim);
  font-style: italic;
  border-left: 2px solid rgba(240, 168, 244, .35);
  padding: 2px 0 2px 11px;
  margin-bottom: 16px;
}

.conv__step {
  /* Umbrechen statt ueberlaufen: Der Zusatz ("Grundstoffe · 70 % Ausbeute")
     haengt an derselben Zeile wie die Ueberschrift und wuerde sie auf
     schmalen Schirmen sonst aus dem Kasten schieben (2026-09-17). */
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 8px;
  font-family: var(--font-heading);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 14px 0 7px;
}
/* margin-left ist mit dem Flex-Gap oben weggefallen - zwei Abstaende
   nebeneinander ergaben einen doppelten. */
.conv__stepnote { color: var(--text-muted); letter-spacing: .04em; text-transform: none; }

.conv__picks { display: flex; flex-wrap: wrap; gap: 8px; }
.conv-pick {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  width: 92px;
  padding: 9px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .02);
  color: var(--text-body);
  font: inherit;
  font-size: 10px;
  cursor: pointer;
}
.conv-pick:hover { border-color: var(--conv-color, var(--border-strong)); }
.conv-pick--on {
  border-color: var(--conv-color, var(--accent-bright));
  background: rgba(255, 255, 255, .06);
  box-shadow: 0 0 14px color-mix(in srgb, var(--conv-color, #7fe9ff) 22%, transparent);
}
.conv-pick__label { text-align: center; line-height: 1.25; color: var(--text-body); }
.conv-sym { display: block; object-fit: contain; }

.conv__amount { display: flex; align-items: center; gap: 10px; }
.conv__input {
  width: 160px;
  padding: 8px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, .3);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 14px;
}
.conv__unit { font-size: 11.5px; color: var(--text-muted); }

.conv__ledger {
  margin-top: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, .22);
  padding: 4px 12px;
}
.conv__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(120, 180, 255, .07);
  font-size: 12px;
}
.conv__row:last-child { border-bottom: none; }
.conv__row > span:first-child { color: var(--text-muted); }
.conv__gain, .conv__cost {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-heading);
  font-size: 14px;
}
.conv__gain { color: var(--accent-green); }
.conv__cost { color: #f0a8f4; }

.conv__blocked {
  margin-top: 10px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--accent-red);
}
.conv__hint { margin-top: 14px; font-size: 11.5px; line-height: 1.5; color: var(--text-muted); }

.conv__go {
  width: 100%;
  margin-top: 14px;
  padding: 11px;
  border: 1px solid var(--accent-green);
  border-radius: var(--radius-sm);
  background: var(--accent-green);
  color: #061309;
  font-family: var(--font-heading);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .07em;
  cursor: pointer;
}
.conv__go:hover:not(:disabled) { background: #79e7a1; }
.conv__go:disabled { opacity: .4; cursor: not-allowed; }

/* --- die laufende Umwandlung ----------------------------------------- */
.conv-run { display: grid; gap: 12px; }
.conv-run__label {
  font-family: var(--font-heading);
  font-size: 11px;
  letter-spacing: .16em;
  color: #f0a8f4;
  text-align: center;
}
.conv-run__stage {
  display: flex;
  align-items: center;
  gap: 14px;
}
.conv-run__side {
  flex: none;
  width: 92px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-family: var(--font-heading);
  font-size: 13px;
  color: var(--text-primary);
}
/* Der Strahl zwischen beiden Seiten: die Fuellung zeigt den Fortschritt, der
   Funke sitzt an seiner Spitze. */
.conv-run__beam {
  position: relative;
  flex: 1;
  height: 10px;
  border-radius: 5px;
  background: rgba(255, 255, 255, .06);
  overflow: visible;
}
.conv-run__beamfill {
  height: 100%;
  border-radius: 5px;
  background: linear-gradient(90deg, rgba(240, 168, 244, .35), #f0a8f4);
  transition: width .9s linear;
}
.conv-run__spark {
  position: absolute;
  top: 50%;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 40%, #fff, #f0a8f4 60%, rgba(240, 168, 244, 0) 72%);
  box-shadow: 0 0 16px rgba(240, 168, 244, .8);
  animation: convSpark 1.4s ease-in-out infinite;
  transition: left .9s linear;
}
.conv-run__foot {
  display: flex;
  justify-content: space-between;
  font-size: 11.5px;
  color: var(--text-muted);
}
@keyframes convSpark {
  0%, 100% { transform: scale(1); opacity: .9; }
  50% { transform: scale(1.35); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .conv-run__spark { animation: none; }
  .conv-run__beamfill, .conv-run__spark { transition: none; }
}

@media (max-width: 620px) {
  .conv { min-width: 0; }
  .conv-pick { width: calc(50% - 4px); }
  .conv-run__stage { flex-direction: column; }
  .conv-run__beam { width: 100%; }
}

/* ===================================================================
   DAS FORSCHER-LOG (Nutzerwunsch 2026-09-13)

   Die vollstaendige Laborakte einer Kreaturenart, im breiten Modal.

   EIN LOGBUCH, KEINE BLAETTERSAMMLUNG. Die erste Fassung zeigte je Reiter
   eine Seite; gemessen sind die Eintraege aber im Median 181 Zeichen und ein
   einziger Absatz - Notizzettel, keine Fliesstexte. Ein halber Gedanke auf
   viel Weiss, und dazwischen ein Klick. Jetzt steht die ganze Chronik
   untereinander, jeder Eintrag mit Zeitstempel; die Reiter darueber wechseln
   den Abschnitt, die Marken darunter springen.

   Entwurf "Stationsterminal", vom Nutzer aus dreien gewaehlt (2026-09-13).

   DIE MASCHINENSCHRIFT MARKIERT DAS PROTOKOLL, SIE TRAEGT ES NICHT: Nur die
   Kopfzeilen und Kennungen stehen in Monospace, der Fliesstext bleibt in der
   Lesetypografie der Oberflaeche. Siebzehn Eintraege durchgehend in
   Maschinenschrift liest niemand - das war der Einwand beim Entwurf.

   Der Rahmen kommt aus `.detail-panel` im Inhalt, nicht aus `.detail-modal`
   - jene Huelle hat keinen (siehe den Kommentar dort).
   =================================================================== */
.dossier {
  display: flex;
  flex-direction: column;
  gap: 0;
  max-height: min(78vh, 780px);
  overflow: hidden;
}
.dossier__head {
  padding: 2px 0 13px;
  border-bottom: 1px solid rgba(120, 180, 255, .14);
}
.dossier__eyebrow {
  font-family: 'Share Tech Mono', monospace;
  font-size: 9.5px;
  letter-spacing: .2em;
  color: #6f7ea6;
  text-transform: uppercase;
}
.dossier__name {
  margin: 3px 0 0;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 21px;
  font-weight: 600;
  letter-spacing: .04em;
  color: #dff3ff;
}
.dossier__scientific {
  margin-top: 1px;
  font-style: italic;
  font-size: 11.5px;
  color: #8b96ba;
}

/* Die sechs Abschnitte. Sie duerfen umbrechen: "Ungeklaertes Phaenomen —
   KRIB-NULL" ist je Art verschieden lang, und ein waagerechter Schieber fuer
   sechs Knoepfe waere umstaendlicher als zwei Zeilen. */
.dossier__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 12px 0 10px;
  /* NICHT SCHRUMPFEN (Nutzerbefund 2026-09-14: "Scrollbalken verdeckt obige
     Log Buttons"). In der Flex-Spalte .dossier ist der Standard `flex-shrink:
     1` - bei einer langen Akte gibt der Browser dem Lesebereich darunter den
     Platz und staucht diese Reihe. Die Knoepfe werden dann angeschnitten. */
  flex: 0 0 auto;
}
.dossier__tab {
  padding: 6px 12px;
  border: 1px solid rgba(120, 180, 255, .2);
  border-radius: var(--radius-sm);
  background: rgba(12, 18, 34, .7);
  color: #9aa7c7;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 11.5px;
  letter-spacing: .06em;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.dossier__tab:hover { color: #cfe4ff; border-color: rgba(120, 180, 255, .4); }
.dossier__tab--on {
  border-color: rgba(127, 233, 255, .6);
  background: rgba(20, 48, 72, .8);
  color: #eafcff;
  box-shadow: 0 0 12px rgba(127, 233, 255, .16);
}

/* Die Sprungmarken. HIER SCHIEBT ES WAAGERECHT, anders als bei den Reitern
   darueber: siebzehn Marken mit Titel umgebrochen waeren eine halbe Seite
   Navigation ueber dem Protokoll. */
.dossier__jumps {
  display: flex;
  gap: 5px;
  overflow-x: auto;
  scrollbar-width: thin;

  /* NICHT SCHRUMPFEN - hier faellt es staerker auf als bei den Reitern
     darueber (Nutzerbefund 2026-09-14: "Scrollbalken verdeckt obige Log
     Buttons").

     ZWEI URSACHEN WIRKTEN ZUSAMMEN: In der Flex-Spalte darf diese Reihe
     schrumpfen, und sie ist zugleich ein Scrollbehaelter. Wird sie gestaucht,
     legt der Browser den waagerechten Scrollbalken INNEN an den unteren Rand -
     also quer ueber die Knoepfe, die er gerade verdraengt hat. */
  flex: 0 0 auto;

  /* Platz fuer den Scrollbalken selbst - er sitzt im Innenabstand. 12 px
     tragen die 8 px, die `::-webkit-scrollbar` global setzt, mit etwas Luft;
     die frueheren 11 px reichten nicht, weil die globale Regel damals gar
     keine Hoehe setzte und der Balken in der Windows-Vorgabe lief. */
  padding: 0 0 12px;
}
.dossier__jump {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  max-width: 210px;
  padding: 4px 9px;
  border: 1px solid rgba(120, 180, 255, .13);
  border-radius: var(--radius-sm);
  background: rgba(9, 14, 28, .6);
  color: #7e8bb0;
  font-size: 10.5px;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.dossier__jump:hover { color: #cfe4ff; border-color: rgba(120, 180, 255, .32); }
.dossier__jump-num {
  font-family: 'Share Tech Mono', monospace;
  font-size: 9.5px;
  color: #4fd9a0;
  opacity: .8;
}
.dossier__jump-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Der Lesebereich und das Protokollfenster darin. */
.dossier__scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  scrollbar-width: thin;
}
.dossier__shell {
  background: rgba(4, 8, 16, .82);
  border: 1px solid rgba(127, 233, 255, .16);
  border-radius: var(--radius-sm);
  padding: 15px 17px 13px;
}

/* Ein Eintrag. */
.dossier__entry { margin-bottom: 17px; }
.dossier__entry:last-of-type { margin-bottom: 4px; }
.dossier__entry-line {
  display: flex;
  align-items: baseline;
  gap: 7px;
  flex-wrap: wrap;
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  letter-spacing: .05em;
  margin-bottom: 5px;
}
.dossier__entry-caret { color: #4fd9a0; }
.dossier__entry-stamp { color: #4fd9a0; }
.dossier__entry-sep { color: #3f4c6d; }
.dossier__entry-title { color: #ffd76a; }

/* DER ABGESETZTE TEXT (Nutzerwunsch: "abgesetzt ein wenig"). Der Strich
   links bindet die Zeilen eines Eintrags zusammen - ohne ihn laufen bei
   siebzehn Eintraegen Kopfzeile und Text ineinander. */
.dossier__entry-text {
  margin-left: 13px;
  padding-left: 13px;
  border-left: 1px solid rgba(127, 233, 255, .13);
}
.dossier__entry-text p {
  margin: 0 0 9px;
  font-size: 13px;
  line-height: 1.62;
  color: #b8c4dd;
}
.dossier__entry-text p:last-child { margin-bottom: 0; }
.dossier__entry-text strong { color: #eafcff; font-weight: 600; }
.dossier__list {
  margin: 0 0 9px;
  padding-left: 19px;
  font-size: 13px;
  line-height: 1.62;
  color: #b8c4dd;
}
.dossier__list li { margin-bottom: 3px; }

/* Der Abschluss. Ohne ihn endet die Chronik mitten im Nichts, und man weiss
   nicht, ob noch etwas nachlaedt. */
.dossier__end {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px dashed rgba(127, 233, 255, .14);
  font-family: 'Share Tech Mono', monospace;
  font-size: 9.5px;
  letter-spacing: .14em;
  color: #3f4c6d;
}
.dossier__empty {
  padding: 28px 0;
  text-align: center;
  color: #6f7ea6;
  font-size: 12.5px;
}

/* Auf schmalen Schirmen tragen die Marken nur noch ihre Nummer - sonst waere
   die Reihe laenger als das Protokoll darunter. */
@media (max-width: 720px) {
  .dossier__jump-title { display: none; }
  .dossier__jump { max-width: none; }
  .dossier__entry-text { margin-left: 0; padding-left: 10px; }
}

/* ---------------------------------------------------------- Flottenreparatur
   (Nutzerwunsch 2026-09-14: "Das ganze passiert in der Werft und ist dort
   dann auch so sichtbar.")

   ZWEI BLOECKE, EINE FORM: oben die laufenden Reparaturen mit
   Fortschrittsbalken, darunter die Angebote fuer beschaedigte Flotten im
   Dock. Sie sehen gleich aus, weil sie dasselbe Ding in zwei Zustaenden
   sind; unterschieden werden sie ueber die Randfarbe - Blau fuer "laeuft",
   Bernstein fuer "wartet auf dich".

   BEWUSST NICHT IN DER BAU-WARTESCHLANGE: Eine Reparatur belegt keinen
   Werftplatz. Sie dort einzureihen haette die Platzzahl darueber zur Luege
   gemacht. */
.shipyard-repairs {
  margin-bottom: 18px;
  padding: 14px 16px;
  border: 1px solid rgba(120, 180, 255, .22);
  border-radius: var(--radius-lg);
  background: rgba(10, 14, 28, .6);
}
.shipyard-repairs--offer {
  border-color: rgba(232, 162, 74, .4);
  background: rgba(38, 26, 10, .45);
}
.shipyard-repairs__head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-heading);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .12em;
  color: #7fe9ff;
  margin-bottom: 12px;
}
.shipyard-repairs--offer .shipyard-repairs__head { color: #e8a24a; }
.shipyard-repairs__row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 9px 0;
  border-top: 1px solid rgba(120, 180, 255, .1);
}
.shipyard-repairs__row:first-of-type { border-top: 0; }
/* Der Name darf schrumpfen, die Knoepfe nicht - sonst bricht bei langen
   Flottennamen die Zeile um und der Knopf rutscht aus dem Blick. */
.shipyard-repairs__name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13.5px;
  color: var(--text-primary);
}
.shipyard-repairs__meta {
  display: block;
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
}
.shipyard-repairs__bar {
  flex: 0 1 220px;
  height: 6px;
  border-radius: 3px;
  background: rgba(120, 180, 255, .14);
  overflow: hidden;
}
.shipyard-repairs__fill {
  height: 100%;
  background: linear-gradient(90deg, #2a6f8f, #7fe9ff);
}
.shipyard-repairs__time {
  flex: none;
  font-variant-numeric: tabular-nums;
  font-size: 12.5px;
  color: #7fe9ff;
  min-width: 68px;
  text-align: right;
}
.shipyard-repairs__cost {
  flex: 0 1 260px;
  font-size: 11.5px;
}
.shipyard-repairs__start,
.shipyard-repairs__cancel {
  flex: none;
  cursor: pointer;
  font-family: var(--font-heading);
  font-size: 11.5px;
  letter-spacing: .08em;
  padding: 7px 14px;
  border-radius: 7px;
  border: 1px solid;
}
.shipyard-repairs__start {
  border-color: rgba(232, 162, 74, .5);
  background: rgba(232, 162, 74, .16);
  color: #f0c98a;
}
.shipyard-repairs__start:hover { background: rgba(232, 162, 74, .28); }
.shipyard-repairs__cancel {
  border-color: rgba(224, 90, 74, .4);
  background: rgba(224, 90, 74, .12);
  color: #ff8f80;
}
.shipyard-repairs__cancel:hover { background: rgba(224, 90, 74, .22); }

@media (max-width: 900px) {
  .shipyard-repairs__row { flex-wrap: wrap; }
  .shipyard-repairs__name { flex-basis: 100%; }
}

/* ====================================================================
   SCHNELLAUSWAHL IM LEERZUSTAND DER KARTE (Nutzerwunsch 2026-09-19)

   "hier hätte ich gern auch eine kleine auflistung meiner Heimat/Kolonien -
   die ich anklicken kann. dann muss ich in der sternen karte nicht immer
   scrollen und suchen. Vielleicht auch aufklappbar meine favoriten."

   Steht unter dem "Ziel auswählen"-Hinweis und verschwindet, sobald ein
   Ziel gewählt ist. Der Hinweis darüber trägt min-height: 62vh und schöbe
   die Liste sonst aus dem Bild - deshalb wird er kleiner, WENN eine
   Schnellauswahl folgt. Browser ohne :has() zeigen beides untereinander,
   nur weiter unten; das ist die harmlosere Hälfte des Verhaltens.
   ==================================================================== */
.starmap-empty:has(+ .starmap-quick) {
  min-height: 0;
  padding: 26px 20px 18px;
}
.starmap-empty:has(+ .starmap-quick) .starmap-empty__icon {
  width: 40px;
  height: 40px;
  margin-bottom: 12px;
  font-size: 17px;
}

.starmap-quick {
  padding: 0 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.starmap-quick__title {
  font-family: var(--font-heading);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: #63709a;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(120, 180, 255, 0.1);
  margin-bottom: 2px;
}
.starmap-quick__title b { color: #7fe9ff; font-weight: 600; }

.starmap-quick__row {
  width: 100%;
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) 14px;
  align-items: center;
  gap: 0 9px;
  padding: 7px 4px;
  background: none;
  border: 0;
  border-bottom: 1px solid rgba(120, 180, 255, 0.05);
  color: #b7c2de;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.starmap-quick__row:hover { background: rgba(120, 180, 255, 0.07); }
.starmap-quick__row > .ph { color: #63709a; font-size: 14px; }
.starmap-quick__row--home > .ph { color: #46d9d0; }

.starmap-quick__ident { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.starmap-quick__name {
  font-size: 12px;
  color: #dbe4ff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.starmap-quick__meta {
  font-size: 10px;
  letter-spacing: 0.04em;
  color: #63709a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.starmap-quick__go { color: #3f4a68; font-size: 12px; }
.starmap-quick__row:hover .starmap-quick__go { color: #7fe9ff; }

.starmap-quick__fav > summary { cursor: pointer; list-style: none; }
.starmap-quick__fav > summary::-webkit-details-marker { display: none; }
.starmap-quick__fav > summary::before {
  content: '\25B8';
  display: inline-block;
  margin-right: 6px;
  transition: transform 0.15s ease;
}
.starmap-quick__fav[open] > summary::before { transform: rotate(90deg); }

/* ====================================================================
   WURMLÖCHER AUF DER STERNENKARTE (Spec 2026-09-19)

   Ein Tor ist ein Paar aus zwei Mündungen und einer Verbindung dazwischen.
   Gezeichnet wird nur, was der Server geliefert hat — ein Ende im Nebel
   fährt gar nicht erst mit. Eine einzelne Mündung ohne Linie ist deshalb
   der Normalfall: ein gefundenes Tor mit unbekanntem Ausgang.

   ALLES IM DOM, nichts auf einer Leinwand. Die Karte zeichnet bereits auf
   drei Canvas-Ebenen in voller Kartengröße und ist seit 2026-08-21 auf
   4096 px gedeckelt, weil Tiefenkartierung Stufe 2 sonst gigabyteweise
   Speicher zog. Die Richtstrahlen nebenan lösen es genauso.
   ==================================================================== */
.starmap-wormhole__mouth {
  position: absolute;
  /* z2 wie die Trümmerfelder: anklickbare Objekte liegen über dem Nebel
     (z3 wäre darüber, aber der Nebel gehört über ein Tor, das man nicht
     sehen darf — der Server liefert es dann ohnehin nicht). */
  z-index: 2;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  cursor: pointer;
  /* Ein Sog, kein Stern: außen dunkel, innen ein heller Kern, dazwischen
     ein Ring, der die Verzerrung andeutet. */
  background:
    radial-gradient(circle at 50% 50%, rgba(216, 180, 255, 0.95) 0%, rgba(150, 90, 230, 0.55) 22%,
      rgba(60, 20, 110, 0.75) 46%, rgba(12, 6, 26, 0.9) 68%, rgba(8, 4, 18, 0) 100%);
  box-shadow: 0 0 14px rgba(170, 110, 255, 0.55), inset 0 0 10px rgba(30, 10, 60, 0.9);
  animation: starmapWormholeSwirl 7s linear infinite;
}

.starmap-wormhole__mouth::before {
  content: '';
  position: absolute;
  inset: 22%;
  border-radius: 50%;
  border: 1px solid rgba(220, 190, 255, 0.5);
  border-right-color: transparent;
  border-bottom-color: transparent;
}

.starmap-wormhole__mouth:hover {
  box-shadow: 0 0 22px rgba(200, 150, 255, 0.85), inset 0 0 10px rgba(30, 10, 60, 0.9);
}

/* Eigene Tore in der Hausfarbe, fremde violett — dieselbe Trennung wie bei
   den Hoheitsgebieten. */
.starmap-wormhole__mouth.starmap-wormhole--own {
  background:
    radial-gradient(circle at 50% 50%, rgba(180, 250, 255, 0.95) 0%, rgba(70, 200, 220, 0.55) 22%,
      rgba(14, 70, 100, 0.75) 46%, rgba(6, 18, 26, 0.9) 68%, rgba(4, 12, 18, 0) 100%);
  box-shadow: 0 0 14px rgba(90, 220, 240, 0.6), inset 0 0 10px rgba(8, 30, 45, 0.9);
}

.starmap-wormhole__link {
  position: absolute;
  /* z1 wie die Richtstrahlen: Die Verbindung ist Kulisse und darf die
     Sterne nicht dämpfen, die sie überquert. */
  z-index: 1;
  transform-origin: 0 50%;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(170, 110, 255, 0.55) 0%,
    rgba(170, 110, 255, 0.14) 35%,
    rgba(170, 110, 255, 0.14) 65%,
    rgba(170, 110, 255, 0.55) 100%);
}

.starmap-wormhole__link.starmap-wormhole--own {
  background: linear-gradient(90deg,
    rgba(90, 220, 240, 0.55) 0%,
    rgba(90, 220, 240, 0.14) 35%,
    rgba(90, 220, 240, 0.14) 65%,
    rgba(90, 220, 240, 0.55) 100%);
}

@keyframes starmapWormholeSwirl {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

/* Eine Flotte im Wurmloch (Spec 2026-09-19).

   Sie kreist spiralförmig um ihren TORAUSGANG - sie ist schon drin, was man
   sieht, ist ihr Herauskommen auf der anderen Seite. Die Position rechnet
   das JS aus der verstrichenen Zeit; hier steht nur, wie sie aussieht.

   Die Positionswechsel bekommen einen weichen Übergang: Der Takt der Karte
   läuft im Sekundenrhythmus, ohne ihn ruckelte die Flotte von Punkt zu
   Punkt. */
.starmap-wormhole__transit {
  position: absolute;
  z-index: 3;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle at 50% 50%,
    rgba(230, 210, 255, 0.98) 0%, rgba(170, 110, 255, 0.85) 45%, rgba(90, 40, 160, 0) 100%);
  box-shadow: 0 0 10px rgba(190, 140, 255, 0.9);
  transition: left 1s linear, top 1s linear;
}

.starmap-wormhole__transit::after {
  content: '';
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid rgba(200, 160, 255, 0.35);
  border-top-color: transparent;
  animation: starmapWormholeSwirl 1.6s linear infinite;
}

/* ====================================================================
   KARTENFILTER (Nutzerwunsch 2026-09-19)

   "Die Karte soll sich dann abdunkeln und die Filter highlighten (also
   diese bleiben dann hell)."

   DIE ABDUNKELUNG IST REIN VISUELL. Sie greift nicht in die zwanzig
   Zeichenfunktionen der Karte ein — die setzen nur noch `is-match`, wenn
   ihr Element zur Auswahl passt. Eine Filterung, die Elemente WEGLÄSST,
   müsste in jede einzelne hinein.

   WARUM !important, und zwar ausnahmsweise mit gutem Grund: Der
   Sternmarker trägt seine Deckkraft INLINE, weil sie vom Nebel abhängt
   (`opacity:' + containerOpacity + '`). Ein Inline-Style schlägt jede
   Klassenregel — ohne !important passierte hier schlicht nichts. Die
   Alternative wäre, die Filterdämpfung in die Zeichenfunktion
   hineinzurechnen; dann stünde eine Anzeigeentscheidung mitten in der
   Nebelberechnung.
   ==================================================================== */
.starmap-world.is-filtered .starmap-system:not(.is-match) {
  opacity: 0.14 !important;
  filter: grayscale(0.8) !important;
  transition: opacity 0.18s ease, filter 0.18s ease;
}

/* Die übrigen Kartenobjekte dämpfen mit — sie tragen keine Trefferklasse,
   weil der Filter nach SYSTEMEN fragt. Ein Trümmerfeld gehört zu keiner
   der sieben Kategorien und ist damit immer „nicht gesucht". */
.starmap-world.is-filtered .starmap-debris-field,
.starmap-world.is-filtered .starmap-asteroid-canvas,
.starmap-world.is-filtered .starmap-beam,
.starmap-world.is-filtered .starmap-wormhole__link {
  opacity: 0.12 !important;
  transition: opacity 0.18s ease;
}

/* Der Treffer bleibt, wie er ist — er bekommt zusätzlich einen leisen
   Schimmer, damit er auf einer vollen Karte auch dann auffällt, wenn
   ringsum wenig gedämpft wurde. */
.starmap-world.is-filtered .starmap-system.is-match {
  transition: opacity 0.18s ease;
}

.starmap-world.is-filtered .starmap-system.is-match::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 50%;
  pointer-events: none;
  border: 1px solid rgba(127, 233, 255, 0.55);
  box-shadow: 0 0 14px rgba(127, 233, 255, 0.35);
  animation: starmapFilterPulse 2.4s ease-in-out infinite;
}

@keyframes starmapFilterPulse {
  0%, 100% { opacity: 0.35; transform: scale(1); }
  50% { opacity: 0.9; transform: scale(1.12); }
}

/* --- Der Reiter selbst --- */
.starmap-filter { display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; }

.starmap-filter__search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border: 1px solid rgba(120, 180, 255, 0.16);
  background: rgba(10, 16, 30, 0.6);
}
.starmap-filter__search .ph { color: #63709a; font-size: 14px; }
.starmap-filter__search input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  color: #dbe4ff;
  font: inherit;
  font-size: 12px;
  outline: none;
}
.starmap-filter__search input::placeholder { color: #4d5878; }

.starmap-filter__rows { display: flex; flex-direction: column; }

.starmap-filter__row {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) 16px;
  align-items: center;
  gap: 0 9px;
  padding: 8px 4px;
  background: none;
  border: 0;
  border-bottom: 1px solid rgba(120, 180, 255, 0.05);
  color: #b7c2de;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.starmap-filter__row:hover { background: rgba(120, 180, 255, 0.07); }
.starmap-filter__row > .ph { color: #63709a; font-size: 14px; }
.starmap-filter__row.is-on { color: #dbe4ff; }
.starmap-filter__row.is-on > .ph { color: #7fe9ff; }
.starmap-filter__label { font-size: 12px; }
.starmap-filter__box { color: #3f4a68; font-size: 15px; }
.starmap-filter__row.is-on .starmap-filter__box { color: #7fe9ff; }

.starmap-filter__note {
  margin: 0;
  font-size: 10px;
  line-height: 1.5;
  color: #63709a;
}

.starmap-filter__clear {
  align-self: flex-start;
  padding: 5px 10px;
  background: none;
  border: 1px solid rgba(120, 180, 255, 0.2);
  color: #8fd8ff;
  font: inherit;
  font-size: 10px;
  letter-spacing: 0.1em;
  cursor: pointer;
}
.starmap-filter__clear:hover { background: rgba(120, 180, 255, 0.1); }

/* ------------------------------------------------------------------
   Das Rundenergebnis (Spec 2026-09-20)

   Das Band steht ueber allem und laesst sich nicht wegklicken - es sagt
   nichts anderes als "hier passiert nichts mehr". Die Seite darunter
   folgt der Bauart des Menuepunkts "Das Signal": ruhige Bloecke, ein
   Balken je Ziel, die Auszeichnungen als Dreispalter.
   ------------------------------------------------------------------ */

.round-end-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  background: linear-gradient(90deg, rgba(120, 90, 30, 0.35), rgba(30, 30, 40, 0.35));
  border-bottom: 1px solid rgba(220, 180, 90, 0.35);
  color: #e8d9ae;
  font-size: 13px;
  letter-spacing: 0.04em;
}

.round-end-banner i {
  font-size: 18px;
  flex: 0 0 auto;
}

.round-result {
  margin-bottom: 22px;
}

.round-result__pending {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 6px;
  color: #9aa4b5;
}

.round-result__head {
  padding: 22px 24px;
  border: 1px solid rgba(220, 180, 90, 0.28);
  border-radius: 6px;
  background: rgba(20, 22, 30, 0.7);
}

/* Der Ausgang faerbt den Kopf - vom vollen Sieg bis zur Null. */
.round-result__head--convergence_averted { border-color: rgba(120, 220, 150, 0.45); }
.round-result__head--costly_partial { border-color: rgba(220, 180, 90, 0.45); }
.round-result__head--reprieve { border-color: rgba(150, 170, 220, 0.45); }
.round-result__head--null_prevails { border-color: rgba(220, 110, 110, 0.45); }

.round-result__eyebrow {
  font-size: 11px;
  letter-spacing: 0.18em;
  color: #8d97a8;
  margin-bottom: 8px;
}

.round-result__title {
  margin: 0 0 10px;
  font-size: 26px;
  line-height: 1.2;
  color: #f0e6cf;
}

.round-result__text {
  margin: 0;
  max-width: 62ch;
  color: #b9c2d0;
  line-height: 1.6;
}

.round-result__block {
  margin-top: 18px;
}

.round-result__blocktitle {
  margin: 0 0 10px;
  font-size: 11px;
  letter-spacing: 0.16em;
  color: #8d97a8;
}

.round-goal {
  margin-bottom: 10px;
}

.round-goal__head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  color: #b9c2d0;
  margin-bottom: 4px;
}

.round-goal__bar {
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.07);
  overflow: hidden;
}

.round-goal__bar span {
  display: block;
  height: 100%;
  background: rgba(150, 170, 220, 0.6);
}

.round-goal.is-reached .round-goal__label {
  color: #a8e8bd;
}

.round-goal.is-reached .round-goal__bar span {
  background: rgba(120, 220, 150, 0.75);
}

.round-award {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: 12px;
  padding: 7px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  font-size: 13px;
}

.round-award__label { color: #8d97a8; }
.round-award__who { color: #e6ecf5; }
.round-award__value { color: #b9c2d0; text-align: right; }

/* DIE AUSZEICHNUNGEN ALS ECHTE TABELLE (Nutzerbefund 2026-09-22: "Tabelle
   'Auszeichnungen' schwimmt der Spielername").

   Das Raster darueber (.round-award) bleibt fuer die EINE Zeile unter "Dein
   Platz" stehen - dort gibt es nichts auszurichten. In der Liste richtet
   jetzt der Browser die Spalten ueber alle Zeilen aus, und das ist der
   eigentliche Unterschied: Ein Grid aus <span> kennt keine gemeinsame
   Spaltenbreite ueber Zeilengrenzen hinweg.

   tabular-nums auf der Zahlenspalte: Proportionale Ziffern sind verschieden
   breit (die 1 schmaler als die 8), wodurch Tausenderstellen versetzt
   untereinander stehen. */
.round-award-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.round-award-table th {
  padding: 6px 10px;
  text-align: left;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #6f7a8d;
  border-bottom: 1px solid rgba(255, 255, 255, .12);
}
.round-award-table td {
  padding: 7px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, .05);
}
.round-award-table th.round-award__value,
.round-award-table td.round-award__value {
  text-align: right;
  font-variant-numeric: tabular-nums;
  width: 1%;
  white-space: nowrap;
}
.round-award-table th.round-award__label,
.round-award-table td.round-award__label { width: 40%; }

/* ===================================================================
   Der Endstand aller Spieler (Nutzerwunsch 2026-09-22)
   =================================================================== */

.standings__head { margin-bottom: 14px; }
.standings__title {
  margin: 0 0 4px;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 20px;
  color: #eafcff;
}
.standings__sub { margin: 0; font-size: 12.5px; color: #8d97a8; }

/* Die Reiterreihe darf umbrechen: Bei fuenfzehn Wertungen passt sie in kein
   Modal auf eine Zeile, und waagerecht zu schieben versteckte die hinteren. */
.standings__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}
.standings__tab {
  padding: 6px 12px;
  border: 1px solid rgba(120, 180, 255, .2);
  border-radius: var(--radius-sm);
  background: rgba(12, 18, 34, .7);
  color: #9aa7c7;
  font-family: 'Chakra Petch', sans-serif;
  font-size: 11.5px;
  letter-spacing: .06em;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.standings__tab:hover { color: #cfe4ff; border-color: rgba(120, 180, 255, .4); }
.standings__tab--on {
  border-color: rgba(127, 233, 255, .6);
  background: rgba(20, 48, 72, .8);
  color: #eafcff;
  box-shadow: 0 0 12px rgba(127, 233, 255, .16);
}

/* Der Tabellenbereich bekommt eine feste Hoehe: Ohne sie springt das Modal
   bei jedem Reiterwechsel auf eine andere Groesse, weil eine Wertung mit
   vierzig Zeilen neben einer mit dreien steht. */
.standings__body {
  max-height: 52vh;
  overflow-y: auto;
  border: 1px solid rgba(120, 180, 255, .16);
  border-radius: var(--radius-sm);
  background: rgba(8, 12, 24, .5);
}

.standings__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.standings__table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 8px 12px;
  text-align: left;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #6f7a8d;
  background: rgba(14, 20, 36, .96);
  border-bottom: 1px solid rgba(120, 180, 255, .22);
}
.standings__table td {
  padding: 8px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, .05);
  color: #cfd8e6;
}
.standings__table tbody tr:last-child td { border-bottom: 0; }

/* Die Rangspalte so schmal wie noetig, damit Namen nicht gedraengt stehen. */
th.standings__rank, td.standings__rank {
  width: 1%;
  white-space: nowrap;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: #7f8b9e;
}
th.standings__value, td.standings__value {
  width: 1%;
  white-space: nowrap;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: #e6ecf5;
}
td.standings__who { color: #e6ecf5; }

/* DIE ERSTEN DREI PLAETZE FARBIG. Das ist keine Verzierung: Das Podium ist
   die Auskunft, wegen der man eine Rangliste oeffnet - es vorn zu erkennen
   erspart das Lesen der Zahlen. */
td.standings__rank--p1 { color: var(--accent-gold); font-weight: 700; }
td.standings__rank--p2 { color: #c7d0dc; font-weight: 700; }
td.standings__rank--p3 { color: #c98b5e; font-weight: 700; }

/* Die eigene Zeile. Ein Streifen am linken Rand statt einer Hintergrundfarbe
   ueber die ganze Breite: Der Streifen findet sich beim Ueberfliegen, ohne
   mit der Podiumsfarbe daneben zu streiten. */
.standings__row--me td {
  background: rgba(127, 233, 255, .07);
}
.standings__row--me td:first-child {
  box-shadow: inset 2px 0 0 var(--accent-cyan, #7fe9ff);
}

.standings__bot {
  margin-left: 7px;
  padding: 1px 5px;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 3px;
  font-size: 9.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #7f8b9e;
  vertical-align: middle;
}

.standings__empty {
  margin: 0;
  padding: 18px 12px;
  text-align: center;
  color: #8d97a8;
  font-size: 13px;
}

/* Der Knopf, der den Endstand oeffnet - auf der Abschlussseite und im
   Erst-Modal derselbe. */
.signal__standings-cta {
  display: flex;
  justify-content: center;
  margin: 0 0 18px;
}

@media (max-width: 720px) {
  .standings__body { max-height: 60vh; }
  .standings__table { font-size: 12px; }
  .standings__table td, .standings__table thead th { padding: 7px 8px; }
}

.round-result--modal .round-result__head {
  border: 0;
  background: none;
  padding: 0 0 8px;
}

.round-result__more {
  margin-top: 14px;
  font-size: 12px;
  color: #8d97a8;
}

@media (max-width: 720px) {
  .round-award {
    grid-template-columns: 1fr auto;
  }

  .round-award__label {
    grid-column: 1 / -1;
  }
}

/* ------------------------------------------------------------------
   Das Filterband über der Karte (Nutzerwunsch 2026-09-20)

   OBEN MITTIG UND ÜBER ALLEM: Es muss auffallen, solange die Karte
   abgedunkelt ist - sonst sucht man den Weg zurück im Reiter, den man
   gerade zugeklappt hat.

   z-index 8 liegt über den Kartenschichten (Nebel 3, Kontur 4,
   Unbekannt-Kulisse 5, Marker 6) und unter den Modalen. Die Minikarte
   und der Navigator sitzen an den Rändern, das Band in der Mitte - sie
   kommen sich nicht ins Gehege.
   ------------------------------------------------------------------ */

.starmap-filter-badge {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 8;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(560px, 60%);
  padding: 7px 8px 7px 14px;
  border: 1px solid rgba(120, 200, 230, 0.45);
  border-radius: 999px;
  background: rgba(12, 18, 28, 0.92);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.55);
  font-size: 12.5px;
  color: #cfe3f2;
}

.starmap-filter-badge > i {
  color: #7ec8e3;
  flex: 0 0 auto;
}

/* Bei vielen Kategorien bleibt das Band schmal und kürzt den Text ab -
   die Alternative wäre ein Band, das die halbe Karte verdeckt. */
.starmap-filter-badge__text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.starmap-filter-badge__clear {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 11px;
  border: 1px solid rgba(220, 120, 120, 0.4);
  border-radius: 999px;
  background: rgba(60, 20, 24, 0.7);
  color: #f0c4c4;
  font-size: 11.5px;
  font-family: inherit;
  cursor: pointer;
}

.starmap-filter-badge__clear:hover {
  border-color: rgba(240, 150, 150, 0.7);
  background: rgba(90, 28, 32, 0.85);
  color: #ffe0e0;
}

@media (max-width: 720px) {
  .starmap-filter-badge {
    max-width: calc(100% - 24px);
  }

  /* Auf schmalen Schirmen zählt der Knopf, nicht die Aufzählung. */
  .starmap-filter-badge__text {
    display: none;
  }
}

/* ------------------------------------------------------------------
   Die Reiter der rechten Orga-Spalte (Nutzerwunsch 2026-09-20)

   Vorher standen Freunde & Feinde, Bewegungen und Wurmlöcher
   untereinander - man scrollte an zwei Tabellen vorbei, um die dritte
   zu sehen.
   ------------------------------------------------------------------ */

.orgb-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 10px;
}

.orgb-tab {
  flex: 1 1 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 8px 10px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 5px;
  background: rgba(18, 24, 34, 0.7);
  color: #9aa4b5;
  font-family: inherit;
  font-size: 12px;
  letter-spacing: 0.04em;
  cursor: pointer;
  /* Bei drei Reitern nebeneinander wird es schmal - der Text darf
     kürzen, statt die Leiste umzubrechen. */
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.orgb-tab:hover {
  border-color: rgba(255, 255, 255, 0.2);
  color: #cfd8e6;
}

.orgb-tab.is-active {
  border-color: rgba(120, 200, 230, 0.55);
  background: rgba(24, 44, 60, 0.85);
  color: #dff0fa;
}

.orgb-tab i {
  flex: 0 0 auto;
  font-size: 15px;
}

/* Auf schmalen Schirmen zählt das Symbol, nicht das Wort. */
@media (max-width: 900px) {
  .orgb-tab span {
    display: none;
  }
}

/* ==========================================================================
   Aktualisierungsbereich (2026-10-02)

   Der Administrationsteil zeigt hier den installierten Stand und spielt
   Aktualisierungspakete ein. Balken und Protokoll sind bewusst schlicht: Man
   sieht sie selten, und dann will man eine Zahl und eine Liste lesen.
   ========================================================================== */

.update__panel {
  padding: 20px 22px;
  margin-bottom: 16px;
}

.update__label {
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 4px;
}

.update__hinweis {
  font-size: 13px;
  line-height: 1.6;
  padding: 12px 14px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .03);
  border-left: 2px solid rgba(120, 180, 255, .3);
}

.update__hinweis--warnung {
  background: rgba(255, 215, 106, .08);
  border-left-color: var(--accent-yellow, #ffd76a);
  color: #ffe9a8;
}

.update__hinweis--fehler {
  background: rgba(224, 85, 97, .09);
  border-left-color: var(--accent-red);
  color: #ffc2c7;
}

.update__hinweis--ok {
  background: rgba(143, 224, 160, .09);
  border-left-color: var(--accent-green, #8fe0a0);
  color: #c4f0ce;
}

.update-balken {
  height: 9px;
  background: rgba(255, 255, 255, .06);
  border-radius: 99px;
  overflow: hidden;
  margin-bottom: 14px;
}

.update-balken i {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--accent-bright, #7ff0e8), #7fa8ff);
  border-radius: 99px;
  transition: width .25s ease;
}

/* Feste Hoehe statt max-height: Der Kasten waechst sonst mit jeder Zeile und
   schiebt den Knopf darunter weg - mitten im Lauf, wenn niemand scrollen will. */
.update-protokoll {
  height: 220px;
  overflow-y: auto;
  background: rgba(0, 0, 0, .35);
  border: 1px solid rgba(120, 180, 255, .12);
  border-radius: 8px;
  padding: 12px 14px;
  font-family: var(--font-body);
  font-size: 12px;
  line-height: 1.75;
  color: var(--text-dim);
}

.update-protokoll__kopf { color: var(--accent-bright, #7ff0e8); margin-top: 8px; }
.update-protokoll__ok { color: var(--accent-green, #8fe0a0); }
.update-protokoll__warnung { color: var(--accent-yellow, #ffd76a); }
.update-protokoll__fehler { color: var(--accent-red); }

/* ==========================================================================
   Bot-Tick-Anzeige im Universums-Detail (2026-09-21)

   Beantwortet die Frage "laeuft mein Cron-Eintrag?", ohne dass jemand per FTP
   in storage/logs/app.log steigen muss.
   ========================================================================== */

.admin-bot-tick__wert {
  font-size: 19px;
  font-weight: 600;
  color: var(--accent-bright, #7ff0e8);
  line-height: 1.3;
}

/* Laenger als 30 Minuten her - grosszuegig gewaehlt, damit die Warnung
   etwas bedeutet, wenn sie kommt. */
.admin-bot-tick__wert.is-alt {
  color: var(--accent-yellow, #ffd76a);
}

.admin-bot-tick__note {
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.5;
  margin-top: 3px;
}

.admin-bot-tick__warnung {
  margin-top: 10px;
  padding: 9px 11px;
  border-radius: 7px;
  font-size: 12.5px;
  line-height: 1.55;
  background: rgba(255, 215, 106, .08);
  border-left: 2px solid var(--accent-yellow, #ffd76a);
  color: #ffe9a8;
}

.admin-bot-tick__warnung code {
  font-family: var(--font-body);
  font-size: 12px;
  background: rgba(0, 0, 0, .3);
  padding: 1px 5px;
  border-radius: 3px;
}

/* Die beiden Wege nebeneinander (2026-09-21): Cron-Eintrag und Spielaufruf.
   Nebeneinander und nicht untereinander, weil der Vergleich die Aussage ist -
   ein voller Spielaufruf neben einem leeren Cron ist genau der Befund, den
   diese Anzeige sichtbar machen soll. */
.admin-bot-tick__quellen {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 11px;
}

@media (max-width: 720px) {
  .admin-bot-tick__quellen {
    grid-template-columns: 1fr;
  }
}

.admin-bot-tick__quelle {
  padding: 8px 10px;
  border-radius: 7px;
  background: rgba(255, 255, 255, .025);
  border: 1px solid rgba(255, 255, 255, .06);
}

/* Der Cron ist der Betriebsweg, der Spielaufruf die Notversorgung - deshalb
   bekommt nur er die farbige Kante. */
.admin-bot-tick__quelle--cron {
  border-left: 2px solid var(--accent-bright, #7ff0e8);
}

.admin-bot-tick__quelle.is-leer {
  opacity: .72;
}

.admin-bot-tick__quelle.is-leer.admin-bot-tick__quelle--cron {
  border-left-color: var(--accent-yellow, #ffd76a);
}

.admin-bot-tick__quelle-kopf {
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  gap: 5px;
}

.admin-bot-tick__quelle-wert {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text-bright, #e8f4ff);
  margin-top: 3px;
  line-height: 1.3;
}

/* ==========================================================================
   Die Einleitung beim Rundenstart (2026-09-21)

   Sie erscheint genau einmal und soll sich wie ein Auftakt lesen, nicht wie
   ein Hilfetext. Deshalb eine Kopfzone mit Fliesstext und darunter Bloecke,
   die man ueberfliegen kann - wer alles liest, bekommt die Geschichte, wer
   scrollt, bekommt die Stichworte.
   ========================================================================== */

.intro {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 4px 2px;
}

.intro__hero {
  padding-bottom: 20px;
  border-bottom: 1px solid rgba(120, 180, 255, .14);
}

.intro__eyebrow {
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--accent-bright, #7ff0e8);
  margin-bottom: 8px;
}

.intro__title {
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-size: 27px;
  letter-spacing: .02em;
}

.intro__lead {
  margin: 0;
  font-size: 15px;
  line-height: 1.7;
  color: var(--text);
  max-width: 68ch;
}

/* Zwei Spalten, solange Platz ist - das Modal ist im wide-Modus breit genug.
   Unter 780 px stapeln sie sich von selbst. */
.intro__blocks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 18px 26px;
}

.intro__block-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 7px;
}

.intro__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 8px;
  font-size: 16px;
  color: var(--intro-color, #46d9d0);
  background: color-mix(in srgb, var(--intro-color, #46d9d0) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--intro-color, #46d9d0) 32%, transparent);
}

.intro__block-title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .02em;
}

.intro__block-text {
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--text-dim);
}

.intro__block-text strong {
  color: var(--text);
  font-weight: 600;
}

.intro__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  padding-top: 18px;
  border-top: 1px solid rgba(120, 180, 255, .14);
}

.intro__hint {
  margin: 0;
  font-size: 12.5px;
  color: var(--text-dim);
  max-width: 52ch;
}

.intro__btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  padding: 12px 26px;
}

@media (max-width: 640px) {
  .intro__title { font-size: 22px; }
  .intro__footer { flex-direction: column; align-items: stretch; }
  .intro__btn { justify-content: center; }
}


/* ==========================================================================
   "Was ist neu?" (Nutzerwunsch 2026-09-21)

   Der Kopf steht, die Liste rollt. Die Bildlaufleiste sitzt deshalb auf
   `.whats-new__list` und nicht auf dem Modal - sonst wandert die
   Ueberschrift beim Blaettern durch zwanzig Fassungen mit nach oben weg.

   Die Hoehe ist an das Fenster gebunden (`max-height: 64vh`) und nicht fest
   gesetzt: Auf einem kleinen Bildschirm waere eine feste Hoehe entweder zu
   gross (Modal laeuft unten heraus) oder zu klein (halbe Liste sichtbar bei
   viel Platz).

   DIE BREITE KOMMT VON `.detail-modal--medium` (760 px), gesetzt in
   `views/whats-new.js`. Die Vorgabe von 420 px war zu eng (Nutzerbefund
   2026-09-21: "das whats new modal darf groesser sein, ist etwas
   gequetscht") - bei fuenf bis sechs Punkten je Fassung brach dort jede
   zweite Zeile. Die Abstaende hier sind auf diese Breite abgestimmt.
   ========================================================================== */
.whats-new {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 6px 4px;
  min-width: 0;
}

.whats-new__head {
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}

.whats-new__eyebrow {
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--accent-bright, #7ff0e8);
  margin-bottom: 8px;
}

.whats-new__heading {
  margin: 0 0 10px;
  font-family: var(--font-heading);
  font-size: 26px;
  letter-spacing: .02em;
}

.whats-new__lead {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
}

.whats-new__list {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 64vh;
  overflow-y: auto;
  /* Platz fuer die Bildlaufleiste, damit sie nicht auf dem Text liegt. */
  padding-right: 10px;
}

.whats-new__entry {
  padding: 16px 18px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .025);
  border: 1px solid rgba(255, 255, 255, .06);
}

/* Die laufende Fassung hebt sich ab - beim Oeffnen soll ohne Suchen klar
   sein, was gerade eingespielt ist. */
.whats-new__entry.is-current {
  border-color: rgba(127, 240, 232, .30);
  background: rgba(127, 240, 232, .05);
}

.whats-new__entry-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.whats-new__version {
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 600;
  color: var(--accent-bright, #7ff0e8);
  font-variant-numeric: tabular-nums;
}

.whats-new__badge {
  font-size: 9.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: 3px;
  background: rgba(127, 240, 232, .14);
  color: #9ff2ec;
}

.whats-new__date {
  margin-left: auto;
  font-size: 11.5px;
  color: var(--text-dimmer);
  font-variant-numeric: tabular-nums;
}

.whats-new__title {
  margin-top: 5px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.45;
}

.whats-new__items {
  margin: 11px 0 0;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
}

.whats-new__items li {
  padding-left: 2px;
}

.whats-new__items li::marker {
  color: var(--text-dimmer);
}

.whats-new__empty {
  padding: 18px 4px;
  font-size: 13.5px;
  color: var(--text-dim);
}

/* Auf dem Telefon greift `max-width: 92vw` von `.detail-modal`, die 760 px
   spielen dort also keine Rolle - nur die Abstaende werden wieder enger. */
@media (max-width: 720px) {
  .whats-new__list {
    max-height: 60vh;
    padding-right: 4px;
  }
  .whats-new__entry {
    padding: 13px 14px;
  }
  .whats-new__heading {
    font-size: 22px;
  }
  .whats-new__date {
    margin-left: 0;
    width: 100%;
  }
}
