/* ═══════════════════════════════════════════════════════════════════════════
 * OPERATOR — LICHT- UND BEWEGUNGSSYSTEM (17.08.2026)
 *
 * Max' Vorgabe in einem Satz: „Ein modernes, hochwertiges, dunkles, kontrolliert
 * leuchtendes KI-Control-System mit subtilen Jarvis-Motion-Vibes — funktional
 * vor verspielt."
 *
 * VORHER GEMESSEN (tools/audit-design.js über neun Ansichten):
 *   · 12 verschiedene Knopfhöhen (14 / 16 / 21 / 25 / 32 / 37 / 39 / 63 px …)
 *   · 9 verschiedene Eckenradien (2 / 4 / 5 / 6 / 9 / 13 px / 50 % …)
 *   · 24 verschiedene Schriftgrößen
 *   · GENAU EIN Schatten im ganzen System — und das war der Fokusring des
 *     Browsers. Licht als Gestaltungsmittel gab es faktisch nicht.
 *   · dafür schon sauber: nur 3 Übergangszeiten, nur EINE Dauer-Animation.
 *
 * Daraus folgt die Arbeitsteilung dieser Datei:
 *   1. LICHT   — vier Stufen, an Bedeutung gebunden, zentral abschaltbar
 *   2. BEWEGUNG— vier Dauern, drei Muster, zentral abschaltbar
 *   3. FORM    — eine Radien-Leiter, eine Knopf-Leiter, eine Schrift-Leiter
 *   4. ZUSTAND — jeder Systemzustand hat genau ein Aussehen
 *
 * ZWEI SCHALTER STEUERN ALLES (aus den Einstellungen, Punkt 77):
 *   [data-motion="voll|reduziert|aus"]   → --m    (Bewegungsfaktor)
 *   [data-licht="voll|dezent|aus"]       → --glut (Lichtfaktor)
 * Beide wirken über Rechnungen auf ALLE Werte. Ein Regler, nicht 200 Stellen.
 * ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Bewegungs- und Lichtfaktor — von den Einstellungen gesetzt. */
  --m: 1;
  --glut: 1;

  /* --- Die vier Dauern. Mehr braucht es nicht. --- */
  --d-tipp:  calc(90ms  * var(--m));   /* Knopf drückt sich, Haken springt   */
  --d-kurz:  calc(150ms * var(--m));   /* Hover, Fokus, Farbwechsel          */
  --d-mittel:calc(240ms * var(--m));   /* Panel fährt ein, Karte erscheint   */
  --d-lang:  calc(420ms * var(--m));   /* Seitenwechsel, große Überblendung  */

  /* --- Die zwei Kurven. Jarvis bewegt sich präzise, nicht verspielt. --- */
  --e-raus: cubic-bezier(.16,.84,.44,1);    /* kommt herein: schnell an, weich aus */
  --e-rein: cubic-bezier(.55,0,.85,.35);    /* geht hinaus: weich an, schnell aus  */
  /* Bewusst KEIN Überschwingen/Bounce — Vorgabe 73. Ein Kontrollsystem federt nicht. */

  /* --- Licht in vier Stufen, alle am Faktor --glut --- */
  --licht-1: 0 0 0 1px rgb(from var(--sys) r g b / calc(.22 * var(--glut)));
  --licht-2: 0 0 12px rgb(from var(--sys) r g b / calc(.28 * var(--glut)));
  --licht-3: 0 0 22px rgb(from var(--sys) r g b / calc(.38 * var(--glut))),
             0 0 2px  rgb(from var(--sys) r g b / calc(.55 * var(--glut)));
  --licht-4: 0 0 34px rgb(from var(--sys) r g b / calc(.50 * var(--glut))),
             0 0 3px  rgb(from var(--sys) r g b / calc(.75 * var(--glut)));

  /* Tiefe kommt aus Schatten, Wichtigkeit aus Licht — nie andersherum. */
  --tiefe-1: 0 1px 2px rgba(0,0,0,.30), 0 2px 8px rgba(0,0,0,.22);
  --tiefe-2: 0 4px 12px rgba(0,0,0,.38), 0 12px 32px rgba(0,0,0,.30);
  --tiefe-3: 0 12px 28px rgba(0,0,0,.45), 0 32px 64px rgba(0,0,0,.40);

  /* --- Radien-Leiter: vier Stufen statt neun Zufallswerte --- */
  --r-xs: 4px;    /* Marken, Haken, winzige Chips */
  --r-s:  6px;    /* Knöpfe, Eingaben            */
  --r:    10px;   /* Karten, Panels              */
  --r-l:  14px;   /* Overlays, Schub, Modale     */

  /* --- Knopf-Leiter: drei Höhen statt zwölf --- */
  --k-gross:  34px;
  --k-normal: 28px;
  --k-klein:  22px;

  /* --- Schrift-Leiter: sechs Stufen statt vierundzwanzig --- */
  --fs-xs: 10.5px;   /* Etiketten in Großbuchstaben  */
  --fs-s:  11.5px;   /* Nebentext, Hinweise          */
  --fs-m:  12.5px;   /* Grundtext in Tabellen        */
  --fs-l:  13.5px;   /* Lesetext                     */
  --fs-xl: 16px;     /* Kartenüberschriften          */
  --fs-2xl: 21px;    /* Seitentitel, große Zahlen    */
}

/* Die Schalter aus den Einstellungen. */
[data-motion="reduziert"] { --m: .55; }
[data-motion="aus"]       { --m: 0; }
[data-licht="dezent"]     { --glut: .5; }
[data-licht="aus"]        { --glut: 0; }

/* Systemeinstellung schlägt alles — wer Bewegung abbestellt hat, bekommt keine. */
@media (prefers-reduced-motion: reduce) { :root { --m: 0; } }

/* ─────────────────────────────────────────────────────────────────────────
 * 1. FORM VEREINHEITLICHEN
 *
 * Die Ansichten setzen an vielen Stellen eigene Maße direkt ins HTML. Statt
 * hundert Stellen anzufassen (und dabei Funktionierendes zu zerlegen), zieht
 * diese Ebene sie auf die Leiter zurück. Wer bewusst etwas anderes will,
 * setzt eine Klasse — der Zufall bekommt keine Ausnahme mehr.
 * ───────────────────────────────────────────────────────────────────────── */
.b            { height: var(--k-normal); border-radius: var(--r-s); }
.b.klein      { height: var(--k-klein); }
.b.winzig     { height: 20px; border-radius: var(--r-xs); }
.b.gross      { height: var(--k-gross); padding: 0 16px; font-size: var(--fs-l); }
.karte,
.filterfeld,
.automatik-leiste,
.agent-kopf,
.mission-kopf { border-radius: var(--r); }
#jarvis-schub,
.palette,
.insp         { border-radius: var(--r-l); }
.m, .marke    { border-radius: var(--r-xs); }

/* ─────────────────────────────────────────────────────────────────────────
 * 2. RÜCKMELDUNG — jede Aktion muss sich anfühlen (Vorgabe 74)
 * ───────────────────────────────────────────────────────────────────────── */

/* Knöpfe: Hover hebt an, Klick drückt. Kein Bounce, kein Wackeln. */
.b {
  transition: background var(--d-kurz) var(--e-raus),
              border-color var(--d-kurz) var(--e-raus),
              color var(--d-kurz) var(--e-raus),
              box-shadow var(--d-kurz) var(--e-raus),
              transform var(--d-tipp) var(--e-raus);
}
.b:hover:not(:disabled)  { transform: translateY(-1px); box-shadow: var(--tiefe-1); }
.b:active:not(:disabled) { transform: translateY(0); transition-duration: var(--d-tipp); }
.b.haupt:hover:not(:disabled) { box-shadow: var(--licht-2), var(--tiefe-1); }

/* Fokus: ein klarer Leuchtrand — für Tastatur UND als Zeichen „hier bist du". */
:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--sys), var(--licht-2);
  border-radius: var(--r-s);
}

/* Karten: heben sich beim Überfahren leicht, wenn sie anklickbar sind. */
.karte { transition: border-color var(--d-kurz) var(--e-raus), box-shadow var(--d-mittel) var(--e-raus); }
.zeile.klick, .zaehler, .diff-datei, .verweis, .ff-b, .core-faehig {
  transition: background var(--d-kurz) var(--e-raus),
              border-color var(--d-kurz) var(--e-raus),
              color var(--d-kurz) var(--e-raus),
              box-shadow var(--d-kurz) var(--e-raus),
              transform var(--d-tipp) var(--e-raus);
}
.zaehler:hover  { transform: translateY(-2px); box-shadow: var(--tiefe-1); }
.zaehler.an     { box-shadow: var(--licht-1), var(--licht-2); }
.verweis:hover  { box-shadow: var(--licht-1); }
.ff-b.an        { box-shadow: var(--licht-1); }

/* Anklickbare Zeile: ein Lichtstreifen links statt eines Farbklecks.
   So sieht man, WO man ist, ohne dass die Zeile die Farbe wechselt. */
.zeile.klick { position: relative; }
.zeile.klick::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--sys); opacity: 0; transform: scaleY(.3);
  transition: opacity var(--d-kurz) var(--e-raus), transform var(--d-kurz) var(--e-raus);
}
.zeile.klick:hover::before { opacity: .9; transform: scaleY(1); }
.zeile.markiert::before    { opacity: 1; transform: scaleY(1); box-shadow: var(--licht-2); }

/* Mehrfachauswahl soll sich stark anfühlen (Vorgabe 74). */
.kast input:checked + span { box-shadow: var(--licht-2); }
.stapel-leiste { box-shadow: var(--licht-1), var(--tiefe-1); }

/* ─────────────────────────────────────────────────────────────────────────
 * 3. ZUSTÄNDE — jeder Systemzustand hat genau ein Aussehen (Vorgabe 79)
 *
 * Vorher trugen Statuspunkte nur eine Farbe. Jetzt trägt jeder Zustand
 * Farbe + Licht + (nur wo etwas WIRKLICH passiert) Bewegung. Ruhende
 * Zustände bewegen sich nicht — sonst wäre das Zappeln bedeutungslos.
 * ───────────────────────────────────────────────────────────────────────── */
.pkt {
  position: relative;
  transition: box-shadow var(--d-kurz) var(--e-raus), background var(--d-kurz) var(--e-raus);
}
.pkt.ok    { box-shadow: 0 0 10px rgb(from var(--ok)   r g b / calc(.55 * var(--glut))); }
.pkt.wait  { box-shadow: 0 0 10px rgb(from var(--wait) r g b / calc(.55 * var(--glut))); }
.pkt.bad   { box-shadow: 0 0 10px rgb(from var(--bad)  r g b / calc(.60 * var(--glut))); }
.pkt.sys   { box-shadow: 0 0 10px rgb(from var(--sys)  r g b / calc(.50 * var(--glut))); }
.pkt.idle  { box-shadow: none; opacity: .7; }

/* „lebt" heißt: da rechnet gerade etwas. Ein weicher Ring, kein Blinken. */
.pkt.lebt::after {
  content: ''; position: absolute; inset: -3px; border-radius: 50%;
  border: 1px solid currentColor; opacity: 0;
  animation: puls-ring calc(2600ms / max(var(--m), .01)) var(--e-raus) infinite;
}
@keyframes puls-ring {
  0%   { opacity: .55; transform: scale(.85); }
  70%  { opacity: 0;   transform: scale(1.6); }
  100% { opacity: 0;   transform: scale(1.6); }
}
[data-motion="aus"] .pkt.lebt::after { animation: none; opacity: .35; transform: scale(1.2); }

/* Marken (Badges) bekommen ihre Bedeutung auch über einen Lichtrand. */
.m.ok   { box-shadow: inset 0 0 0 1px rgb(from var(--ok)   r g b / calc(.35 * var(--glut))); }
.m.wait { box-shadow: inset 0 0 0 1px rgb(from var(--wait) r g b / calc(.35 * var(--glut))); }
.m.bad  { box-shadow: inset 0 0 0 1px rgb(from var(--bad)  r g b / calc(.40 * var(--glut))); }
.m.sys  { box-shadow: inset 0 0 0 1px rgb(from var(--sys)  r g b / calc(.35 * var(--glut))); }

/* Eine Karte, die auf Max wartet, leuchtet am Rand — einmal, dauerhaft, ruhig. */
.karte.ruft  { box-shadow: inset 0 0 0 1px rgb(from var(--wait) r g b / calc(.32 * var(--glut))),
                           0 0 24px rgb(from var(--wait) r g b / calc(.10 * var(--glut))); }
.karte.lebt  { box-shadow: inset 0 0 0 1px rgb(from var(--ok) r g b / calc(.26 * var(--glut))); }

/* ─────────────────────────────────────────────────────────────────────────
 * 4. ARBEITS-ANIMATIONEN (Vorgabe 72)
 *
 * Nur dort, wo wirklich etwas läuft. Hört die Arbeit auf, hört die Bewegung
 * auf — sonst gewöhnt man sich daran und sieht sie nicht mehr.
 * ───────────────────────────────────────────────────────────────────────── */

/* Fortschrittsbalken einer laufenden Mission: ein wanderndes Licht darüber. */
.balken.laeuft { position: relative; overflow: hidden; }
.balken.laeuft::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent,
              rgb(from var(--sys) r g b / calc(.45 * var(--glut))), transparent);
  transform: translateX(-100%);
  animation: wandern calc(1800ms / max(var(--m), .01)) linear infinite;
}
@keyframes wandern { to { transform: translateX(100%); } }
[data-motion="aus"] .balken.laeuft::after { animation: none; opacity: 0; }

/* Der Balken selbst wächst weich in seine neue Länge, statt zu springen. */
.balken > i { transition: width var(--d-lang) var(--e-raus); }

/* Zahl hat sich geändert: kurz aufleuchten, nicht hüpfen. */
.z.frisch { animation: aufleuchten calc(900ms / max(var(--m), .01)) var(--e-raus) 1; }
@keyframes aufleuchten {
  0%   { color: var(--sys); text-shadow: 0 0 14px rgb(from var(--sys) r g b / .8); }
  100% { color: inherit;    text-shadow: none; }
}

/* ─────────────────────────────────────────────────────────────────────────
 * 5. ERSCHEINEN — Panels, Overlays, Detailansichten (Vorgabe 75)
 *
 * Nichts springt auf. Alles kommt aus einer Richtung und richtet den Blick
 * dorthin, wo es erscheint.
 * ───────────────────────────────────────────────────────────────────────── */
@keyframes rein-unten { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes rein-rechts{ from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: none; } }
@keyframes rein-sanft { from { opacity: 0; transform: scale(.985); }      to { opacity: 1; transform: none; } }

#jarvis-schub          { animation: rein-unten var(--d-mittel) var(--e-raus) 1; box-shadow: var(--tiefe-3), var(--licht-2); }
.insp, [data-insp]     { animation: rein-rechts var(--d-mittel) var(--e-raus) 1; }
.palette-hg            { animation: rein-sanft var(--d-kurz) var(--e-raus) 1; }
.palette               { animation: rein-unten var(--d-mittel) var(--e-raus) 1; box-shadow: var(--tiefe-3), var(--licht-2); }
#farbwelt-menue        { animation: rein-unten var(--d-mittel) var(--e-raus) 1; box-shadow: var(--tiefe-3); }
.stapel-leiste         { animation: rein-unten var(--d-kurz) var(--e-raus) 1; }
.filterfeld            { animation: rein-unten var(--d-mittel) var(--e-raus) 1; }
#fluss-liste > .karte  { animation: rein-unten var(--d-mittel) var(--e-raus) 1; }

/* Der Hintergrund tritt zurück, wenn etwas Wichtiges davor liegt. */
.palette-hg { backdrop-filter: blur(3px) saturate(.85); }

/* ─────────────────────────────────────────────────────────────────────────
 * 6. SCROLLEN (Vorgabe 71)
 *
 * Zwei Dinge, mehr nicht: Abschnitte blenden beim Erscheinen sanft ein, und
 * klebende Köpfe bekommen beim Scrollen eine Kante, damit man sieht, dass
 * darunter etwas durchläuft. Kein Parallax, keine Effekte um ihrer selbst
 * willen — das wäre genau das „billig futuristisch", das Max nicht will.
 * ───────────────────────────────────────────────────────────────────────── */
.flaeche { scroll-behavior: smooth; }
[data-motion="aus"] .flaeche { scroll-behavior: auto; }

/* Wird von js/core/motion.js gesetzt, sobald der Abschnitt ins Bild kommt. */
.einzug        { opacity: 0; transform: translateY(14px); }
.einzug.da     { opacity: 1; transform: none;
                 transition: opacity var(--d-mittel) var(--e-raus),
                             transform var(--d-mittel) var(--e-raus); }
[data-motion="aus"] .einzug { opacity: 1; transform: none; }

/* Klebende Tabellenköpfe und die Kopfzeile: Kante + Tiefe erst beim Scrollen. */
.tab-titel { transition: box-shadow var(--d-kurz) var(--e-raus), background var(--d-kurz) var(--e-raus); }
.geschoben .tab-titel { box-shadow: 0 6px 16px rgba(0,0,0,.35); }
#kopf { transition: box-shadow var(--d-kurz) var(--e-raus), border-color var(--d-kurz) var(--e-raus); }
#kopf.geschoben { box-shadow: 0 4px 20px rgba(0,0,0,.45); border-bottom-color: var(--line-hell); }

/* Scrollbalken gehören zur Handschrift — dünn, ruhig, sichtbar wenn gebraucht. */
.flaeche, .chat-log, .gespr-log, .diff-code, .roh, .ergebnis, #inhalt * {
  scrollbar-width: thin;
  scrollbar-color: var(--line-hell) transparent;
}
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line-hell); border-radius: 5px;
  border: 2px solid transparent; background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--sys); background-clip: content-box; }

/* ─────────────────────────────────────────────────────────────────────────
 * 7. NAVIGATION — der aktive Punkt trägt Licht, nicht nur Farbe
 * ───────────────────────────────────────────────────────────────────────── */
.nav-p { transition: background var(--d-kurz) var(--e-raus), color var(--d-kurz) var(--e-raus); position: relative; }
.nav-p::before {
  content: ''; position: absolute; left: 0; top: 6px; bottom: 6px; width: 2px;
  background: var(--sys); border-radius: 0 2px 2px 0;
  transform: scaleY(0); transform-origin: center;
  transition: transform var(--d-mittel) var(--e-raus);
}
.nav-p.an::before { transform: scaleY(1); box-shadow: var(--licht-2); }
.nav-p:hover::before { transform: scaleY(.5); }

/* ─────────────────────────────────────────────────────────────────────────
 * 8. GESPRÄCH — der Kern reagiert auf den Zustand (Vorgabe 72)
 * Die vier Zustände unterscheiden sich in FARBE und TAKT, nicht nur in Farbe.
 * ───────────────────────────────────────────────────────────────────────── */
.gespr-reaktor { transition: border-color var(--d-kurz) var(--e-raus), box-shadow var(--d-mittel) var(--e-raus); }
.gespr[data-zustand="hoert"]    .gespr-reaktor { box-shadow: 0 0 24px rgb(from var(--ok)    r g b / calc(.35 * var(--glut))); }
.gespr[data-zustand="denkt"]    .gespr-reaktor { box-shadow: 0 0 24px rgb(from var(--brain) r g b / calc(.35 * var(--glut))); }
.gespr[data-zustand="arbeitet"] .gespr-reaktor { box-shadow: 0 0 28px rgb(from var(--sys)   r g b / calc(.40 * var(--glut))); }
.gespr[data-zustand="spricht"]  .gespr-reaktor { box-shadow: 0 0 30px rgb(from var(--wait)  r g b / calc(.40 * var(--glut))); }

/* Beim Zuhören ein Pegel-Eindruck statt eines gleichförmigen Pulses:
   drei Ringe, leicht versetzt — das liest sich als „Ton kommt an". */
.gespr[data-zustand="hoert"] .gr-ring { animation-duration: calc(1500ms / max(var(--m), .01)); }
.gespr[data-zustand="denkt"] .gr-ring { animation-duration: calc(1000ms / max(var(--m), .01)); }

/* ─────────────────────────────────────────────────────────────────────────
 * 9. WAS NICHT LEUCHTET
 *
 * Genauso wichtig wie die Liste oben (Vorgabe 68: „nicht alles darf leuchten").
 * Fließtext, Tabellenzellen, Nebentext, ruhende Zustände und alles, was nur
 * Information trägt, bekommen KEIN Licht. Licht heißt hier immer: hier ist
 * etwas aktiv, wichtig oder wartet auf dich.
 * ───────────────────────────────────────────────────────────────────────── */
.neben, .hinweis-klein, .lesetext, .zeit, .keine-quelle { text-shadow: none; box-shadow: none; }

/* ═══════════════════════════════════════════════════════════════════════════
 * 10. EINSTELLUNGEN (Vorgaben 76 bis 78)
 *
 * Aufbau wie eine Systemsteuerung: Kategorien links, Inhalt rechts. Jede Zeile
 * ist ein Paar aus Beschriftung mit Erklärung und genau einem Bedienelement.
 * Keine Zeile ohne Erklärung — wer eine Einstellung nicht versteht, fasst sie
 * nicht an, und dann kann sie auch gleich weg.
 * ═══════════════════════════════════════════════════════════════════════════ */
.einst { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: var(--a4); align-items: start; }

.einst-nav {
  display: flex; flex-direction: column; gap: 2px; position: sticky; top: 0;
  background: var(--s1); border: 1px solid var(--line); border-radius: var(--r);
  padding: 6px; overflow: hidden;
}
.einst-p {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 9px 10px; border-radius: var(--r-s); color: var(--dim);
  transition: background var(--d-kurz) var(--e-raus), color var(--d-kurz) var(--e-raus);
  position: relative;
}
.einst-p::before {
  content: ''; position: absolute; left: 0; top: 8px; bottom: 8px; width: 2px;
  background: var(--sys); border-radius: 0 2px 2px 0;
  transform: scaleY(0); transition: transform var(--d-mittel) var(--e-raus);
}
.einst-p:hover { background: var(--s2); color: var(--text); }
.einst-p.an { background: var(--sys-weich); color: var(--text); }
.einst-p.an::before { transform: scaleY(1); box-shadow: var(--licht-2); }
.ep-ico { width: 20px; text-align: center; font-size: 15px; flex-shrink: 0; }
.ep-text { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ep-text b { font-size: var(--fs-m); font-weight: 600; }
.ep-text em { font-style: normal; font-size: var(--fs-xs); color: var(--dim2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.einst-inhalt { display: flex; flex-direction: column; gap: var(--a4); min-width: 0; }

/* Eine Einstellungszeile */
.e-zeile {
  display: flex; align-items: center; gap: var(--a3); justify-content: space-between;
  padding: 11px var(--a3); border-bottom: 1px solid var(--line); min-height: 46px;
}
.e-zeile:last-child { border-bottom: 0; }
label.e-zeile { cursor: pointer; }
label.e-zeile:hover { background: var(--s2); }
.e-zeile.gesperrt { opacity: .55; cursor: not-allowed; }
.e-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.e-text b { font-size: var(--fs-l); font-weight: 550; }
.e-text em { font-style: normal; font-size: var(--fs-s); color: var(--dim2); line-height: 1.45; }
.e-wert { font-size: var(--fs-m); text-align: right; flex-shrink: 0; max-width: 55%; }
.e-wahl { display: flex; gap: 4px; flex-wrap: wrap; justify-content: flex-end; flex-shrink: 0; }

.e-hinweis {
  margin: var(--a3); padding: 10px 12px; font-size: var(--fs-s); line-height: 1.55;
  color: var(--dim); background: var(--s2); border-left: 2px solid var(--line-hell);
  border-radius: 0 var(--r-s) var(--r-s) 0;
}
.e-hinweis code { background: var(--s3); padding: 1px 5px; border-radius: var(--r-xs); font-size: .95em; }

/* Der Schalter — das Bedienelement, das am meisten benutzt wird.
   Deshalb bekommt es echtes Feedback: der Knopf fährt, der Rahmen leuchtet. */
.schalter {
  position: relative; width: 40px; height: 22px; flex-shrink: 0;
  background: var(--s3); border: 1px solid var(--line-hell); border-radius: 11px;
  transition: background var(--d-kurz) var(--e-raus), border-color var(--d-kurz) var(--e-raus),
              box-shadow var(--d-kurz) var(--e-raus);
}
.schalter input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; margin: 0; }
.schalter i {
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--dim2); display: block;
  transition: transform var(--d-mittel) var(--e-raus), background var(--d-kurz) var(--e-raus);
}
.schalter.an { background: var(--sys-weich); border-color: var(--sys); box-shadow: var(--licht-2); }
.schalter.an i { transform: translateX(18px); background: var(--sys); }
.schalter input:disabled { cursor: not-allowed; }
.schalter input:focus-visible { outline: none; }
.schalter:has(input:focus-visible) { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--sys); }

/* Agentenzeile in den Einstellungen */
.e-tabelle { display: flex; flex-direction: column; }
.e-agent {
  display: grid; grid-template-columns: 26px minmax(0, 1fr) 78px 110px 40px 60px;
  gap: 10px; align-items: center; padding: 8px var(--a3);
  border-bottom: 1px solid var(--line);
}
.e-agent:last-child { border-bottom: 0; }
.e-agent:hover { background: var(--s2); }
.ea-ico { font-size: 15px; text-align: center; }
.ea-name { min-width: 0; display: flex; flex-direction: column; }
.ea-name b { font-size: var(--fs-m); font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ea-name em { font-style: normal; font-size: var(--fs-xs); color: var(--dim2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ea-abt { text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 1000px) {
  .einst { grid-template-columns: minmax(0, 1fr); }
  .einst-nav { position: static; flex-direction: row; overflow-x: auto; }
  .einst-p { flex: 0 0 auto; }
  .einst-p .ep-text em { display: none; }
  .einst-p::before { top: auto; bottom: 0; left: 8px; right: 8px; width: auto; height: 2px;
    border-radius: 2px 2px 0 0; transform: scaleX(0); }
  .einst-p.an::before { transform: scaleX(1); }
}
@media (max-width: 720px) {
  .e-zeile { flex-direction: column; align-items: stretch; gap: 8px; }
  .e-wert, .e-wahl { text-align: left; justify-content: flex-start; max-width: none; }
  .e-zeile .schalter { align-self: flex-start; }
  .e-agent { grid-template-columns: 26px minmax(0, 1fr) 40px; gap: 8px; }
  .e-agent .ea-modell, .e-agent .ea-abt, .e-agent .b { display: none; }
}

/* ── Einstellungen am Handy: die Kategorienleiste muss sich als wischbar zeigen
 *
 * Gemessen bei 390 px: die neun Kategorien lagen in einer waagerecht wischbaren
 * Leiste, sichtbar war nur „Allgemein" — und der aktive Bereich („Darstellung")
 * stand ausserhalb des Bildes. Man sah also eine Liste mit einem Eintrag und
 * einen Inhalt, der nicht dazu passte.
 *
 * Das Haus hat fuer genau diesen Fall schon eine Regel (Task #566): ein
 * scrollbarer Kasten braucht ein sichtbares Zeichen, sonst sieht er
 * abgeschnitten aus statt wischbar. Dieselbe Loesung, gleiches Aussehen —
 * nicht eine zweite Erfindung fuer dieselbe Sache. */
@media (max-width: 1000px) {
  .einst-nav { position: relative; scroll-behavior: smooth; }
  .einst-nav::after {
    content: '›'; position: absolute; top: 0; right: 0; bottom: 0; width: 26px;
    display: flex; align-items: center; justify-content: flex-end; padding-right: 5px;
    font-size: 15px; font-weight: 700; color: var(--dim2); pointer-events: none;
    background: linear-gradient(to right, transparent, var(--s1) 62%);
    border-radius: 0 var(--r) var(--r) 0;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
 * 11. AUSKLAPPEN (Vorgabe 75)
 *
 * Diffs, technische Details und Stufenlisten sprangen bisher auf. Jetzt fahren
 * sie ein — kurz und aus einer Richtung, damit der Blick mitgeht.
 *
 * Bewusst KEIN Höhen-Übergang: eine Höhe von 0 auf „automatisch" lässt sich
 * ohne Messung nicht animieren, und die Messung kostet bei einem 4000-Zeilen-
 * Diff mehr, als die Bewegung wert ist. Verschiebung und Deckkraft reichen —
 * sie sind auch das, was man wirklich sieht.
 * ───────────────────────────────────────────────────────────────────────── */
[data-diff-halter]:not([hidden]),
.tiefe[open] > .tiefe-inhalt,
.diff-fenster {
  animation: rein-unten var(--d-mittel) var(--e-raus) 1;
}

/* Die Zusammenfassung eines Commits ist der Einstieg — sie bekommt beim
 * Überfahren dieselbe Rückmeldung wie jede andere anklickbare Zeile. */
.diff-datei:hover { box-shadow: inset 2px 0 0 var(--sys); }

/* Der Pfeil vor „Technische Details" dreht sich, statt zu springen. */
.tiefe > summary::before {
  display: inline-block;
  transition: transform var(--d-kurz) var(--e-raus);
}
.tiefe[open] > summary::before { content: '▸'; transform: rotate(90deg); }

/* Der Chat und der Gesprächsverlauf laufen beim Öffnen sanft an, statt mit
 * einem harten Sprung an der letzten Nachricht zu stehen. */
.chat-log > .chat-n:last-child,
.gespr-log > .gespr-n:last-child { animation: rein-unten var(--d-kurz) var(--e-raus) 1; }

/* ── Die letzten Fast-Dubletten bei den Knopfhöhen ────────────────────────
 *
 * Aufgeschlüsselt nach Bauteil (nicht geraten): 20 px `.b.winzig`,
 * 21 px `.verweis`, 22 px `.b.klein`, 25 px `.ff-b`, 28 px `.b`, 31 px
 * `.bahn-raus-p`. Ein bis drei Pixel Unterschied zwischen Dingen, die
 * nebeneinander stehen — das sieht niemand bewusst, aber es macht eine Reihe
 * unruhig. Auf die Leiter gezogen: 20 / 22 / 28.
 *
 * WAS BEWUSST ABWEICHT und deshalb hier NICHT angefasst wird:
 *   42 px `.core-faehig`  — Beschriftungen rings um den Kern, keine Knöpfe
 *   46 px `.gespr-reaktor`— der Kern selbst
 *   54 px `.einst-p`      — Zeilen einer Kategorienliste
 *   63 px `.zaehler`      — Kennzahlkarten, die man anklicken kann
 * Sie alle auf Knopfhöhe zu zwingen, wäre Einheitlichkeit gegen den Sinn.
 * ───────────────────────────────────────────────────────────────────────── */
.verweis      { height: var(--k-klein); padding: 0 7px; }
.ff-b         { height: var(--k-klein); }
.bahn-raus-p  { height: var(--k-normal); }

/* ── Kopfzeile: das Suchfeld war auf 49 px zusammengedrückt ───────────────
 *
 * Gemessen bei 1600 px Fensterbreite: `.suche` 49 px breit, das Tastenkürzel
 * „Strg K" auf zwei Zeilen umgebrochen und 38 px hoch — es hing sichtbar aus
 * dem Feld heraus.
 *
 * Ursache ist nicht das Stylesheet von gestern, sondern Wachstum: der
 * Systempuls hat inzwischen SIEBEN Felder (zuletzt „Kontingent" dazu). Die
 * bestehenden Regeln blenden ab 1560/1400/1240 px einzelne Felder aus — sie
 * waren auf sechs Felder gerechnet. Der Puls ist ein Flex-Kasten mit fester
 * Breite je Feld, das Suchfeld hat `flex: 1` und gibt als Einziges nach.
 *
 * Zwei Regeln reichen: Das Suchfeld darf nicht unter eine benutzbare Breite
 * fallen, und der Puls muss schrumpfen dürfen, statt seinen Nachbarn zu
 * verdrängen. Das Kürzel bricht nie um — es verschwindet lieber ganz.
 * ───────────────────────────────────────────────────────────────────────── */
.suche { min-width: 190px; }
.puls  { min-width: 0; overflow-x: auto; scrollbar-width: none; }
.puls::-webkit-scrollbar { display: none; }

.suche kbd { white-space: nowrap; line-height: 1.25; }
/* Ist wenig Platz, ist das Kürzel das Erste, was geht — es ist ein Hinweis,
   kein Bedienelement. Strg+K funktioniert weiter, auch ohne Aufkleber. */
@media (max-width: 1500px) { .suche kbd { display: none; } }

/* ══ Handy-Leitern 19.08.2026 ═══════════════════════════════════════════════
 * Max: „die Handy-Ansicht ist fuer'n Arsch". Gemessen bei 390 px ueber alle
 * Ansichten — und die Ursache sitzt nicht in einzelnen Klassen, sondern in den
 * beiden Leitern oben in dieser Datei. Sie sind fuer einen Bildschirm gemacht,
 * den man 60 cm vor sich hat, nicht fuer ein Geraet in der Hand:
 *
 *   --fs-xs 10,5 px  → gemessen 260× allein in „Koennen"
 *   --fs-s  11,5 px  → Nebentext, Hinweise, halbe Missionsliste
 *   --k-klein 22 px  → Antippziel; Richtwert ist 44 px (Apple) / 48 px (Google)
 *
 * Eine Leiter anzuheben trifft alles auf einmal — das ist der Grund, warum es
 * hier steht und nicht als zwanzig Einzelregeln in app.css. Der Block MUSS am
 * Dateiende stehen: system.css wird nach app.css geladen, und beide setzen
 * :root — wer spaeter kommt, gewinnt.
 *
 * Die grossen Stufen (xl, 2xl) bleiben fast unveraendert: Ueberschriften waren
 * nie das Problem, und sie mitzuziehen wuerde nur Zeilen umbrechen lassen. */
@media (max-width: 430px) {
  :root {
    /* Schrift-Leiter: unten anheben, oben fast lassen */
    --fs-xs:  12px;     /* war 10,5 */
    --fs-s:   13px;     /* war 11,5 */
    --fs-m:   14px;     /* war 12,5 */
    --fs-l:   15px;     /* war 13,5 */
    --fs-xl:  17px;     /* war 16   */
    --fs-2xl: 22px;     /* war 21   */

    /* Knopf-Leiter: der Daumen ist breiter als der Mauszeiger */
    --k-klein:  32px;   /* war 22 */
    --k-normal: 38px;   /* war 28 */
    --k-gross:  44px;   /* war 34 */
  }
}

/* ── Hart kodierte Kleinschriften am Handy anheben ─────────────────────────
 * Die Schrift-Leiter in system.css ist am Handy angehoben (fs-xs 10,5->12 usw.).
 * 79 Stellen im CSS setzen die Groesse aber als feste Zahl statt ueber die
 * Variable — die Leiter erreicht sie nicht. Gemessen: in "Koennen" blieben so
 * 104 Elemente bei 11,5 px stehen, obwohl --fs-s laengst 13 px liefert.
 *
 * Dieser Block ist ERZEUGT: aus beiden CSS-Dateien wurden die Selektoren
 * gelesen, die 8,5/9,5/10,5/11,5 px fest setzen — nur Regeln der obersten
 * Ebene, denn eine Regel aus einem Schreibtisch-@media darf am Handy nicht
 * gelten. Wer eine dieser Stellen kuenftig auf var(--fs-*) umstellt, kann sie
 * hier streichen. */
@media (max-width: 430px) {
  /* auf 12.5px */
  .suche kbd,
  .kopf-welle-text,
  .kopf-knopf .zahl,
  .nav-gruppe,
  .nav-p .mrk,
  .huelle[data-nav="schmal"] .nav-p .mrk,
  .insp-kopf .art,
  .kz .k,
  .q,
  .m,
  .core-faehig-n,
  .core-strahl-kopf,
  .graph-label,
  .graph-l,
  .graph-hinweis,
  .schirm-marke,
  .bahn-kopf,
  .palette .t .art,
  #farbwelt-menue > b,
  .b .anzahl,
  .zaehler .z-k,
  .ff-k,
  .ff-b .anzahl,
  .ff-wahl,
  .tab-kopf,
  .gespr-zeit,
  .chat-zeit,
  .chat-mini,
  .chat-anhang .g,
  .zl-wer,
  .zl-mission,
  .vertrag .k,
  .cp-wort,
  .af-log-kopf,
  .lage-brain-fuss,
  .stimm-raster.waehlt .stimm-kachel::after { font-size: 12.5px; }

  /* auf 12px */
  .marke .v2,
  .puls-p .k,
  .core-faehig-u,
  .ansicht-schalter b { font-size: 12px; }

  /* auf 13.5px */
  .karte > header h3,
  .kz .n,
  .zeile .neben,
  .zeile .zeit,
  .b.klein,
  .graph-ebene button,
  .graph-zahlen,
  .ansicht-schalter button, .ansicht-schalter a,
  .b.winzig,
  .hinweis-klein,
  .verweis,
  .kast input:checked + span::after,
  .ff-b,
  .ff-eigen,
  .gz-unter,
  .gespr-fuss,
  .chat-datei,
  .chat-anhang,
  .chat-fuss,
  .agent-zustand .za,
  .zl-zeit,
  .ergebnis-code,
  .roh,
  .diff-kurz,
  .diff-datei .d-n,
  .diff-datei .d-z,
  .diff-datei .d-auf,
  .diff-fenster-kopf,
  .diff-code,
  .diff-abgeschnitten,
  .freigabe-warnung,
  .cz-text span,
  .af-log-z span,
  .af-log-z time { font-size: 13.5px; }

}

/* ══ Handy-Gestaltung 19.08.2026, zweiter Durchgang ═════════════════════════
 * Max: „brain, jarvis core, alles mögliche soll auch schön mobil sein."
 * Der erste Durchgang machte es bedienbar. Dieser macht es ansehnlich.
 * Alles bei 390 px gemessen, nicht geschaetzt. */

@media (max-width: 430px) {

  /* ── 1. Kennzahlen zwei nebeneinander statt untereinander ──
   * .r-4 verlangt minmax(190px, 1fr). Bei 390 px Schirm bleiben nach Rand und
   * Innenabstand 366 px — zwei Spalten a 190 plus Abstand passen NICHT, also
   * fiel das Raster auf EINE Spalte zurueck. Ergebnis: vier Karten unterein-
   * ander, 428 px Hoehe fuer vier Zahlen. Mit 150 px passen zwei nebeneinander
   * (2x150 + 12 = 312) und die Seite wird knapp halb so lang.
   * minmax(0, …) statt nacktem 1fr — sonst sprengt der laengste Wert das Gitter. */
  .raster.r-4,
  .raster.r-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .raster.r-2 { grid-template-columns: minmax(0, 1fr); }

  /* Eine einzelne Kachel in der letzten Reihe darf die volle Breite nehmen,
   * statt als halbe Kachel neben einer Luecke zu stehen. */
  .raster.r-4 > :last-child:nth-child(odd),
  .raster.r-3 > :last-child:nth-child(odd) { grid-column: 1 / -1; }

  /* ── 2. Brain-Graph: Steuerung und Legende unter das Bild ──
   * Beide lagen absolut UEBER dem Graphen. Bei 390 px bricht die Steuerung um
   * und schiebt sich in die Legende — im Code steht dazu schon ein Vermerk
   * (Task #566), behoben wurde aber nur die Klickbarkeit per pointer-events,
   * nicht das Bild. Gemessen ueberlagerten sich „TIEFE 1 2 3 4", „Zur Mitte",
   * „Neu ordnen" und „Zentralgehirn" sichtbar. Am Handy stehen sie jetzt
   * hintereinander unter dem Graphen — dort ist Platz, und nichts deckt
   * den Graphen ab. */
  .graph-rahmen { display: flex; flex-direction: column; }
  .graph-rahmen > canvas { order: 1; }
  .graph-steuer {
    position: static; order: 2;
    margin: 10px 0 0; padding: 0;
    justify-content: flex-start; gap: 8px;
  }
  .graph-legende {
    position: static; order: 3;
    flex-direction: row; flex-wrap: wrap;
    max-width: none; width: 100%;
    margin-top: 8px; gap: 6px 12px;
    pointer-events: auto;              /* darf wieder normal sein, liegt ja frei */
  }
  .graph-steuer .b { background: transparent; }

  /* ── 3. Reiter: zeigen, dass es rechts weitergeht ──
   * .reiter scrollt waagerecht (overflow-x: auto), aber ohne jedes Zeichen
   * dafuer — gemessen ragte der letzte Reiter 43 px heraus und sah aus wie
   * abgeschnitten. Ein weicher Verlauf am rechten Rand sagt: hier geht es
   * weiter. Die Rollleiste selbst bleibt unsichtbar. */
  .reiter {
    position: relative;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent 100%);
  }
  .reiter::-webkit-scrollbar { display: none; }
  .reiter > * { flex: 0 0 auto; }

  /* ── 4. Lange Platzhalter in Suchfeldern abschneiden statt ueberlaufen ──
   * „Firma, Projekt, Agent, Mission, Notiz — irgendetwas" lief bei 390 px aus
   * dem Feld heraus. Drei Punkte sind ehrlicher als ein abgehacktes Wort. */
  input[type="text"], input[type="search"], input:not([type]) {
    text-overflow: ellipsis;
  }

  /* ── 5. Zahl und Erlaeuterung nebeneinander duerfen umbrechen ──
   * „90 %" (28 px) neben „Woraus sich die Gesundheit ergibt" passte auf 390 px
   * nicht in eine Zeile und schob sich ineinander. */
  .karte [style*="display:flex"][style*="align-items:baseline"] { flex-wrap: wrap; }
}
