@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Inter:wght@400;500;600;700&display=swap');

/* ==========================================================================
   cyberscale.app -- Design-System

   Die Farben sind unveraendert uebernommen; nur --text-faint wurde angehoben.
   Vorher #5a5955 auf --surface: Kontrast 2,6:1. Das war fuer die 11px-Labels,
   die ueberall die Kennzahlen beschriften, zu wenig -- WCAG AA verlangt 4,5:1.
   Der neue Wert liegt bei 4,5:1 und wirkt kaum heller. Fuer rein dekorative
   Elemente (Punkte, Rahmen) gibt es --text-ghost mit dem alten Wert.
   ========================================================================== */

:root {
  --bg: #0d0d0f;
  --surface: #18181b;
  --surface-2: #202024;
  --surface-3: #26262b;
  --border: #2a2a2f;
  --border-soft: #232327;
  --text: #ece9e4;
  --text-dim: #8c8a86;
  --text-faint: #86847f;
  --text-ghost: #5a5955;
  --accent: #e8590c;
  --accent-soft: #f2864d;
  --accent-bg: rgba(232, 89, 12, 0.1);
  --accent-line: rgba(232, 89, 12, 0.28);
  --success: #5fd88f;
  --success-bg: rgba(95, 216, 143, 0.1);
  --warn: #f2b84d;
  --warn-bg: rgba(242, 184, 77, 0.12);
  --danger: #f16060;
  --danger-bg: rgba(241, 96, 96, 0.12);

  --radius: 10px;
  --radius-sm: 8px;
  --radius-lg: 14px;
  --sidebar-w: 236px;
  /* 71 statt 60. Nicht willkuerlich: der Kopf der Website ist 71 px hoch
     (16 px Polster oben und unten um eine Zeile von 1,05rem, plus die
     Linie), und seit Variante B ist es DERSELBE Kopf. 60 px waeren beim
     Wechsel von /app/ auf /seo/ ein Sprung von elf Pixeln. */
  --topbar-h: 71px;

  /* Hintergrund der klebenden Kopfleiste und die Farbe, die AUF dem
     Akzent lesbar ist.

     Beide standen bisher nur in magazin.css. Sie gehoeren aber in den
     gemeinsamen Satz: der Bau stellt genau diesen :root-Block der
     magazin.css voran ("eine Wahrheit fuer die Farben"), und seit die
     App dieselbe Kopfleiste traegt, braucht sie ihn auch. */
  --band: rgba(13, 13, 15, 0.86);
  --auf-akzent: #0d0d0f;

  /* Die Breite, in der die Website steht (.mag-kopf in magazin.css).
     Seit dem 25.08.2026 steht die App im selben Kasten -- Kopf,
     Seitenleiste und Inhalt. Gemessen live: das Logo sitzt auf beiden
     Seiten an derselben Stelle, vorher sprang es um 264 px. */
  --seite-max: 1180px;
  --mono: 'IBM Plex Mono', ui-monospace, monospace;
  --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.22);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

/* Ein sichtbarer Fokusring fuer alles Bedienbare. Vorher gab es keinen --
   mit der Tastatur war nicht erkennbar, wo man sich befindet. */
:focus-visible {
  outline: 2px solid var(--accent-soft);
  outline-offset: 2px;
  border-radius: 4px;
}

.num { font-variant-numeric: tabular-nums; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- Grundgeruest ---------------------------------------------------------- */

/* Seit Variante B liegt der Kopf UEBER beiden Spalten, nicht neben der
   Seitenleiste. Im Markup steht er aber weiter in .app-body -- die
   dreizehn Seiten sind Kopien aus dem Repo und wandern Byte fuer Byte
   nach dist/app/, da laesst sich nichts umhaengen.

   display:contents loest .app-body auf, ohne es zu entfernen: Kopf und
   Inhalt werden selbst zu Feldern des Gitters und finden ueber
   grid-area ihren Platz. */
/* VIER SPALTEN, VON DENEN ZWEI LEER SIND.

   Die beiden 1fr aussen sind die Raender; dazwischen stehen Leiste und
   Inhalt in genau der Breite, in der auch die Website steht. So fluchtet
   die App mit /seo/ und /magazin/, statt daneben ueber den ganzen Schirm
   zu laufen.

   DER KOPF SPANNT UEBER ALLE VIER. Das Band muss von Kante zu Kante
   gehen -- ein Balken, der in der Mitte aufhoert, sieht aus wie ein
   Kasten, nicht wie eine Kopfzeile. Zentriert wird nur sein INHALT, und
   zwar in .kopf-innen. Genau so macht es die Website mit
   .mag-kopf-band und .mag-kopf. */
.app-shell {
  display: grid;
  grid-template-columns:
    1fr
    var(--sidebar-w)
    minmax(0, calc(var(--seite-max) - var(--sidebar-w)))
    1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "kopf   kopf   kopf   kopf"
    ".      leiste inhalt .";
  min-height: 100vh;
}

.app-body { display: contents; }

/* --- Sidebar --------------------------------------------------------------- */

.sidebar {
  grid-area: leiste;
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: 18px 12px;
  display: flex;
  flex-direction: column;
  position: sticky;
  /* Klebt UNTER dem Kopf, nicht unter der Bildschirmkante -- sonst
     schoebe sie sich beim Scrollen darunter. */
  top: var(--topbar-h);
  height: calc(100vh - var(--topbar-h));
  overflow-y: auto;
  z-index: 40;

  /* OHNE SICHTBARE ROLLLEISTE.

     Gescrollt wird weiter -- mit Rad, Wischen, Tabulator und den
     Pfeiltasten. Nur der Balken ist weg.

     Zwei Gruende. Er stand mitten im Bild, keine zwei Zentimeter neben
     der Wortmarke, fuer anderthalb Bildschirme Inhalt. Und er nahm 16
     der 236 Pixel, die diese Leiste hat: die Beschriftung der Suche
     musste deshalb erst auf "Suchen" gekuerzt werden, und die Taste
     "Ctrl K" war davor schon abgeschnitten.

     Der Preis ist ehrlich zu nennen: ohne Balken sieht man nicht, dass
     unten noch etwas kommt. Was dort steht -- die Website-Punkte und
     die Rechtstexte -- steht aber auch oben im Kopf beziehungsweise auf
     jeder Seite im Fuss. Nichts davon ist nur hier zu finden. */
  scrollbar-width: none;
}

.sidebar::-webkit-scrollbar { display: none; }

/* HIER STAND DIE WORTMARKE. Seit Variante B traegt die gemeinsame
   Kopfleiste sie -- zwei Zentimeter darueber, in derselben Spalte.
   Zweimal dasselbe Logo untereinander sieht nach einem Fehler aus.

   Die einfarbige Maske aus img/marke-einfarbig.svg wird damit nirgends
   mehr gebraucht; im Kopf steht dieselbe Zeichnung inline, weil ein
   Logo, das eine Zehntelsekunde spaeter erscheint, die Leiste springen
   laesst. Die Datei bleibt liegen, sie kostet nichts und die
   zweifarbige Fassung daneben wird noch gebraucht. */

.sidebar-section-label {
  font-family: var(--mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--text-faint);
  padding: 14px 10px 6px;
}

.sidebar-nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  color: var(--text-dim);
  margin-bottom: 1px;
  position: relative;
  transition: background 0.12s ease, color 0.12s ease;
}

.sidebar-nav a:hover { background: var(--surface-2); color: var(--text); }

.sidebar-nav a.active {
  background: var(--accent-bg);
  color: var(--accent-soft);
  font-weight: 500;
}

/* Kante links statt nur Flaeche -- die aktive Seite ist so auch beim
   Ueberfliegen sofort erkennbar. */
.sidebar-nav a.active::before {
  content: "";
  position: absolute;
  left: 0; top: 7px; bottom: 7px;
  width: 2px;
  border-radius: 0 2px 2px 0;
  background: var(--accent);
}

.sidebar-nav .icon {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  opacity: 0.85;
}

.sidebar-nav .icon svg { width: 100%; height: 100%; display: block; }

.sidebar-footer {
  margin-top: auto;
  padding-top: 14px;
}

/* HIER STAND DER RUECKWEG "cyberscale.io". Ein einzelner Verweis auf die
   Hauptseite ergibt keinen Sinn mehr, wenn die ganze Website oben in der
   Kopfleiste steht. */

/* Die Website-Punkte in der Seitenleiste -- vollstaendig und immer.

   Sie sind das Gegenstueck zu .kopf-nav a.zweitrangig: was oben aus
   Platzgruenden fehlt, steht hier. Zwei der sieben ueberschneiden sich
   deshalb nicht mit dem Kopf, fuenf schon -- eine Gruppe aus zwei
   uebriggebliebenen Punkten waere aber keine Navigation, sondern ein
   Rest. Lieber die ganze Liste zweimal als eine halbe einmal.

   Auf schmalen Schirmen ist genau das die zweite Gruppe aus dem
   Entwurf: Werkzeuge oben, die Website darunter. */
.leiste-www { display: block; margin-top: 14px; flex-shrink: 0; }

/* Knapper als die Werkzeugliste darueber: keine Symbole, halber
   Zeilenabstand. Das ist der Rangunterschied und zugleich der Platz,
   den der Kontingent-Kasten unten braucht. */
.leiste-www__nav {
  display: flex;
  flex-direction: column;
}

.leiste-www__nav a {
  padding: 5px 10px;
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  color: var(--text-dim);
  text-decoration: none;
}

.leiste-www__nav a:hover,
.leiste-www__nav a:focus-visible {
  background: var(--surface-2);
  color: var(--text);
}

/* Rechtliche Pflichtangaben. Sie liegen auf der Hauptdomain, hier steht nur
   der Verweis -- so gibt es genau eine Fassung des Textes. */
.sidebar-recht {
  padding: 2px 8px 8px;
  font-size: 11.5px;
  color: var(--text-dim);
}

.sidebar-recht a {
  color: inherit;
}

.sidebar-recht a:hover,
.sidebar-recht a:focus-visible {
  color: var(--text);
  text-decoration: underline;
}

/* HIER STAND DER KONTOKASTEN DER SEITENLEISTE -- Kreis mit Anfangs-
   buchstabe, Adresse, darunter der Abmelde-Knopf. Seit Variante B steht
   das Konto rechts oben im Kopf (.konto-chip); ein zweiter Kontobereich
   unten in der Leiste waere dieselbe Auskunft ein zweites Mal.

   Ersatzlos geloescht und nicht auskommentiert: eine tote Regel, die
   noch dasteht, wird beim naechsten Umbau wieder mitgeschleppt. */

/* Kontingentanzeige im Fuss: zeigt den tatsaechlichen Stand statt einen
   Tarif zu bewerben, den es nicht gibt. */
.sidebar-quota {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 10px;
  background: var(--surface-2);
}

.sidebar-quota__label {
  font-family: var(--mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  margin: 0 0 8px;
}

.sidebar-quota__text { font-size: 12px; color: var(--text-dim); margin: 0 0 10px; line-height: 1.45; }
.sidebar-quota .btn { width: 100%; padding: 7px; font-size: 12px; }

/* Wieviel noch da ist, als Balken. Er steht NEBEN der Zahl und nicht an
   ihrer Stelle: ein Balken allein laesst sich nicht ablesen, eine Zahl
   allein nicht ueberfliegen. */
.sidebar-quota__balken {
  display: block;
  height: 4px;
  background: var(--border);
  border-radius: 3px;
  margin: 0 0 10px;
  overflow: hidden;
}

.sidebar-quota__balken i {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 3px;
}

/* --- Die gemeinsame Kopfleiste ---------------------------------------------

   VARIANTE B: ein Kopf statt zwei. Links die Website, rechts die App,
   dazwischen ein Strich.

   SIE SIEHT AUS WIE DER KOPF DER WEBSITE, UND DAS IST DER GANZE PUNKT.
   Die Werte stammen von dort und sind am 24.08.2026 im Betrieb
   nachgemessen: 71 px hoch, --band als Grund, eine Linie aus
   --border-soft darunter, dahinter ein Weichzeichner. Wer sie hier
   aendert, aendert die Naht zwischen /app/ und /seo/ -- der Kopf der
   Website steht in magazin.css unter .mag-kopf-band.

   Das BAND geht von Kante zu Kante, sein INHALT steht in denselben
   1180 px wie die Website. Damit sitzt das Logo auf beiden Seiten an
   derselben Stelle -- vorher sprang es beim Klick auf "Werkzeuge" um
   264 Pixel nach links. */

.topbar {
  grid-area: kopf;
  position: sticky;
  top: 0;
  /* Ueber der Seitenleiste (40), die ihrerseits ueber dem Inhalt liegt. */
  z-index: 50;
  height: var(--topbar-h);
  background: var(--band);
  backdrop-filter: saturate(1.3) blur(10px);
  -webkit-backdrop-filter: saturate(1.3) blur(10px);
  border-bottom: 1px solid var(--border-soft);
}

/* 24 px Polster wie .mag-kopf, damit das Logo bei derselben x-Position
   landet und nicht 2 Pixel daneben. */
.kopf-innen {
  max-width: var(--seite-max);
  height: 100%;
  margin: 0 auto;
  padding: 0 24px;
  display: flex;
  align-items: center;
  gap: 20px;
}

/* Die Wortmarke. Dieselbe Groesse wie im Kopf der Website. */
.kopf-marke {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
}

.kopf-marke__bild { flex: 0 0 auto; }

/* Die Navigation der Website. Sie darf NICHT umbrechen -- die Leiste ist
   71 px hoch, eine zweite Zeile haette dort keinen Platz und schoebe den
   Inhalt darunter weg. Stattdessen fallen unter 1400 px zwei Punkte
   heraus (siehe .zweitrangig), und die Seitenleiste faengt sie auf. */
.kopf-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
  white-space: nowrap;
}

.kopf-nav a {
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  color: var(--text-dim);
  text-decoration: none;
}

.kopf-nav a:hover {
  background: var(--surface-2);
  color: var(--text);
}

/* Wo man gerade ist -- hier immer "Werkzeuge". Der Strich darunter statt
   nur einer Farbe: wer Farben nicht unterscheidet, saehe sonst keinen
   Unterschied. Dieselbe Regel wie auf der Website. */
.kopf-nav a[aria-current="page"] {
  color: var(--text);
  box-shadow: inset 0 -2px 0 var(--accent);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

/* SOFTWAREENTWICKLUNG UND TOOLS STEHEN NICHT IM KOPF -- IMMER NICHT.

   Bis zum 25.08.2026 hing das an einer Medienabfrage bei 1400 px: auf
   breiten Schirmen standen alle sieben da, darunter fielen zwei heraus.
   Diese Rechnung galt fuer einen Kopf, der so breit war wie der Schirm.

   Seit die App im 1180-px-Kasten der Website steht, gibt es keine
   Bildschirmbreite mehr, bei der alle sieben passen: 48 px Polster
   abgezogen bleiben 1132, und Marke, Navigation, Strich, Suche, Sprache
   und Konto brauchen zusammen rund 1290. Mit den beiden weniger sind es
   1119 -- es passt, aber knapp.

   Die Medienabfrage ist damit weg und die Regel schlicht. Erreichbar
   bleiben beide: .leiste-www zeigt in der Seitenleiste alle sieben,
   ebenfalls immer. */
.kopf-nav a.zweitrangig { display: none; }

/* DER STRICH. Er trennt, was zur Website gehoert, von dem, was zur App
   gehoert. Ohne ihn liest sich die Leiste als eine einzige, sehr lange
   Navigation -- das war der Einwand im Entwurf, und er stimmt. */
.kopf-strich {
  width: 1px;
  height: 26px;
  background: var(--border);
  flex-shrink: 0;
  /* Schiebt sich selbst und alles danach an den rechten Rand. Diese
     Aufgabe hatte die Suche, solange sie hier stand und den freien Platz
     aufnahm; seit sie in der Seitenleiste sitzt, faellt sie dem Strich
     zu. Ohne das klebte die App-Bedienung an der Navigation, und der
     freie Platz stuende rechts aussen. */
  margin-left: auto;
}

/* Schiebt alles Weitere nach rechts und gibt der Suche den Platz, den
   sie kriegen kann. */
.kopf-projekt { position: relative; flex-shrink: 0; }

.topbar__burger {
  display: none;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  width: 34px; height: 34px;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.topbar__burger svg { width: 16px; height: 16px; }

/* Projektwaehler. Auf dem Dashboard steuert er die ganze Seite, deshalb
   sitzt er ganz links. */
.proj-chip {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 6px 10px 6px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: var(--sans);
  font-size: 13px;
  cursor: pointer;
  transition: border-color 0.12s ease;
}

/* [hidden] ALLEIN REICHT HIER NICHT.

   Das Browser-Grundblatt setzt fuer [hidden] display:none -- aber mit
   derselben, also der schwaechsten Staerke. Das display:inline-flex zwei
   Zeilen darueber gewinnt, und zwar seit es diesen Chip gibt: wer ohne
   Projekt auf dem Dashboard stand, sah einen leeren Kasten mit der
   Aufschrift "Projekt", der auf nichts zeigte.

   In der alten, zweiten Leiste ist es niemandem aufgefallen. In der
   gemeinsamen Kopfleiste steht er direkt hinter dem Strich, an der
   auffaelligsten Stelle der Zeile. Dasselbe gilt fuer die DR-Plakette
   daneben. */
.proj-chip[hidden],
.proj-chip .badge[hidden] { display: none; }

.proj-chip:hover { border-color: var(--text-ghost); }
.proj-chip__icon { width: 15px; height: 15px; color: var(--text-faint); flex-shrink: 0; }
.proj-chip__name { font-weight: 500; max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proj-chip__caret { width: 13px; height: 13px; color: var(--text-faint); flex-shrink: 0; }

/* Die Suche der App -- oben in der Seitenleiste, ueber der Liste, die
   sie durchsucht. Sie stand bis zum 25.08.2026 im Kopf; dort wurde sie
   zusammengedrueckt, sobald die App in den 1180-px-Kasten zog.

   Sie heisst .leiste-suche und nicht mehr .topbar__search: ein Name,
   der die falsche Stelle nennt, schickt den naechsten Leser dorthin.
   Die id paletteBtn ist geblieben -- daran haengt initPalette, und die
   Kommandopalette selbst hat sich nicht bewegt. */
.leiste-suche {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 0 10px;
  height: 34px;
  margin-bottom: 14px;
  /* Nichts darf umbrechen: der Kasten ist so hoch wie eine Zeile. */
  white-space: nowrap;
  /* DIE LEISTE IST EIN SPALTEN-FLEXBOX MIT FESTER HOEHE.

     Passt ihr Inhalt nicht hinein -- und seit die Website-Gruppe dazu
     gehoert, passt er nicht --, schrumpfen ihre Kinder, statt dass sie
     scrollt. Als einziges Kind mit fester Hoehe traf es diesen Knopf:
     34 px angegeben, 19 gemessen, die Beschriftung klebte oben und
     unten am Rand. Kein Fehler in einer Konsole, nur ein Kasten, der
     falsch aussieht. */
  flex-shrink: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-faint);
  font-size: 13px;
  font-family: var(--sans);
  cursor: pointer;
  transition: border-color 0.12s ease, color 0.12s ease;
}

.leiste-suche:hover { border-color: var(--text-ghost); color: var(--text-dim); }
.leiste-suche svg { width: 14px; height: 14px; flex-shrink: 0; }

/* Damit eine laengere Uebersetzung den Kasten nicht wieder sprengt:
   die Beschriftung wird abgeschnitten, Lupe und Taste bleiben stehen.
   Kuerzer ist besser, aber verlassen sollte man sich darauf nicht --
   "Search tools" ist heute kurz, das naechste Sprachpaar vielleicht
   nicht. */
.leiste-suche > span {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.leiste-suche kbd {
  margin-left: auto;
  flex-shrink: 0;
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-faint);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
}

/* --- Inhaltsflaeche -------------------------------------------------------- */

/* AUSDRUECKLICH INS FELD GESETZT, nicht der automatischen Platzierung
   ueberlassen. Solange das Gitter zwei Spalten hatte, landete der Inhalt
   von selbst richtig -- mit den beiden Randspalten rutschte er in die
   erste freie Zelle, und das ist der linke Rand. 269 Pixel breit, ohne
   Fehlermeldung. */
.main {
  grid-area: inhalt;
  padding: 26px 28px 72px;
  width: 100%;
  min-width: 0;
}

.main--narrow { max-width: 1120px; }

.page-eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--accent-soft);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  margin: 0 0 8px;
}

.page-title {
  font-size: 26px;
  font-weight: 700;
  margin: 0 0 6px;
  letter-spacing: -0.015em;
}

.page-sub {
  color: var(--text-dim);
  font-size: 14.5px;
  margin: 0 0 28px;
  max-width: 620px;
  line-height: 1.6;
}

.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}

.page-head .page-sub { margin: 0; }

.page-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12.5px;
  color: var(--text-faint);
  font-family: var(--mono);
}

/* --- Panels ---------------------------------------------------------------- */

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--border-soft);
  /* Mit zwei Umschaltern im Kopf reicht eine Zeile nicht immer. */
  flex-wrap: wrap;
}

/* Der zweite Umschalter soll den Platz zwischen Titel und Zeitraum fuellen,
   statt rechts an den Rand zu springen. */
.panel__head .seg:first-of-type { margin-right: auto; }

.panel__title {
  font-size: 14px;
  font-weight: 600;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.panel__link { font-size: 12px; color: var(--text-dim); transition: color 0.12s ease; }
.panel__link:hover { color: var(--accent-soft); }
.panel__body { padding: 16px; }
.panel__body--flush { padding: 0; }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
}

/* --- Dashboard-Raster ------------------------------------------------------ */

.dash {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 336px;
  gap: 18px;
  align-items: start;
}

.dash__col {
  display: grid;
  gap: 18px;
  min-width: 0;
  /* Abfragebehaelter: ob vier Kacheln nebeneinander passen, haengt an der
     Breite dieser Spalte, nicht am Fenster. Bei 1280px Fenster ist die
     Spalte nur 619px breit -- eine Fensterabfrage haette das verfehlt. */
  container-type: inline-size;
}

/* --- Kennzahlen ------------------------------------------------------------ */

.kpi-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}

.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 15px 16px 13px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-height: 118px;
}

.kpi__label {
  font-family: var(--mono);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-faint);
  margin: 0;
}

.kpi__value-row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }

.kpi__value {
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  margin: 0;
}

.kpi__unit { font-size: 14px; color: var(--text-faint); font-weight: 500; }

.kpi__delta {
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 500;
}

.kpi__delta--up { color: var(--success); }
.kpi__delta--down { color: var(--danger); }
.kpi__delta--flat { color: var(--text-faint); }

.kpi__foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 7px;
}
.kpi__note { font-size: 11.5px; color: var(--text-dim); margin: 0; }
.kpi__spark { display: block; flex-shrink: 0; }
.kpi__spark--breit { width: 100%; height: 28px; }

.kpi__bar {
  height: 5px;
  border-radius: 3px;
  background: var(--surface-3);
  overflow: hidden;
  width: 100%;
}

.kpi__bar span { display: block; height: 100%; border-radius: 3px; }
.kpi--empty .kpi__value { color: var(--text-ghost); font-weight: 500; }

/* --- Segmentierte Umschalter ----------------------------------------------- */

.seg {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.seg button {
  border: 0;
  background: none;
  color: var(--text-dim);
  font-family: var(--mono);
  font-size: 11px;
  padding: 4px 9px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.seg button:hover:not(:disabled) { color: var(--text); }
.seg button[aria-selected="true"] { background: var(--accent); color: #fff; }
.seg button:disabled { opacity: 0.3; cursor: not-allowed; }

/* --- Diagramm -------------------------------------------------------------- */

.chart-wrap { position: relative; }
.chart { display: block; width: 100%; height: auto; }
.chart__grid line { stroke: var(--border-soft); stroke-width: 1; }
.chart__axis { fill: var(--text-faint); font-family: var(--mono); font-size: 10px; }
.chart__bar { fill: var(--accent); transition: fill 0.1s ease; }
.chart__col:hover .chart__bar, .chart__col.is-active .chart__bar { fill: var(--accent-soft); }

/* Nachgetragene Monatswerte aus dem Index von DataForSEO -- blasser, damit
   sie sich von den eigenen Messungen unterscheiden. */
.chart__bar--verlauf { fill: var(--accent); opacity: 0.42; }
.chart__col:hover .chart__bar--verlauf { fill: var(--accent-soft); opacity: 0.7; }
.chart__hit { fill: transparent; }

.chart-tip {
  position: absolute;
  pointer-events: none;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 9px;
  font-size: 12px;
  white-space: nowrap;
  box-shadow: var(--shadow);
  transform: translate(-50%, -115%);
  opacity: 0;
  transition: opacity 0.1s ease;
  z-index: 5;
}

.chart-tip.is-visible { opacity: 1; }
.chart-tip dl { display: grid; grid-template-columns: auto auto; gap: 2px 12px; margin: 5px 0 0; }
.chart-tip dt { color: var(--text-dim); }
.chart-tip dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }

/* Gestapelte Flaechen: eine Bahn je Positionsgruppe. */
.chart__bahn { transition: opacity 0.12s ease; }
.chart-wrap:hover .chart__bahn { opacity: 0.82; }

.legende { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }

.legende span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-dim);
  background: var(--surface-2);
  border-radius: 5px;
  padding: 3px 8px;
}

.legende i { width: 9px; height: 9px; border-radius: 2px; display: block; flex-shrink: 0; }
.chart-tip strong { font-variant-numeric: tabular-nums; }
.chart-tip span { color: var(--text-faint); font-family: var(--mono); font-size: 10.5px; display: block; }

/* --- Verteilungsbalken ----------------------------------------------------- */

.dist { display: grid; gap: 11px; }

.dist-row {
  display: grid;
  grid-template-columns: 66px minmax(0, 1fr) 46px;
  align-items: center;
  gap: 12px;
}

.dist-label { font-size: 12.5px; color: var(--text-dim); }
.dist-track { height: 8px; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.dist-fill { height: 100%; border-radius: 4px; transition: width 0.35s ease; }
.dist-count { font-size: 13px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }

/* --- Tabellen -------------------------------------------------------------- */

.dtable { width: 100%; border-collapse: collapse; font-size: 13px; }

.dtable th {
  text-align: left;
  padding: 10px 16px;
  font-family: var(--mono);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
  font-weight: 500;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.dtable td {
  padding: 11px 16px;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: middle;
}

.dtable tbody tr:last-child td { border-bottom: none; }
.dtable tbody tr:hover td { background: var(--surface-2); }
.dtable .num { text-align: right; font-variant-numeric: tabular-nums; }
.dtable .keyword-cell { max-width: 230px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.table-scroll { overflow-x: auto; }

.rank-pill {
  display: inline-block;
  min-width: 26px;
  text-align: center;
  padding: 2px 7px;
  border-radius: 5px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  background: var(--surface-3);
  color: var(--text-dim);
}

.rank-pill--top3 { background: var(--success-bg); color: var(--success); }
.rank-pill--top10 { background: var(--accent-bg); color: var(--accent-soft); }
.rank-pill--none { background: transparent; color: var(--text-faint); }

/* --- Rankende Seite -------------------------------------------------------- */

.ziel {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--text-dim);
  max-width: 170px;
  display: inline-block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

/* Zwei eigene Seiten konkurrieren um dasselbe Keyword. */
.ziel--wechsel { color: var(--warn); }

/* --- Befundliste ----------------------------------------------------------- */

.issue-list { display: flex; flex-direction: column; }

.issue {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-soft);
}

.issue:last-child { border-bottom: none; }

.issue__icon {
  width: 24px; height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.issue__icon svg { width: 13px; height: 13px; }
.issue__label { flex: 1; font-size: 13.5px; }
.issue__count { font-family: var(--mono); font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; }

.issue--crit .issue__icon { background: var(--danger-bg); color: var(--danger); }
.issue--crit .issue__count { color: var(--danger); }
.issue--warn .issue__icon { background: var(--warn-bg); color: var(--warn); }
.issue--warn .issue__count { color: var(--warn); }
.issue--ok .issue__icon { background: var(--success-bg); color: var(--success); }
.issue--ok .issue__count { color: var(--success); }

.issue-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 16px;
  border-top: 1px solid var(--border-soft);
  font-size: 12px;
  color: var(--text-faint);
  font-family: var(--mono);
}

.issue-foot b { color: var(--text-dim); font-weight: 500; }

/* --- Sicherheits-Befunde --------------------------------------------------- */

/* Sitzt zwischen Zahlenliste und Fusszeile und trennt sich nach oben mit
   derselben Linie wie die Fusszeile nach unten. */
.sec-befund {
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 12px 16px;
  border-top: 1px solid var(--border-soft);
}

.sec-befund__titel {
  margin: 0;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-faint);
}

/* Der Abstand steckt schon im gap darueber. */
.sec-befund .pruef__chips { margin-top: 5px; }

/* --- Aenderungen ----------------------------------------------------------- */

.chg-liste { display: flex; flex-direction: column; }

.chg {
  display: grid;
  grid-template-columns: 54px minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 10px;
  padding: 9px 16px;
  border-bottom: 1px solid var(--border-soft);
  font-size: 13px;
}

.chg:last-child { border-bottom: none; }

.chg__wert {
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.chg__wert--up { color: var(--success); }
.chg__wert--down { color: var(--danger); }
.chg__was { color: var(--text-dim); min-width: 0; }
.chg__wann { font-family: var(--mono); font-size: 10.5px; color: var(--text-faint); white-space: nowrap; }

/* --- Weitere Pruefungen ---------------------------------------------------- */

.pruef { display: flex; flex-direction: column; }

.pruef__zeile {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: start;
  padding: 11px 16px;
  border-bottom: 1px solid var(--border-soft);
}

.pruef__zeile:last-child { border-bottom: none; }
.pruef__zeile--leer { opacity: 0.62; }
.pruef__icon { width: 16px; height: 16px; color: var(--text-faint); margin-top: 1px; }
.pruef__icon svg { width: 100%; height: 100%; display: block; }
.pruef__name { font-size: 13px; margin: 0 0 3px; }
.pruef__wert { font-size: 12px; color: var(--text-dim); margin: 0; line-height: 1.45; }
.pruef__wann { font-family: var(--mono); font-size: 10.5px; color: var(--text-faint); white-space: nowrap; }
.pruef__wert a { color: var(--accent-soft); }

.pruef__chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }

.pruef__chips span {
  font-family: var(--mono);
  font-size: 10.5px;
  background: var(--surface-3);
  color: var(--text-dim);
  border-radius: 4px;
  padding: 2px 7px;
}

.pruef__chips span.acht { background: var(--warn-bg); color: var(--warn); }

/* --- Backlink-Beispiele ---------------------------------------------------- */

.bl-anchor { color: var(--text-dim); font-size: 12px; }
.bl-domain { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }

.bl-folge {
  font-family: var(--mono);
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--surface-3);
  color: var(--text-faint);
}

.bl-folge--do { background: var(--success-bg); color: var(--success); }

/* --- Projektvergleich ------------------------------------------------------ */

.cmp-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--border-soft);
}

.cmp-row:last-child { border-bottom: none; }
.cmp-row:hover { background: var(--surface-2); }
.cmp-row.is-current .cmp-domain { color: var(--accent-soft); font-weight: 600; }
.cmp-domain { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmp-stats { display: flex; align-items: center; gap: 12px; font-size: 12px; color: var(--text-faint); font-family: var(--mono); }
.cmp-stats b { color: var(--text); font-weight: 600; }

.cmp-wann { display: block; font-family: var(--mono); font-size: 10.5px; color: var(--text-faint); margin-top: 2px; }

/* Aelter als drei Tage: der Zeitplan laeuft taeglich, das ist also eine
   ausgefallene Messung und keine Normalitaet. */
.cmp-wann--alt { color: var(--warn); }

.cmp-weg {
  background: none;
  border: 0;
  padding: 2px;
  border-radius: 4px;
  color: var(--text-ghost);
  cursor: pointer;
  display: inline-flex;
  opacity: 0;
  transition: opacity 0.12s ease, color 0.12s ease;
}

.cmp-weg svg { width: 13px; height: 13px; }
.cmp-row:hover .cmp-weg, .cmp-weg:focus-visible { opacity: 1; }
.cmp-weg:hover { color: var(--danger); }

/* --- Messzuverlaessigkeit -------------------------------------------------- */

.mess { display: grid; gap: 11px; }

.mess__zeile { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: baseline; }
.mess__name { font-size: 12.5px; color: var(--text-dim); }
.mess__anteil { font-family: var(--mono); font-size: 11px; color: var(--text-faint); font-variant-numeric: tabular-nums; }

.mess__punkte { display: flex; gap: 3px; grid-column: 1 / -1; }

.mess__punkte i {
  flex: 1;
  height: 16px;
  border-radius: 2px;
  background: var(--success);
  display: block;
}

/* Kein Messwert an diesem Tag. */
.mess__punkte i.leer { background: var(--surface-3); }

/* Vor der ersten Messung -- keine Luecke, sondern noch keine Zeit. Zaehlt
   deshalb auch nicht in den Anteil. */
.mess__punkte i.vorher { background: var(--surface-2); opacity: 0.5; }

/* --- Schnellzugriff -------------------------------------------------------- */

.qa-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }

.qa {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-dim);
  font-size: 12.5px;
  font-family: var(--sans);
  cursor: pointer;
  text-align: left;
  transition: border-color 0.12s ease, color 0.12s ease;
}

.qa:hover { border-color: var(--accent-line); color: var(--text); }
.qa svg { width: 15px; height: 15px; color: var(--accent-soft); flex-shrink: 0; }

/* --- Leerzustaende --------------------------------------------------------- */

.empty {
  padding: 26px 18px;
  text-align: center;
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1.6;
}

.empty svg { width: 22px; height: 22px; color: var(--text-ghost); margin-bottom: 8px; }
.empty a { color: var(--accent-soft); }
.empty__hint { font-size: 12px; color: var(--text-faint); margin: 6px 0 0; }

/* --- Buttons und Formulare ------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  font-family: var(--sans);
  transition: opacity 0.12s ease, transform 0.05s ease, border-color 0.12s ease;
}

.btn:active { transform: scale(0.98); }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { opacity: 0.9; }

.btn-ghost {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--border);
}

.btn-ghost:hover { border-color: var(--text-ghost); color: var(--text); }

/* Umriss in der Markenfarbe. Die Export-Knoepfe stehen neben einer Zeile
   Fliesstext und gingen als graue Kaesten darin unter -- ein gefuellter
   Knopf waere fuer eine Nebensaechlichkeit im Kopfbereich aber zu laut und
   wuerde dem Registrieren-Knopf den Rang ablaufen.

   Farbe traegt der Rahmen und die Schrift, die Flaeche bleibt fast leer:
   --accent-soft auf dem dunklen Grund liegt bei rund 7:1 und damit deutlich
   ueber der Anforderung -- anders als weisse Schrift auf gefuelltem Orange. */
.btn-akzent {
  background: var(--accent-bg);
  color: var(--accent-soft);
  border: 1px solid var(--accent-line);
}

.btn-akzent:hover {
  border-color: var(--accent);
  background: rgba(232, 89, 12, 0.16);
}

/* Ohne das leuchtet der gesperrte Knopf beim Ueberfahren weiter auf, als
   liesse sich noch etwas anklicken. */
.btn-akzent:disabled:hover {
  border-color: var(--accent-line);
  background: var(--accent-bg);
}

.btn-akzent svg { width: 14px; height: 14px; }
.btn-sm { padding: 7px 12px; font-size: 12.5px; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn svg { width: 15px; height: 15px; }

.icon-btn {
  background: none;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text-faint);
  width: 28px; height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease;
}

.icon-btn:hover { color: var(--text); border-color: var(--border); }
.icon-btn svg { width: 15px; height: 15px; }
.icon-btn.is-busy svg { animation: spin 0.8s linear infinite; }

@keyframes spin { to { transform: rotate(360deg); } }

.input {
  width: 100%;
  padding: 11px 13px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
  outline: none;
}

.input:focus { border-color: var(--accent); }
.input::placeholder { color: var(--text-faint); }

select.input {
  appearance: none;
  padding-right: 32px;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-faint) 50%), linear-gradient(135deg, var(--text-faint) 50%, transparent 50%);
  background-position: calc(100% - 16px) 52%, calc(100% - 11px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.badge {
  font-family: var(--mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 3px 7px;
  border-radius: 5px;
  background: var(--accent-bg);
  color: var(--accent-soft);
  white-space: nowrap;
}

.badge--muted { background: var(--surface-3); color: var(--text-dim); }
.error-text { color: var(--danger); font-size: 13px; margin-top: 10px; }

/* --- Erstmessung ----------------------------------------------------------- */

.erst { margin-top: 18px; }
.erst__titel { font-size: 13px; color: var(--text-dim); margin: 0 0 6px; }

.erst__zeile {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  font-size: 13px;
  color: var(--text-dim);
  border-bottom: 1px solid var(--border-soft);
}

.erst__zeile:last-child { border-bottom: none; }

.erst__punkt {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--text-ghost);
  flex-shrink: 0;
}

.erst__zeile--laeuft .erst__punkt { background: var(--accent); animation: erstPuls 1.1s ease-in-out infinite; }
.erst__zeile--fertig .erst__punkt { background: var(--success); }
.erst__zeile--fertig { color: var(--text); }
.erst__zeile--fehlt .erst__punkt { background: var(--warn); }

.erst__status { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--text-faint); }

@keyframes erstPuls { 50% { opacity: 0.3; } }

/* --- Werkzeugseiten -------------------------------------------------------

   Diese vier Klassen standen in jeder der acht Werkzeugseiten noch einmal im
   Kopf. .form-row war dabei schon dreifach auseinandergelaufen: sechsmal mit
   max-width 480px, einmal 560px, einmal ganz ohne. Vereinheitlicht auf 560px,
   weil der Ranking-Tracker zwei Felder nebeneinander hat.
   ------------------------------------------------------------------------- */

.form-row { display: flex; gap: 10px; flex-wrap: wrap; max-width: 560px; }
.form-row input { flex: 1; min-width: 180px; }

.project-bar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.project-bar select, .project-bar input { flex: 1; min-width: 160px; }

.quota-badge { font-size: 12px; color: var(--text-faint); margin-top: 10px; font-family: var(--mono); }

.export-row { display: flex; gap: 10px; margin-top: 14px; }

@media (max-width: 700px) {
  .form-row { flex-direction: column; }
  .project-bar { flex-direction: column; align-items: stretch; }
}

/* --- Werkzeugkacheln ------------------------------------------------------- */

.tool-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 14px;
}

.tool-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  transition: border-color 0.15s ease, transform 0.15s ease;
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: inherit;
}

.tool-card:hover { border-color: var(--accent); transform: translateY(-2px); }

.tool-card-icon {
  width: 32px; height: 32px;
  border-radius: var(--radius-sm);
  background: var(--accent-bg);
  color: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
}

.tool-card-icon svg { width: 16px; height: 16px; }
.tool-card h3 { font-size: 14.5px; margin: 0; font-weight: 600; }
.tool-card p { font-size: 12.5px; color: var(--text-dim); margin: 0; line-height: 1.55; flex: 1; }

.tool-card-status {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--success);
  display: flex;
  align-items: center;
  gap: 6px;
}

.tool-card-status .pulse { width: 6px; height: 6px; border-radius: 50%; background: var(--success); }
.tool-card.soon { opacity: 0.55; }
.tool-card.soon .tool-card-status { color: var(--text-faint); }
.tool-card.soon .tool-card-status .pulse { background: var(--text-faint); }

/* --- Terminal / Aktivitaet ------------------------------------------------- */

.terminal { background: #0a0a0b; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.panel .terminal { border: 0; border-radius: 0; }

.terminal-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 13px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.terminal-bar .tdot { width: 9px; height: 9px; border-radius: 50%; background: var(--border); }
.terminal-bar .label { margin-left: 8px; font-family: var(--mono); font-size: 11px; color: var(--text-faint); }

.terminal-body {
  padding: 14px 16px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.85;
  color: var(--text-dim);
  min-height: 120px;
  overflow-x: auto;
}

.terminal-body .prompt { color: var(--accent-soft); }
.terminal-body .ok { color: var(--success); }
.terminal-body .ts { color: var(--text-faint); }

.terminal-body .cursor {
  display: inline-block;
  width: 7px; height: 13px;
  background: var(--accent-soft);
  margin-left: 2px;
  vertical-align: middle;
  animation: blink 1s step-end infinite;
}

@keyframes blink { 50% { opacity: 0; } }

/* --- Kommandopalette ------------------------------------------------------- */

.palette-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.62);
  backdrop-filter: blur(2px);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 12vh 16px 16px;
  z-index: 100;
}

.palette-backdrop[hidden] { display: none; }

.palette {
  width: min(560px, 100%);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: 62vh;
}

.palette__input {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--border);
  background: transparent;
  padding: 15px 18px;
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  outline: none;
}

.palette__input::placeholder { color: var(--text-faint); }
.palette__list { list-style: none; margin: 0; padding: 6px; overflow-y: auto; }

.palette__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  color: var(--text-dim);
  cursor: pointer;
}

.palette__item[aria-selected="true"] { background: var(--accent-bg); color: var(--accent-soft); }
.palette__item svg { width: 15px; height: 15px; flex-shrink: 0; opacity: 0.8; }
.palette__kind { margin-left: auto; font-family: var(--mono); font-size: 10px; color: var(--text-faint); }
.palette__empty { padding: 22px; text-align: center; color: var(--text-faint); font-size: 13px; }

/* --- Menue ----------------------------------------------------------------- */

.menu {
  position: absolute;
  min-width: 236px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 5px;
  z-index: 60;
  max-height: 320px;
  overflow-y: auto;
}

.menu[hidden] { display: none; }

/* Die Adresse ueber dem Abmelden-Knopf. Kein Menuepunkt -- sie ist
   nichts, was man anklicken kann, und sieht deshalb auch nicht so aus. */
.menu__kopf {
  margin: 0;
  padding: 8px 10px 6px;
  font-size: 12px;
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Konto, rechts aussen im Kopf ------------------------------------------

   Der Kasten mit Adresse und Abmelde-Knopf stand bis zum 25.08.2026 unten
   in der Seitenleiste. Im Entwurf sitzt an seiner Stelle ein Chip mit den
   Anfangsbuchstaben; alles Weitere klappt darunter auf. */

/* Der Aufruf fuer Gaeste steht im Kopf, und dort ist die Hoehe fest.
   "Kostenlos registrieren" sind zwei Woerter; ohne diese Regel bricht
   der Knopf auf zwei Zeilen, wird 52 px hoch und schiebt sich in einer
   71-px-Leiste gegen die Kanten. */
#topbarAuth .btn {
  white-space: nowrap;
  flex-shrink: 0;
}

.kopf-konto { position: relative; flex-shrink: 0; }

.konto-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 11px 0 5px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: var(--sans);
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color 0.12s ease;
}

.konto-chip:hover { border-color: var(--text-ghost); }

.konto-chip__kuerzel {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--auf-akzent);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

/* Auf schmalen Schirmen bleibt der Kreis, das Wort geht -- er ist auch
   ohne Beschriftung als Konto erkennbar, ein Kreis mit Initialen an der
   rechten oberen Ecke ist die gelaeufigste Form dafuer, die es gibt. */
@media (max-width: 640px) {
  .konto-chip { padding: 0 5px; }
  .konto-chip__wort { display: none; }
}

.menu__item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--text-dim);
  font-family: var(--sans);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

.menu__item:hover { background: var(--surface-2); color: var(--text); }
.menu__item[aria-current="true"] { color: var(--accent-soft); }
.menu__item .badge { margin-left: auto; }
.menu__sep { height: 1px; background: var(--border-soft); margin: 5px 0; }

/* --- Umbrueche ------------------------------------------------------------- */

@media (max-width: 1180px) {
  .dash { grid-template-columns: 1fr; }
}

@container (max-width: 700px) {
  .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@container (max-width: 340px) {
  .kpi-row { grid-template-columns: 1fr; }
}

/* Rueckfall fuer Browser ohne Container-Queries. */
@supports not (container-type: inline-size) {
  @media (max-width: 1300px) {
    .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
}

/* Schmal: die Seitenleiste klappt zum Menue, und die Kopfleiste gibt die
   Navigation der Website ab. Was bleibt, ist die Bedienung der App --
   Projekt, Suche, Sprache, Konto -- plus der Burger ganz rechts.

   Damit ist die aufgeklappte Leiste genau das Menue aus dem Entwurf:
   Werkzeuge oben, weil man dafuer hier ist, die Website darunter unter
   eigener Ueberschrift. Nicht zwei Menues nebeneinander. */
@media (max-width: 860px) {
  /* Schmal gibt es keine Raender zu verteilen: eine Spalte, volle
     Breite. Die Seitenleiste wird ohnehin zum aufklappenden Menue und
     verlaesst das Gitter. */
  .app-shell {
    grid-template-columns: 1fr;
    grid-template-areas: "kopf" "inhalt";
  }
  .kopf-innen { padding: 0 14px; gap: 12px; }
  .topbar__burger { display: inline-flex; }
  .kopf-nav, .kopf-strich { display: none; }
  .sidebar {
    position: fixed;
    left: 0; top: 0;
    width: 260px;
    height: 100vh;
    /* Ueber der Kopfleiste (50) und ihrem Vorhang (55): ein Menue, durch
       das der Kopf durchscheint, sieht kaputt aus. */
    z-index: 60;
    transform: translateX(-100%);
    transition: transform 0.18s ease;
    box-shadow: var(--shadow);
  }
  .sidebar.is-open { transform: translateX(0); }
  .sidebar-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.55); z-index: 55; }
  .sidebar-backdrop[hidden] { display: none; }
  .main { padding: 20px 16px 64px; }
  /* Die Tastenkombination steht auf einem Telefon fuer nichts. */
  .leiste-suche kbd { display: none; }
}

@media (max-width: 560px) {
  .kpi-row { grid-template-columns: 1fr; }
  .qa-grid { grid-template-columns: 1fr; }
  .page-title { font-size: 22px; }
  .proj-chip__name { max-width: 96px; }
  /* Das Schild bleibt, das Wort geht. Bei 375 px stehen Marke, Projekt,
     Suche, Sprache, Konto und Burger nebeneinander -- die 85 Pixel des
     Schriftzugs sind die einzigen, die sich ohne Verlust streichen
     lassen. */
  .kopf-marke span { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}


/* --- Sprachumschalter ------------------------------------------------------ */

.lang-toggle { display:inline-flex; align-items:center; gap:2px; margin-left:10px; padding:2px; background:var(--surface-2); border:1px solid var(--border); border-radius:8px; flex-shrink:0; }
.lang-opt { display:inline-flex; align-items:center; gap:5px; padding:4px 7px; border:none; background:none; color:var(--text-faint); font-family:var(--mono); font-size:11px; font-weight:600; line-height:1; border-radius:6px; cursor:pointer; }
.lang-opt:hover { color:var(--text-dim); }
.lang-opt.is-active { background:var(--surface); color:var(--text); }
.lang-flag { height:11px; width:auto; display:block; border-radius:2px; box-shadow:0 0 0 1px rgba(0,0,0,.3) inset; }
@media (max-width:640px) { .lang-code { display:none; } .lang-opt { padding:5px 6px; } }
