/* namebox Design-System v1 */
:root {
  /* Die Marke: schwarze Wortmarke, ein rotes Zeichen. Rot ist Signal, nicht
     Fläche — sechs schwarze Buchstaben, ein rotes „x". Entsprechend sparsam
     wird es hier eingesetzt: aktive Navigation, Hauptknopf, Verweise. */
  --nb-schwarz:    #121214;   /* Wortmarken-Schwarz */
  --nb-schwarz-hi: #26262b;   /* angehoben, für Hover auf der Seitenleiste */
  --nb-rot:        #ef4040;   /* Markenrot. Auf Schwarz 5,1:1 */
  --nb-rot-tief:   #d92d2d;   /* Fläche auf Hell — Weiß darauf 4,8:1 */
  --nb-rot-text:   #c92626;   /* Schrift auf Hell — 5,1:1 auf --nb-bg */

  /* Die alten Namen bleiben als Verweis stehen: der Code greift an rund
     200 Stellen darauf zu, und ein Umbenennen brächte Risiko ohne Gewinn. */
  --nb-sidebar:     var(--nb-schwarz);
  --nb-sidebar-hi:  var(--nb-schwarz-hi);
  --nb-accent:      var(--nb-rot-tief);
  --nb-accent-hell: var(--nb-rot);
  --nb-signal:      var(--nb-rot);
  --nb-blue:        var(--nb-rot-text);   /* historischer Name, heute Markenrot */
  --nb-bg: #f5f5f6;
  --nb-card: #ffffff;
  --nb-line: #e3e3e6;
  --nb-text: #14141a;
  --nb-muted: #6b6b75;
  --nb-ok: #2e9e5b;
  --nb-warn: #e0a11e;
  /* Dunkler als das Markenrot, damit ein Fehlerzustand nicht wie ein
     Markenakzent aussieht. Die beiden stehen im UI gelegentlich nebeneinander. */
  --nb-bad: #a3201a;
  /* Flächen und Zustände. Ohne eigene Token müsste der Dunkelmodus
     Regeln überschreiben statt Werte zu tauschen — das ist die Stelle,
     an der solche Umschalter sonst auseinanderfallen. */
  --nb-flaeche: #f0f0f2;      /* ruhige Fläche: Chips, Badges, Zeilen-Hover */
  --nb-zebra:   #fafafa;      /* jede zweite Tabellenzeile */
  /* Zeile unter dem Zeiger: bewusst ein Hauch Markenrot statt Grau. Mit
     einem Grauton war der Hintergrund identisch mit dem der Branchen-
     kennzeichnung — die verschwand beim Zeigen einfach in der Zeile. */
  --nb-zeile-hover: rgba(239, 64, 64, .055);
  --nb-hover:   #f7f7f8;      /* Knopf unter dem Zeiger */
  --nb-line-stark: #c9c9d0;   /* Linie, die auffallen soll */
  --nb-side-icon:  #9a9aa4;   /* Symbole der Seitenleiste in Ruhe */
  --nb-backdrop: rgba(18, 18, 20, .5);
  --nb-ok-bg:   #dff3e7;  --nb-ok-fg:   #1c6e40;
  --nb-bad-bg:  #f8e3df;  --nb-bad-fg:  #a03325;
  --nb-warn-bg: #f9efd8;  --nb-warn-fg: #8a6414;  --nb-warn-line: #ecd9a8;
  --nb-rot-bg:  #fbe6e6;
  --nb-invers: #14141a;  --nb-invers-fg: #ffffff;  --nb-invers-hover: #2c2c34;
  --nb-kopf-bg: #121214;  --nb-kopf-fg: #ffffff;
  --nb-r: 8px;
  --nb-shadow: 0 1px 3px rgba(18, 18, 20, .08);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--nb-bg); color: var(--nb-text);
}
/* Verweise ruhen in der Textfarbe und werden erst beim Zeigen rot. Vorher war
   jeder Firmenname rot — auf einer Trefferseite fünfzig Signale nebeneinander,
   also gar keins mehr. Die Wortmarke macht es vor: sechs Buchstaben schwarz,
   einer rot. Rot ist hier die Interaktion, nicht der Ruhezustand. */
a { color: var(--nb-text); text-decoration: none; }
a:hover { color: var(--nb-blue); text-decoration: underline; text-underline-offset: 2px; }

/* ---- Layout ---- */
#app { display: flex; min-height: 100vh; }
/* ---- Seitenleiste ----
   Zwei Weiten: breit mit Bereichsnamen, schmal nur mit Symbolen. Vierzehn
   unbeschriftete Symbole sind ein Ratespiel — der Name daneben kostet Breite,
   spart aber jedes Mal das Überlegen. Wer die Breite für die Trefferliste
   braucht, klappt sie zu; die Wahl wird gemerkt. */
.nb-side {
  width: 208px; background: var(--nb-sidebar); color: #fff; flex-shrink: 0;
  display: flex; flex-direction: column; padding: 12px 10px;
  position: sticky; top: 0; height: 100vh; gap: 2px;
  transition: width .14s ease;
}
.nb-side.schmal { width: 60px; align-items: center; padding: 12px 0; }
/* Fester Logobereich in beiden Zustaenden. Vorher trugen Wortmarke und
   Zeichen unterschiedliche Aussenabstaende — dadurch sass die Navigation im
   schmalen Zustand 6 px hoeher als im offenen und sprang beim Umschalten. */
.nb-side .logo {
  height: 30px; margin: 0 0 14px; padding-left: 10px;
  display: flex; align-items: center; flex: none;
}
.nb-side.schmal .logo { padding-left: 0; justify-content: center; }
.nb-side button {
  width: 100%; height: 40px; border: 0; background: transparent; border-radius: 6px;
  color: var(--nb-side-icon); cursor: pointer; display: flex; align-items: center;
  gap: 11px; padding: 0 10px; margin: 0; font: inherit; font-size: 13px;
  font-weight: 500; text-align: left; white-space: nowrap; overflow: hidden;
}
.nb-side button .ico { display: flex; flex: none; }
.nb-side.schmal button { width: 40px; justify-content: center; padding: 0; }
.nb-side.schmal button .txt { display: none; }
/* Der Weiten-Umschalter dreht sich mit: im schmalen Zustand zeigt er nach
   rechts und heißt „Breiter" — die Beschriftung sieht dort ohnehin niemand. */
.nb-side.schmal .nb-side__weite { opacity: .7; }
.nb-side button:hover { background: var(--nb-sidebar-hi); color: #fff; }
.nb-side button.active { background: var(--nb-accent-hell); color: #fff; }
.nb-side .spacer { flex: 1; }
.nb-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.nb-topbar {
  background: var(--nb-card); border-bottom: 1px solid var(--nb-line); padding: 0 20px;
  height: 52px; display: flex; align-items: center; gap: 14px; position: sticky; top: 0; z-index: 40;
}
.nb-topbar h1 { font-size: 17px; margin: 0; font-weight: 700; }
.nb-topbar h1 .sub { color: var(--nb-muted); font-weight: 500; }
/* Ohne Wortmarke davor trägt der Bereichsname die Kopfzeile allein. */
.nb-topbar h1 { font-size: 17px; font-weight: 700; letter-spacing: -.015em; }
.nb-topbar .spacer { flex: 1; }
.nb-content { padding: 18px 20px; flex: 1; }

/* ---- Karten / Tabellen ---- */
.nb-card {
  background: var(--nb-card); border: 1px solid var(--nb-line); border-radius: var(--nb-r);
  padding: 14px 16px; margin-bottom: 14px;
}
/* Überschrift, nicht Etikett: dunkel und schwer wie die Wortmarke. Vorher
   war sie gedämpft und 600 — genau wie der Tabellenkopf darunter, wodurch
   die Seite keine Rangfolge mehr hatte. */
.nb-card h3 { margin: 0 0 11px; font-size: 14.5px; color: var(--nb-text);
  font-weight: 700; letter-spacing: -.012em; }
/* Lange Zeichenketten ohne Leerzeichen — Dateipfade, Adressen, Kennungen — haben
   keine Stelle zum Umbrechen und schoben sich sonst aus der Karte heraus.

   ACHTUNG, Unterschied mit Folgen: „anywhere" zählt auch bei der Berechnung der
   MINDESTBREITE mit. In einer Tabelle hält der Browser dann ein einzelnes Zeichen
   für die schmalstmögliche Spalte — die Spalte „Firma" fiel dadurch auf 50 px
   zusammen und brach Buchstabe für Buchstabe um. „break-word" bricht genauso,
   lässt die Mindestbreite aber unberührt. Deshalb hier ausschließlich break-word. */
.nb-card { overflow-wrap: break-word; }
.nb-table-wrap { overflow-x: auto; }
.nb-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.nb-table th {
  text-align: left; padding: 9px 10px; border-bottom: 2px solid var(--nb-line);
  color: var(--nb-muted); font-weight: 600; white-space: nowrap; position: sticky; top: 0;
  font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
  background: var(--nb-card); z-index: 2;
}
.nb-table td { padding: 8px 10px; border-bottom: 1px solid var(--nb-line); vertical-align: middle; }
.nb-table tbody tr:nth-child(even) { background: var(--nb-zebra); }
.nb-table tbody tr:hover { background: var(--nb-zeile-hover); }

/* ---- Bedienelemente ---- */
.nb-btn {
  display: inline-flex; align-items: center; gap: 7px; padding: 8px 14px;
  border: 1px solid var(--nb-line); border-radius: var(--nb-r); background: var(--nb-card);
  color: var(--nb-text); font-size: 13.5px; cursor: pointer; font-weight: 500;
}
.nb-btn:hover { border-color: var(--nb-line-stark); background: var(--nb-hover); }
.nb-btn.primary { background: var(--nb-invers); border-color: var(--nb-invers); color: var(--nb-invers-fg); }
.nb-btn.primary:hover { background: var(--nb-invers-hover); border-color: var(--nb-invers-hover); }
.nb-btn.accent { background: var(--nb-accent); border-color: var(--nb-accent); color: #fff; }
.nb-btn.danger { color: var(--nb-bad); }
.nb-btn.small { padding: 4px 9px; font-size: 12.5px; border-radius: 6px; }
.nb-btn:disabled { opacity: .5; cursor: default; }
.nb-input, .nb-select, textarea.nb-input {
  padding: 8px 10px; border: 1px solid var(--nb-line); border-radius: 6px; font-size: 13.5px;
  background: var(--nb-card); color: var(--nb-text); font-family: inherit; min-width: 0;
}
.nb-input:focus, .nb-select:focus { outline: 2px solid rgba(239, 64, 64, .30); border-color: var(--nb-rot); }
label.nb-label { display: block; font-size: 12.5px; color: var(--nb-muted); margin: 10px 0 4px; font-weight: 600; }

/* Fläche plus Haarlinie statt nur Fläche.
   Als reines Grau (--nb-flaeche) verschwand der Chip auf dem Seitenhintergrund:
   #f0f0f2 auf #f5f5f6 sind rund 1,05:1 — im Handbuch standen die Kapitel-
   Sprungmarken dadurch als graue Wolke auf grauem Grund. Mit Kartenfläche und
   Linie liest er sich sowohl in einer weißen Karte als auch daneben. */
.nb-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--nb-card); border: 1px solid var(--nb-line); border-radius: 5px;
  padding: 3px 10px; font-size: 12.5px; margin: 2px 3px 2px 0; white-space: nowrap;
}
/* Anklickbare Chips — Kapitelsprünge, Listen, Profile — zeigen das beim Zeigen. */
a.nb-chip { color: var(--nb-text); text-decoration: none; }
a.nb-chip:hover {
  color: var(--nb-blue); border-color: var(--nb-blue); text-decoration: none;
}
.nb-chip .x { cursor: pointer; color: var(--nb-muted); font-weight: 700; }

/* Spalte „Berufe" in den Stellenanzeigen.

   Zwei Probleme steckten hier: Die Bezeichnungen der Bundesagentur werden über
   hundert Zeichen lang und schoben die Tabelle als nicht umbrechende Chips so
   weit auf, dass Kontakt und Aktion aus dem Bild liefen. Und die Pillenform
   selbst passt nur zu einzeiligen Schlagworten — mehrzeilig wird daraus eine
   große grüne Fläche. Deshalb: gedeckelte Spalte und schlichte Aufzählung. */
.nb-berufe { max-width: 260px; }
.nb-beruf {
  position: relative; padding: 2px 0 2px 13px; font-size: 12.5px; line-height: 1.35;
  color: var(--nb-text);
}
.nb-beruf + .nb-beruf { margin-top: 3px; }
.nb-beruf::before {
  content: ""; position: absolute; left: 2px; top: .62em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--nb-accent); opacity: .55;
}
/* Kontakt: E-Mail-Adressen sind oft lang und brechen von sich aus nicht um. */
.nb-table td a[href^="mailto:"] { overflow-wrap: break-word; }
.nb-chip .x:hover { color: var(--nb-bad); }
.nb-badge {
  display: inline-block; padding: 2px 9px; border-radius: 5px; font-size: 12px; font-weight: 600;
  background: var(--nb-flaeche); color: var(--nb-text);
}
.nb-badge.ok { background: var(--nb-ok-bg); color: var(--nb-ok-fg); }
.nb-badge.bad { background: var(--nb-bad-bg); color: var(--nb-bad-fg); }
.nb-badge.warn { background: var(--nb-warn-bg); color: var(--nb-warn-fg); }
.nb-badge.blue { background: var(--nb-rot-bg); color: var(--nb-blue); }

/* Zwischenüberschrift der Filterspalte („Wen suchen Sie?", „Website" …) */
.nb-filter-block {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--nb-muted); margin: 14px 0 5px 2px;
}
.nb-filter-block:first-child { margin-top: 4px; }

/* Warnung im Fließtext (z. B. „Filter wurde nicht angewendet") */
.nb-warn {
  background: var(--nb-warn-bg); color: var(--nb-warn-fg); border: 1px solid var(--nb-warn-line);
  border-radius: 8px; padding: 7px 10px; margin-top: 8px;
}

/* ---- Tabs ---- */
.nb-tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--nb-line); margin-bottom: 14px; flex-wrap: wrap; }
.nb-tabs button {
  border: 0; background: transparent; padding: 9px 14px; font-size: 13.5px; cursor: pointer;
  color: var(--nb-muted); border-bottom: 2px solid transparent; font-weight: 500;
}
.nb-tabs button:hover { color: var(--nb-text); }
.nb-tabs button.active { color: var(--nb-blue); border-bottom-color: var(--nb-blue); font-weight: 600; }

/* ---- Filter-Sidebar (Suche) ---- */
.nb-filter-group { border: 1px solid var(--nb-line); border-radius: var(--nb-r); margin-bottom: 8px; background: var(--nb-card); }
.nb-filter-group > .head {
  display: flex; align-items: center; gap: 9px; padding: 10px 12px; cursor: pointer; user-select: none;
}
.nb-filter-group > .head .cnt {
  background: var(--nb-blue); color: #fff; border-radius: 6px; min-width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center; font-size: 11.5px; font-weight: 700;
}
.nb-filter-group > .head .arrow { margin-left: auto; color: var(--nb-muted); transition: transform .15s; }
.nb-filter-group.open > .head .arrow { transform: rotate(180deg); }
.nb-filter-group.hasval { border-color: var(--nb-blue); }
.nb-filter-group > .body { padding: 4px 12px 12px; border-top: 1px solid var(--nb-line); }

/* ---- Toast / Modal ---- */
#nb-toasts { position: fixed; bottom: 18px; right: 18px; z-index: 300; }
.nb-toast {
  background: var(--nb-invers); color: var(--nb-invers-fg); border-radius: 10px; padding: 10px 16px;
  margin-top: 8px; box-shadow: 0 4px 16px rgba(0,0,0,.25); font-size: 13.5px; max-width: 360px;
}
.nb-toast.err { background: var(--nb-bad); }
.nb-modal-bg {
  position: fixed; inset: 0; background: var(--nb-backdrop); z-index: 200;
  display: flex; align-items: flex-start; justify-content: center; padding: 6vh 16px;
}
.nb-modal {
  background: var(--nb-card); border-radius: 10px; width: 100%; max-width: 640px; max-height: 86vh;
  display: flex; flex-direction: column; overflow: hidden;
}
.nb-modal.wide { max-width: 980px; }
.nb-modal > .head {
  background: var(--nb-kopf-bg); color: var(--nb-kopf-fg); padding: 13px 18px; font-weight: 600;
  display: flex; align-items: center;
}
.nb-modal > .head .x { margin-left: auto; cursor: pointer; opacity: .8; font-size: 18px; }
.nb-modal > .head .x:hover { opacity: 1; }
.nb-modal > .body { padding: 16px 18px; overflow-y: auto; }
.nb-modal > .foot { padding: 12px 18px; border-top: 1px solid var(--nb-line); display: flex; gap: 8px; justify-content: flex-end; }

/* ---- Login ---- */
.nb-login {
  min-height: 100vh; display: flex; align-items: center; justify-content: center; width: 100%;
  background: linear-gradient(160deg, #0a0a0c 0%, var(--nb-schwarz) 55%, #2a1416 100%);
}
.nb-login .box { background: var(--nb-card); border-radius: 12px; padding: 34px 36px; width: 360px; }
.nb-login h1 { margin: 0 0 4px; font-size: 34px; line-height: 1; }
.nb-login .sub { color: var(--nb-muted); margin-bottom: 18px; }
.nb-login .nb-input { width: 100%; margin-bottom: 10px; }
.nb-login .nb-btn { width: 100%; justify-content: center; }

/* ---- Kleinkram ---- */
.nb-muted { color: var(--nb-muted); }
.nb-num { font-variant-numeric: tabular-nums; }
.nb-grid { display: grid; gap: 14px; }
.nb-grid.c2 { grid-template-columns: 1fr 1fr; }
.nb-grid.c3 { grid-template-columns: repeat(3, 1fr); }
.nb-grid.c4 { grid-template-columns: repeat(4, 1fr); }
.nb-kpi { text-align: left; }
.nb-kpi .v { font-size: 26px; font-weight: 800; letter-spacing: -.02em; margin-top: 3px;
  font-variant-numeric: tabular-nums; }
.nb-kpi .l { color: var(--nb-muted); font-size: 12.5px; font-weight: 600; }
.nb-pagination { display: flex; align-items: center; gap: 6px; margin-top: 12px; flex-wrap: wrap; }
.nb-pagination button { min-width: 32px; }
.nb-empty { text-align: center; color: var(--nb-muted); padding: 36px 10px; }
.nb-spin {
  /* Der sichtbare Ring steckt im Pseudo-Element und ist absolut positioniert.
     Damit hängt seine Größe an nichts mehr, was der Elternteil vorgibt — vorher
     wurde der Kreis je nach Layout zur Ellipse gezogen, auf schmalen Schirmen
     bis über die halbe Seite. Der äußere Kasten darf beliebig breit werden;
     er hält nur noch die Höhe und zentriert. */
  position: relative; height: 22px; margin: 26px auto;
}
.nb-spin::after {
  content: ''; position: absolute; top: 0; left: 50%; margin-left: -11px;
  width: 22px; height: 22px; box-sizing: border-box;
  border: 3px solid var(--nb-line); border-top-color: var(--nb-blue);
  border-radius: 50%; animation: nbspin .8s linear infinite;
}
@keyframes nbspin { to { transform: rotate(360deg); } }
/* ---- Spaltenraster der Module ----
   Diese Aufteilungen standen als Inline-Angaben in den JS-Modulen, wo keine
   Media-Query sie zurücknehmen kann. Hier stehen sie einmal — und weiter unten
   klappen sie auf schmalen Schirmen untereinander. */
.nb-spalten { display: grid; gap: 14px; align-items: start; }
.nb-spalten--seite   { grid-template-columns: minmax(0, 1fr) 330px; }
.nb-spalten--zwei    { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
.nb-spalten--paar    { grid-template-columns: 1fr 1fr; gap: 4px 14px; margin: 2px 0; }
/* Merkmal über dem Wert statt daneben — dieselbe Begründung wie im Handbuch:
   Eine feste Titelspalte richtet sich nach der längsten Überschrift und lässt
   bei allen kurzen eine Lücke stehen. */
.nb-spalten--merkmal { grid-template-columns: minmax(0, 1fr); row-gap: 12px; margin: 0; }
.nb-spalten--merkmal dt { font-weight: 700; letter-spacing: -.01em; margin-bottom: 1px; }
.nb-spalten--merkmal dd { margin: 0; color: var(--nb-muted); line-height: 1.6; }

/* ---- Suche: Filter neben Treffern ---- */
.nb-suche { display: flex; gap: 16px; align-items: flex-start; }
.nb-suche__filter { width: 340px; flex-shrink: 0; }
.nb-suche__treffer { flex: 1 1 auto; min-width: 0; }

/* ==========================================================================
   Schmale Schirme

   Die Anwendung war auf Schreibtischbreite gebaut: feste 340-px-Filterspalte,
   dauerhaft sichtbare Seitenleiste, Tabellen ohne Rollbereich. Auf dem Handy
   blieb für die Trefferspalte rechnerisch nichts übrig — sie fiel auf 0 px
   zusammen, und die Seite ließ sich quer schieben.
   ========================================================================== */

@media (max-width: 900px) {
  .nb-grid.c3, .nb-grid.c4 { grid-template-columns: 1fr 1fr; }
  .nb-content { padding: 12px; }

  /* Filter über die Treffer statt daneben */
  .nb-suche { flex-direction: column; }
  .nb-suche__filter { width: 100%; }
  .nb-suche__treffer { width: 100%; }

  /* Alle Modulraster untereinander */
  .nb-spalten--seite, .nb-spalten--zwei { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 560px) {
  /* Auch die engeren Paare: zwei Spalten Kästchen oder ein 170-px-Begriff neben
     dem Wert sind auf einem Handy zu viel. */
  .nb-spalten--paar { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 700px) {
  /* Die Seitenleiste wandert nach unten: als Leiste über die volle Breite,
     waagerecht rollbar. 60 px am linken Rand sind auf einem 375-px-Schirm ein
     Sechstel der Fläche — die fehlt der eigentlichen Arbeit. */
  #app { flex-direction: column; }
  .nb-side {
    width: 100%; height: auto; flex-direction: row; align-items: center;
    position: fixed; bottom: 0; left: 0; top: auto; z-index: 50;
    padding: 4px 6px; gap: 2px; overflow-x: auto; overflow-y: hidden;
    border-top: 1px solid rgba(255, 255, 255, .12);
    /* Platz für die Bedienleiste des Browsers am unteren Rand */
    padding-bottom: max(4px, env(safe-area-inset-bottom));
    -webkit-overflow-scrolling: touch;
  }
  /* Unten liegend zählt nur die Symbolreihe — Namen passten dort nie. */
  .nb-side, .nb-side.schmal { width: 100%; padding: 4px 6px; gap: 2px; }
  .nb-side button, .nb-side.schmal button { width: 40px; justify-content: center; padding: 0; }
  .nb-side button .txt { display: none; }
  .nb-side .nb-side__weite { display: none; }
  .nb-side .logo { display: none; }
  .nb-side .spacer { flex: 0 0 auto; width: 6px; }
  .nb-side button { flex: 0 0 auto; width: 40px; margin: 0; }

  /* Damit die untere Leiste nichts verdeckt */
  .nb-main { padding-bottom: 60px; }

  .nb-content { padding: 10px; }
  .nb-grid.c2, .nb-grid.c3, .nb-grid.c4 { grid-template-columns: minmax(0, 1fr); }

  /* Tabellen rollen in ihrem eigenen Bereich, statt die Seite zu verbreitern */
  .nb-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .nb-table { min-width: 560px; }

  /* Kopfzeile: Titel darf kürzen statt umzubrechen */
  .nb-topbar { padding: 0 12px; gap: 8px; }
  .nb-topbar h1 { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  .nb-card { padding: 12px; }

  /* Auf Fingerbedienung: iOS zoomt bei Schriftgrößen unter 16 px hinein */
  .nb-input, .nb-select, textarea.nb-input { font-size: 16px; }
  .nb-btn { padding: 9px 14px; }

  .nb-modal-bg { padding: 3vh 10px; }
  .nb-modal { width: 100%; max-height: 92vh; }

  /* --- Die eigentliche Ursache des Querlaufs ---
     Die Module bauen ihre Werkzeugleisten als Flex-Zeilen direkt im JavaScript
     zusammen — Suchfeld, Auswahlfelder, Knöpfe nebeneinander, ohne Umbruch. Auf
     Schreibtischbreite passt das, auf 375 px schiebt jede dieser Zeilen die Seite
     auf. Weil die Angaben inline stehen, lassen sie sich nicht einzeln
     überschreiben; erlaubt man aber allen Elementen hier den Umbruch, wirkt das
     genau auf die Flex-Zeilen und lässt alles andere unberührt (flex-wrap hat auf
     Nicht-Flex-Elementen keine Wirkung). */
  .nb-content div, .nb-content form, .nb-content p { flex-wrap: wrap; }

  /* Umbrechen allein genügt nicht: Eine Flex-Spalte ohne Mindestbreite wird
     lieber schmalgequetscht als umgebrochen — im SalesManager stand „Telefonate"
     dadurch Buchstabe für Buchstabe untereinander. Mit einer Mindestbreite
     entscheidet sich der Umbruch, sobald es eng wird. min() deckelt auf die
     verfügbare Breite, es kann also nichts hinausragen. */
  .nb-content > div > div, .nb-card > div > div { min-width: min(100%, 240px); }

  /* Feste Feldbreiten aus den Modulen (90 px PLZ, 340 px Spalte …) dürfen nie
     breiter werden als der Platz, der da ist. */
  .nb-content input, .nb-content select, .nb-content textarea,
  .nb-input, .nb-select, textarea.nb-input { max-width: 100%; }

  /* Kennzahlen untereinander statt nebeneinander */
  .nb-card.nb-kpi { min-width: 0; }

  /* Reiter: lieber waagerecht schieben als in drei Reihen umbrechen */
  .nb-tabs {
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .nb-tabs::-webkit-scrollbar { display: none; }
  .nb-tabs button { flex: 0 0 auto; white-space: nowrap; }

  /* Lange Pfade und Kennungen brechen, statt die Karte zu sprengen */
  .nb-content, .nb-card, .nb-table td { overflow-wrap: break-word; }
}

/* ---- Dunkelmodus ----
   Zwei Wege führen hierher: die Systemeinstellung des Betriebssystems und der
   Schalter in der Kopfzeile. Der Schalter setzt data-theme auf <html> und hat
   Vorrang — deshalb schließt die Systemregel data-theme="light" ausdrücklich
   aus, sonst könnte man am Systemdunkel nicht vorbei ins Helle schalten.

   Getauscht werden ausschließlich Werte. Jede Regel weiter oben bleibt, wie
   sie ist; das ist der Grund, warum die Flächen oben eigene Token bekommen
   haben. Rot bleibt Rot — nur die Schriftfarbe wandert ins Hellere, weil
   #c92626 auf dunklem Grund nur noch 2,2:1 erreicht. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { color-scheme: dark; }
}
:root[data-theme="dark"] { color-scheme: dark; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --nb-rot-text: #ff6b6b;
    --nb-sidebar: #000000;
    --nb-sidebar-hi: #1e1e24;
    --nb-bg: #0f0f12;
    --nb-card: #1a1a1f;
    --nb-line: #2c2c34;
    --nb-line-stark: #3d3d47;
    --nb-text: #ececef;
    --nb-muted: #9b9ba6;
    --nb-flaeche: #24242b;
    --nb-zebra: #1e1e23;
    --nb-zeile-hover: rgba(239, 64, 64, .13);
    --nb-hover: #24242b;
    --nb-side-icon: #8b8b96;
    --nb-backdrop: rgba(0, 0, 0, .66);
    --nb-shadow: 0 1px 3px rgba(0, 0, 0, .5);
    --nb-ok-bg:   #14301f;  --nb-ok-fg:   #6ddba0;
    --nb-bad-bg:  #3a1512;  --nb-bad-fg:  #ff8f84;
    --nb-warn-bg: #34280d;  --nb-warn-fg: #e8bf63;  --nb-warn-line: #4a3a14;
    --nb-rot-bg:  #3a1416;
    --nb-invers: #ececef;  --nb-invers-fg: #14141a;
  --nb-invers-hover: #cfcfd6;
  --nb-kopf-bg: #24242b;  --nb-kopf-fg: #ececef;
    --nb-invers-hover: #cfcfd6;
    --nb-kopf-bg: #24242b;  --nb-kopf-fg: #ececef;
    --nb-ok: #4cbf7a;
    --nb-warn: #e8bf63;
    --nb-bad: #ff8f84;
  }
}
:root[data-theme="dark"] {
  --nb-rot-text: #ff6b6b;
  --nb-sidebar: #000000;
  --nb-sidebar-hi: #1e1e24;
  --nb-bg: #0f0f12;
  --nb-card: #1a1a1f;
  --nb-line: #2c2c34;
  --nb-line-stark: #3d3d47;
  --nb-text: #ececef;
  --nb-muted: #9b9ba6;
  --nb-flaeche: #24242b;
  --nb-zebra: #1e1e23;
  --nb-zeile-hover: rgba(239, 64, 64, .13);
  --nb-hover: #24242b;
  --nb-side-icon: #8b8b96;
  --nb-backdrop: rgba(0, 0, 0, .66);
  --nb-shadow: 0 1px 3px rgba(0, 0, 0, .5);
  --nb-ok-bg:   #14301f;  --nb-ok-fg:   #6ddba0;
  --nb-bad-bg:  #3a1512;  --nb-bad-fg:  #ff8f84;
  --nb-warn-bg: #34280d;  --nb-warn-fg: #e8bf63;  --nb-warn-line: #4a3a14;
  --nb-rot-bg:  #3a1416;
  --nb-invers: #ececef;  --nb-invers-fg: #14141a;
  --nb-ok: #4cbf7a;
  --nb-warn: #e8bf63;
  --nb-bad: #ff8f84;
}

/* Das Logo trägt schwarze Buchstaben — auf dunklem Grund unsichtbar.
   Deshalb zwei Dateien, umgeschaltet über dieselbe Regel wie die Farben. */
.nb-logo-dunkel { display: block; }
.nb-logo-hell { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .nb-logo-dunkel { display: none; }
  :root:not([data-theme="light"]) .nb-logo-hell   { display: block; }
}
:root[data-theme="dark"] .nb-logo-dunkel { display: none; }
:root[data-theme="dark"] .nb-logo-hell   { display: block; }
:root[data-theme="light"] .nb-logo-dunkel { display: block; }
:root[data-theme="light"] .nb-logo-hell   { display: none; }

/* Umschalter in der Kopfzeile */
.nb-theme {
  border: 1px solid var(--nb-line); background: var(--nb-card); color: var(--nb-muted);
  width: 32px; height: 32px; border-radius: 8px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; padding: 0;
}
.nb-theme:hover { background: var(--nb-hover); color: var(--nb-text); border-color: var(--nb-line-stark); }
.nb-theme .mond { display: none; }
:root[data-theme="dark"] .nb-theme .sonne { display: none; }
:root[data-theme="dark"] .nb-theme .mond  { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .nb-theme .sonne { display: none; }
  :root:not([data-theme="light"]) .nb-theme .mond  { display: block; }
}
:root[data-theme="light"] .nb-theme .sonne { display: block; }
:root[data-theme="light"] .nb-theme .mond  { display: none; }

/* Ankreuzfelder und Auswahlknöpfe zeichnet der Browser sonst in seinem eigenen
   Blau — das war die letzte Farbe in der Oberfläche, die nicht zur Marke gehört. */
input[type="checkbox"], input[type="radio"], input[type="range"], progress {
  accent-color: var(--nb-accent);
}

/* Auswahl-Markierung: dieselbe Logik. */
::selection { background: rgba(239, 64, 64, .22); }

/* ---- Tastaturbedienung ----
   Ohne sichtbaren Fokus ist die Oberfläche ohne Maus nicht benutzbar. Der Ring
   sitzt außerhalb des Elements, damit er in dichten Tabellen nicht abgeschnitten
   wird, und nutzt :focus-visible — bei Mausklicks erscheint er also nicht. */
a:focus-visible, button:focus-visible, [tabindex]:focus-visible,
.nb-btn:focus-visible, .nb-side button:focus-visible {
  outline: 2px solid var(--nb-rot);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---- Bewegung ----
   Wer im Betriebssystem weniger Bewegung eingestellt hat, bekommt sie hier auch
   nicht. Der Ladering bleibt sichtbar, er dreht sich nur langsamer statt gar
   nicht — ganz ohne Bewegung wäre nicht mehr erkennbar, dass etwas läuft. */
@media (prefers-reduced-motion: reduce) {
  .nb-spin::after { animation-duration: 2.4s; }
  * { transition-duration: .01ms !important; }
}

/* Kleine Marke für Nebenangaben in der Trefferzeile — erkannte Technik,
   Social-Media-Profile. Leiser als ein Badge (nur Haarlinie, keine Fläche),
   damit die Zeile nicht mit der Branchenkennzeichnung darunter konkurriert. */
.nb-tag {
  display: inline-flex; align-items: center;
  /* Der Rahmen zählt bei der Außenkante mit: 1 px Rahmen plus 8 px Polster
     ergibt dieselben 9 px wie beim gefüllten Badge daneben. Sonst wirken die
     beiden Markenarten unterschiedlich groß, obwohl sie es nicht sind. */
  padding: 1px 8px; border: 1px solid var(--nb-line); border-radius: 4px;
  font-size: 11px; line-height: 1.45; color: var(--nb-muted); white-space: nowrap;
}
a.nb-tag--link { color: var(--nb-muted); text-decoration: none; }
a.nb-tag--link:hover {
  color: var(--nb-blue); border-color: var(--nb-blue); text-decoration: none;
}

/* ==========================================================================
   Umbrüche nach verfügbarem Platz, nicht nach Fensterbreite
   ==========================================================================
   Die Regeln oben messen das Fenster. Solange die Seitenleiste 60 px breit war,
   ging das auf. Mit der offenen Leiste nimmt sie 208 px — der Inhalt hat also
   148 px weniger, die Raster brechen aber erst um, wenn das FENSTER schmal wird.
   Sichtbar wurde das im SalesManager: Die Karten liefen rechts aus dem Bild,
   obwohl das Fenster breit genug schien.

   Ein Container-Query misst den Bereich selbst und ist damit unabhängig davon,
   wie breit die Leiste gerade steht. Die Regeln hier sind zusätzlich — die
   Fensterregeln oben bleiben als Vorgabe für alte Browser bestehen.

   Die Schwellen entsprechen den bisherigen abzüglich der schmalen Leiste:
   900 → 840, 700 → 640, 560 → 500.
   (Gemessen wird der Inhalt selbst, die Leistenbreite spielt keine Rolle.) */
.nb-main { container-type: inline-size; container-name: inhalt; }

@container inhalt (max-width: 840px) {
  .nb-grid.c3, .nb-grid.c4 { grid-template-columns: 1fr 1fr; }
  .nb-content { padding: 12px; }
  .nb-suche { flex-direction: column; }
  .nb-suche__treffer { width: 100%; }
  /* Übereinander gestapelt schoben die zwölf Filtergruppen die Trefferliste
     komplett unter den sichtbaren Bereich — es sah aus, als käme nichts
     zurück. Mit eigener Rollhöhe bleiben die Filter erreichbar und die
     Treffer stehen direkt darunter. */
  .nb-suche__filter {
    width: 100%; max-height: 42vh; overflow-y: auto;
    border-bottom: 1px solid var(--nb-line); padding-bottom: 8px; margin-bottom: 4px;
  }
  .nb-spalten--seite, .nb-spalten--zwei { grid-template-columns: minmax(0, 1fr); }
}

@container inhalt (max-width: 640px) {
  .nb-content { padding: 10px; }
  .nb-grid.c2, .nb-grid.c3, .nb-grid.c4 { grid-template-columns: minmax(0, 1fr); }
  .nb-table { min-width: 560px; }
  .nb-card { padding: 12px; }

  /* Dieselbe Begründung wie im Fensterblock: Die Module bauen ihre
     Werkzeugleisten als Flex-Zeilen im JavaScript zusammen, ohne Umbruch. */
  .nb-content div, .nb-content form, .nb-content p { flex-wrap: wrap; }
  .nb-content > div > div, .nb-card > div > div { min-width: min(100%, 240px); }
  .nb-content input, .nb-content select, .nb-content textarea,
  .nb-input, .nb-select, textarea.nb-input { max-width: 100%; }
  .nb-card.nb-kpi { min-width: 0; }
  .nb-tabs button { flex: 0 0 auto; white-space: nowrap; }
  .nb-content, .nb-card, .nb-table td { overflow-wrap: break-word; }
}

@container inhalt (max-width: 500px) {
  .nb-spalten--paar { grid-template-columns: minmax(0, 1fr); }
}

/* Sortierbarer Spaltenkopf. Nur die Spalten, für die es einen Schlüssel gibt,
   bekommen Zeiger und Hover — die übrigen bleiben unauffällig, damit niemand
   dort einen Klick versucht. */
.nb-th--sort { cursor: pointer; user-select: none; }
.nb-th--sort:hover { color: var(--nb-text); }
.nb-th--sort.ist-sortiert { color: var(--nb-blue); }
/* Der Doppelpfeil zeigt an, dass hier sortiert werden kann — leise genug,
   um die Spaltenbeschriftung nicht zu stören, aber immer sichtbar. */
.nb-th--sort .pfeil { margin-left: 4px; opacity: .35; font-weight: 400; }
.nb-th--sort:hover .pfeil { opacity: .7; }
.nb-th--sort.ist-sortiert .pfeil { opacity: 1; }

/* Schnellfilter im Spaltenkopf. Er sitzt neben dem Sortierpfeil und blättert
   durch die gängigen Werte — ohne dass man dafür die Filterspalte aufklappen
   muss. Ruhig gesetzt, solange nichts gewählt ist; mit Wert wird er zur
   sichtbaren Marke, damit niemand übersieht, dass die Liste eingeschränkt ist. */
.nb-th__blatt {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: 6px; padding: 1px 5px; border: 1px solid transparent;
  border-radius: 4px; background: transparent; color: var(--nb-muted);
  cursor: pointer; font: inherit; font-size: 10.5px; letter-spacing: 0;
  text-transform: none; vertical-align: middle; opacity: .45;
}
.nb-th--sort:hover .nb-th__blatt { opacity: .9; }
.nb-th__blatt:hover { color: var(--nb-blue); border-color: var(--nb-blue); opacity: 1; }
.nb-th__blatt.ist-gesetzt {
  opacity: 1; color: var(--nb-blue); border-color: var(--nb-line);
  background: var(--nb-card); font-weight: 600;
}
.nb-th__blatt .wert { white-space: nowrap; max-width: 108px; overflow: hidden; text-overflow: ellipsis; }

/* ---- Klebender Tabellenkopf ----
   Der Kopf ist seit jeher als position: sticky angelegt, klebte aber nie: Ein
   Element mit overflow-x: auto ist ein eigener Scroll-Container, und sticky
   bezieht sich dann darauf statt auf die Seite. Da der Container vertikal gar
   nicht rollte, gab es nichts, woran der Kopf hätte kleben können.

   Mit einer Höhenbegrenzung rollt die Tabelle in sich — und der Kopf bleibt
   beim Durchgehen von fünfzig Zeilen stehen, statt nach der dritten Zeile aus
   dem Bild zu laufen. Die Grenze ist großzügig, damit kurze Listen weiterhin
   ganz zu sehen sind und kein zweiter Rollbalken ohne Not entsteht. */
.nb-table-wrap { max-height: calc(100vh - 260px); min-height: 220px; overflow: auto; }
.nb-table thead th { position: sticky; top: 0; z-index: 2; }

@media (max-width: 700px) {
  /* Auf dem Handy verschachtelte Rollbereiche vermeiden: Dort ist der Schirm
     ohnehin kurz, und zwei ineinanderliegende Rollflächen sind mit dem Finger
     kaum zu treffen. */
  .nb-table-wrap { max-height: none; min-height: 0; overflow-x: auto; overflow-y: visible; }
}
