/* Minixley Dashboard — weiss, minimalistisch, klinisch klar.
   Vorbild: ChatGPT-App. Monochrome Flaechen, Farbakzente nur fuer
   Zustaende (laeuft/fertig/fehlgeschlagen), Icons als Strichzeichnung. */
:root {
  --bg: #ffffff;
  --bg-soft: #f7f7f8;
  --bg-hover: #ececec;
  --line: #e4e4e7;
  --txt: #0d0d0d;
  --txt-dim: #6b6b70;
  --txt-faint: #a1a1aa;
  --ink: #0d0d0d;           /* Buttons/Marke: schwarz auf weiss */
  --ok: #059669;
  --run: #d97706;
  --err: #dc2626;
  --radius: 14px;
  --sidebar-w: 288px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
/* KEIN DOPPELTIPP-ZOOM.
   touch-action: manipulation erlaubt Wischen und Scrollen weiter und
   nimmt genau die eine Geste weg, die hier stoert: den Doppeltipp, der
   die Seite vergroessert. `none` waere hier falsch — das wuerde auch
   das Scrollen abschalten. Der Kneifzoom haengt am viewport-Tag in
   index.html und am gesturestart-Riegel in app.js. */
html { touch-action: manipulation; -webkit-text-size-adjust: 100%; }
body {
  background: var(--bg);
  color: var(--txt);
  font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}
.hidden { display: none !important; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

.ic { width: 20px; height: 20px; fill: none; stroke: currentColor;
      stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- Marke ---------- */
.brand-mark {
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--ink); color: #fff;
  font: 600 24px/52px -apple-system, sans-serif;
  text-align: center; margin: 0 auto;
}
.brand-mark.small {
  width: 24px; height: 24px; border-radius: 50%;
  font-size: 13px; line-height: 24px; display: inline-block;
  vertical-align: -5px; margin-right: 6px;
}
.brand-mark.big { width: 60px; height: 60px; font-size: 28px; line-height: 60px; }

/* ---------- Login ---------- */
/* DIESELBE MEDIZIN WIE .shell (18.08.2026, dritter Anlauf).
   position:fixed mit inset:0 heisst: das Login ist IMMER schirmhoch —
   die iOS-Tastatur schrumpft das Layout nicht, sie legt sich davor.
   Zwei Fehlversuche standen hier: erst starr zentriert (Feld unterm
   Brett), dann overflow-y:auto (scrollt nicht, weil die Flaeche ja
   weiterhin volle Hoehe hat und der Inhalt hineinpasst). Richtig ist,
   was .shell laengst tut: die HOEHE an die gemessene Sichthoehe
   binden (--sicht aus visualViewport, gesetzt in app.js). Geht die
   Tastatur auf, wird das Login niedriger, margin:auto zentriert die
   Karte im Rest — und wo es eng wird, scrollt es wirklich. */
.login {
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--sicht, 100dvh);
  display: flex;
  justify-content: center; background: var(--bg); padding: 24px;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
/* OBEN VERANKERT, NICHT ZENTRIERT (18.08.2026, vierter Anlauf und
   die eigentliche Einsicht): margin:auto zentrierte die Karte in der
   JEWEILIGEN Hoehe — und iOS aendert --sicht auch beim Oeffnen des
   Einfuege-Menues. Jede Aenderung = neu zentriert = die Karte ruckt
   unter dem Finger weg, das Paste-Menue klappt zu. Eine oben
   verankerte Karte bewegt sich bei Hoehenaenderungen GAR NICHT:
   unten wird abgeschnitten, oben bleibt fest. */
.login-card { width: 100%; max-width: 330px; text-align: center;
              margin: clamp(16px, 10vh, 110px) auto 24px; }
.login-card h1 { font-size: 26px; font-weight: 700; margin: 14px 0 6px; letter-spacing: -.3px; }
.login-card p { color: var(--txt-dim); margin-bottom: 18px; }
.login-card input {
  width: 100%; padding: 13px 14px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--bg); color: var(--txt);
  font: inherit; margin-bottom: 12px; outline: none; text-align: center;
}
.login-card input:focus { border-color: var(--ink); }
.btn.primary {
  width: 100%; padding: 13px; border-radius: var(--radius);
  background: var(--ink); color: #fff; font-weight: 600;
}
.login-error { color: var(--err); margin-top: 14px; }
/* Der Zweitknopf unterm Verbinden: bewusst leise. */
.login-card .btn.ghost {
  width: 100%; padding: 11px; margin-top: 10px;
  border-radius: var(--radius); border: 1px solid var(--line);
  background: none; color: var(--txt-dim); font-weight: 500;
}
.login-card .btn.ghost:active { background: var(--bg-hover); }

/* ---------- Shell ---------- */
/* DER RAHMEN SCHRUMPFT MIT DER TASTATUR (16.08.2026).
   Hier stand height: 100dvh — und dvh schrumpft beim Oeffnen der
   Tastatur NICHT: die Einheit meint die Browserleisten, nicht die
   Tastatur. Also blieb die Seite schirmhoch, die Tastatur legte sich
   darueber, und die WebView schob die ganze Seite hoch, um das Feld
   sichtbar zu machen. Von aussen: "Ich kann das Textfeld selber immer
   noch scrollen, und darunter ist Abstand."
   --tastatur setzt app.js aus visualViewport. */
/* DIE SICHTBARE HOEHE, nicht die gerechnete (16.08.2026).
   `--sicht` kommt aus visualViewport.height und IST der Platz ueber der
   Tastatur. Der Rueckfall `100dvh - --tastatur` gilt nur, wo es
   visualViewport nicht gibt — dort ist die Subtraktion das Beste, was
   geht. Wo es ihn gibt, war sie die Ursache des Springens: zwei
   Groessen, die iOS beide veraendert, und nicht im selben Augenblick. */
.shell {
  display: flex;
  height: var(--sicht, calc(100dvh - var(--tastatur, 0px)));
}

/* ---------- Sidebar ---------- */
.sidebar {
  width: var(--sidebar-w); flex: none;
  background: var(--bg-soft);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
}
.sidebar-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 14px 10px;
}
.brand { font-weight: 700; font-size: 16px; letter-spacing: -.2px; }
#sidebar-close { display: none; }

.nav-item {
  display: flex; align-items: center; gap: 10px;
  margin: 2px 10px; padding: 10px 12px; text-align: left;
  border-radius: 10px; font-weight: 500;
}
.nav-item:hover, .nav-item.active { background: var(--bg-hover); }
.nav-item .ic { width: 18px; height: 18px; }

.section-label {
  padding: 16px 20px 6px; font-size: 11px; font-weight: 600;
  letter-spacing: .7px; text-transform: uppercase; color: var(--txt-faint);
}
.task-list { flex: 1; overflow-y: auto; padding: 0 10px; }
.task-item {
  width: 100%; text-align: left; padding: 9px 10px;
  border-radius: 10px; display: flex; gap: 10px; align-items: center;
}
.task-item:hover, .task-item.active { background: var(--bg-hover); }
.task-item-title {
  flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 13.5px;
}
.task-item-time { flex: none; font-size: 11px; color: var(--txt-faint); }

.dot { width: 7px; height: 7px; border-radius: 50%; flex: none;
       display: inline-block; background: var(--txt-faint); }
.dot.running   { background: var(--run); animation: pulse 1.6s ease-in-out infinite; }
.dot.completed { background: var(--ok); }
.dot.failed    { background: var(--err); }
.dot.ok        { background: var(--ok); }
@keyframes pulse { 50% { opacity: .3; } }

.sidebar-foot {
  padding: 12px 20px; border-top: 1px solid var(--line);
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--txt-dim);
}
.link-btn { margin-left: auto; color: var(--txt-faint); font-size: 12px; }
.link-btn:hover { color: var(--txt); }

/* ---------- Hauptbereich ---------- */
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; background: var(--bg); }
.topbar {
  display: flex; align-items: center; gap: 8px;
  padding: calc(8px + env(safe-area-inset-top)) 12px 8px;
  border-bottom: 1px solid var(--line);
}
.icon-btn { color: var(--txt-dim); padding: 8px; border-radius: 10px;
            display: inline-flex; }
.icon-btn:hover { background: var(--bg-hover); color: var(--txt); }
#menu-btn { display: none; }
.title { font-weight: 600; font-size: 15px;
         white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.title-state { margin-left: auto; font-size: 12px; color: var(--txt-dim); flex: none; }

.view { flex: 1; display: flex; flex-direction: column; min-height: 0; }

.ki-pane { width: 100%; max-width: 980px; margin: 0 auto; padding: 34px 24px 48px; overflow-y: auto; overflow-x: hidden; }
.ki-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 24px; }
.ki-head h2 { font-size: 30px; margin-top: 4px; }
.ki-head p { color: var(--txt-dim); margin-top: 3px; }
.ki-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 18px; overflow-x: auto; }
.ki-tab { padding: 10px 13px; color: var(--txt-dim); border-bottom: 2px solid transparent; white-space: nowrap; }
.ki-tab.active { color: var(--txt); border-color: var(--ink); font-weight: 600; }
.ki-notice { min-height: 24px; color: var(--ok); font-size: 13px; margin-bottom: 8px; }
.ki-notice.error { color: var(--err); }
.ki-project { margin-bottom: 16px; padding: 18px; }
.ki-project h3 { margin-bottom: 12px; }
.ki-round-list { display: grid; gap: 10px; }
.ki-round { display: flex; gap: 10px; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); }
.ki-round.ki-dragging { opacity: .5; }
.ki-round-grip { color: var(--txt-faint); cursor: grab; padding-top: 8px; }
.ki-round-body { min-width: 0; flex: 1; }
.ki-round-top { display: flex; gap: 10px; align-items: center; justify-content: space-between; }
.ki-meta { color: var(--txt-faint); font-size: 12px; margin: 4px 0 8px; }
.ki-prompt { width: 100%; min-height: 76px; resize: vertical; border: 1px solid var(--line); border-radius: 8px; padding: 9px; background: var(--bg-soft); color: var(--txt); font: inherit; }
.ki-controls { display: flex; gap: 8px; align-items: center; margin-top: 9px; flex-wrap: wrap; }
.ki-model { min-height: 38px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg-soft); color: var(--txt); padding: 0 8px; }
.ki-state { font-size: 12px; border-radius: 999px; padding: 3px 8px; background: var(--bg-hover); white-space: nowrap; }
.ki-state-laeuft { color: var(--run); } .ki-state-fertig { color: var(--ok); } .ki-state-fehlgeschlagen { color: var(--err); }
@media (max-width: 600px) { .ki-pane { padding: 24px 14px 36px; } .ki-round { padding: 10px 8px; } }

/* ---------- Startseite / Bedienfeld ---------- */
.home-pane {
  flex: 1; overflow-y: auto; width: 100%; max-width: 920px;
  margin: 0 auto; padding: 42px 24px calc(36px + env(safe-area-inset-bottom));
}
.home-intro { margin-bottom: 32px; }
.home-kicker {
  color: var(--txt-faint); font-size: 11px; font-weight: 650;
  letter-spacing: 1.1px; text-transform: uppercase;
}
.home-intro h1 {
  margin-top: 7px; font-size: clamp(28px, 5vw, 40px); line-height: 1.15;
  letter-spacing: -.8px;
}
.home-intro p { margin-top: 8px; color: var(--txt-dim); font-size: 15px; }
.home-status {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px; margin-bottom: 38px;
}
.home-status-card {
  min-height: 116px; padding: 16px; border: 1px solid var(--line);
  border-radius: var(--radius); display: flex; flex-direction: column;
  gap: 7px; background: var(--bg);
}
.home-status-card strong { display: flex; align-items: center; gap: 7px; font-size: 15px; }
.home-section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 12px;
}
.home-section-head h2 { font-size: 17px; letter-spacing: -.2px; }
.home-section-head span { color: var(--txt-faint); font-size: 12px; }
.home-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.home-action {
  min-height: 76px; width: 100%; padding: 14px 16px;
  border: 1px solid var(--line); border-radius: var(--radius);
  display: flex; align-items: center; gap: 13px; text-align: left;
  background: var(--bg); transition: background .15s ease, border-color .15s ease;
}
.home-action:hover { background: var(--bg-soft); border-color: #d4d4d8; }
.home-action > .ic:first-child { width: 22px; height: 22px; color: var(--txt-dim); flex: none; }
.home-action > span { display: flex; flex: 1; min-width: 0; flex-direction: column; }
.home-action strong { font-size: 15px; }
.home-action small { margin-top: 2px; color: var(--txt-dim); font-size: 12.5px; }
.home-action .chevron { width: 17px; height: 17px; color: var(--txt-faint); flex: none; }
.home-system { margin-top: 36px; }
.home-system .home-actions { align-items: stretch; }
.home-session-card { cursor: default; }
.home-session-card:hover { background: var(--bg); border-color: var(--line); }
.home-session-card > span { min-width: 0; }
.home-session-card strong { display: block; }
.home-session-card #home-session-state { white-space: nowrap; font-weight: 500; }
.home-session-card .btn { flex: none; }
.home-system-notice { min-height: 22px; margin-top: 12px; color: var(--ok); font-size: 13px; }
.home-system-notice.error { color: var(--err); }
.home-action:disabled { cursor: wait; opacity: .55; }
.home-action:disabled small::after { content: " · Bitte warten"; }
@media (max-width: 780px) {
  .home-status { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 520px) {
  .home-pane { padding: 28px 16px calc(28px + env(safe-area-inset-bottom)); }
  .home-intro { margin-bottom: 24px; }
  .home-status { gap: 9px; margin-bottom: 30px; }
  .home-status-card { min-height: 108px; padding: 14px; }
  .home-actions { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Chat ----------
   DIESE KLASSEN SIND DER CHAT — auch der auf der Chef-Seite. Erzeugt
   werden sie seit 14.08.2026 von Chat() in bausteine.js, nicht mehr
   von der Auszeichnung in index.html; die Optik ist dieselbe
   geblieben.

   Warum sie NICHT mit dem Baustein nach bausteine.css umgezogen sind:
   weiter unten in dieser Datei holt `.shell, .main, .view, .chat-log,
   .composer-wrap … { max-width: 100% }` die 720 px hier wieder ein —
   gleiche Spezifitaet, spaetere Stelle, also gewinnt die 100 %. In
   bausteine.css (das NACH styles.css geladen wird) haetten die 720 px
   plotzlich gewonnen, und das Gespraech waere ueber Nacht schmaler
   geworden. Ein Umzug, der die Kaskade dreht, ist kein Umzug. */
.chat-scroll { flex: 1; overflow-y: auto; scroll-behavior: smooth; }
.chat-empty { text-align: center; padding: 72px 32px 24px; }
.chat-empty h2 { font-size: 22px; font-weight: 700; margin-top: 18px; letter-spacing: -.3px; }

.chat-log { max-width: 720px; margin: 0 auto; padding: 20px 16px 8px; }
.msg { margin-bottom: 16px; display: flex; }
.msg.user { justify-content: flex-end; }
.bubble {
  /* KOMPLETT RUND (16.08.2026). Die abgeflachte Ecke unten rechts war
     der Sprechblasen-Zipfel; Luca will die Blase im Normalzustand
     rundum rund. */
  max-width: 85%; padding: 11px 16px; border-radius: 22px;
  white-space: pre-wrap; word-wrap: break-word;
}
.msg.user .bubble { background: var(--bg-soft); }
/* Die ANTWORT ist keine Blase, sondern ein Text: volle Breite, etwas
   groesser, mit Luft zwischen den Zeilen. "Der Text kann wirklich von
   links nach rechts gehen und ein bisschen groesser sein." */
.msg.ai .bubble {
  max-width: 100%; width: 100%; padding: 2px 0 0;
  font-size: 15.5px; line-height: 1.65; white-space: normal;
}

/* Der gesetzte Text einer Antwort (bausteine.js: Markdown). */
.md > * { margin: 0 0 10px; }
.md > *:last-child { margin-bottom: 0; }
.md h2 { font-size: 17.5px; font-weight: 650; margin: 16px 0 6px; letter-spacing: -.2px; }
.md h3 { font-size: 15.5px; font-weight: 650; margin: 14px 0 5px; }
.md h4 { font-size: 14px; font-weight: 650; margin: 12px 0 4px; color: var(--txt-dim); }
.md > *:first-child { margin-top: 0; }
.md ul { padding-left: 22px; }
.md li { margin-bottom: 4px; }
.md blockquote {
  padding-left: 12px; border-left: 2px solid var(--line); color: var(--txt-dim);
}
.md code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .88em; background: var(--bg-soft); padding: 1px 5px; border-radius: 6px;
}
.md pre {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; line-height: 1.5; background: var(--bg-soft);
  border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; overflow-x: auto; white-space: pre;
}

/* Denk-Animation: weicher, atmender Punkt wie in der ChatGPT-App */
.thinking {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--ink); display: inline-block;
  animation: breathe 1.1s ease-in-out infinite;
}
@keyframes breathe {
  0%, 100% { transform: scale(.65); opacity: .35; }
  50%       { transform: scale(1);   opacity: 1; }
}

.task-chip {
  display: inline-block; margin-top: 8px; padding: 5px 12px;
  border-radius: 999px; border: 1px solid var(--line);
  background: var(--bg-soft); color: var(--txt);
  font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.task-chip:hover { border-color: var(--ink); }

/* ---------- Eingabezeile ---------- */
.composer-wrap {
  max-width: 720px; width: 100%; margin: 0 auto;
  /* Der untere Abstand war zu gross (14 px PLUS sicherer Bereich, und
     der ist auf dem iPhone allein schon 34 px). 6 px reichen — die
     Home-Anzeige braucht den Rest ohnehin fuer sich.

     UND DIE TASTATUR SCHIEBT MIT (16.08.2026). --tastatur setzt
     app.js aus visualViewport; ohne das legt sich die Tastatur ueber
     die Zeile, und darunter bleibt Luft, durch die man scrollen kann.
     max() statt Addition: sicherer Bereich UND Tastatur zugleich
     waeren doppelt — die Tastatur deckt ihn ja ab. */
  padding: 8px 12px;
  /* Der sichere Bereich zaehlt nur OHNE Tastatur — steht sie da,
     deckt sie ihn ab, und ein Abstand darueber waere Luft. Der
     Rahmen selbst schrumpft schon (siehe .shell). */
  padding-bottom: max(6px, calc(6px + env(safe-area-inset-bottom)
                                    - var(--tastatur, 0px)));
}
.speech-status { font-size: 12.5px; color: var(--txt-dim); padding: 0 8px 6px; }
.speech-status.error { color: var(--err); }
.composer {
  display: flex; gap: 8px; align-items: flex-end;
  border: 1px solid var(--line); border-radius: 26px;
  padding: 8px 8px 8px 16px; background: var(--bg);
  box-shadow: 0 2px 12px rgba(0,0,0,.04);
}
.composer:focus-within { border-color: #c8c8cd; }
.composer textarea {
  flex: 1; resize: none; max-height: 140px; border: none; outline: none;
  background: none; color: var(--txt); font: inherit; padding: 8px 0;
}
/* ---------- Eingabezeile mit Werkzeugleiste (Chef) ----------
   Zugeklappt nur die Leiste, offen die Textzeile darueber. Der Abstand
   nach unten war zu gross und der Text darin abgeschnitten: die alte
   Zeile stand auf `align-items: flex-end` mit fester Polsterung, und
   eine wachsende textarea rutschte darin nach oben aus dem Bild. Hier
   traegt jede Zeile ihre eigene Hoehe. */
.composer.werkzeug {
  display: block; padding: 6px 8px 6px 8px; border-radius: 24px;
}
.composer.werkzeug .composer-text { padding: 6px 8px 2px; }
.composer.werkzeug textarea {
  width: 100%; max-height: 40vh; padding: 4px 0; line-height: 1.45;
}
.composer.werkzeug.zu .composer-text { display: none; }
.composer-leiste {
  display: flex; align-items: center; gap: 6px;
}
.composer-links, .composer-rechts {
  display: flex; align-items: center; gap: 4px;
}
/* Rechts ruecken sie zusammen — das Plus bleibt links stehen, wo es
   allein ist und nichts verdraengt. */
.composer-rechts { gap: 0; }
.composer-links { flex: 1; min-width: 0; }
/* Das Plus fuehrt zu den Gespraechen und war zu klein zum Treffen. */
.round-btn.plus { font-size: 26px; font-weight: 300; line-height: 1; }

/* Die Modellwahl in der Leiste: leise, klein, ohne Rahmen — sie ist
   eine Angabe, kein Knopf. Sie verschwindet, sobald etwas im Feld
   steht ("unten verschwindet auch die Modellauswahl, sobald man einen
   Text ausgewaehlt hat"). */
.composer-modell {
  display: inline-flex; align-items: center; max-width: 42vw;
  font-size: 12.5px; color: var(--txt-dim); padding: 0 2px;
}
.composer-modell > select {
  appearance: none; -webkit-appearance: none; border: 0; outline: 0;
  background: transparent; color: inherit; font: inherit;
  max-width: 100%; text-overflow: ellipsis; padding: 6px 2px;
}
.composer.werkzeug:not(.zu) .composer-modell { display: none; }

/* Das Tempo: ein Tacho, der seinen Stand zeigt, ohne dass man ihn
   antippt. Der Punkt erscheint nur, wenn dieses Gespraech von der
   Vorgabe der Ebene abweicht — sonst waere er ein Dauerlicht ohne
   Aussage. */
.composer-tempo {
  position: relative; flex: none;
  width: 36px; height: 36px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: none; color: var(--txt-dim); cursor: pointer;
}
.composer-tempo:hover { background: var(--bg-hover); color: var(--txt); }
.composer-tempo.gesetzt { color: var(--txt); }
.composer-tempo.gesetzt::after {
  content: ""; position: absolute; right: 5px; top: 6px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--run); border: 1.5px solid var(--bg);
}

/* Der Regler. Nicht zu klein, nicht zu gross: 44 px Griff ist das Mass
   fuer einen Daumen, und die Bahn darf man auf ihrer ganzen Laenge
   treffen. Die Einrastung macht step=1 — kein Nachbau. */
.pillendialog.tempo { width: min(320px, calc(100vw - 24px)); padding: 10px; }
.tempo-inhalt { padding: 2px 6px 6px; }
.tempo-wert {
  font-size: 16px; font-weight: 550; padding: 2px 8px 10px;
}
.tempo-regler {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 44px; background: none; margin: 0;
}
.tempo-regler::-webkit-slider-runnable-track {
  height: 8px; border-radius: 999px; background: var(--bg-hover);
}
.tempo-regler::-moz-range-track {
  height: 8px; border-radius: 999px; background: var(--bg-hover);
}
.tempo-regler::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 26px; height: 26px; border-radius: 50%; margin-top: -9px;
  background: var(--txt); border: 3px solid var(--bg);
  box-shadow: 0 1px 6px rgba(0,0,0,.28);
}
.tempo-regler::-moz-range-thumb {
  width: 26px; height: 26px; border-radius: 50%; border: 3px solid var(--bg);
  background: var(--txt); box-shadow: 0 1px 6px rgba(0,0,0,.28);
}
.tempo-skala {
  display: flex; justify-content: space-between;
  padding: 0 4px; font-size: 10.5px; color: var(--txt-faint);
  letter-spacing: .4px;
}

.round-btn {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--txt-dim); border: 1px solid transparent;
}
.round-btn:hover { background: var(--bg-hover); color: var(--txt); }
/* DER KREIS KLEINER, DER PFEIL GLEICH GROSS. Der schwarze Fleck war
   so gross wie das Mikrofon daneben und zog das Auge auf sich; der
   Pfeil darin traegt die Bedeutung, nicht die Scheibe darum. */
.round-btn.solid { background: var(--ink); color: #fff; width: 32px; height: 32px; }
.round-btn.solid:hover { background: #2d2d2d; color: #fff; }
.round-btn.solid:disabled { opacity: .25; }
.round-btn.recording { background: var(--ink); color: #fff; animation: pulse 1.4s infinite; }
label.round-btn { cursor: pointer; }

/* Aufnahme-Wellenform: fuenf Balken, live vom Mikrofonpegel getrieben */
.wave { display: flex; align-items: center; gap: 3px; height: 40px; padding: 0 4px; }
.wave span {
  width: 4px; height: 8px; border-radius: 2px; background: var(--ink);
  transition: height .08s linear;
}

/* ---------- Aufgaben-Detail ---------- */
.task-detail {
  flex: 1; overflow-y: auto; max-width: 720px; width: 100%;
  margin: 0 auto; padding: 20px 16px calc(20px + env(safe-area-inset-bottom));
}
.detail-state {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 12px; border-radius: 999px; font-size: 13px; font-weight: 600;
  background: var(--bg-soft); border: 1px solid var(--line);
}
.detail-title { font-size: 21px; font-weight: 700; letter-spacing: -.3px; margin: 14px 0 6px; }
.detail-meta { color: var(--txt-faint); font-size: 13px; margin-bottom: 20px; }
.detail-block { margin-bottom: 20px; }
.detail-block h3 {
  font-size: 11px; font-weight: 600; letter-spacing: .7px;
  text-transform: uppercase; color: var(--txt-faint); margin-bottom: 8px;
}
.detail-block .card {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 14px 16px;
  white-space: pre-wrap; word-wrap: break-word;
}
.detail-block .card.error { border-color: #fecaca; color: var(--err); background: #fef2f2; }
.detail-actions { display: flex; gap: 10px; margin-top: 26px; }
.btn.secondary {
  padding: 11px 18px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--bg); font-weight: 600;
}
.btn.secondary:hover { border-color: var(--ink); }
.btn.primary.inline { width: auto; padding: 11px 18px; }

/* ---------- Dateien ---------- */
.files-pane {
  flex: 1; overflow-y: auto; max-width: 720px; width: 100%;
  margin: 0 auto; padding: 14px 16px calc(20px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column;
}
.files-bar { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
.crumbs { flex: 1; display: flex; align-items: center; flex-wrap: wrap;
          gap: 2px; font-size: 13.5px; color: var(--txt-dim); min-width: 0; }
.crumbs button { padding: 4px 6px; border-radius: 8px; font-weight: 500; }
.crumbs button:hover { background: var(--bg-hover); color: var(--txt); }
.crumbs .ic { width: 14px; height: 14px; color: var(--txt-faint); }
.files-list { flex: none; }
.file-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 10px; border-radius: 12px; cursor: default;
}
.file-row:hover { background: var(--bg-soft); }
.file-row .ic { width: 19px; height: 19px; color: var(--txt-dim); flex: none; }
.file-row.is-dir { cursor: pointer; }
.file-name { flex: 1; min-width: 0; white-space: nowrap;
             overflow: hidden; text-overflow: ellipsis; font-size: 14.5px; }
.file-size { flex: none; font-size: 12px; color: var(--txt-faint); }
.file-act { flex: none; display: flex; gap: 2px; }
.file-act button { padding: 7px; border-radius: 9px; color: var(--txt-faint);
                   display: inline-flex; }
.file-act button:hover { background: var(--bg-hover); color: var(--txt); }
.file-act .del:hover { color: var(--err); }
.files-hint { font-size: 12px; color: var(--txt-faint); margin-top: 14px; }
.files-empty { color: var(--txt-faint); text-align: center; padding: 36px 0; }

/* ---------- Personen ----------
   Eine grosse Fassung der Geraete-Sprache: Auftakt, dann echte Spuren statt
   einer Verwaltungstabelle. Farben und Abstaende bleiben ausschliesslich hier. */
.personen-pane {
  flex: 1; overflow-y: auto; overflow-x: hidden; width: 100%;
  max-width: 720px; margin: 0 auto;
  padding: 14px 16px calc(24px + env(safe-area-inset-bottom));
}
.personen-auftakt { margin-bottom: 14px; padding: 22px 20px 18px;
  border-radius: 26px 26px 26px 8px; background: var(--ink); color: var(--bg); }
.personen-ueberzeile { display: block; margin-bottom: 4px; font-size: 10px;
  font-weight: 750; letter-spacing: .14em; opacity: .7; }
.personen-kopf { display: flex; align-items: baseline; gap: 14px;
  justify-content: space-between; }
.personen-kopf > *, .personen-zeile > *, .personen-zeilenkopf > * { min-width: 0; }
.personen-kopf h2 { margin: 0; font-size: clamp(24px, 6vw, 32px);
  line-height: 1.08; letter-spacing: -.03em; overflow-wrap: anywhere; }
.personen-kopf strong { flex: none; font-size: 12px; }
.personen-auftakt p { margin: 10px 0 0; max-width: 42ch; font-size: 12.5px;
  line-height: 1.45; opacity: .72; }
.personen-neu { margin-top: 14px; border-color: currentColor; color: inherit; }
.personen-anlernen { margin-bottom: 14px; padding: 16px;
  border: 1px solid var(--line); border-radius: 8px 18px 18px; background: var(--bg); }
.personen-anlernen h3 { margin: 0 0 6px; font-size: 18px; }
.personen-anlernen > p { margin: 6px 0 12px; color: var(--txt-dim);
  font-size: 12px; line-height: 1.45; }
.personen-lernfeld { display: block; color: var(--txt-dim); font-size: 12px;
  font-weight: 700; }
.personen-lernfeld input { display: block; width: 100%; margin-top: 5px;
  padding: 10px 11px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--bg); color: var(--txt); }
.personen-bilder-knopf { display: inline-flex; margin-top: 10px; cursor: pointer; }
.personen-vorschau { display: grid; grid-template-columns: minmax(0, 1fr); gap: 7px; }
.personen-bildkarte { display: grid; grid-template-columns: 64px minmax(0, 1fr) auto;
  align-items: center; gap: 10px; min-width: 0; padding: 7px;
  border: 1px solid var(--line); border-radius: 9px 14px 14px; }
.personen-bildkarte img { width: 64px; height: 64px; object-fit: cover; border-radius: 7px; }
.personen-bildkarte div { min-width: 0; }
.personen-bildkarte strong, .personen-bildkarte span { display: block;
  overflow-wrap: anywhere; }
.personen-bildkarte strong { font-size: 13px; }
.personen-bildkarte span { color: var(--txt-faint); font-size: 11px; }
.personen-bildkarte .danger { color: var(--err); border-color: var(--err); }
.personen-fortschritt { width: 100%; margin: 4px 0 8px; }
.personen-anlernaktionen { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.personen-status { margin: 0 0 10px; color: var(--txt-dim); font-size: 13px;
  overflow-wrap: anywhere; }
.personen-status:empty { display: none; }
.personen-status.fehler { padding: 11px 13px; border: 1px solid var(--line);
  border-left: 4px solid var(--err); border-radius: 8px 13px 13px 8px;
  color: var(--err); background: var(--bg); }
.personen-liste { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
.personen-zeile { display: block; min-width: 0;
  padding: 13px 14px; border: 1px solid var(--line); border-radius: 8px 16px 16px;
  background: var(--bg); }
.personen-zeilenkopf { display: flex; align-items: center; gap: 13px; min-width: 0; }
.personen-symbol { flex: none; width: 30px; height: 30px; color: var(--txt-dim); }
.personen-inhalt { flex: 1; min-width: 0; }
.personen-inhalt strong, .personen-inhalt span, .personen-zuletzt span,
.personen-zuletzt time { display: block; overflow-wrap: anywhere; }
.personen-inhalt strong { font-size: 15px; }
.personen-inhalt span, .personen-zuletzt { color: var(--txt-dim); font-size: 11.5px; }
.personen-zuletzt { flex: none; min-width: 0; max-width: 42%; text-align: right; }
.personen-zuletzt span { color: var(--txt-faint); font-size: 10px; }
.personen-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 12px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.personen-form label { min-width: 0; color: var(--txt-dim); font-size: 11px;
  font-weight: 700; }
.personen-form input, .personen-form textarea { display: block; width: 100%;
  margin-top: 4px; padding: 9px 10px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--bg); color: var(--txt); font: inherit;
  font-size: 13px; font-weight: 400; resize: vertical; }
.personen-form textarea { min-height: 68px; }
.personen-schluessel { grid-column: 1 / -1; margin: 0; color: var(--txt-faint);
  font-size: 11px; line-height: 1.45; overflow-wrap: anywhere; }
.personen-aktionen { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }
.personen-aktionen .danger { color: var(--err); border-color: var(--err); }
@media (max-width: 480px) {
  .personen-zeilenkopf { align-items: flex-start; }
  .personen-zuletzt { max-width: 38%; }
  .personen-form { grid-template-columns: minmax(0, 1fr); }
  .personen-bildkarte { grid-template-columns: 56px minmax(0, 1fr); }
  .personen-bildkarte img { width: 56px; height: 56px; }
  .personen-bildkarte button { grid-column: 1 / -1; min-height: 42px; }
}

/* ---------- KiLey OS ----------
   Eine App in der App. Sie traegt ihre Bedienung selbst: die Kopfleiste
   der Anwendung ist hier weg (JS setzt .kos-an auf die Huelle), und
   stattdessen schweben drei Dinge ueber dem Gespraech — Menue links,
   Modusschalter in der Mitte, Ausgang rechts.

   NUR DIESE DREI SIND AUS GLAS. Der Drawer selbst ist es ausdruecklich
   nicht ("Der Drawer ist nicht Glasmorphismus, nur das Icon-Symbol
   oben"): eine Flaeche, auf der man liest, braucht Ruhe. */
.kos-kopf {
  position: absolute; top: 0; left: 0; right: 0; z-index: 12;
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; pointer-events: none;
  padding: calc(8px + env(safe-area-inset-top)) 12px 8px;
}
.kos-kopf > * { pointer-events: auto; }
.kos-schwebt, .kos-schalter {
  background: rgba(255,255,255,.72);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid rgba(255,255,255,.85);
  box-shadow: 0 1px 0 rgba(255,255,255,.7) inset,
              0 6px 20px rgba(0,0,0,.10);
}
.kos-schwebt {
  width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--txt); cursor: pointer;
}
.kos-schalter { display: flex; border-radius: 999px; padding: 3px; gap: 2px; }
.kos-lasche {
  border: 0; background: none; font: inherit; font-size: 14.5px;
  font-weight: 500; color: var(--txt-dim); cursor: pointer;
  padding: 6px 18px; border-radius: 999px;
}
.kos-lasche.an {
  background: var(--bg); color: var(--txt);
  box-shadow: 0 1px 3px rgba(0,0,0,.10);
}
/* Platz fuer die schwebende Reihe: sie liegt UEBER dem Gespraech, also
   muss der Verlauf darunter anfangen. */
.shell.kos-an .topbar { display: none; }
.shell.kos-an #view-chef { position: relative; }
/* KEIN padding-top MEHR AM RAHMEN (16.08.2026). Es schob den ganzen
   Verlauf unter die Knoepfe: der Text hoerte an einer unsichtbaren
   Kante auf, statt darunter durchzulaufen. Luca: "Wenn ich den Text
   scrolle, verschwindet er nicht hinter dem Button, sondern hinter
   einer Flaeche. Die Flaeche muss weg."

   Jetzt reicht der Scrollbereich bis ganz nach oben, der Abstand sitzt
   INNEN am Verlauf (.chat-log), und darueber liegt ein Farbverlauf:
   oben deckend, nach unten durchsichtig. */
.shell.kos-an .chef-voll { padding-top: 0; }
.shell.kos-an .chat-log { padding-top: calc(64px + env(safe-area-inset-top)); }
.kos-verlauf {
  position: absolute; left: 0; right: 0; z-index: 11;
  pointer-events: none;   /* faerbt nur — faengt keinen Tipp ab */
}
.kos-verlauf.oben {
  top: 0; height: calc(120px + env(safe-area-inset-top));
  background: linear-gradient(to bottom,
              var(--bg) 0%, var(--bg) 45%, transparent 100%);
}

/* DIE EINGABEZEILE LIEGT UEBER DEM GESPRAECH, NICHT DARUNTER.
   Im Fluss darunter endete der Verlauf an ihrer Oberkante. Jetzt
   scrollt der Text dahinter durch und laeuft nach unten aus; die
   Textflaeche selbst bleibt deckend weiss ("der Hintergrund von der
   Textflaeche bleibt weiss, aber der Hintergrund, wo die Textflaeche
   drauf liegt, verschwindet komplett").

   --eingabe setzt ki-chef.js aus der gemessenen Hoehe: sie wechselt,
   sobald die Textzeile aufgeht. Eine feste Zahl waere beim ersten
   mehrzeiligen Text falsch. */
.shell.kos-an .chat-rahmen { position: relative; }
.shell.kos-an .chat-scroll { padding-bottom: 0; }
.shell.kos-an .chat-log { padding-bottom: calc(var(--eingabe, 88px) + 12px); }
.shell.kos-an .composer-wrap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 11;
  background: linear-gradient(to top,
              var(--bg) 0%, var(--bg) 42%, transparent 100%);
}

/* DER DRAWER LIEGT UNTER DEM INHALT — der Inhalt schiebt sich weg.
 *
 * Bis zum 16.08.2026 stand hier genau dieser Satz als Kommentar, und
 * der Code tat das Gegenteil: der Drawer fuhr mit z-index 14 UEBER den
 * Dialog, davor ein schwarzer Schleier. Luca: „Der Drawer ist über dem
 * Inhalt. Ich wollte aber, wenn der Drawer auftaucht, dass der Inhalt
 * sich nach rechts schiebt und der Drawer fix unter dem Inhalt ist."
 *
 * Jetzt wirklich: der Drawer steht fest ganz unten (z-index 1) und
 * bewegt sich nie. Der Inhalt darueber wandert nach rechts und gibt
 * ihn frei. Kein schwarzer Schleier, sondern ein heller: der Dialog
 * verblasst, statt abgedunkelt zu werden — er ist ja noch da, nur
 * gerade nicht dran.
 */
.kos-drawer {
  position: absolute; z-index: 1; top: 0; bottom: 0; left: 0;
  width: min(84vw, 320px);
  background: var(--bg-soft); color: var(--txt);
  display: flex; flex-direction: column;
  padding: calc(10px + env(safe-area-inset-top)) 0
           calc(10px + env(safe-area-inset-bottom));
  overflow-y: auto;
}
/* Was sich BEWEGT: alles ausser dem Drawer. Der Kopf faehrt mit, sonst
   bliebe der Menueknopf ueber dem offenen Drawer stehen.

   UND ES MUSS DECKEND SEIN. Genau daran ist die erste Fassung
   gescheitert (16.08.2026): der Drawer lag korrekt unten, aber der
   Dialog darueber war durchsichtig — also schien der Drawer die ganze
   Zeit durch, der Inhalt wirkte abgeschnitten und antippbar war
   nichts. Ein Schieber, der etwas verdecken soll, braucht eine
   Flaeche. */
#view-chef > .kos-kopf,
#view-chef > .kos-verlauf,
#view-chef > .chef-voll {
  transition: transform .26s cubic-bezier(.2,.9,.25,1);
}
/* KEIN `will-change: transform` (16.08.2026 wieder entfernt).
   Es stand hier dauerhaft und hob damit dauerhaft eine Ebene an —
   auch waehrend niemand schiebt. Ueber einem Scrollbereich ist das in
   der WKWebView ein bekannter Weg, das Schwungscrollen zu verlieren.
   `will-change` gehoert gesetzt, wenn eine Aenderung BEVORSTEHT, nicht
   fuer immer; und die Verschiebung hier laeuft einmal beim Oeffnen des
   Drawers, nicht in einer Schleife. */
.shell.kos-an #view-chef > .chef-voll {
  position: relative; z-index: 2; background: var(--bg);
}
/* WENN DER DRAWER OFFEN IST, wird das weggeschobene Panel zur Karte:
   runde linke Kanten und ein weicher Schatten zur Fuge hin — es liegt
   ja sichtbar UEBER dem Drawer. Zu, wenn der Drawer zu ist: dann ist
   es wieder die ganze Seite und braucht keine Kante. */
#view-chef.kos-offen > .chef-voll,
#view-chef.kos-offen > .kos-verlauf {
  border-top-left-radius: 22px;
  border-bottom-left-radius: 22px;
  box-shadow: -18px 0 40px rgba(0,0,0,.16);
  overflow: hidden;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #view-chef.kos-offen > .chef-voll,
  :root:not([data-theme="light"]) #view-chef.kos-offen > .kos-verlauf {
    box-shadow: -18px 0 44px rgba(0,0,0,.55);
  }
}
:root[data-theme="dark"] #view-chef.kos-offen > .chef-voll,
:root[data-theme="dark"] #view-chef.kos-offen > .kos-verlauf {
  box-shadow: -18px 0 44px rgba(0,0,0,.55);
}
/* Der Kopf liegt ueber dem Inhalt und faehrt mit ihm. Er braucht
   keine eigene Flaeche — darunter liegt jetzt eine. */
.shell.kos-an #view-chef > .kos-kopf { z-index: 12; }
#view-chef.kos-offen > .kos-kopf,
#view-chef.kos-offen > .kos-verlauf,
#view-chef.kos-offen > .chef-voll {
  transform: translateX(min(84vw, 320px));
}
/* Der helle Schleier LIEGT AUF DEM INHALT, nicht daneben: er faengt
   den Tipp ab, mit dem man den Drawer wieder schliesst, und laesst
   den Dialog verblassen. Ausserhalb des geschobenen Inhalts waere er
   ein grauer Balken ueber dem Drawer. */
.kos-schleier {
  position: absolute; inset: 0; z-index: 13;
  background: rgba(255,255,255,.55);
  -webkit-backdrop-filter: saturate(60%) blur(1px);
  backdrop-filter: saturate(60%) blur(1px);
  transition: transform .26s cubic-bezier(.2,.9,.25,1);
  transform: translateX(min(84vw, 320px));
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .kos-schleier {
    background: rgba(0,0,0,.45);
  }
}
:root[data-theme="dark"] .kos-schleier { background: rgba(0,0,0,.45); }

/* EINSTELLUNGEN UNTEN LINKS, nicht oben in der Leiste.
   Luca: „Einstellungen machst Du oben ganz weg. Das machst Du unten
   als Icon links, auch als Glas-Icon, wenn der Drawer offen ist."
   Also zweimal dasselbe Ziel: im Drawer unten, und als schwebendes
   Glas-Icon, solange er offen ist. */
.kos-fuss {
  margin-top: auto; display: flex; align-items: center; gap: 6px;
  padding: 8px 14px 0; border-top: 1px solid var(--line);
}
.kos-icon {
  width: 38px; height: 38px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--txt-dim); cursor: pointer; border: 0; background: none;
}
.kos-icon:hover { background: var(--bg-hover); color: var(--txt); }
.kos-fuss .kos-rest {
  flex: 1; text-align: right; font-size: 12px; color: var(--txt-faint);
}
/* Das Glas-Icon: es erscheint NUR bei offenem Drawer, unten links,
   ueber allem. */
.kos-glas {
  position: absolute; z-index: 15;
  left: 14px; bottom: calc(14px + env(safe-area-inset-bottom));
  width: 44px; height: 44px; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  color: var(--txt); cursor: pointer;
}
#view-chef.kos-offen .kos-glas { display: inline-flex; }
.kos-titel {
  padding: 10px 20px 6px; font-size: 12px; font-weight: 600;
  letter-spacing: .5px; text-transform: uppercase; color: var(--txt-faint);
}
.kos-zeile {
  display: flex; align-items: center; gap: 12px; width: 100%;
  border: 0; background: none; font: inherit; color: var(--txt);
  text-align: left; cursor: pointer;
  padding: 11px 20px; border-radius: 0;
}
.kos-zeile:hover { background: var(--bg-hover); }
.kos-zeile.an { background: var(--bg-soft); font-weight: 550; }
.kos-zeile > span { flex: 1; min-width: 0; overflow: hidden;
                    text-overflow: ellipsis; white-space: nowrap; }
.kos-zeile > em { font-style: normal; font-size: 12px; color: var(--txt-faint); }
.kos-trenner { height: 1px; background: var(--line); margin: 8px 20px; }

/* Die Reiter oben im Drawer: Icon + Name. `haupt` (Projekte) ist
   dick und einen Tick groesser — der meistbenutzte Weg zuerst. */
.kos-reiter {
  display: flex; align-items: center; gap: 12px; width: 100%;
  border: 0; background: none; font: inherit; color: var(--txt);
  text-align: left; cursor: pointer;
  padding: 10px 20px; font-size: 14px; font-weight: 500;
}
.kos-reiter:hover { background: var(--bg-hover); }
.kos-reiter .ic { width: 18px; height: 18px; flex: none;
                  color: var(--txt-dim); }
.kos-reiter.haupt { font-size: 15.5px; font-weight: 700; padding-top: 12px;
                    padding-bottom: 12px; }
.kos-reiter.haupt .ic { width: 20px; height: 20px; color: var(--txt); }

/* Gespraech mit Wisch-Loeschen: rote Grundflaeche, Inhalt gleitet. */
.kos-wisch { position: relative; overflow: hidden; }
.kos-wisch-grund {
  position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: flex-end; padding-right: 22px;
  background: #d5453a; color: #fff;
}
.kos-wisch-grund .ic { width: 18px; height: 18px; }
.kos-wisch-inhalt {
  position: relative; background: var(--bg-soft);
  transition: transform .18s ease;
  touch-action: pan-y;
}
/* Am Rechner: der Muelleimer erscheint beim Zeigen. Am Touch-Geraet
   gibt es kein hover — dort ist das Wischen der Weg. */
.kos-wisch-loeschen {
  border: 0; background: none; cursor: pointer; color: var(--txt-faint);
  padding: 6px; margin: -6px 0; border-radius: 8px;
  display: none; flex: none;
}
.kos-wisch-loeschen .ic { width: 15px; height: 15px; }
.kos-wisch-loeschen:hover { color: #d5453a; background: var(--bg-hover); }
@media (hover: hover) {
  .kos-wisch-inhalt:hover .kos-wisch-loeschen { display: inline-flex; }
}

@media (prefers-color-scheme: dark) {
  .kos-schwebt, .kos-schalter {
    background: rgba(32,32,36,.78); border-color: rgba(255,255,255,.14);
  }
}

/* ---------- Chef: eine Seite, die ganze Hoehe ----------
   Mobile first, wie vom Nutzer verlangt: der Dialog bekommt alles, was
   nach Kopfzeile und sicherem Bereich uebrig ist. Kein height: calc()
   mit abgezaehlten Pixeln — die Zahl stimmt bei der ersten Aenderung
   an der Kopfzeile nicht mehr. Flex rechnet selbst. */
.chef-voll {
  flex: 1; display: flex; flex-direction: column; min-height: 0;
  padding: 0 12px 12px;
}
@media (min-width: 761px) {
  .chef-voll { padding: 0 20px 20px; }
}

/* ---------- Die Einstellungen: eine Pille, die aufgeht ----------
   DRITTER ANLAUF (16.08.2026), und die zwei davor waren beide falsch.
   Erst zwei Faltungen ueber dem Gespraech, dann eine Schublade von
   unten mit einer Liste darin. Der Nutzer:

     "Die Einstellungen gefallen mir nicht, das sind keine Dialoge.
      Das ist einfach wieder nur eine Liste. Ich hab eine Pille, die
      geht auf — und die Pille macht nicht von unten ein Dropdown auf,
      das macht keinen Sinn. Die Pille macht eine elegante Pille auf,
      also so einen Dialog an sich selber, wo dann wieder Einstellungen
      sind, die dann wieder andere Pillen oeffnen. Glasmorphismus."

   Also: das Ding waechst AUS der Klinke heraus, an derselben Stelle,
   in derselben Form. Kein Blatt von unten — das ist die Geste fuer
   "neue Ebene", und hier bleibt man auf derselben.

   Glas heisst hier: durchscheinender Grund mit Unschaerfe dahinter,
   ein heller Rand oben, ein weicher Schatten. Kein Grau auf Grau.
   Die Farbe bleibt monochrom (styles.css Zeile 1), das Material
   aendert sich. */
.pillendialog-schleier {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(20,20,22,.18);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  animation: pd-ein .14s ease-out;
}
@keyframes pd-ein { from { opacity: 0; } }

.pillendialog {
  position: fixed; z-index: 41;
  width: min(360px, calc(100vw - 24px));
  max-height: min(70dvh, 620px); overflow-y: auto;
  border-radius: 24px;
  background: rgba(255,255,255,.78);
  -webkit-backdrop-filter: saturate(180%) blur(22px);
  backdrop-filter: saturate(180%) blur(22px);
  border: 1px solid rgba(255,255,255,.9);
  box-shadow: 0 1px 0 rgba(255,255,255,.7) inset,
              0 18px 50px rgba(0,0,0,.18),
              0 2px 8px rgba(0,0,0,.06);
  padding: 6px;
  transform-origin: top right;
  animation: pd-auf .18s cubic-bezier(.2,.9,.25,1);
}
@keyframes pd-auf {
  from { opacity: 0; transform: scale(.9) translateY(-6px); }
}

/* Eine Zeile im Dialog IST eine Pille: Beschriftung links, der
   aktuelle Wert rechts. Ein Tipp oeffnet die naechste Pille. */
.pd-zeile {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: 0; background: none; font: inherit; cursor: pointer;
  color: var(--txt); text-align: left;
  padding: 11px 14px; border-radius: 18px;
}
.pd-zeile:hover { background: rgba(0,0,0,.05); }
.pd-zeile > span { flex: 1; min-width: 0; font-size: 15px; }
.pd-zeile > em {
  font-style: normal; font-size: 13.5px; color: var(--txt-dim);
  max-width: 55%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap;
}
.pd-zeile::after {
  content: ""; flex: none; width: 6px; height: 6px; margin-left: 2px;
  border-right: 1.6px solid var(--txt-faint);
  border-bottom: 1.6px solid var(--txt-faint);
  transform: rotate(-45deg);
}
.pd-zeile.zurueck::after { display: none; }
.pd-zeile.zurueck::before {
  content: ""; flex: none; width: 6px; height: 6px; margin-right: 4px;
  border-left: 1.6px solid var(--txt-dim);
  border-bottom: 1.6px solid var(--txt-dim);
  transform: rotate(45deg);
}
/* Eine Wahlzeile: kein Pfeil, dafuer ein Haken beim Gewaehlten. */
.pd-zeile.wahl::after {
  content: "✓"; width: auto; height: auto; border: 0; transform: none;
  color: transparent; font-size: 15px; font-weight: 700; margin: 0;
}
.pd-zeile.wahl.an::after { color: var(--txt); }
.pd-zeile > small {
  display: block; font-size: 12.5px; color: var(--txt-dim);
  line-height: 1.35; margin-top: 2px;
}
.pd-titel {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px 6px; font-size: 12px; font-weight: 600;
  letter-spacing: .5px; text-transform: uppercase; color: var(--txt-faint);
}
.pd-trenner { height: 1px; background: rgba(0,0,0,.07); margin: 4px 10px; }

@media (prefers-color-scheme: dark) {
  .pillendialog {
    background: rgba(32,32,36,.82);
    border-color: rgba(255,255,255,.14);
    box-shadow: 0 1px 0 rgba(255,255,255,.10) inset,
                0 18px 50px rgba(0,0,0,.5);
  }
  .pd-zeile:hover { background: rgba(255,255,255,.07); }
  .pd-trenner { background: rgba(255,255,255,.10); }
}

/* Die Klinke oben rechts. Sie war zu klein zum Treffen — 44 px ist das
   Mass, unter dem ein Ziel auf dem Telefon zur Gluecksache wird; 34
   plus Innenabstand kommt dort hin. */
.chef-kopfleiste { display: flex; justify-content: flex-end; padding: 2px 0 6px; }
.chef-pille {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 34px; padding: 0 14px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg-soft);
  color: var(--txt); font: inherit; font-size: 14px; font-weight: 500;
  cursor: pointer;
}
.chef-pille:hover { background: var(--bg-hover); }
.chef-pille::after {
  content: ""; width: 6px; height: 6px; margin-top: -3px;
  border-right: 1.6px solid var(--txt-dim);
  border-bottom: 1.6px solid var(--txt-dim);
  transform: rotate(45deg);
}

/* ---------- Mobil ---------- */
.scrim { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.28); z-index: 8; }
@media (max-width: 760px) {
  .sidebar {
    position: fixed; z-index: 9; inset: 0 auto 0 0; height: 100dvh;
    transform: translateX(-105%); transition: transform .22s ease;
    width: min(84vw, var(--sidebar-w));
    box-shadow: 8px 0 28px rgba(0,0,0,.12);
  }
  .shell.nav-open .sidebar { transform: none; }
  /* pan-y, damit das Wischen nach links/rechts bei uns ankommt und das
     Scrollen in der Liste trotzdem der Browser macht. */
  .sidebar { touch-action: pan-y; }
  .shell.nav-open .scrim { display: block; }
  #menu-btn, #sidebar-close { display: inline-flex; }
}

/* ---------- Marke: echtes K-Logo ---------- */
.brand-logo {
  display: block; margin: 0 auto; border-radius: 22%;
  object-fit: contain;
}
.brand-logo.small {
  display: inline-block; width: 24px; height: 24px;
  vertical-align: -6px; margin: 0 7px 0 0; border-radius: 6px;
}
.brand-logo.big { width: 72px; height: 72px; border-radius: 20px; }
.tagline {
  font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase;
  color: var(--txt-faint); margin: 4px 0 16px !important;
}

/* ---------- iPhone: kein Auto-Zoom, kein seitliches Wandern ----------
   iOS Safari zoomt beim Antippen automatisch hinein, sobald ein
   Eingabefeld eine Schrift KLEINER als 16px hat — und zoomt danach nicht
   zurueck. Deshalb hier ausdruecklich 16px auf allen Eingaben; das ist
   der eigentliche Fix, nicht user-scalable=no (das wuerde auch das
   absichtliche Vergroessern verbieten).
   Dazu waagerecht dichtmachen, damit sich die Seite wie eine App anfuehlt
   und nicht seitlich verschieben laesst. */
textarea, input, select { font-size: 16px !important; }
html, body { max-width: 100%; overflow-x: hidden; }
.shell, .main, .view, .chat-log, .composer-wrap, .files-pane, .task-detail {
  max-width: 100%;
}
.bubble, .file-name, .detail-block .card { overflow-wrap: anywhere; }

/* Aufraeum-Knopf neben der Abschnittsueberschrift */
.section-label { display: flex; align-items: center; justify-content: space-between; }
.label-btn { color: var(--txt-faint); padding: 2px 4px; border-radius: 6px;
             display: inline-flex; }
.label-btn:hover { color: var(--err); background: var(--bg-hover); }
.label-btn .ic { width: 15px; height: 15px; }
.btn.secondary.danger:hover { border-color: var(--err); color: var(--err); }
.btn.secondary:disabled { opacity: .35; }

/* ---------- Live-Verlauf einer laufenden Aufgabe ---------- */
.live-list {
  max-height: 300px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-soft); padding: 8px 4px;
}
.live-row { display: flex; gap: 10px; align-items: baseline; padding: 5px 10px; }
.live-dot {
  flex: none; width: 6px; height: 6px; border-radius: 50%;
  background: var(--run); margin-top: 6px;
}
.live-row.thought .live-dot { background: var(--txt-faint); }
.live-text { font-size: 13.5px; color: var(--txt); overflow-wrap: anywhere; }
.live-row.thought .live-text { color: var(--txt-dim); font-style: italic; }
.live-row:last-child .live-dot { animation: pulse 1.4s infinite; }

/* ---------- M5 Einstellungen ----------
   Vorher standen 386 Zeilen Maske am Stueck. Jetzt: eine Uebersicht und
   neun Unterseiten, jede mit eigener Adresse (#/einstellungen/<seite>).
   Kopfzeile mit Zuruecktaste wie bei den Ball-Spuren — am Telefon ist das
   der Weg, den der Daumen kennt. */
.m5-topbar { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.m5-titel { font-size: 21px; font-weight: 650; letter-spacing: -.3px;
            flex: 1; min-width: 0; overflow: hidden; white-space: nowrap;
            text-overflow: ellipsis; }
.m5-zurueck { flex: none; width: 40px; height: 40px; border-radius: 12px;
              border: 1px solid var(--line); background: var(--bg);
              color: var(--txt-dim); font-size: 22px; line-height: 1; }
.m5-zurueck:hover { border-color: var(--ink); color: var(--txt); }
.m5-uebersicht { margin-bottom: 22px; }
.automation-pane { flex: 1; overflow-y: auto; max-width: 860px; width: 100%; margin: 0 auto; padding: 18px 16px calc(28px + env(safe-area-inset-bottom)); }
.automation-status-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 22px; }
.status-card { display: flex; flex-direction: column; gap: 5px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.status-card strong { display: flex; align-items: center; gap: 8px; font-size: 15px; }
.status-label { color: var(--txt-faint); font-size: 11px; font-weight: 600; letter-spacing: .7px; text-transform: uppercase; }
.status-meta { color: var(--txt-dim); font-size: 12.5px; }
.status-meta.dirty { color: var(--run); font-weight: 600; }

/* Abschnitte: eine Ueberschrift, ein Satz dazu, dann die Felder. */
.m5-block { margin: 0 0 30px; }
.m5-block > h3, .klapp-titel {
  font-size: 15.5px; font-weight: 650; letter-spacing: -.2px;
  color: var(--txt); margin: 0 0 4px;
}
.m5-erklaerung {
  color: var(--txt-dim); font-size: 12.5px; line-height: 1.5;
  margin: 0 0 12px; max-width: 64ch;
}
.m5-block .card {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px;
}
/* Eingeklappt: das selten Gebrauchte bleibt erreichbar, ohne mitzuschreien. */
details.m5-block { border: 1px solid var(--line); border-radius: var(--radius);
                   padding: 14px 16px; background: var(--bg); }
details.m5-block > summary {
  cursor: pointer; list-style: none; display: flex; flex-wrap: wrap;
  align-items: baseline; gap: 4px 10px; min-height: 30px;
}
details.m5-block > summary::-webkit-details-marker { display: none; }
details.m5-block > summary::after {
  content: "einblenden"; margin-left: auto; color: var(--txt-faint);
  font-size: 12px; font-weight: 600;
}
details.m5-block[open] > summary::after { content: "ausblenden"; }
details.m5-block[open] > summary { margin-bottom: 12px; }
details.m5-block .card { background: var(--bg-soft); }
.klapp-hinweis { color: var(--txt-faint); font-size: 12px; }
.klapp-hinweis.warnung { color: #92400e; font-weight: 600; }
details.m5-block.heikel { border-color: #fde68a; background: #fffdf6; }
details.m5-block.heikel .card { background: #fff; border-color: #fde68a; }
.m5-block details.m5-block { margin-top: 18px; margin-bottom: 0; }

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 16px; white-space: normal !important; }
/* Seitliches Scrollen: ein Rasterfeld ist von Haus aus min-width:auto, also
   mindestens so breit wie sein laengstes untrennbares Wort. Am 10.08.2026
   liess sich "M5 Einstellungen" und "Launcher" darum seitlich schieben,
   "Dateien" nicht — dort ist die Spalte flex mit min-width:0 und die
   Dateinamen kuerzen mit Ellipse. Drei Regeln halten das zusammen:
   minmax(0, 1fr) statt 1fr, min-width:0 auf den Flex-Spalten, und lange
   Werte brechen um. Das overflow-x unten ist nur noch der Fangzaun. */
.feld-hilfe, .feld-jetzt, .m5-erklaerung { overflow-wrap: anywhere; }
.automation-pane, .launcher-pane, .home-pane, .files-pane { overflow-x: hidden; }
.form-grid label { display: flex; flex-direction: column; min-width: 0; gap: 6px; color: var(--txt-dim); font-size: 12.5px; font-weight: 500; }
.form-grid input:not([type="checkbox"]), .form-grid select, .form-grid textarea { width: 100%; border: 1px solid var(--line); border-radius: 10px; padding: 10px 11px; background: var(--bg); color: var(--txt); font: inherit; outline: none; }
.form-grid input:focus, .form-grid select:focus, .form-grid textarea:focus { border-color: var(--ink); }
.form-grid textarea { resize: vertical; min-height: 100px; }
.form-grid .wide { grid-column: 1 / -1; }

/* ---------- Bausteine einer Einstellung ----------
   Beschriftung, aktueller Wert, Bedienelement, Grenzen, Erklaerung — in
   dieser Reihenfolge und fuer jede Sorte gleich. Wer eine Schwelle
   dazuhaengt (Schuetteln, Kippen, hell/dunkel), schreibt nur das HTML aus
   der Vorlage in app.js und bekommt diese Optik; eigene Farben oder eigene
   Abstaende im Skript waeren der Anfang einer zweiten Optik. */
.feld { display: flex; flex-direction: column; min-width: 0; gap: 6px; }
.feld-kopf { display: flex; align-items: center; gap: 10px; min-width: 0; }
.feld-name { flex: 1; min-width: 0; color: var(--txt-dim); font-size: 12.5px;
             font-weight: 600; overflow-wrap: anywhere; }
.feld-wert { flex: none; color: var(--txt); font-size: 12.5px; font-weight: 700;
             font-variant-numeric: tabular-nums; }
.feld-wert:empty { display: none; }
/* Die Enden der Skala stehen unter dem Regler — eine Grenze, die man nicht
   sieht, merkt man erst, wenn der Server den Wert ablehnt. */
.feld-grenzen { display: flex; justify-content: space-between; gap: 10px;
                color: var(--txt-faint); font-size: 11px;
                overflow-wrap: anywhere; margin-top: -2px; }
.feld-grenzen:empty { display: none; }
.form-grid input[type="range"] {
  width: 100%; height: 34px; padding: 0; border: none; border-radius: 0;
  background: none; accent-color: var(--ink); cursor: pointer;
}
/* Schalter: fingergross und mit einem Wort daneben, das sagt, was gilt. */
.feld.schalter .feld-name { font-size: 14px; color: var(--txt); }
.form-grid .feld.schalter input[type="checkbox"] {
  flex: none; appearance: none; -webkit-appearance: none; margin: 0;
  width: 48px; height: 28px; border-radius: 999px; background: var(--line);
  position: relative; cursor: pointer; transition: background .15s;
}
.form-grid .feld.schalter input[type="checkbox"]::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 22px; height: 22px; border-radius: 50%; background: var(--bg);
  transition: transform .15s;
}
.form-grid .feld.schalter input[type="checkbox"]:checked { background: var(--ink); }
.form-grid .feld.schalter input[type="checkbox"]:checked::after { transform: translateX(20px); }
/* Ein Satz unter jedem Feld, das sich nicht von selbst erklaert. */
.feld-hilfe { color: var(--txt-faint); font-size: 11.5px; font-weight: 400;
              line-height: 1.5; margin-top: -1px; }
/* Was gerade gilt — damit sichtbar ist, was man ueberschreibt. */
.feld-jetzt { color: var(--txt-dim); font-size: 11.5px; font-weight: 600; }
.feld-jetzt:empty { display: none; }
.automation-actions { position: sticky; bottom: -1px; display: flex; align-items: center; gap: 10px; padding: 14px 0; background: rgba(255,255,255,.96); border-top: 1px solid var(--line); }
.automation-actions .status-meta { margin-right: auto; }
.automation-actions .btn { display: inline-flex; align-items: center; gap: 8px; }
.automation-actions .btn .ic { width: 17px; height: 17px; }
.automation-notice { margin-bottom: 14px; padding: 10px 12px; border-radius: 10px; background: var(--bg-soft); border: 1px solid var(--line); font-size: 13px; }
.automation-notice.success { color: var(--ok); border-color: #a7f3d0; background: #ecfdf5; }
.automation-notice.warning { color: #92400e; border-color: #fde68a; background: #fffbeb; }
.automation-notice.error { color: var(--err); border-color: #fecaca; background: #fef2f2; }
.automation-notfall { display: flex; align-items: center; gap: 16px; justify-content: space-between;
  margin-bottom: 14px; padding: 14px 16px; border-radius: var(--radius);
  background: var(--bg-soft); border: 1px solid var(--line); }
.automation-notfall strong { color: var(--txt); font-size: 14px; }
.automation-notfall p { color: var(--txt-dim); font-size: 12px; line-height: 1.5; margin: 4px 0 0; }
.automation-notfall-schalter input { appearance: none; -webkit-appearance: none; margin: 0;
  width: 48px; height: 28px; border-radius: 999px; background: var(--line);
  position: relative; cursor: pointer; }
.automation-notfall-schalter input::after { content: ""; position: absolute; top: 3px; left: 3px;
  width: 22px; height: 22px; border-radius: 50%; background: var(--bg);
  transition: transform .15s; }
.automation-notfall-schalter input:checked { background: var(--ink); }
.automation-notfall-schalter input:checked::after { transform: translateX(20px); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
@media (max-width: 620px) {
  .automation-status-grid, .form-grid { grid-template-columns: minmax(0, 1fr); }
  .form-grid .wide { grid-column: auto; }
  details.m5-block > summary::after { content: ""; }
  .automation-actions { flex-wrap: wrap; }
  .automation-actions .status-meta { flex-basis: 100%; }
}

/* ---------- Launcher-Reiter: Vorschau + Editor ----------
   Am Rechner nebeneinander, am Handy untereinander — die Vorschau oben,
   die Einstellungen darunter, damit man beim Tippen sieht, was passiert. */
.launcher-pane {
  flex: 1; overflow-y: auto; width: 100%;
  max-width: 980px; margin: 0 auto;
  padding: 14px 16px calc(20px + env(safe-area-inset-bottom));
  display: grid; gap: 18px; grid-template-columns: minmax(0, 1fr);
  align-content: start;
}
@media (min-width: 900px) {
  .launcher-pane { grid-template-columns: 360px minmax(0, 1fr); align-items: start; }
  .preview-wrap { position: sticky; top: 12px; }
}

.preview-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.preview-titel { font-weight: 600; font-size: 13px; }
.preview-tools { margin-left: auto; display: flex; gap: 6px; }
.chip {
  font-size: 12px; padding: 5px 10px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg); color: var(--txt);
}
.chip:hover { border-color: var(--ink); }
.chip.ghost { color: var(--txt-faint); pointer-events: none; }

/* Das Geraet
   ----------------------------------------------------------------
   WARUM ECHTE PIXEL: Die erste Fassung rechnete in Prozent und cqw.
   Damit verschob sich das Layout mit jeder Fensterbreite — auf dem
   iPhone sah die Vorschau nicht mehr aus wie der M5. Jetzt ist der
   Bildschirm exakt 320x240 CSS-Pixel gross, mit denselben Abstaenden
   wie device/main.py, und wird als Ganzes skaliert. Was hier steht,
   kann sich damit gar nicht mehr anders verhalten als das Geraet. */
.geraet { display: flex; flex-direction: column; align-items: center; }
.geraet-rand {
  background: #2b2b2e; padding: 10px 10px 14px; border-radius: 14px;
  box-shadow: 0 10px 30px rgba(0,0,0,.22), inset 0 1px 0 rgba(255,255,255,.09);
  max-width: 100%;
}
.geraet-fuss {
  width: 62%; height: 9px; background: #17171a;
  border-radius: 0 0 9px 9px; display: flex; justify-content: center;
}
.geraet-fuss span { width: 34%; height: 3px; margin-top: 3px;
  background: #4a4a50; border-radius: 2px; }

.screen-scale {
  width: calc(320px * var(--z, 1)); height: calc(240px * var(--z, 1));
  max-width: 100%;
}
.screen {
  width: 320px; height: 240px; flex: none;
  transform: scale(var(--z, 1)); transform-origin: top left;
  position: relative; overflow: hidden; border-radius: 3px;
  background: #E8DCBE; color: #2A2519;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}
.screen.dark { background: #1E1B15; color: #EDE2C8; }

/* Kopfzeile: HEAD_H = 26 */
.screen-bar {
  position: absolute; inset: 0 0 auto 0; height: 26px;
  display: flex; align-items: center; gap: 6px; padding: 0 6px;
  background: #F2E6C9; border-bottom: 1px solid #9A8E72; font-size: 12px;
}
.screen.dark .screen-bar { background: #272319; border-color: #574F3F; }
.cube { width: 12px; height: 9px; border: 2px solid #2A2519;
        border-radius: 1px; flex: none; }
.screen.dark .cube { border-color: #4E4A40; }
.bar-titel { font-weight: 700; letter-spacing: .3px; }
.bar-mitte { margin: 0 auto; opacity: .7; }
.batt { width: 20px; height: 10px; border: 1.5px solid currentColor;
        border-radius: 2px; padding: 1px; flex: none; }
.batt i { display: block; height: 100%; width: 70%; background: #839B4B; }

/* Kacheln: GAP 6, TILE_W 151, TILE_H 77, ab y = 32 */
.tiles { position: absolute; inset: 26px 0 42px 0; }
.tile {
  position: absolute; width: 151px; height: 77px;
  background: #F7EDD6; border: 1px solid #9A8E72; border-radius: 6px;
  box-shadow: 2px 2px 0 #C0B08C;
}
.screen.dark .tile { background: #2B2720; border-color: #574F3F;
                     box-shadow: 2px 2px 0 #100E0A; }
.tile.leer { background: none; border: 1px dashed #C0B08C; box-shadow: none; }
/* Icon sitzt auf (x+10, y+16) und ist 44 Pixel breit — wie im Launcher */
.tile .ic { position: absolute; left: 4px; top: 10px; width: 52px; height: 54px; }
.tile span {
  position: absolute; left: 56px; top: 20px; right: 4px;
  font-size: 12px; font-weight: 700; letter-spacing: .2px;
  white-space: nowrap; overflow: hidden;
}
.tile .balken { position: absolute; right: 6px; bottom: 6px;
                display: flex; align-items: flex-end; gap: 2px; height: 10px; }
.tile .balken i { width: 4px; border-radius: 1px; display: block; }

/* Fusszeile: FOOT_Y = 198, drei Drittel */
.screen-foot {
  position: absolute; left: 0; right: 0; top: 198px; height: 36px;
  display: flex; gap: 12px; padding: 0 6px;
}
.fkey {
  flex: 1; background: #DCCFB0; border: 1px solid #9A8E72; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; box-shadow: 2px 2px 0 #C0B08C;
}
.fkey.mid { color: #8A7F66; }
.fkey.aus { visibility: hidden; }
.screen.dark .fkey { background: #231F19; border-color: #574F3F;
                     box-shadow: 2px 2px 0 #100E0A; }

/* Editor */
.editor-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px; }
.editor-head h3 { font-size: 15px; }
.editor-status { font-size: 12px; color: var(--txt-faint); margin-left: auto; }
.app-list { display: flex; flex-direction: column; gap: 8px; }
.app-row {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--bg);
}
.app-row.aus { opacity: .45; }
.app-row .griff { display: flex; flex-direction: column; gap: 2px; flex: none; }
.app-row .griff button {
  width: 26px; height: 20px; border: 1px solid var(--line); border-radius: 5px;
  font-size: 11px; line-height: 1; color: var(--txt-dim);
}
.app-row .griff button:hover { border-color: var(--ink); color: var(--txt); }
.app-row input[type="text"] {
  flex: 1; min-width: 0; padding: 8px 10px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--bg); color: var(--txt);
  font: inherit; outline: none;
}
.app-row input:focus { border-color: var(--ink); }
.app-row .datei { font-size: 11px; color: var(--txt-faint); flex: none; }
.icon-pick { position: relative; flex: none; }
.icon-pick > button {
  width: 40px; height: 40px; border: 1px solid var(--line); border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
}
.icon-pick > button:hover { border-color: var(--ink); }
.icon-menu {
  /* VIER Spalten, nicht drei. Bei zwoelf Icons waren drei Spalten vier
     Reihen hoch (~190 px); die Auswahl liegt in einem Scroll-Container
     (.ansicht-scroll weiter oben, overflow-y: auto) und wurde an dessen
     Rand abgeschnitten. Der Nutzer am 12.08.2026: "Im Launcher in der App
     fehlen zwei, drei Icons, zum Beispiel das Prozessor-Icon."
     Vier Spalten sind drei Reihen (~140 px) und passen. */
  position: absolute; right: 0; top: 44px; z-index: 20;
  display: grid; grid-template-columns: repeat(4, 40px); gap: 4px; padding: 6px;
  max-height: 40vh; overflow-y: auto;
  background: var(--bg); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0,0,0,.14);
}
.icon-menu button {
  width: 40px; height: 40px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
}
.icon-menu button:hover, .icon-menu button.aktiv { background: var(--bg-hover); }
.augen { flex: none; padding: 8px; border-radius: 8px; color: var(--txt-faint); }
.augen:hover { background: var(--bg-hover); color: var(--txt); }
.editor-actions { display: flex; gap: 10px; margin-top: 14px; }

/* ---------- Ball-Spuren ----------
   Eigene Seiten statt einer langen: jede Seite fuellt den Bereich, die
   Adresse sagt welche. Die Zeilenregel ist dieselbe wie am Geraet — die
   Nebenangabe steht RECHTS, nicht darunter; darum min-width:0 auf dem
   Titel, sonst schiebt ein langer Name die Angabe aus dem Bild. */
.spiel-pane {
  flex: 1; overflow-y: auto; overflow-x: hidden; width: 100%;
  max-width: 720px; margin: 0 auto;
  padding: 14px 16px calc(24px + env(safe-area-inset-bottom));
}

.spiel-leiste { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0; }
.spiel-abschnitt { margin: 16px 0 6px; font-size: 12.5px; font-weight: 600;
  color: var(--txt-dim); }
.spiel-koordinate { padding: 10px 13px; border: 1px solid var(--line);
  border-radius: 12px; font-size: 13px; overflow-wrap: anywhere; }
.spiel-meldung { padding: 10px 13px; border-radius: 12px; font-size: 13px;
  border: 1px solid var(--line); overflow-wrap: anywhere; }
.spiel-meldung.schlecht { border-color: var(--warn, #d4795f);
  color: var(--warn, #d4795f); }
.spiel-leer { color: var(--txt-dim); font-size: 13.5px; line-height: 1.5; }
.spiel-fussnote { margin-top: 6px; font-size: 11.5px; color: var(--txt-faint);
  overflow-wrap: anywhere; }
.spiel-stand:empty { display: none; }

/* Warm/Kalt: dieselben Werte in vier Karten, am Rechner nebeneinander und
   am Telefon untereinander. minmax(0, ...) ist hier Teil der Bedienbarkeit:
   ohne die Null schiebt ein SVG das ganze Dashboard seitlich. */
.spiel-signal-quelle { display: flex; flex-direction: column; gap: 4px;
  border: 2px solid var(--line); border-radius: 14px; padding: 12px 14px;
  margin-bottom: 12px; font-size: 12.5px; line-height: 1.45; }
.spiel-signal-quelle.nachgestellt { border-style: dashed; }
.spiel-signal-quelle strong { font-size: 12px; letter-spacing: .06em; }
.spiel-signal-quelle span { color: var(--txt-dim); }
.spiel-signal-vergleich { display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.spiel-signal-karte { min-width: 0; padding: 12px; border: 1px solid var(--line);
  border-radius: 16px; background: var(--bg); }
.spiel-signal-kopf { display: flex; gap: 8px; align-items: center;
  justify-content: space-between; }
.spiel-signal-kopf strong { min-width: 0; font-size: 14px; }
.spiel-signal-trend { flex: none; color: var(--akzent); font-size: 13px; }
.spiel-signal-meta { display: block; color: var(--txt-dim); font-size: 11.5px;
  margin: 3px 0 7px; overflow-wrap: anywhere; }
.spiel-signal-karte svg { display: block; width: 100%; height: auto; }
@media (max-width: 560px) {
  .spiel-signal-vergleich { grid-template-columns: minmax(0, 1fr); }
}

/* Die laufende Ausnahme steht auf jeder Spielseite bei den Daten. */
.spiel-testmodus { margin: 0 0 16px; padding: 14px; border: 2px solid var(--line); border-radius: 12px; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.spiel-testmodus.an { border-color: #ff8a3d; background: rgba(255,138,61,.12); }
.spiel-testmodus strong { font-size: 1.05rem; }
.spiel-zonen { flex-basis: 100%; display: grid; gap: 8px; }
.spiel-zone { display: flex; justify-content: space-between; align-items: center; }

/* ---------- Ball-Spuren: eigene Optik, weil es ein Spiel ist ----------
   Der Rest des Dashboards ist Werkzeug: schwarz auf weiss, sachlich. Ein
   Spiel darf anders aussehen — Kacheln statt Zeilen, Farbe je Typ, eine
   Karte. Die Farben stehen HIER als Variablen und nicht in spiel.js: eine
   Anzeige, die sich ihre eigenen Farben ausdenkt, ist der Anfang einer
   zweiten Optik (dieselbe Regel wie am Geraet in theme.py). */
:root {
  --typ-wald: #2f7d55;
  --typ-licht: #c98a17;
  --typ-klang: #7c5cd6;
  --typ-wasser: #2b6fb5;
  --typ-stein: #7a6a58;
  --typ-wind: #2a9aa5;
  --spiel-flaeche: #fbfaf8;
  --spiel-tinte: #1f2924;
  --spiel-papier: #f2ead9;
}
.spiel-pane { background: var(--spiel-flaeche); }

/* Kopf einer Seite: Titel links, Menue rechts — dieselbe Regel wie am
   Geraet, die Nebenangabe steht neben der Sache, nicht darunter. */
.spiel-topbar { display: flex; align-items: center; gap: 10px;
  margin: 2px 0 16px; }
.spiel-kopf { font-size: 21px; margin: 0; flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.spiel-zurueck { flex: none; width: 34px; height: 34px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--bg); color: var(--txt);
  font-size: 17px; line-height: 1; cursor: pointer; }
.spiel-zurueck:hover { border-color: var(--ink); }

/* --- Sammlung als Auftakt, nicht als Reihe gleich lauter Kennzahlen --- */
.spiel-sammlungs-held { position: relative; overflow: hidden; margin-bottom: 12px;
  padding: 23px 22px 18px; border-radius: 28px 28px 28px 8px;
  color: var(--spiel-papier); background:
    radial-gradient(circle at 92% -8%, var(--typ-wald) 0 13%, transparent 14%),
    radial-gradient(circle at 86% 12%, var(--typ-wasser) 0 7%, transparent 8%),
    var(--spiel-tinte); box-shadow: 0 10px 28px rgba(31,41,36,.16); }
.spiel-sammlungs-held::after { content: ""; position: absolute; width: 80px;
  height: 80px; right: -34px; bottom: -34px; border: 12px solid var(--typ-licht);
  border-radius: 50%; opacity: .42; pointer-events: none; }
.spiel-sammlungs-kopf { display: flex; align-items: flex-start; gap: 16px;
  justify-content: space-between; position: relative; z-index: 1; }
.spiel-sammlungs-kopf > *, .spiel-sammlungs-text { min-width: 0; }
.spiel-sammlungs-text { display: flex; flex-direction: column; gap: 2px; }
.spiel-sammlungs-text strong { font-size: clamp(25px, 6vw, 34px); line-height: 1.08;
  letter-spacing: -.035em; overflow-wrap: anywhere; }
.spiel-sammlungs-text > span:last-child { font-size: 12.5px; opacity: .72; }
.spiel-ueberzeile { display: block; font-size: 10px; font-weight: 750;
  letter-spacing: .14em; }
.spiel-stufe { flex: none; padding: 5px 8px; border: 1px solid currentColor;
  border-radius: 999px; font-size: 10px; letter-spacing: .08em; }
.spiel-typenstand { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px; margin: 20px 0 16px; position: relative; z-index: 1; }
.spiel-typstand { min-width: 0; display: flex; align-items: center; gap: 6px;
  padding: 7px 8px; border: 1px solid rgba(255,255,255,.18); border-radius: 9px;
  background: rgba(255,255,255,.06); }
.spiel-typstand i { flex: none; width: 8px; height: 8px; border-radius: 50%;
  background: var(--akzent); box-shadow: 0 0 0 3px rgba(255,255,255,.08); }
.spiel-typstand span { min-width: 0; flex: 1; overflow: hidden;
  text-overflow: ellipsis; font-size: 11px; text-transform: capitalize; }
.spiel-typstand b { flex: none; font-size: 11px; }
.spiel-typstand.leer { border-style: dashed; opacity: .56; }
.spiel-held-aktion { position: relative; z-index: 1; border: 0; padding: 0;
  background: none; color: inherit; font: inherit; font-size: 12.5px;
  font-weight: 650; cursor: pointer; }
.spiel-held-aktion:hover { text-decoration: underline; }

/* Ein Ereignis ist die Naht zwischen Besitz und Geschichte. */
.spiel-ereignis { width: 100%; min-width: 0; display: flex; align-items: center;
  gap: 13px; text-align: left; margin: 0 0 20px; padding: 13px 15px;
  border: 1px solid var(--line); border-left: 4px solid var(--akzent, var(--ink));
  border-radius: 8px 16px 16px 8px; background: var(--bg); color: var(--txt);
  font: inherit; cursor: pointer; }
.spiel-ereignis:hover { border-color: var(--akzent, var(--ink)); }
.spiel-spurpunkt { flex: none; width: 14px; height: 14px; border-radius: 50%;
  background: var(--akzent, var(--ink)); box-shadow: 0 0 0 5px var(--spiel-papier); }
.spiel-ereignis-inhalt { min-width: 0; flex: 1; }
.spiel-ereignis-inhalt strong, .spiel-ereignis-inhalt > span { display: block;
  overflow-wrap: anywhere; }
.spiel-ereignis-inhalt strong { margin: 1px 0; font-size: 14px; }
.spiel-ereignis-inhalt > span:last-child { color: var(--txt-dim); font-size: 11.5px; }
.spiel-ereignis time { flex: none; align-self: flex-start; color: var(--txt-faint);
  font-size: 10.5px; }
[data-art="begegnung"] { --akzent: var(--typ-licht); }
[data-art="route"] { --akzent: var(--typ-wind); }
[data-art="leer"] { --akzent: var(--typ-stein); }

/* Die Nebenwege sind bewusst verschieden hoch: eine Spielspur, kein
   Verwaltungsraster aus vier identischen Karten. */
.spiel-spuren-module { display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
.spiel-spuren-modul { min-width: 0; min-height: 92px; display: flex;
  align-items: flex-end; gap: 10px; text-align: left; padding: 14px;
  border: 1px solid var(--line); border-top: 3px solid var(--akzent);
  border-radius: 8px 17px 17px; background: var(--bg); color: var(--txt);
  font: inherit; cursor: pointer; }
.spiel-spuren-modul.breit { grid-row: span 2; min-height: 193px;
  background: linear-gradient(150deg, var(--bg) 55%, var(--spiel-papier)); }
.spiel-spuren-modul:last-child { grid-column: 1 / -1; }
.spiel-spuren-modul:hover { border-color: var(--akzent); }
.spiel-spuren-modul > * { min-width: 0; }
.spiel-spuren-modul > b { flex: none; align-self: center; color: var(--akzent);
  font-size: 22px; }
.spiel-modul-inhalt { min-width: 0; flex: 1; }
.spiel-modul-inhalt strong { display: block; margin: 3px 0 1px; font-size: 25px;
  line-height: 1; overflow-wrap: anywhere; }
.spiel-modul-inhalt > span:last-child { display: block; color: var(--txt-dim);
  font-size: 11.5px; overflow-wrap: anywhere; }
.spiel-versuch { width: 100%; min-width: 0; display: grid;
  grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; margin-top: 16px;
  padding: 12px 14px; text-align: left; border: 1px dashed var(--akzent);
  border-radius: 12px; background: transparent; color: var(--txt); font: inherit;
  cursor: pointer; }
.spiel-versuch div { min-width: 0; font-size: 11px; font-weight: 750;
  letter-spacing: .09em; }
.spiel-versuch span { min-width: 0; color: var(--txt-dim); font-size: 11.5px;
  overflow-wrap: anywhere; }
.spiel-versuch b { grid-column: 2; grid-row: 1 / span 2; align-self: center;
  color: var(--akzent); font-size: 20px; }

@media (max-width: 520px) {
  .spiel-sammlungs-held { padding: 20px 17px 16px; }
  .spiel-typenstand { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .spiel-ereignis { align-items: flex-start; }
  .spiel-ereignis time { max-width: 62px; text-align: right; overflow-wrap: anywhere; }
  .spiel-spuren-module { grid-template-columns: minmax(0, 1fr); }
  .spiel-spuren-modul.breit { grid-row: auto; min-height: 116px; }
  .spiel-spuren-modul:last-child { grid-column: auto; }
}

/* --- Ballkacheln --- */
.spiel-raster { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px; margin-top: 4px; }
.spiel-ball {
  position: relative; overflow: hidden; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: 16px; background: var(--bg);
  padding: 14px 13px 12px; color: var(--txt); font: inherit;
  display: flex; flex-direction: column; gap: 4px;
  transition: transform .12s ease, border-color .12s ease;
}
.spiel-ball:hover { border-color: var(--ink); transform: translateY(-2px); }
.spiel-ball .marke { width: 30px; height: 30px; border-radius: 50%;
  background: var(--akzent); opacity: .18; position: absolute;
  top: 11px; right: 11px; }
.spiel-ball .punkt { width: 9px; height: 9px; border-radius: 50%;
  background: var(--akzent); position: absolute; top: 21px; right: 21px; }
.spiel-ball .name { font-weight: 600; font-size: 14.5px; padding-right: 34px;
  overflow-wrap: anywhere; }
.spiel-ball .art { font-size: 11.5px; color: var(--akzent); font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em; }
.spiel-ball .ort { font-size: 11.5px; color: var(--txt-dim);
  overflow-wrap: anywhere; }
.spiel-ball-herkunft, .spiel-ball-freund { width: fit-content; max-width: 100%;
  padding: 2px 6px; border-radius: 999px; background: var(--bg-soft);
  color: var(--txt-dim); font-size: 10.5px; overflow-wrap: anywhere; }
.spiel-ball-freund { border: 1px solid var(--akzent); color: var(--akzent); }
.sterne { display: flex; gap: 3px; margin-top: 2px; }
.sterne i { width: 7px; height: 7px; border-radius: 50%;
  background: var(--line); }
.sterne i.an { background: var(--akzent); }

/* --- Steckbrief --- */
.spiel-held { border-radius: 18px; padding: 20px 18px; color: #fff;
  background: var(--akzent); margin-bottom: 14px; }
.spiel-held h3 { margin: 0 0 4px; font-size: 22px; overflow-wrap: anywhere; }
.spiel-held .unter { font-size: 13px; opacity: .9; }
.spiel-held .sterne i { background: rgba(255,255,255,.35); }
.spiel-held .sterne i.an { background: #fff; }
.spiel-werte { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px; margin-bottom: 14px; }
.spiel-wert { border: 1px solid var(--line); border-radius: 14px;
  padding: 11px 12px; background: var(--bg); }
.spiel-wert strong { display: block; font-size: 15px; overflow-wrap: anywhere; }
.spiel-wert span { font-size: 11px; color: var(--txt-dim); }
.spiel-datenliste { display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 7px; }
.spiel-datenzeile { display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px;
  background: var(--bg); }
.spiel-datenmitte { flex: 1; min-width: 0; }
.spiel-datenmitte strong, .spiel-datenmitte span { display: block;
  overflow-wrap: anywhere; }
.spiel-datenmitte span, .spiel-datenzeile > b { color: var(--txt-dim);
  font-size: 11.5px; }
.spiel-datenzeile > b { flex: none; text-align: right; }
.spiel-route-tag { display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 7px; margin-bottom: 12px; }
.spiel-route-tag h3 { margin: 0 0 2px; font-size: 15px; }

/* --- Albumseiten: jede Typspur hat ihren festen Platz, auch leer. --- */
.spiel-typgruppe { min-width: 0; margin: 0 0 14px; padding: 14px;
  border: 1px solid var(--line); border-left: 5px solid var(--akzent);
  border-radius: 7px 18px 18px 7px; background: var(--bg); }
.spiel-typgruppe.leer { border-left-style: dashed; background: transparent; }
.spiel-typgruppe-kopf { display: flex; align-items: baseline; gap: 12px;
  justify-content: space-between; }
.spiel-typgruppe-kopf > * { min-width: 0; }
.spiel-typgruppe-kopf h3 { margin: 0; font-size: 16px; text-transform: capitalize;
  overflow-wrap: anywhere; }
.spiel-typgruppe-kopf b { flex: none; color: var(--akzent); font-size: 10.5px;
  letter-spacing: .06em; text-transform: uppercase; }
.spiel-luecke { width: 100%; margin-top: 10px; padding: 14px; border: 1px dashed var(--akzent);
  border-radius: 11px; background: transparent; color: var(--txt-dim); font: inherit;
  font-size: 12px; text-align: left; cursor: pointer; }
.spiel-luecke:hover { color: var(--akzent); }

/* --- Menue im Menue --- */
.spiel-menue { position: relative; flex: none; }
.spiel-menue-liste { position: absolute; right: 0; top: 38px; z-index: 30;
  min-width: 194px; background: var(--bg); border: 1px solid var(--line);
  border-radius: 14px; padding: 6px; box-shadow: 0 12px 30px rgba(0,0,0,.13); }
.spiel-menue-liste button { display: block; width: 100%; text-align: left;
  padding: 10px 12px; border: 0; border-radius: 10px; background: none;
  color: var(--txt); font: inherit; cursor: pointer; }
.spiel-menue-liste button:hover { background: var(--bg-soft); }
.spiel-menue-liste button.gefahr { color: var(--err); }
.spiel-menue-liste hr { border: 0; border-top: 1px solid var(--line);
  margin: 5px 4px; }

/* --- Karte --- */
.spiel-karte { border: 1px solid var(--line); border-radius: 18px;
  background: var(--bg); overflow: hidden; position: relative; }
.spiel-karte svg { display: block; width: 100%; height: auto; }
.spiel-kartenquelle { position: absolute; right: 5px; bottom: 5px;
  padding: 2px 5px; border-radius: 4px; background: rgba(255, 255, 255, .86);
  color: #222; font-size: 10px; line-height: 1.2; }
.spiel-kartenquelle a { color: inherit; text-decoration: none; }
.spiel-karte-fuss { display: flex; gap: 14px; flex-wrap: wrap;
  padding: 11px 14px; border-top: 1px solid var(--line); font-size: 12px;
  color: var(--txt-dim); }

/* Die Farbe kommt aus data-typ, nicht aus dem Skript. */
[data-typ="wald"]   { --akzent: var(--typ-wald); }
[data-typ="licht"]  { --akzent: var(--typ-licht); }
[data-typ="klang"]  { --akzent: var(--typ-klang); }
[data-typ="wasser"] { --akzent: var(--typ-wasser); }
[data-typ="stein"]  { --akzent: var(--typ-stein); }
[data-typ="wind"]   { --akzent: var(--typ-wind); }

/* Verbrauchskarte: eigene Zaehlung, Sperrlage. Farben aus den Tokens. */
.verbrauch-card {
  margin: 6px 10px; padding: 6px 10px; border-radius: 8px;
  font-size: 11px; color: var(--muted, #9aa3ad);
  background: var(--panel, rgba(255,255,255,.04));
  overflow-wrap: anywhere;
}
.verbrauch-card.gesperrt { color: var(--danger, #e2574d); }

/* Der Plan des laufenden Agenten: Punkte mit Haken statt nur
   "Aufgabenliste aktualisiert" (12.08.2026). */
.live-plan { margin: 0 0 10px; padding: 10px 12px; position: sticky; top: 0; background: var(--surface, rgba(127,127,127,.08));
  border-left: 2px solid var(--accent, #888); border-radius: 6px; }
.live-plan-kopf { font-size: 12px; color: var(--muted, #888); margin-bottom: 4px; }
.live-plan-punkt { font-size: 13px; line-height: 1.5; }
.live-plan-punkt.completed { color: var(--muted, #888); text-decoration: line-through; }
.live-plan-punkt.in_progress { font-weight: 600; }

/* ── Kühlschrank (aus dem alten Cloudboard geholt, 13.08.2026) ─────── */
.kuehl { padding: 16px; display: grid; gap: 16px; }
.kuehl-kopf { display: flex; align-items: flex-end; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; }
.kuehl-ort { font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 4px; }
.kuehl-titel { font-size: 22px; font-weight: 700; margin: 0; letter-spacing: -.3px; }
.kuehl-notiz { color: var(--muted); font-size: 12.5px; margin: 4px 0 0; }
.kuehl-tuer { border: 0; font: inherit; font-size: 12.5px; min-height: 40px;
  padding: 8px 16px; border-radius: 999px; background: var(--surface);
  color: var(--ink); box-shadow: var(--schweben); cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px; }
.kuehl-tuer.offen { background: color-mix(in srgb, var(--warn) 16%, var(--surface));
  color: var(--warn); }
.kuehl-oben { display: grid; gap: 16px; grid-template-columns: minmax(0, 1.4fr) minmax(260px, .8fr); }
.kuehl-karte { background: var(--surface); border-radius: var(--r-karte, 20px);
  box-shadow: var(--schweben); padding: 20px; display: grid; gap: 16px; }
.kuehl-kartenkopf { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; font-size: 15px; font-weight: 650; }
.kuehl-chip { font-size: 11px; font-weight: 650; padding: 4px 12px; border-radius: 999px;
  background: color-mix(in srgb, var(--ok) 14%, var(--surface)); color: var(--ok); }
.kuehl-grad { font-size: 24px; font-weight: 700; color: var(--accent); }
.kuehl-kennzahlen { display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.kuehl-kennzahl { background: var(--bg); border-radius: 13px; padding: 12px;
  display: grid; gap: 4px; }
.kuehl-label { font-size: 11px; color: var(--muted); }
.kuehl-wert { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.kuehl-regler { width: 100%; accent-color: var(--accent); }
.kuehl-skala { display: flex; justify-content: space-between; font-size: 11px;
  color: var(--muted); }
.kuehl-tipp { margin: 0; font-size: 12.5px; color: var(--muted); background: var(--bg);
  border-radius: 13px; padding: 12px; }
.kuehl-filter { display: flex; gap: 6px; flex-wrap: wrap; }
.kuehl-zone { border: 0; font: inherit; font-size: 12.5px; min-height: 36px;
  padding: 6px 14px; border-radius: 999px; background: var(--bg); color: var(--muted);
  cursor: pointer; }
.kuehl-zone.an { background: var(--ink); color: var(--bg); font-weight: 650; }
.kuehl-gitter { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px; }
.kuehl-stueck { background: var(--bg); border-radius: 13px; padding: 14px; display: grid;
  gap: 4px; }
.kuehl-stueckkopf { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; font-size: 14px; }
.kuehl-zonenname { font-size: 11px; color: var(--muted); }
.kuehl-einkauf { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; background: var(--bg); border-radius: 13px; padding: 14px; }
.kuehl-liste { margin: 0; font-size: 13px; padding: 14px; border-radius: 13px;
  background: color-mix(in srgb, var(--accent) 12%, var(--surface)); color: var(--ink); }
.punkt.p-vorrat { background: var(--muted); }
@media (max-width: 900px) {
  .kuehl-oben { grid-template-columns: minmax(0, 1fr); }
  .kuehl-kennzahlen { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ===================================================================
   EINSTELLUNGEN (ea-*) — 16.08.2026
   ===================================================================

   Luca: "Das aktuelle Design gefaellt mir nicht, das ist sehr klobig
   und auch nicht verschachtelt, so wie du's beim Chat gemacht hast."

   Also dieselbe Sprache wie der Pillendialog im Chat — die Zeilen sind
   woertlich dieselben Bausteine (.pd-zeile, .pd-titel), damit sich
   "eine Ebene tiefer" ueberall gleich anfuehlt. Was hier dazukommt,
   ist nur der Rahmen und die Kachel.

   KEIN GLAS. Glas ist im KiLey-OS bewusst dem schwebenden Symbol
   vorbehalten; alles andere ist flaechig. Und keine Farbe: die Palette
   in Zeile 1 ist monochrom, Farbe bleibt den Zustaenden.

   Dunkel gehoert dazu und nicht als Nachtrag: die Werte stehen unten
   im selben Block, nicht verstreut. */

/* Der Rahmen: Vollbild aus dem Drawer. */
.ea-voll {
  position: fixed; inset: 0; z-index: 60;
  display: flex; flex-direction: column;
  background: var(--bg);
  animation: ea-ein .16s ease-out;
}
@keyframes ea-ein { from { opacity: 0; transform: translateY(8px); } }

.ea-kopf {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: max(10px, env(safe-area-inset-top)) 16px 10px;
  border-bottom: 1px solid var(--line);
}
/* KLEINER UND DICKER (16.08.2026). Luca: „Bei den Einstellungen ist es
   wie zu klobig, die Schrift oben ist bisschen dicker und kleiner, also
   zum Beispiel jetzt Projekte."

   17px/600 war eine Ueberschrift. Ein Vollbildkopf ist aber keine
   Ueberschrift, sondern ein Schild: er sagt, wo man ist, und soll
   dabei nicht laut sein. 15px/650 mit etwas engerer Laufweite liest
   sich fester und nimmt weniger Platz. */
.ea-kopf > strong {
  font-size: 15px; font-weight: 650; letter-spacing: -.01em;
}
.ea-zu {
  border: 0; background: none; font: inherit; font-size: 14.5px;
  font-weight: 500; color: var(--txt-dim); cursor: pointer;
  padding: 8px 4px; min-height: 38px;
}
.ea-zu:hover { color: var(--txt); }

/* Der Zurueck-Weg im Projekte-Vollbild. Er steht LINKS an der Stelle
   des Titels: wer eine Ebene tiefer ist, braucht dort den Rueckweg,
   nicht die Wiederholung dessen, was er schon sieht. */
.pv-zurueck {
  border: 0; background: none; font: inherit; font-size: 15px;
  font-weight: 650; letter-spacing: -.01em; color: var(--txt);
  cursor: pointer; padding: 6px 2px; min-height: 38px;
  max-width: 70%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; text-align: left;
}
.pv-voll .ea-inhalt { padding: 12px 14px max(24px, env(safe-area-inset-bottom)); }

.ea-inhalt {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 8px 12px max(24px, env(safe-area-inset-bottom));
  -webkit-overflow-scrolling: touch;
}
/* Als Reiter liegt der Baum direkt im Panel — dort kommt der Abstand
   von der Seite, nicht vom Rahmen. */
#ki-einstellungen .ea-baum { max-width: 620px; }

/* Eine Kachel: ein Agent. Der Name ist die Zeile, darunter der Satz,
   der sagt WOFUER er da ist, darunter die haeufigen Griffe. */
.ea-kachel {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 4px 4px 10px; margin-bottom: 10px;
}
.ea-kachel > .pd-zeile { font-size: 16px; font-weight: 550; }
.ea-kachel > .blatt-erklaerung { padding: 0 14px 8px; }

.ea-pillen { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 10px; }
.ea-pille {
  border: 1px solid var(--line); background: var(--bg); color: var(--txt-dim);
  font: inherit; font-size: 12.5px; line-height: 1;
  padding: 8px 11px; border-radius: 999px; cursor: pointer;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ea-pille:hover { background: var(--bg-hover); color: var(--txt); }

/* Der erklaerende Satz. Er stand schon im Chef-Dialog im Markup und
   hatte NIE eine Regel — bis hierher lief er als nackter Absatz mit
   Textgroesse des Fliesstexts mit. */
.blatt-erklaerung {
  font-size: 12.5px; line-height: 1.45; color: var(--txt-dim);
  padding: 2px 14px 8px;
}
.blatt-erklaerung.ea-warn { color: var(--run); }

/* Knoepfe: einer traegt, die anderen tragen nicht. */
.ea-leiste { display: flex; flex-wrap: wrap; gap: 8px; padding: 6px 14px 4px; }
.ea-knopf {
  border: 1px solid var(--line); background: var(--bg); color: var(--txt);
  font: inherit; font-size: 14px; font-weight: 500;
  min-height: 38px; padding: 0 16px; border-radius: 999px; cursor: pointer;
}
.ea-knopf:hover { background: var(--bg-hover); }
.ea-knopf.haupt { background: var(--ink); border-color: var(--ink); color: #fff; }
.ea-knopf.haupt:hover { opacity: .88; }
.ea-knopf.warnend { color: var(--err); border-color: var(--err); }

/* Eine Zahl mit ihrer Einheit. */
.ea-zahlzeile { display: flex; align-items: center; gap: 10px; padding: 6px 14px; }
.ea-zahl {
  width: 8.5em; font: inherit; font-size: 15px;
  font-variant-numeric: tabular-nums;
  padding: 9px 12px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--bg); color: var(--txt);
}
.ea-zahlzeile > span { font-size: 13px; color: var(--txt-dim); }

/* Die Zahlen des Gedaechtnisses. Zwei Spalten, Ziffern untereinander. */
.ea-zahlen {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 16px;
  padding: 4px 14px 8px;
}
.ea-zahlen > dt { font-size: 13.5px; color: var(--txt-dim); }
.ea-zahlen > dd {
  font-size: 13.5px; font-variant-numeric: tabular-nums; text-align: right;
}

/* Das Bearbeitungsfeld. Monospace, weil hier Einrueckung Bedeutung
   traegt, und hoch genug, dass man einen Absatz im Ganzen sieht. */
.ea-text {
  display: block; width: calc(100% - 28px); margin: 4px 14px 10px;
  min-height: 52vh; resize: vertical;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; line-height: 1.55;
  padding: 12px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--bg-soft); color: var(--txt);
}

/* Die Vorschau. Kein zweites Schriftbild erfinden — es ist derselbe
   Text, nur gesetzt. */
.ea-vorschau { padding: 2px 14px 12px; font-size: 14px; line-height: 1.6; }
.ea-vorschau h2 { font-size: 17px; margin: 14px 0 6px; }
.ea-vorschau h3 { font-size: 15px; margin: 12px 0 4px; }
.ea-vorschau h4 { font-size: 13.5px; margin: 10px 0 4px; color: var(--txt-dim); }
.ea-vorschau p { margin: 0 0 8px; }
.ea-vorschau ul { margin: 0 0 8px; padding-left: 20px; }
.ea-vorschau li { margin-bottom: 3px; }
.ea-vorschau blockquote {
  margin: 0 0 8px; padding-left: 12px; color: var(--txt-dim);
  border-left: 2px solid var(--line);
}
.ea-vorschau code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .88em; background: var(--bg-soft); padding: 1px 5px;
  border-radius: 6px;
}
.ea-vorschau pre {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; line-height: 1.5; background: var(--bg-soft);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 12px; margin: 0 0 8px; overflow-x: auto;
}

/* KEIN DUNKELBLOCK, UND DAS IST ABSICHT. Dieses Dashboard definiert
   seine Tokens nur einmal (Zeile 4) — es ist eine bewusst helle,
   monochrome Oberflaeche. Die beiden vorhandenen dark-Bloecke gelten
   dem Glas-Dialog, der mit festen Farbwerten arbeitet und deshalb
   umschalten MUSS. Wer hier einen dritten anlegt, faerbt Flaechen um,
   deren Grund sich nicht mitfaerbt: ein weisser Knopf auf weissem
   Grund. Erst die Tokens, dann die Bloecke. */

/* Die Meldung des Rahmens. Ein Knopf, weil man sie wegtippen koennen
   muss: sie steht ueber allem, bis der Nutzer sie gesehen hat. */
.ea-meldung {
  display: block; width: 100%; text-align: left; cursor: pointer;
  font: inherit; font-size: 13px; line-height: 1.45;
  color: var(--err); background: var(--bg-soft);
  border: 1px solid var(--err); border-radius: 12px;
  padding: 10px 14px; margin: 4px 0 10px;
}

/* Kein Weiterreichen des Scrollens an die Seite: wer im Gespraech am
   Ende ankommt, soll nicht den Rahmen darunter mitziehen. Zusammen mit
   dem scrollTo in app.js ist das der zweite Riegel gegen die
   verrutschte Seite bei offener Tastatur. */
.chat-scroll { overscroll-behavior: contain; }

/* Der atmende Punkt bekommt eine Stimme. Die Zeile sagt, WORAN der
   Chef gerade ist ("liest eine Datei"); sie kommt aus dem, was Hermes
   ohnehin protokolliert. Leise gesetzt — sie ist ein Lebenszeichen,
   keine Antwort. */
.bubble.denkt { display: flex; align-items: center; gap: 10px; }
.denkt-text {
  font-size: 13.5px; color: var(--txt-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Ein abgeschalteter Agent bleibt sichtbar, aber leise: er ist eine
   Entscheidung, kein Loch in der Liste. */
.ea-kachel.aus { opacity: .55; }
.ea-textzeile {
  flex: 1; min-width: 0; font: inherit; font-size: 15px;
  padding: 9px 12px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--bg); color: var(--txt);
}

/* Eine Meldung, die KEIN Fehler ist. Vorher war jede rot — "Gesichert
   und committet" sah aus wie ein Absturz. Wer Erfolg und Fehlschlag
   gleich faerbt, macht die Farbe wertlos. */
.ea-meldung.gut { color: var(--ok); border-color: var(--ok); }
/* Eine Zeile, die nur zeigt: kein Knopf, kein Pfeil, kein Tippziel. */
.ea-feste-zeile {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; font-size: 15px; color: var(--txt);
}
.ea-feste-zeile > span { flex: 1; min-width: 0; }
.ea-feste-zeile > em {
  font-style: normal; font-size: 13.5px; color: var(--txt-dim);
}

/* ============================================================
   FÄCHER UND PIPELINE  (16.08.2026)

   Luca hatte drei Entwürfe zur Wahl und nahm C: „ich will C
   Fächer." Der Grund steht im Entwurf selbst — die Liste ist
   zweitrangig, die Abhängigkeit ist das Bild. Man sieht, WARUM
   drei gleichzeitig liefen und warum eine nicht darf.

   Und: *„mir ist es wichtig, dass ich sehe, was die grade machen
   auf den einzelnen Seiten … was das Prompt war, was da rauskam."*
   Deshalb trägt jede Stufenzeile ihren Agenten, ihr Modell und
   ihr Ergebnis — nicht nur einen Zustandspunkt.
   ============================================================ */
:root {
  --fa-linie: #c6ccd4;
  --fa-akzent: #0e6b66;      /* fertig */
  --fa-warm: #b4541f;        /* läuft / beanstandet */
  --fa-halt: #6b5ba8;        /* blocked — wartet auf einen Menschen */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --fa-linie: #2a3038;
    --fa-akzent: #4fb3ac;
    --fa-warm: #e08b54;
    --fa-halt: #a394e0;
  }
}
:root[data-theme="dark"] {
  --fa-linie: #2a3038; --fa-akzent: #4fb3ac;
  --fa-warm: #e08b54; --fa-halt: #a394e0;
}

.fa-strang { position: relative; padding-left: 26px; }
.fa-strang::before {
  content: ""; position: absolute; left: 7px; top: 10px; bottom: 14px;
  width: 1px; background: var(--fa-linie);
}
.fa-knoten {
  position: relative; padding: 0 0 20px; display: block; width: 100%;
  text-align: left; background: none; border: 0; cursor: pointer;
}
.fa-knoten::before {
  content: ""; position: absolute; left: -23px; top: 6px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--bg); border: 2px solid var(--fa-linie);
}
.fa-knoten.z-fertig::before,
.fa-knoten.z-complete::before {
  background: var(--fa-akzent); border-color: var(--fa-akzent);
}
.fa-knoten.z-laeuft::before,
.fa-knoten.z-running::before {
  border-color: var(--fa-warm); border-width: 3px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--fa-warm) 18%, transparent);
}
.fa-knoten.z-rot::before,
.fa-knoten.z-failed::before {
  background: var(--fa-warm); border-color: var(--fa-warm);
}
.fa-knoten.z-blocked::before {
  background: var(--fa-halt); border-color: var(--fa-halt);
}
.fa-knoten.z-skipped::before { opacity: .45; }
.fa-knoten b { font-weight: 600; letter-spacing: -.01em; font-size: 14.5px;
               display: block; }
.fa-knoten .fa-wort { color: var(--txt-dim); font-size: 12.5px; margin-top: 2px; }
.fa-knoten .fa-wort .hebt { color: var(--fa-warm); font-weight: 600; }
.fa-knoten .fa-wort .haelt { color: var(--fa-halt); font-weight: 600; }
.fa-knoten .fa-notiz {
  margin-top: 6px; font-size: 11.5px; color: var(--txt-dim);
  font-family: ui-monospace, Menlo, monospace; font-variant-numeric: tabular-nums;
}
.fa-knoten:hover b { text-decoration: underline; text-underline-offset: 2px; }
.fa-faecher {
  margin-left: 14px; padding-left: 20px;
  border-left: 1px dashed var(--fa-linie);
}
.fa-faecher .fa-knoten::before { left: -27px; }
.fa-gabel {
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--txt-dim); margin: 2px 0 10px 14px;
}

/* Die Stufenleiste der Detailseite. Kein Fortschrittsbalken: ein
   Balken sagt „wie weit", diese Zeilen sagen „wer, womit, was kam
   raus" — das war die Frage. */
.fa-stufen { display: flex; flex-direction: column; }
.fa-stufe {
  /* minmax(0, 1fr) statt 1fr: eine Rasterspalte ist von Haus aus
     mindestens so breit wie ihr laengster unteilbarer Inhalt — ein
     Bauagentenbericht in Monospace schoebe die ganze Seite
     waagerecht. Ein Test bewacht das. */
  display: grid; grid-template-columns: 10px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: start; padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.fa-stufe:last-child { border-bottom: 0; }
.fa-stufe > .fa-punkt {
  width: 10px; height: 10px; border-radius: 50%; margin-top: 5px;
  border: 2px solid var(--fa-linie); background: var(--bg);
}
.fa-stufe.z-complete > .fa-punkt { background: var(--fa-akzent); border-color: var(--fa-akzent); }
.fa-stufe.z-running > .fa-punkt {
  border-color: var(--fa-warm); border-width: 3px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--fa-warm) 18%, transparent);
}
.fa-stufe.z-failed > .fa-punkt { background: var(--fa-warm); border-color: var(--fa-warm); }
.fa-stufe.z-blocked > .fa-punkt { background: var(--fa-halt); border-color: var(--fa-halt); }
.fa-stufe.z-skipped { opacity: .5; }
.fa-stufe.unter { padding-left: 22px; }
.fa-stufe .fa-name { font-weight: 600; font-size: 14px; letter-spacing: -.01em; }
.fa-stufe .fa-wer { color: var(--txt-dim); font-size: 12px; margin-top: 2px; }
.fa-stufe .fa-was { color: var(--txt-dim); font-size: 12.5px; margin-top: 4px; }
.fa-stufe .fa-was b { color: var(--txt); font-weight: 600; }
.fa-stufe .fa-rechts {
  text-align: right; font-size: 11.5px; color: var(--txt-dim);
  font-family: ui-monospace, Menlo, monospace; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.fa-mehr {
  margin-top: 6px; font-size: 12px; color: var(--txt-dim);
  background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: 8px; padding: 8px 10px; white-space: pre-wrap;
  font-family: ui-monospace, Menlo, monospace; overflow-x: auto;
}
.fa-jetzt {
  border-left: 3px solid var(--fa-warm); padding-left: 11px;
  margin-left: -3px; background: color-mix(in srgb, var(--fa-warm) 5%, transparent);
}
.fa-kopf { display: flex; gap: 8px; align-items: baseline; }
.fa-griff {
  flex: none; color: var(--txt-faint); cursor: grab; line-height: 0;
  padding-top: 2px;
}
.fa-griff:active { cursor: grabbing; }
.fa-griff .ic { width: 15px; height: 15px; }

/* ============================================================
   KILEY OS — PROJEKTE, AGENTEN, RUNS
   ============================================================
   Eigene Sprache, bewusst NICHT die der KI-Seite. Am 16.08.2026
   hatte ich deren Karten (`kip-karte`, `Panel()`, `kip-grid`) in
   diesen Rahmen gezogen; der Nutzer: „Du hast die Logiken
   vermischt … da sind so Karten im Hintergrund, wir haben nichts
   auf Karten."

   ABER NICHT FLACH ALS DOGMA. Nachtrag desselben Tages: „Es ist
   nicht ganz flach, wir haben schon Glasmorphismus in so kleinen
   Icons oder Symbolen — orientier dich am Chat. Und Karten haben wir
   schon, aber halt neue Karten … nicht im Hintergrund, sondern zum
   Beispiel eine Grafik oder eine Statistik, aber halt clean,
   ordentlich, schön platziert … kann auch mal eine dunkle Fläche
   sein, so eine Pille. Diese Details machen's aus. Nicht überall."

   Also:
     * LISTEN sind flach — Haarlinien und Weißraum, keine Kästen.
       Eine Liste in Kacheln zerfällt in Einzelteile, die man nicht
       mehr überfliegen kann.
     * GLAS gibt es an den kleinen schwebenden Symbolen, genau wie im
       Chat (`.kos-schwebt`): Menü, Plus, Aktion.
     * EINE KARTE trägt eine Zahl oder eine Grafik — nie eine Liste.
       Sie steht mittig im Satzspiegel, nicht angeklebt, und sie ist
       selten. Zwei Karten nebeneinander sind schon eine zu viel.
     * EINE PILLE trägt einen einzelnen Zustand oder eine Zahl, dunkel
       auf hell. Sie ist der einzige Ort mit Farbfläche.
     * Zahlen tabellarisch, damit Spalten stehen.
     * Überschriften klein und fest, nicht groß und dünn.
   ============================================================ */

.os-flaeche { display: flex; flex-direction: column; gap: 26px; }

/* Die Abschnittsmarke: „PROJEKTE", „AGENTEN", „RUNS". Klein, gesperrt,
   leise — sie ordnet, sie ruft nicht. */
.os-marke {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; padding: 0 0 8px;
  border-bottom: 1px solid var(--line);
}
.os-marke > b {
  font-size: 11px; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--txt-dim);
}
.os-marke > span {
  font-size: 12px; color: var(--txt-faint);
  font-variant-numeric: tabular-nums;
}

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

/* Eine Zeile: Punkt · Text · Zahlen. Als Knopf, wenn sie irgendwohin
   führt — dann bekommt sie beim Zeigen einen Untergrund, nie einen
   Rahmen. */
.os-zeile {
  display: grid; grid-template-columns: 12px minmax(0, 1fr) auto;
  gap: 12px; align-items: baseline; width: 100%;
  border: 0; background: none; font: inherit; color: inherit;
  text-align: left; cursor: default;
  padding: 12px 8px; border-bottom: 1px solid var(--line);
  border-radius: 8px;
}
.os-liste > .os-zeile:last-child { border-bottom: 0; }
button.os-zeile { cursor: pointer; }
button.os-zeile:hover { background: var(--bg-soft); }
.os-zeile.tief { padding-left: 26px; }
.os-zeile.tief > .os-punkt { margin-left: -18px; }

.os-punkt {
  width: 9px; height: 9px; border-radius: 50%; align-self: start;
  margin-top: 6px; border: 2px solid var(--fa-linie); background: var(--bg);
}
.os-zeile.z-fertig > .os-punkt,
.os-zeile.z-complete > .os-punkt {
  background: var(--fa-akzent); border-color: var(--fa-akzent);
}
.os-zeile.z-laeuft > .os-punkt,
.os-zeile.z-running > .os-punkt {
  border-color: var(--fa-warm); border-width: 3px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--fa-warm) 16%, transparent);
}
.os-zeile.z-failed > .os-punkt,
.os-zeile.z-rot > .os-punkt {
  background: var(--fa-warm); border-color: var(--fa-warm);
}
.os-zeile.z-blocked > .os-punkt {
  background: var(--fa-halt); border-color: var(--fa-halt);
}
.os-zeile.z-frei > .os-punkt { border-color: var(--line); }
.os-zeile.z-skipped { opacity: .45; }

.os-name { font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.os-zeile.tief .os-name { font-size: 14px; font-weight: 550; }
.os-unter {
  font-size: 12.5px; color: var(--txt-dim); margin-top: 2px;
  overflow-wrap: anywhere;
}
.os-unter .hebt { color: var(--fa-warm); font-weight: 600; }
.os-unter .haelt { color: var(--fa-halt); font-weight: 600; }
.os-rechts {
  text-align: right; white-space: nowrap;
  font-size: 12px; color: var(--txt-dim);
  font-variant-numeric: tabular-nums;
}
.os-rechts b { display: block; font-size: 14px; color: var(--txt);
               font-weight: 600; }

/* Die Zeit- und Zahlenzeile unter einem Eintrag. Monospace, weil
   darin Pfade und Zahlen stehen, die untereinander lesbar bleiben
   sollen. */
.os-zahlen {
  margin-top: 5px; font-size: 11.5px; color: var(--txt-faint);
  font-family: ui-monospace, Menlo, monospace;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}

/* Der Plan eines Agenten — seine eigene Todo-Liste. Keine Balken:
   die Punkte selbst sind die Auskunft. */
.os-plan { margin-top: 8px; display: flex; flex-direction: column; gap: 3px; }
.os-plan > div { font-size: 12.5px; color: var(--txt-dim);
                 display: flex; gap: 8px; }
.os-plan > div > i { font-style: normal; width: 12px; flex: none; }
.os-plan > div.fertig { color: var(--txt-faint); }
.os-plan > div.jetzt { color: var(--txt); font-weight: 550; }

/* Ein Block Rohtext: Prompt, Bericht, Prüflaufausgabe. Er scrollt in
   sich, damit die Seite nie waagerecht läuft. */
.os-roh {
  margin-top: 8px; font-size: 12px; color: var(--txt-dim);
  background: var(--bg-soft); border-radius: 8px; padding: 10px 12px;
  white-space: pre-wrap; overflow-x: auto;
  font-family: ui-monospace, Menlo, monospace;
  max-height: 46vh; overflow-y: auto;
}
.os-falt { border-bottom: 1px solid var(--line); }
.os-falt > summary {
  cursor: pointer; padding: 11px 8px; font-size: 13px; font-weight: 600;
  color: var(--txt-dim); list-style: none;
}
.os-falt > summary::-webkit-details-marker { display: none; }
.os-falt > summary::before { content: "▸ "; color: var(--txt-faint); }
.os-falt[open] > summary::before { content: "▾ "; }
.os-falt > .os-roh { margin: 0 8px 12px; }

.os-leer {
  padding: 18px 8px; font-size: 13px; color: var(--txt-faint);
}

/* DIE KARTE. Sie trägt eine Zahl oder eine Grafik — nie eine Liste.
   Glas wie die schwebenden Symbole im Chat, damit sie zur selben
   Familie gehört, aber ruhiger: weniger Blur, kein Schlagschatten
   nach außen. */
.os-karte {
  border-radius: 16px; padding: 18px 20px;
  background: rgba(255,255,255,.62);
  -webkit-backdrop-filter: saturate(170%) blur(16px);
  backdrop-filter: saturate(170%) blur(16px);
  border: 1px solid rgba(255,255,255,.8);
  box-shadow: 0 1px 0 rgba(255,255,255,.7) inset,
              0 2px 10px rgba(0,0,0,.05);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .os-karte {
    background: rgba(38,38,42,.6); border-color: rgba(255,255,255,.10);
    box-shadow: 0 1px 0 rgba(255,255,255,.06) inset,
                0 2px 10px rgba(0,0,0,.3);
  }
}
:root[data-theme="dark"] .os-karte {
  background: rgba(38,38,42,.6); border-color: rgba(255,255,255,.10);
}

/* Die Kennzahlen darin: gleich breit, mittig, mit Haarlinien
   getrennt. Balance statt links angeklebt. */
.os-zahlenreihe {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(72px, 1fr));
  gap: 0;
}
.os-zahl {
  text-align: center; padding: 2px 10px;
  border-right: 1px solid var(--line);
}
.os-zahl:last-child { border-right: 0; }
.os-zahl > b {
  display: block; font-size: 26px; font-weight: 600; letter-spacing: -.03em;
  line-height: 1.05; font-variant-numeric: tabular-nums;
}
.os-zahl > span {
  display: block; margin-top: 5px; font-size: 10.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--txt-dim);
}
.os-zahl.hebt > b { color: var(--fa-warm); }
.os-zahl.haelt > b { color: var(--fa-halt); }

/* DIE PILLE. Dunkel auf hell, der einzige Ort mit Farbfläche. Für
   genau eine Auskunft — „Risiko ROT", „5/7", „main geschützt". */
.os-pille {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em;
  background: var(--ink); color: var(--bg);
  font-variant-numeric: tabular-nums;
}
.os-pille.stumm { background: var(--bg-soft); color: var(--txt-dim); }
.os-pille.warm { background: var(--fa-warm); color: #fff; }
.os-pille.halt { background: var(--fa-halt); color: #fff; }
.os-pille.gut  { background: var(--fa-akzent); color: #fff; }

/* RFID-Kartei (ki-rfid.js): dieselbe flache Form wie KiLey OS,
   dazu Eingabefelder im Stil des Formular-Rasters. */
.rfid-feld { margin: 14px 0 4px; }
.rfid-eingabe {
  width: 100%; border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 11px; background: var(--bg); color: var(--txt);
  font: inherit; outline: none;
}
.rfid-eingabe:focus { border-color: var(--ink); }
textarea.rfid-eingabe { resize: vertical; min-height: 72px; }
.rfid-eingabe.mono {
  font-family: ui-monospace, Menlo, monospace; font-size: 12px;
}
.rfid-eingabe:disabled { color: var(--txt-faint); background: var(--bg-soft); }
.rfid-block {
  display: flex; gap: 8px; align-items: center;
  padding: 4px 0;
}
.rfid-blocknr {
  min-width: 30px; text-align: right;
  color: var(--txt-faint); font-variant-numeric: tabular-nums;
  font-size: 12px;
}
.rfid-lage { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.rfid-knoepfe { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.rfid-status { margin-top: 8px; min-height: 1.2em; }

/* Ein schwebendes Symbol IN der Fläche — dieselbe Glasfamilie wie
   Menü und Plus im Chat, nur kleiner. Für „Neue Runde" und
   dergleichen. */
.os-tat {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 14px 7px 11px; border-radius: 999px;
  font-size: 13.5px; font-weight: 550; color: var(--txt); cursor: pointer;
  background: rgba(255,255,255,.72);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid rgba(255,255,255,.85);
  box-shadow: 0 1px 0 rgba(255,255,255,.7) inset,
              0 6px 20px rgba(0,0,0,.10);
}
.os-tat .ic { width: 16px; height: 16px; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .os-tat {
    background: rgba(32,32,36,.78); border-color: rgba(255,255,255,.14);
  }
}
:root[data-theme="dark"] .os-tat {
  background: rgba(32,32,36,.78); border-color: rgba(255,255,255,.14);
}
.os-kopfrechts { display: flex; align-items: center; gap: 8px; }
.kos-rechtsgruppe { display: flex; align-items: center; gap: 8px; }

/* ============ DASHBOARD-KARTEN (Übersicht) ============
   Projekte als Dinge, nicht als Zeilen. Dezentes Glas nur auf der
   Kopfkarte (os-karte); die Projekt-Karten sind ruhig und flach,
   damit die Seite nicht schimmert wie eine Vitrine. */
.osd-gitter {
  display: grid; gap: 10px; padding-top: 12px;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
.osd-karte {
  display: flex; flex-direction: column; gap: 6px; text-align: left;
  font: inherit; color: inherit; cursor: pointer;
  padding: 14px 16px; border-radius: 16px;
  background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 1px 4px rgba(0,0,0,.04);
  transition: border-color .12s ease, transform .12s ease;
}
.osd-karte:hover { border-color: var(--txt-faint); transform: translateY(-1px); }
.osd-karte.lebt { border-color: color-mix(in srgb, var(--fa-warm) 45%, var(--line)); }
.osd-kopf { display: flex; align-items: center; justify-content: space-between;
            gap: 10px; }
.osd-kopf > b { font-size: 15.5px; font-weight: 650; letter-spacing: -.01em;
                min-width: 0; overflow: hidden; text-overflow: ellipsis;
                white-space: nowrap; }
.osd-was {
  font-size: 12.5px; color: var(--txt-dim); line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}
.osd-meta {
  font-size: 11px; color: var(--txt-faint);
  font-family: ui-monospace, Menlo, monospace;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.osd-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.osd-chip {
  font-size: 11.5px; font-weight: 600; padding: 4px 10px;
  border-radius: 999px; background: var(--bg-soft); color: var(--txt-dim);
  cursor: pointer;
}
.osd-chip:hover { background: var(--bg-hover); color: var(--txt); }
.osd-chip.lebt { background: var(--fa-warm); color: #fff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .osd-karte {
    background: rgba(255,255,255,.04); box-shadow: none;
  }
}
:root[data-theme="dark"] .osd-karte {
  background: rgba(255,255,255,.04); box-shadow: none;
}

/* ================= WORKFLOWS =================
   Der Ablauf als Graph, nicht als Liste. Dieselbe Familie wie
   os-karte (Glas, ruhig), aber eine eigene Form: eine Spine mit
   nummerierten Stationen, daran Karten. Mobile-first einspaltig;
   ab 900px liegt das Werkzeug rechts neben dem Ablauf. */

.wfg-titelkarte { display: flex; flex-direction: column; gap: 8px; }
.wfg-titelzeile { display: flex; align-items: center; gap: 10px; }
.wfg-name {
  font-size: 22px; font-weight: 650; letter-spacing: -.02em; margin: 0;
  font-family: ui-monospace, Menlo, monospace;
}
.wfg-was { font-size: 13.5px; color: var(--txt-dim); line-height: 1.45; }
.wfg-titelzahlen {
  display: flex; gap: 14px; font-size: 12px; color: var(--txt-faint);
  font-variant-numeric: tabular-nums;
}
.wfg-warnzahl { color: var(--fa-warm); font-weight: 600; }

.wfg-spalten { display: grid; gap: 26px; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) {
  .wfg-spalten { grid-template-columns: minmax(0, 1fr) 260px; }
  .wfg-werkzeug { position: sticky; top: 84px; align-self: start; }
}

/* Die Spine: Punkt-Spalte links, Karte rechts. */
.wfg { display: flex; flex-direction: column; padding-top: 14px; }
.wfg-schritt {
  display: grid; grid-template-columns: 34px minmax(0, 1fr);
  gap: 12px; align-items: stretch;
  border: 0; background: none; font: inherit; color: inherit;
  text-align: left; padding: 0; margin: 0;
}
.wfg-bearbeiten .wfg-schritt { cursor: pointer; }
.wfg-bearbeiten .wfg-schritt:hover .wfg-karte {
  border-color: var(--txt-faint);
}

.wfg-spur { display: flex; flex-direction: column; align-items: center; }
.wfg-punkt {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
  background: var(--bg-soft); color: var(--txt-faint);
  border: 2px solid var(--line);
}
.wfg-punkt.gut {
  background: var(--ink); color: var(--bg); border-color: var(--ink);
}
.wfg-punkt.fehlt {
  background: var(--fa-warm); color: #fff; border-color: var(--fa-warm);
}
.wfg-linie { flex: 1; width: 2px; background: var(--line); min-height: 14px; }

.wfg-karte {
  margin-bottom: 14px; padding: 12px 14px; border-radius: 14px;
  background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 1px 4px rgba(0,0,0,.04);
}
.wfg-kopf { display: flex; align-items: baseline; gap: 8px; }
.wfg-kopf > b { font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.wfg-kopf > code {
  font-size: 10.5px; color: var(--txt-faint);
  font-family: ui-monospace, Menlo, monospace;
}
.wfg-satz {
  margin-top: 3px; font-size: 12.5px; color: var(--txt-dim);
  line-height: 1.45;
}
.wfg-fuss {
  margin-top: 8px; display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}
.wfg-rolle { font-size: 12px; font-weight: 600; color: var(--txt); }
.wfg-rolle.fehlt { color: var(--fa-warm); }
.wfg-profil {
  font-size: 10.5px; padding: 2px 8px; border-radius: 999px;
  background: var(--bg-soft); color: var(--txt-dim);
  font-family: ui-monospace, Menlo, monospace;
}

/* Übersprungene Stufe im Bearbeiten-Modus: ausgegraut, gestrichelt. */
.wfg-aus .wfg-karte { border-style: dashed; background: transparent;
  box-shadow: none; opacity: .55; }
.wfg-aus .wfg-satz { display: none; }

/* Der Parallel-Fächer in der Bauen-Karte — die Bahnen selbst sagen
   es; keine Markierungslinie an der Kante. */
.wfg-bahnen { margin-top: 10px; display: flex; gap: 6px; flex-wrap: wrap; }
.wfg-bahn {
  font-size: 11px; font-weight: 600; padding: 4px 10px;
  border-radius: 8px; background: var(--bg-soft); color: var(--txt-dim);
  border: 1px dashed var(--line);
}

/* Das Werkzeug rechts (bzw. unten auf dem Telefon). */
.wfg-werkzeug { display: flex; flex-direction: column; gap: 10px; }
.wfg-werkzeug .os-tat { justify-content: center; }
.wfg-hilfe {
  font-size: 12px; color: var(--txt-faint); line-height: 1.5;
  padding-top: 4px;
}

/* Die Workflow-Karten in der Übersicht: ein Gitter, je Karte der
   Mini-Ablauf als Punktspur. */
.wfg-einleitung {
  font-size: 13px; color: var(--txt-dim); line-height: 1.5;
  padding: 2px 2px 0;
}
.wfg-gitter {
  display: grid; gap: 10px; padding-top: 12px;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.wfg-mini {
  display: flex; flex-direction: column; gap: 6px; text-align: left;
  font: inherit; color: inherit; cursor: pointer;
  padding: 13px 15px; border-radius: 14px;
  background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 1px 4px rgba(0,0,0,.04);
  transition: border-color .12s ease, transform .12s ease;
}
.wfg-mini:hover { border-color: var(--txt-faint); transform: translateY(-1px); }
.wfg-mini-kopf { display: flex; align-items: center; gap: 8px; }
.wfg-mini-kopf > b {
  font-size: 14px; font-weight: 650;
  font-family: ui-monospace, Menlo, monospace;
}
.wfg-mini-was {
  font-size: 12px; color: var(--txt-dim); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}
.wfg-mini-spur { display: flex; align-items: center; gap: 4px; margin-top: 2px; }
.wfg-mini-punkt {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ink); flex: none;
}
.wfg-mini-punkt.fehlt { background: var(--fa-warm); }
.wfg-mini-punkt.breit { width: 18px; border-radius: 4px; }
.wfg-mini.aus { opacity: .55; }
.wfg-mini.aus .wfg-mini-punkt { background: var(--txt-faint); }
.wfg-neu { border-style: dashed; background: transparent; box-shadow: none; }
.wfg-neu > b { font-family: inherit; color: var(--txt-dim); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wfg-karte,
  :root:not([data-theme="light"]) .wfg-mini {
    background: rgba(255,255,255,.04);
    box-shadow: none;
  }
  :root:not([data-theme="light"]) .wfg-neu { background: transparent; }
  :root:not([data-theme="light"]) .wfg-punkt.gut {
    background: var(--txt); color: var(--bg); border-color: var(--txt);
  }
  :root:not([data-theme="light"]) .wfg-mini-punkt { background: var(--txt); }
  :root:not([data-theme="light"]) .wfg-mini-punkt.fehlt { background: var(--fa-warm); }
}
:root[data-theme="dark"] .wfg-karte,
:root[data-theme="dark"] .wfg-mini {
  background: rgba(255,255,255,.04); box-shadow: none;
}
:root[data-theme="dark"] .wfg-punkt.gut {
  background: var(--txt); color: var(--bg); border-color: var(--txt);
}
:root[data-theme="dark"] .wfg-mini-punkt { background: var(--txt); }
:root[data-theme="dark"] .wfg-mini-punkt.fehlt { background: var(--fa-warm); }

/* --- Sprache & Stimmen: Anbieter-Karten (20.08.2026) ------------------ */
.sprach-karten { display: flex; flex-direction: column; gap: 10px; }
.sprach-karte { padding: 14px; }
.sprach-karte.aktiv { border: 1px solid var(--txt); }
.sprach-kopf { display: flex; align-items: baseline; gap: 8px;
  flex-wrap: wrap; }
.sprach-anbieter { color: var(--txt-dim); font-size: 13px; }
.sprach-badge { margin-left: auto; font-size: 12px; padding: 2px 8px;
  border-radius: 999px; background: var(--ink); color: var(--bg); }
.sprach-werte { margin-top: 6px; color: var(--txt-dim); font-size: 13px; }
.sprach-aktionen { display: flex; gap: 8px; flex-wrap: wrap;
  margin-top: 10px; }
.sprach-neu { display: flex; gap: 8px; align-items: center;
  flex-wrap: wrap; }
.sprach-neu select { max-width: 220px; }
.sprach-reglerwert { color: var(--txt-dim); font-size: 12px;
  margin-left: 6px; }
.sprach-bearbeiten { border: 1px dashed var(--line); }
