/* ===========================================================================
   AGORA — Liste und Detail
   ===========================================================================
   ALLE Farben stehen als Variablen auf :root und kommen zur Laufzeit vom Server
   (GET /api/me/oberflaeche → farben). Die Werte hier sind nur der Ausgangszustand,
   damit die Seite auch beim ersten Bild nicht weiss aufblitzt. Wer eine Farbe
   ändert, ändert EINE Variable — nicht zweihundert Regeln. Genau deshalb steht in
   diesem Blatt kein einziger fester Farbwert unterhalb von :root.

   Größe hängt an --os-skala (eine Wurzel). Listenbreite und Ecken bleiben
   eigene Variablen. Die alten data-dichte-Regeln sind gelöscht.
   =========================================================================== */

:root {
  /* die zehn Farbfelder aus src/oberflaeche.js — gleiche Namen, damit niemand
     zwischen Server und Blatt übersetzen muss (akzent_text → --akzent-text).

     Dunkelsatz von g-sv.eu (15.08.2026): warmes Papier statt kaltem Blaugrau.
     Gespeicherte Farben des Kontos gewinnen danach über Inline-Styles. */
  --hintergrund: #14110e;
  --flaeche:     #1e1a16;
  --text:        #f4efe6;
  --gedaempft:   #c9c0b2;
  --akzent:      #d4a24a;
  --akzent-text: #1a0f0c;
  --rahmen:      #3d352c;
  --gut:         #8fbfa8;
  --warn:        #f0c078;
  --schlecht:    #f0b4b4;

  /* abgeleitete Flächen: aus --flaeche und --text gemischt. So folgt jeder
     Hover-, Auswahl- und Codeblock-Ton automatisch der gewählten Farbe — auch
     bei einem hellen Thema, wo ein festes rgba(255,255,255,.06) unsichtbar wäre. */
  --flaeche-hoch: color-mix(in srgb, var(--flaeche) 88%, var(--text));
  --flaeche-tief: color-mix(in srgb, var(--flaeche) 60%, var(--hintergrund));
  --akzent-hauch: color-mix(in srgb, var(--akzent) 16%, transparent);
  --akzent-rand:  color-mix(in srgb, var(--akzent) 45%, var(--rahmen));
  --akzent-weich: color-mix(in srgb, var(--akzent) 14%, var(--hintergrund));
  --warn-grund:   color-mix(in srgb, var(--warn) 18%, var(--hintergrund));
  --schlecht-grund: color-mix(in srgb, var(--schlecht) 16%, var(--hintergrund));
  --gut-grund:    color-mix(in srgb, var(--gut) 16%, var(--hintergrund));
  --akzent-hover: color-mix(in srgb, var(--akzent) 78%, var(--text));
  --fokus: #8cb4ff;

  /* Formensprache g-sv.eu: System-Schrift im Fliesstext, Georgia in Ueberschriften.
     Abstaende, Haarlinie und Karteninnenraum kommen aus Variablen, damit Dichte
     und Ecken-Regler sie mitnehmen. */
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --serif: Georgia, "Iowan Old Style", Palatino, "Times New Roman", serif;
  --max: 68rem;
  --linie: 1px;
  --raster-abstand: calc(var(--luft) * 1.5);
  --karte-innen: calc(var(--luft) * 1.75);
  --karten-min: 21rem;
  --kachel-min: 17rem;
  --schrift-titel: 1.28em;
  --schrift-abschnitt: 1.05em;
  --schrift-klein: .86em;
  /* Zeichen in der Titelleiste: 22 px reichte nicht, das Motiv zu lesen.
     40 px ist dieselbe Kante wie .marke-zeichen auf der Anmeldekarte. */
  --kopf-zeichen: 40px;

  /* Das BLATT hinter einer Datei-Vorschau (T1-B, 25.08.2026). Bewusst KEIN
     Themafarbton: die Kachel zeigt das DOKUMENT, nicht die Oberfläche. Ein PDF
     und eine HTML-Seite bringen schwarze Schrift auf weissem Grund mit; läge
     dahinter --flaeche eines dunklen Themas, stünde schwarz auf schwarz.
     Gleiche Haltung und gleicher Ort wie beim Urteilskasten darunter: ein fester
     Wert gehört hierher als Variable, nicht als Hex mitten in eine Regel. */
  --blatt: #ffffff;

  /* Urteilskasten: feste Lesbarkeit, wenn die Nutzerpalette unlesbar ist.
     Werte stehen HIER in :root (Fehlerpaar von g-sv.eu), nicht als Hex darunter. */
  --urteil-grund: #3a1818;
  --urteil-text: #f0b4b4;
  --urteil-rand: #f0b4b4;
  --urteil-knopf: color-mix(in srgb, #f0b4b4 22%, #3a1818);
  --urteil-klein: color-mix(in srgb, #f0b4b4 78%, #f4efe6);

  /* Die Schiene trägt Symbol UND Wort — NEBENEINANDER, wie in der heutigen Oberfläche
     (/work/ui/ → `.sidebar`, 244 px). 58 px reichten für das Symbol allein, 86 px für
     ein winziges Wort DARUNTER; beides war zu eng. Owner 09.08.2026: „mach aber noch
     etwas breiter … und dass man die Nutzung richtig lesen kann — wie beim os 0".
     Die „Nutzung" ist der Auslastungs-Streifen an der Schiene (#ub-streifen,
     uebersicht.css), und der ist genau --schiene-knopf breit: 74 px waren zu wenig
     für „x von y", 204 px sind es nicht.

     --schiene-knopf ist absichtlich eine eigene Variable: der Balken am aktiven Knopf
     sitzt auf der halben Differenz zur Schienenbreite
     ((204 − 226) / 2 = −11 px, also genau auf der Schienenkante), und diese Rechnung
     soll man an EINER Stelle ändern können. Wer eine der beiden Zahlen anfasst, fasst
     die andere mit an — auch im eingeklappten Fall (body.schiene-schmal weiter unten
     setzt BEIDE neu: 64/46, Differenz −9 px).
     ⚠️ Beide MÜSSEN am selben Element deklariert werden. Stünde --schiene-knopf nur
     hier und body.schiene-schmal überschriebe allein --schiene, behielte der Knopf
     seinen an :root ausgerechneten Wert — Variablen werden dort aufgelöst, wo sie
     stehen, nicht dort, wo sie benutzt werden. */
  --schiene: 226px;
  --schiene-knopf: 204px;
  --listenbreite: 320px;
  --radius: 10px;
  --skala: 1;

  /* Eine Wurzel für Klein/Normal/Gross. Die drei Masse hängen daran,
     damit ein Wert alle Abstände und die Schrift mitnimmt. */
  --os-skala: 1;
  --zeile-y: calc(10px * var(--os-skala));
  --luft: calc(12px * var(--os-skala));
  --schrift: calc(14.5px * var(--os-skala));
  /* Fingerziel. Steht seit 08.08.2026 als Literale 44px in der schmalen
     Anordnung (WCAG 2.2 / Apple / Google). Hier als Name, damit die Modellwahl
     dieselbe Kante benutzt und nicht eine zweite Zahl erfindet. select.js
     verwies schon auf --tap, ohne dass sie hier stand. */
  --tap: 44px;

  /* DAS SYMBOL EINES CHATS (19.08.2026). Zwei Grössen, weil es an zwei Orten steht:
     in der Listenzeile klein neben dem Titel, auf der Startfläche gross in der Kachel.
     Eine Grösse für ein Bild-Symbol gab es hier bisher nicht — deshalb neu und nicht
     als nackte Zahl in die Regel geschrieben. Beide sind bewusst grob: das Bild wird
     genau dafür gemalt (src/chatbild.js), feine Details gäbe es dort ohnehin keine. */
  --chatbild: 26px;
  --chatbild-kachel: 40px;

  /* ————— DIE BEWEGUNG (M6) — ein Satz Zeiten und Kurven fuer alles —————
     Owner: „das gilt fuer alle Panel, ich will alle so animated haben live wie
     bei agora". Damit ist agora die Vorlage, und eine Vorlage braucht Zahlen, die
     man abschreiben kann. Hier stehen sie:
       schnell  120ms  Knopfdruck, Aufklappen, Hover — alles, was der Finger anstoesst
       normal   200ms  Karten, Wechsel innerhalb einer Ansicht
       langsam  400ms  Seitenwechsel, das Startbild
       kurve    cubic-bezier(.2,.8,.2,1) — schnell los, weich aus. Dieselbe Kurve
                wie in den Startbild-Videos: schwere Dinge, die ruhig zur Ruhe kommen
       versatz  40ms   je Karte, damit das Auge von oben links nach unten rechts folgt
     `--einfach` bleibt als Name bestehen (vier Fundstellen) und ist jetzt
     schlicht „schnell" — es stand ueberall dort, wo etwas auf eine Eingabe
     antwortet. Wer eine neue Regel schreibt, nimmt eine der drei Zeiten und
     erfindet keine vierte. */
  --schnell: 120ms;
  --normal:  200ms;
  --langsam: 400ms;
  --kurve:   cubic-bezier(.2, .8, .2, 1);
  --versatz: 40ms;
  --einfach: var(--schnell);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; height: 100%;
  background: var(--hintergrund); color: var(--text);
  font: var(--schrift)/1.55 var(--sans);
  -webkit-text-size-adjust: 100%;
}
h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 1.25;
  color: var(--text);
}
h1 { font-size: var(--schrift-titel); }
h2 { font-size: var(--schrift-abschnitt); }
h3 { font-size: 1em; }
body { overflow: hidden; }   /* gescrollt wird in der Liste und im Detail, nie die Seite */

.versteckt { display: none !important; }
.gedaempft { color: var(--gedaempft); }
.klein { font-size: var(--schrift-klein); }
.gut-text { color: var(--gut); }
.warn-text { color: var(--warn); }
.fehler { color: var(--schlecht); margin: .5em 0 0; }

a { color: var(--akzent); text-decoration: none; }
/* JEDE :hover-Regel in diesem Blatt steht in @media (hover: hover) — und zwar an
   ihrer alten Stelle, damit sich die Reihenfolge (und damit der Sieger bei gleicher
   Gewichtung) nicht verschiebt. WARUM: ein Finger hat keinen Zeiger, der irgendwo
   stehen bleibt. Chromium und Safari lassen den zuletzt angetippten Knopf im
   Hover-Zustand hängen; im Abzug vom 08.08. sass der helle Hover-Hintergrund auf
   einem Schienenknopf NEBEN dem wirklich gewählten — zwei Knöpfe sahen aus wie der
   aktive. Auf einem Gerät ohne Zeiger gibt es diesen Zustand jetzt gar nicht mehr. */
@media (hover: hover) { a:hover { text-decoration: underline; } }

:focus-visible { outline: 2px solid var(--fokus); outline-offset: 2px; }

/* ---------- Knöpfe und Felder ---------------------------------------------- */
button {
  font: inherit; cursor: pointer; color: var(--text);
  background: var(--flaeche-hoch); border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius); padding: .42em .8em;
  transition: background var(--einfach), border-color var(--einfach);
}
@media (hover: hover) { button:hover:not(:disabled) { border-color: var(--akzent-rand); } }
button:disabled { opacity: .45; cursor: not-allowed; }
button.haupt { background: var(--akzent); color: var(--akzent-text); border-color: transparent; width: 100%; padding: .6em; font-weight: 600; }
button.still { background: transparent; border-color: transparent; color: var(--gedaempft); }
@media (hover: hover) { button.still:hover { color: var(--text); background: var(--flaeche-hoch); } }
button.gefahr { color: var(--schlecht); }
@media (hover: hover) { button.gefahr:hover { border-color: var(--schlecht); } }
button.rund { display: grid; place-items: center; width: 2.1em; height: 2.1em; padding: 0; flex: 0 0 auto; }
/* 🔴 DER PLUS-KNOPF DARF NICHTS MALEN, WENN ER GEPARKT IST (Owner 05.09.2026, 23:48:
   „unten ist etwas defekt" — ein „+ Neuer Chat" hing unter dem Fensterrand).
   kopfSchieneOrdnen() (agora.js) setzt `hidden` und haengt den Knopf an <body>,
   damit letzte.js -> knopfNeu ihn nicht neu anlegt. `hidden` bringt aber nur die
   UA-Regel `[hidden] { display: none }` mit (0-1-0) — und `button.rund` eine Zeile
   darueber ist eine AUTOREN-Regel (0-1-1). Autor schlaegt UA IMMER, unabhaengig von
   der Spezifitaet. Der Knopf blieb also `display: grid`, stand als 30x30-Kasten HINTER
   `.app` (height: 100%) und machte das Dokument 30 px hoeher als das Fenster: erst der
   sichtbare Rest am unteren Rand, dann eine Seite, die ueberhaupt scrollen KANN — und
   damit den Kopf mit Zeichen und Wortmarke nach oben aus dem Bild schieben kann.
   Kennung + Attribut (1-1-0) schlaegt `button.rund` (0-1-1). Kein !important noetig. */
#btn-neuer-chat[hidden] { display: none; }

/* Symbolknöpfe: kein Kasten im Ruhezustand (Owner 29.08.). Die allgemeine
   Knopf-Regel setzt Fläche und Rahmen. `button:hover:not(:disabled)` (0-2-2)
   überstimmte `button.still:hover` (0-2-1) — nach dem Überfahren blieb ein
   heller Rahmen stehen. Tastatur-Fokus bleibt sichtbar (--fokus), weich und
   mit demselben Radius, nur bei :focus-visible, sonst hängt der Ring nach
   dem Klick. */
button.rund,
button.still {
  background: transparent;
  border-color: transparent;
}
@media (hover: hover) {
  button.rund:hover:not(:disabled),
  button.still:hover:not(:disabled),
  .schiene button:hover:not(:disabled) {
    border-color: transparent;
    background: var(--flaeche-hoch);
    color: var(--text);
  }
}
button.rund:focus,
button.still:focus,
.schiene button:focus {
  outline: none;
}
button.rund:focus-visible,
button.still:focus-visible,
.schiene button:focus-visible {
  outline: var(--linie) solid var(--fokus);
  outline-offset: var(--linie);
}

input, select, textarea {
  font: inherit; color: var(--text); background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen); border-radius: var(--radius); padding: .45em .6em;
  width: 100%;
}
/* Native <option>-Listen malt das OS weiss-blau. OSWahl (.wahl-liste) ersetzt
   das Popup; bleibt ein natives Feld (Team-Tafel, Rückfall ohne Skript),
   tragen die Optionen dieselbe Palette — kein eigener Hex. */
select option {
  background: var(--flaeche-hoch);
  color: var(--text);
}
select option:checked {
  background: var(--akzent-hauch);
  color: var(--akzent);
}
input[type="color"] { padding: 2px; height: 2.2em; cursor: pointer; }
input[type="checkbox"], input[type="radio"] { width: auto; accent-color: var(--akzent); }
input[type="range"] { accent-color: var(--akzent); padding: 0; border: 0; background: transparent; }
label { display: block; margin: .7em 0; color: var(--gedaempft); font-size: .88em; }
label > input, label > select, label > textarea { margin-top: .3em; color: var(--text); font-size: 1.06em; }

/* ---------- Anmeldung ------------------------------------------------------ */
.anmeldung { position: fixed; inset: 0; display: grid; place-items: center; padding: 20px; overflow: auto; }
.anmeldekarte {
  width: 100%; max-width: 380px; background: var(--flaeche);
  border: var(--linie) solid var(--rahmen); border-radius: calc(var(--radius) * 1.6); padding: var(--karte-innen);
}
.marke { display: flex; align-items: center; gap: 9px; font-size: 1.15em; font-weight: 600; margin-bottom: 18px; }
.marke small { color: var(--gedaempft); font-weight: 400; font-size: .7em; }
.marke-zeichen { width: 26px; height: 26px; color: var(--akzent); }
.anmeldekarte h2 { margin: 0 0 .3em; font-family: var(--serif); font-size: var(--schrift-titel); font-weight: 600; }

/* ---------- Die Schale ----------------------------------------------------- */
/* grid-template-rows: minmax(0, 1fr) — DIE Zeile, ohne die auf dem breiten Bildschirm
   die ganze SEITE wächst statt der Liste. Bis zum 08.08.2026 stand hier nur
   `height: 100%` und keine Zeilen-Angabe: die eine Zeile war damit implizit `auto`,
   und eine auto-Zeile wird von ihrem Inhalt aufgeblasen — `height: 100%` begrenzt nur
   den Kasten, nicht die Zeile darin. Gemessen bei 1440×900, Owner-Sitzung:
     #/projekte (83 Zeilen)                  → documentElement.scrollHeight 5471
     #/tools (21)                            → 2169
     Themen-Doc „ki-historie" (294 118 Zch.) → 68 796
   Weder #liste noch #detail war dabei ein Scroll-Behälter (scrollHeight === clientHeight),
   und weil `body { overflow: hidden }` das Fenster-Scrollen abschaltet, lagen „Einstellungen"
   und „Admin" der Schiene tausende Pixel UNTER dem Bildschirmrand — unerreichbar.
   `minmax(0, 1fr)` statt `1fr`: die Null als min-Wert nimmt den Grid-Kindern zugleich ihre
   automatische Mindesthöhe (CSS-Grid §6.6 — die greift nur bei einer auto-Mindestspur),
   sonst schöbe der Inhalt die Spalten wieder auf. Die schmale Anordnung (unten) und der
   1500-px-Block setzen nur `grid-template-columns` neu; diese Zeilenregel gilt dort weiter. */
/* ---------- Die Anwendung: Kopf oben, Schale darunter ---------------------
   DIESELBE MASSNAHME WIE IN .schale, und zwar aus demselben Grund: `minmax(0, 1fr)`
   nimmt der zweiten Rasterzeile ihre automatische Mindesthöhe. Stünde hier `1fr`,
   schöbe ein langes Themen-Doc die Schale wieder über den Bildschirmrand hinaus —
   genau der Fehler, der am 08.08.2026 in os2 repariert wurde (68 796 px). Der Kopf
   selbst ist `auto`: er ist genau so hoch wie die Zeile, die er trägt. */
.app {
  display: grid;
  /* DREI Zeilen, und jedes Kind bekommt seinen Platz ausdruecklich zugewiesen.
     WARUM: `uebersicht.js` haengt die Limit-Warnung mit `kopf.after(kasten)` als
     ZWEITES Kind ein. Mit nur zwei Zeilen (`auto minmax(0,1fr)`) schnappte sich der
     Warnkasten damit die flexible Zeile — er wurde bildschirmhoch, und die eigentliche
     App rutschte in eine stillschweigend angelegte Zeile darunter, halb aus dem Bild.
     Gemeldet vom Owner am 30.08.2026 („das ganze Layout ist defekt, ich kann nichts
     mehr freigeben"), sichtbar als olivgruener Block ueber der halben Seite.
     Ausdrueckliche Plaetze wirken auch dann, wenn der Kasten `display:none` ist —
     ein verstecktes Rasterkind legt keine Zeile an. */
  grid-template-rows: auto auto minmax(0, 1fr);
  height: 100%;
}
.app > .kopf { grid-row: 1; }
.app > #limit-warnung { grid-row: 2; }
.app > .schale { grid-row: 3; }

.kopf {
  display: flex; align-items: center; gap: calc(var(--luft) * 0.7);
  padding: calc(var(--luft) * 0.5) var(--luft);
  border-bottom: var(--linie) solid var(--rahmen); background: var(--flaeche-tief);
  padding-top: calc(var(--luft) * 0.5 + env(safe-area-inset-top));
}
/* `.kopf-marke` lebt wieder: Logo + Wort in der Titelleiste, daneben die
   Symbolreihe (#schiene-kopf). */
.kopf-rechts { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
#kopf-konto { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 22vw; }

/* Die Zeile. Breit steht sie mittig und begrenzt — eine 2000 px breite Suchzeile
   liest sich schlechter als eine, die so breit ist wie das, was darunter steht. */
.zeile-box {
  position: relative; display: flex; align-items: center;
  flex: 1 1 auto; min-width: 0; max-width: 780px; margin: 0 auto;
}
.zeile-box > svg { position: absolute; left: 10px; color: var(--gedaempft); pointer-events: none; }
.zeile-box input { padding-left: 32px; padding-right: 84px; width: 100%; }
/* Die Zeile trägt einen Schrägstrich → sie ist eine BEFEHLSzeile. Das sieht man,
   bevor man Enter drückt: der Rahmen nimmt die Akzentfarbe an. */
.zeile-box.befehl input { border-color: var(--akzent-rand); }
.zeile-leer {
  position: absolute; right: 60px; display: grid; place-items: center;
  width: 1.7em; height: 1.7em; padding: 0; border-color: transparent;
  background: transparent; color: var(--gedaempft);
}
.zeile-kbd {
  position: absolute; right: 8px; pointer-events: none;
  font-size: .72em; color: var(--gedaempft); border: var(--linie) solid var(--rahmen);
  border-radius: 5px; padding: 1px 5px; background: var(--flaeche);
}

/* DIE LISTE SCHRUMPFT MIT, STATT DAS DETAIL AUFZUFRESSEN.
   ---------------------------------------------------------------------------
   Gemessen am 09.08.2026: bei einem 900 px breiten Fenster nehmen Schiene (226)
   und Liste (320) zusammen 546 px — dem Detail bleiben 294 px Inhalt. Das ist
   genau der Bereich zwischen „schmal" (≤860 px, dort liegen Liste und Detail
   ohnehin übereinander) und „breit", und dort nutzte den Platz keiner von beiden:
   die Liste hatte mehr, als sie braucht, das Detail zu wenig, um etwas zu zeigen.
   Owner 09.08.: „ich will, dass der Platz effizient genutzt wird!"
   `clamp` statt einer Medienabfrage: 26 % der Fensterbreite, nach unten bei 232 px
   gebremst (darunter bricht ein Chattitel mit Zeitangabe um) und nach oben bei
   --listenbreite, dem eingestellten Wert. Ab rund 1230 px ist die Liste damit
   wieder ihre vollen 320 px breit — es verändert sich also NUR der Bereich, in dem
   es klemmte. Die Einstellbarkeit bleibt: wer --listenbreite ändert, verschiebt
   die Obergrenze mit. */
.schale {
  display: grid;
  grid-template-columns:
    var(--schiene)
    clamp(232px, 26vw, var(--listenbreite))
    minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  height: 100%;
}

.schiene {
  display: flex; flex-direction: column; align-items: center;
  gap: calc(var(--luft) * 0.35);
  padding: var(--luft) 0;
  background: var(--flaeche-tief);
  border-right: var(--linie) solid var(--rahmen);
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--akzent) 35%, var(--rahmen)) transparent;
}
/* Marke MIT Schriftzug, wie in /work/ui/ (`.side-brand`). Sie ist aria-hidden — der
   Name der Anwendung steht im <title>, ein Vorleseprogramm braucht ihn nicht zweimal.
   Eingeklappt bleibt nur das Zeichen stehen. */
.schiene-marke {
  display: flex; align-items: center; gap: 9px;
  width: var(--schiene-knopf); padding: 4px 10px 0;
  color: var(--akzent); margin-bottom: var(--luft); opacity: 1;
}
.schiene-marke-wort {
  font-family: var(--serif); font-size: 1.02em; font-weight: 600; letter-spacing: -.02em; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.schiene-gruppe { display: flex; flex-direction: column; gap: calc(var(--luft) * 0.25); width: 100%; align-items: center; }

/* Kopfzeile in #kopf: Logo · Lupe · neuer Chat. Einklappen gehört neben
   Übersicht in der Schiene (C7.4), Aktualisieren links vom Zahnrad in der
   Konto-Zeile (C7.5). Der Kopf zwingt die Knöpfe nicht mehr in eine volle
   Schienenbreite — sie sind nur so breit wie das Symbol. */
.schiene-kopf {
  display: flex; flex-wrap: nowrap; flex-direction: row; align-items: center;
  gap: calc(var(--luft) * 0.25);
  width: auto; flex: 1 1 auto; min-width: 0; padding: 0;
}
.schiene-kopf button.rund {
  width: 2.1em; height: 2.1em; min-width: 2.1em; min-height: 2.1em;
  padding: 0; flex: 0 0 auto;
}
.schiene-logo {
  display: grid; place-items: center;
  width: 2.1em; height: 2.1em; flex: 0 0 auto;
  border-radius: var(--radius); color: var(--akzent);
}
.schiene-logo img { width: 1.4em; height: 1.4em; display: block; }
body.schiene-schmal .schiene-kopf {
  flex-direction: row; width: auto; padding: 0;
}
body.schiene-weg #schiene { display: none; }
body.schiene-weg .schale {
  grid-template-columns: clamp(232px, 26vw, var(--listenbreite)) minmax(0, 1fr);
}
body.schiene-weg .schale[data-ohne-liste="1"] {
  grid-template-columns: minmax(0, 1fr);
}
#btn-schiene-auf {
  display: none;
  position: fixed;
  left: var(--luft);
  top: calc(var(--luft) + env(safe-area-inset-top));
  z-index: 40;
  background: var(--flaeche);
}
body.schiene-weg #btn-schiene-auf:not([hidden]) { display: grid; }
body[data-titelzone] #btn-schiene-auf {
  top: calc(var(--cos-titel-h, 0px) + var(--luft));
}
.schiene-unten { margin-top: auto; }
/* SYMBOL UND WORT IN EINER ZEILE — das ist der Unterschied zum 09.08. früh, wo das
   Wort klein unter dem Symbol stand. `.schiene button` fasst ALLE Knöpfe der Schiene:
   die Bereiche und „Einklappen". Damit sehen sie gleich aus und verhalten sich gleich,
   ohne dass es zwei Regelsätze braucht. (Bis zum 10.08.2026 hing hier noch „Farben
   retten" mit drin — der Knopf ist gestrichen, siehe `.farb-urteil` weiter unten.) */
.schiene button {
  position: relative; width: var(--schiene-knopf); padding: calc(var(--luft) * 0.75) calc(var(--luft) * 0.85);
  display: flex; flex-direction: row; align-items: center; gap: calc(var(--luft) * 0.9);
  background: transparent; border-color: transparent; color: var(--gedaempft);
  text-align: left; min-height: calc(var(--tap) - var(--luft) * 0.35);
  transition:
    background var(--schnell) var(--kurve),
    color var(--schnell) var(--kurve),
    border-color var(--schnell) var(--kurve);
}
.schiene button > svg { flex: 0 0 auto; }
/* Das Wort NEBEN dem Symbol. Es steht immer da, wo die Schiene ausgeklappt ist — ein
   title= gibt es auf einem Finger-Gerät nicht. Eine Zeile, notfalls mit
   Auslassungspunkten: ein umbrechendes Wort würde die Knöpfe unterschiedlich hoch
   machen und die Schiene damit unruhig. */
.schiene-wort {
  flex: 1 1 auto; min-width: 0;
  font-size: .95em; line-height: 1.2; letter-spacing: -.005em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (hover: hover) {
  .schiene button:hover { background: var(--flaeche-hoch); color: var(--text); }
  .schiene button[data-bereich][aria-current="page"]:hover,
  .schiene button[data-bereich].aktiv:hover,
  .schiene .schiene-ast-zeile.ist-offen:hover,
  .schiene .schiene-ast-zeile.aktiv:hover,
  .schiene .schiene-ast-zeile[aria-current="page"]:hover {
    background: color-mix(in srgb, var(--akzent) 20%, transparent);
  }
}
/* aria-current="page" statt aria-selected: die Schiene ist eine <nav> mit Knöpfen und
   KEINE Tabliste (siehe agora.js, schieneZeichnen). aria-selected ausserhalb einer
   role="tablist"/"listbox" ist eine Rolle, die es nicht gibt — jetzt steht hier das
   Attribut, das eine Navigation wirklich trägt. */
/* Nur der Bereichsknopf (data-bereich). Ohne diese Enge träfe der Balken
   auch eine Ast-Zeile, sobald sie aria-current trägt — der Balken sitzt
   auf der Schienenkante, nicht am Eintrag. Der alte ungeschärfte Satz
   (Tresor-Kopie am Dateiende) ist gelöscht, nicht überschrieben. */
.schiene button[data-bereich][aria-current="page"],
.schiene button[data-bereich].aktiv { background: var(--akzent-hauch); color: var(--akzent); }
.schiene button[data-bereich][aria-current="page"] .schiene-wort,
.schiene button[data-bereich].aktiv .schiene-wort { font-weight: 650; }
/* Der aktive Bereich bekommt zusätzlich einen Balken — Farbe allein trägt keine
   Aussage, wenn der Nutzer den Akzent auf Grau stellt (und das darf er).
   Der Knopf steht mittig in der Schiene, links bleiben (--schiene - --schiene-knopf)/2;
   genau so weit geht der Balken nach aussen und sitzt damit auf der Schienenkante. */
.schiene button[data-bereich][aria-current="page"]::before,
.schiene button[data-bereich].aktiv::before {
  content: ""; position: absolute; top: 6px; bottom: 6px; width: 3px;
  left: calc((var(--schiene-knopf) - var(--schiene)) / 2);
  border-radius: 0 3px 3px 0; background: var(--akzent);
}
/* Der Punkt sitzt an der Ecke des SYMBOLS, nicht an der des Knopfes: der Knopf ist
   jetzt zehnmal so breit wie das Symbol, und ein Punkt am äusseren Rand sähe aus, als
   gehörte er zum Nachbarn. Das Symbol ist 21 px breit und beginnt bei der Polsterung
   von 10 px — seine rechte obere Ecke liegt also bei 31 px. */
.schiene .punkt {
  position: absolute; top: 6px; left: 24px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--akzent); border: 1.5px solid var(--flaeche-tief);
}

/* ===========================================================================
   LETZTE IN DER SCHIENE (29.08.2026)
   ===========================================================================
   Unter „Chats" und „Arbeitsbereich" die zuletzt benutzten Eintraege, oben
   „Neuer Chat". Lange Titel eine Zeile mit Auslassung, Zeit als Abstand
   (OSZeit.vor). Punkt nur wenn etwas los ist: --gut = Lauf, --warn = Docs
   ueberholt. Kein eigener Farbwert.

   Auf dem Handy gehoert die Liste in die offene Leiste (geraet.css), nicht
   in die Bodenleiste — sonst schiebt 393 px. Deshalb: unter 860 px erst
   ausgeblendet, im Overlay wieder an. */
.schiene-ast-kopf {
  display: flex; flex-direction: row; align-items: stretch;
  width: var(--schiene-knopf); gap: 0;
}
.schiene .schiene-ast-kopf > button[data-bereich] {
  width: auto; flex: 1 1 auto; min-width: 0;
}
.schiene .schiene-ast-klapp {
  width: auto; flex: 0 0 auto; min-width: 0; min-height: 0;
  padding: calc(var(--luft) * 0.4);
  justify-content: center; color: var(--gedaempft);
}
.schiene .schiene-ast-klapp[aria-expanded="false"] svg { transform: rotate(-90deg); }
.schiene-ast {
  display: flex; flex-direction: column; gap: 0;
  width: var(--schiene-knopf); min-width: 0; padding: 0 0 calc(var(--luft) * 0.4);
}
.schiene-ast[hidden] { display: none; }
/* 100 % statt der festen --schiene-knopf-Breite: sobald der Ast senkrecht
   rollt, nimmt sein Rollbalken ~15 px vom Innenmass. Ein Kind mit fester
   204-px-Breite passt dann nicht mehr hinein und schiebt waagerecht — die
   Querachse eines Spalten-Flex schrumpft nicht. Der Ast selbst bleibt
   --schiene-knopf breit (oben), die Zeilen folgen ihm. */
.schiene .schiene-ast-zeile,
.schiene .schiene-ast-mehr {
  width: 100%; max-width: 100%; min-height: 0; min-width: 0;
  padding: calc(var(--luft) * 0.35) calc(var(--luft) * 0.5) calc(var(--luft) * 0.35) calc(var(--luft) * 0.7);
  gap: calc(var(--luft) * 0.35);
  font-size: var(--schrift-klein); color: var(--gedaempft);
}
/* Offener Eintrag in der Schiene. Klassen aus letzte.js (`ist-offen`) und
   agora.js (`aktiv`, dieselbe Marke wie .liste-zeile.aktiv). aria-current nur
   als Rückfall, falls Agent 5 den Eintrag so auszeichnet — der Bereichsknopf
   bleibt über [data-bereich] getrennt. Der alte Einzeiler (nur Farbe am
   Elter, Name blieb --text) ist gelöscht. scroll-margin: der Ast scrollt
   selbst (.schiene-ast), scrollIntoView hält den Eintrag im sichtbaren Feld. */
.schiene .schiene-ast-zeile.ist-offen,
.schiene .schiene-ast-zeile.aktiv,
.schiene .schiene-ast-zeile[aria-current="page"] {
  background: var(--akzent-hauch);
  color: var(--akzent);
  box-shadow: inset calc(var(--linie) * 3) 0 0 var(--akzent);
  scroll-margin-block: var(--luft);
}
.schiene .schiene-ast-zeile.ist-offen .schiene-ast-name,
.schiene .schiene-ast-zeile.aktiv .schiene-ast-name,
.schiene .schiene-ast-zeile[aria-current="page"] .schiene-ast-name {
  color: inherit;
  font-weight: 650;
}
.schiene-ast-punkt {
  flex: 0 0 0.5em; width: 0.5em; height: 0.5em; border-radius: 50%;
  background: var(--gedaempft);
}
.schiene-ast-punkt.gut { background: var(--gut); }
.schiene-ast-punkt.warn { background: var(--warn); }
.schiene-ast-punkt.aus { background: transparent; }
.schiene-ast-name {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text); text-align: left;
}
/* Die Zeit darf als LETZTE schrumpfen, nicht als Erste zulangen. Mit
   `flex: 0 0 auto` war sie unantastbar und nahm dem Titel „gerade eben" ab
   (11 Zeichen). Jetzt gedeckelt und selbst mit Auslassung. */
.schiene-ast-zeit {
  flex: 0 1 auto; min-width: 0; max-width: calc(var(--tap) * 1.7);
  color: var(--gedaempft); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.schiene-ast-satz {
  margin: 0; padding: calc(var(--luft) * 0.35) calc(var(--luft) * 0.7);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.schiene-kopf #btn-neuer-chat { color: var(--text); }
.schiene-kopf .schiene-wort { display: none; }
.schiene-kopf .schiene-klapp { margin-top: 0; }

/* Box in Box: „Übersicht" ist die äussere, der Einklapp-Knopf sitzt in einer
   eigenen kleinen darin. Die Box ist Geschwister von #schiene-haupt — sonst
   wischt schieneZeichnen() den Knopf (innerHTML). Radien und Abstände nur aus
   Variablen. Die zwei 30.08.-Anläufe haben den Knopf IN #schiene-haupt gehängt
   und ihn damit beim nächsten Zeichnen zerstört; ausserdem blieb
   `.schiene .schiene-klapp { display: none }` stehen. Hier gilt das Gegenteil:
   alte Ausblendung gelöscht, Knopf sichtbar wo die Übersicht sichtbar ist. */
.schiene-oben-box {
  display: flex;
  align-items: center;
  gap: calc(var(--luft) * 0.25);
  padding: calc(var(--luft) * 0.2);
  border: var(--linie) solid var(--rahmen);
  border-radius: calc(var(--radius) * 1.4);
  background: var(--flaeche-tief);
  flex: 0 0 auto;
  width: var(--schiene-knopf);
  box-sizing: border-box;
}
.schiene-oben-box > button[data-bereich] {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
}
.schiene-klapp-box {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: calc(var(--radius) * 1.1);
  background: var(--flaeche);
}
.schiene-oben-box .schiene-klapp,
.schiene-klapp-box #btn-schiene-klapp {
  margin-top: 0;
  display: flex;
  width: auto;
  min-width: var(--tap);
  min-height: var(--tap);
  justify-content: center;
  align-items: center;
}
body.schiene-schmal .schiene-oben-box { flex-direction: column; width: var(--schiene-knopf); }

/* Dieselbe Liste nicht zweimal — aber NUR noch schmal.
   🔴 Die Begruendung von damals war: „die mittlere Spalte IST die Liste."
   Die mittlere Spalte gibt es breit nicht mehr (Owner 30.08.2026), also war
   diese Regel der Grund, warum der Ausklapper genau dann verschwand, wenn man
   ihn braucht — der Owner mit Abzug: „wenn ich auf Chat gehe, ist der Dropdown
   nicht dort." Breit bleibt der Baum jetzt stehen; schmal (bis 720 px) gibt es
   die Listenspalte weiterhin, dort waere er wirklich doppelt. */
@media (max-width: 720px) {
  .schale[data-bereich="chats"] .schiene-ast[data-ast="chats"],
  .schale[data-bereich="chats"] .schiene-ast-klapp[data-ast="chats"] {
    display: none;
  }
}
@media (min-width: 861px) {
  body.schiene-schmal .schiene-ast,
  body.schiene-schmal .schiene-ast-klapp { display: none; }
  body.schiene-schmal .schiene-ast-kopf { width: var(--schiene-knopf); justify-content: center; }
  body.schiene-schmal .schiene .schiene-ast-kopf > button[data-bereich] {
    width: var(--schiene-knopf); justify-content: center;
  }
}
@media (max-width: 860px) {
  /* Bodenleiste: nur die Reiter. Der neue Chat sitzt in der Kopfzeile,
     nicht hier — sonst schöbe er die Reiter aus 393 px. Das Overlay
     (geraet.css, data-ebene=leiste) holt den Baum zurueck. */
  .schiene-ast,
  .schiene-ast-klapp { display: none; }
  .schiene-ast-kopf { width: auto; }
  .schiene .schiene-ast-kopf > button[data-bereich] { width: auto; }
  /* Einklappen sitzt in der Übersicht-Box, auch schmal. Die alte Regel
     `#btn-schiene-klapp { display: none }` ist gelöscht: sie traf den Knopf,
     sobald kopfSchieneOrdnen() ihn aus dem Kopf in die Schiene gelegt hat
     (Lauf b6200f4d), und der zweite Anlauf konnte sie nicht überstimmen. */
  .kopf-wort { display: none; }
  .schiene-oben-box { width: auto; max-width: 40vw; }
}

/* ---------- DER URTEILSKASTEN AUF DER FARBSEITE ----------------------------
   Die festen Werte stehen in :root (--urteil-*), nicht hier. Er sagt beim
   AUSWÄHLEN, welches Farbpaar unter 4,5:1 liegt. Würde er aus der gerade
   gewählten Palette gemalt, wäre er genau dann unlesbar, wenn man ihn braucht.

   HIER STAND BIS ZUM 10.08.2026 `#btn-farben-notfall`, der Knopf „Farben retten" an
   der Schiene. Der Owner hat ihn gestrichen — „wofür brauche ich das? das ist doch
   Zurücksetzen bei der Farbenauswahl". Er hatte recht: seit unlesbare Farben gar
   nicht mehr gespeichert werden können, gibt es die Lage nicht mehr, für die er
   gebaut war. Seine feste Palette ist geblieben, weil ihre Begründung geblieben ist —
   sie sitzt nur jetzt an der Stelle, an der der Schaden entsteht. */
.farb-urteil {
  background: var(--urteil-grund); color: var(--urteil-text); border: var(--linie) solid var(--urteil-rand);
  border-radius: var(--radius); padding: var(--karte-innen);
}
.farb-urteil .farb-urteil-kopf { margin: 0 0 .5em; font-family: var(--serif); font-weight: 600; }
.farb-urteil ul { margin: 0 0 .6em; padding-left: 1.2em; }
.farb-urteil li { margin: .15em 0; }
.farb-urteil li b { font-variant-numeric: tabular-nums; }
.farb-urteil .farb-urteil-klein { font-size: var(--schrift-klein); color: var(--urteil-klein); margin: 0 0 .6em; }
.farb-urteil button {
  width: auto; font-size: .9em;
  background: var(--urteil-knopf); color: var(--urteil-text); border: var(--linie) solid var(--urteil-rand);
}
@media (hover: hover) {
  .farb-urteil button:hover { background: color-mix(in srgb, var(--urteil-text) 18%, var(--urteil-grund)); border-color: var(--urteil-text); }
}

/* ---------- EINKLAPPEN — ein sichtbarer Knopf, kein Kürzel -----------------
   Owner 09.08.2026: keine einzige Strg-Kombination. Also steht hier ein Knopf, den
   man sieht. Verhalten und Aussehen wie in /work/ui/ (`.side-min-btn`): ruhig,
   gedämpft, unter allem anderen; die Pfeile drehen sich, wenn die Schiene schmal ist.
   Die eigentlichen Einklapp-Regeln stehen weiter unten unter „SCHIENE EINGEKLAPPT",
   hinter `min-width: 861px` — schmal liegt die Schiene unten und es gibt nichts
   einzuklappen. */
.schiene-klapp { margin-top: calc(var(--luft) * 0.3); font-size: var(--schrift-klein); }
.schiene-klapp svg { transition: transform var(--normal) var(--kurve); }

/* ===========================================================================
   DIE NUTZUNG AN DER SCHIENE — LESBAR, NICHT MINIATUR
   ===========================================================================
   Owner 09.08.2026: „…und dass man die Nutzung richtig lesen kann — wie beim os 0,
   also dem, was gerade live ist." Vorbild ist damit `ui/style.css:257-271`
   (`.usage-mini`), und zwar Zahl für Zahl:
     · je Konto der NAME und der PLAN IM KLARTEXT nebeneinander („Max 20x"),
     · darunter je eine Zeile „5-Stunden" und „7-Tage": Wort links, Prozentzahl
       rechts (`.um-top`), und DARUNTER — nicht daneben — der Balken (`.um-bar`),
     · Balken 8 px hoch, Spur sichtbar AUCH BEI 0 %, Füllung grün → amber → rot.

   WARUM DIESE REGELN HIER STEHEN UND NICHT IN uebersicht.css:
   Das MARKUP des Streifens gehört uebersicht.js (streifenZeichnen), die Formgebung
   der SCHIENE gehört diesem Blatt — der Streifen ist ein Teil der Schiene, er hängt
   als letztes Kind darin (uebersicht.js → schiene.appendChild) und richtet sich nach
   `--schiene-knopf`, das hier deklariert ist. Wer die Schiene ändert, muss den
   Streifen mitändern können, ohne eine fremde Datei anzufassen.

   ⚠️ ALLE SELEKTOREN SIND MIT `.schiene ` VORANGESTELLT — mit Absicht.
   uebersicht.css trägt einen ÄLTEREN Block für denselben Streifen (dort ab
   „Der Streifen an der Schiene"). Er stammt aus der Zeit der 86 px schmalen
   Symbolspalte und setzt Schriftgrössen von .54em/.58em (bei 14,5 px Grundschrift
   sind das 7,8 px) sowie `.ub-s-zeile { display: flex; align-items: center }` —
   also Wort, Zahl und Balken NEBENEINANDER auf 74 px. Genau das war der Tadel.
   Dieses Blatt wird VOR uebersicht.css geladen; bei gleicher Gewichtung gewänne
   also der alte Block. Ein Klassenname mehr im Selektor (0,2,x gegen 0,1,x) dreht
   das um, ohne dass eine Datei angefasst werden muss, die einem anderen gehört.
   Verschwindet der alte Block dort, bleiben diese Regeln richtig — sie hängen
   nicht an seiner Existenz.

   AUFBAU DES MARKUPS (uebersicht.js → streifenZeichnen/zeileStreifen), damit man
   die Selektoren lesen kann, ohne die Datei aufzuschlagen:
     .ub-streifen
       .ub-s-konto            — ein Konto
         .ub-s-kopf           — .ub-s-name (Konto) + .ub-s-plan (Klartext)
         .ub-s-zeile[.warn|.schlecht|.akzent]
           .ub-s-oben         — <i> Wort   <u> Prozentzahl oder „—"
           .ub-s-bar[.unbekannt] > b     — Spur und Füllung
         .ub-s-aus/.ub-s-grund — „Auslastung geht aktuell nicht" samt Grund
       .ub-s-note             — der Massstab-Satz unter allen Konten
   =========================================================================== */
.schiene .ub-streifen {
  width: var(--schiene-knopf); margin-top: 10px; padding: 9px 10px 10px;
  display: flex; flex-direction: column; gap: 9px; align-items: stretch;
  background: var(--flaeche); border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius); color: var(--gedaempft); flex: 0 0 auto;
}
.schiene .ub-s-konto { display: flex; flex-direction: column; gap: 7px; text-align: left; }
/* Zwei Konten sind zwei Rechnungen — ohne Trennlinie liest man vier Balken als einen
   Block und bezieht die 7-Tage-Zahl des zweiten auf den Plan des ersten. */
.schiene .ub-s-konto + .ub-s-konto { padding-top: 9px; border-top: var(--linie) solid var(--rahmen); }
.schiene .ub-s-kopf { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
.schiene .ub-s-name {
  flex: 1 1 auto; min-width: 0;
  font-size: .82em; line-height: 1.25; font-weight: 650; letter-spacing: 0;
  text-transform: none; text-align: left; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* DER PLAN GEHÖRT NEBEN DEN NAMEN, NICHT IN DEN title: 63 % auf einem Max 5x sind ein
   Viertel dessen, was 63 % auf einem Max 20x bedeuten. Ein Prozentwert ohne seinen
   Massstab ist eine Zahl, die in die Irre führt — und ein title existiert auf einem
   Finger-Gerät nicht. */
.schiene .ub-s-plan {
  flex: 0 0 auto; font-size: .78em; line-height: 1.25; font-weight: 600;
  color: var(--akzent); background: var(--akzent-hauch);
  border-radius: 99px; padding: 1px 7px; white-space: nowrap;
}
/* ⚠️ HIER STAND `.schiene` — am 20.08.2026 auf `.schiene`
   ZURÜCKGENOMMEN. Der zweite Selektor war für die Sparstufe `kompakt` der
   Übersicht da: sie ersetzte dort die Ringe durch genau diese Zeile.
   🔴 GEMESSEN AM SELBEN TAG, 16:05: die Stufe griff auf 1920x1080, 1536x864 und
   1440x900 — also überall, nicht nur auf schmalen Geräten. Owner: „Wo sind bei
   der Uebersicht meine Kreise hin mit den %?" und „Ich will im Dashboard nix
   klappbar haben, Alter!"
   Die Übersicht zeigt ihre Auslastung seitdem auf JEDEM Gerät als Ringe. Diese
   Form gehört wieder allein der Schiene, wo sie herkommt und wo sie die einzige
   ist, die in 64 px Breite passt.

   Wort und Zahl ÜBER dem Balken, nicht daneben — eins zu eins `ui/style.css:260`
   (`.um-row` ist column, `.um-top` ist die Zeile darüber). */
.schiene .ub-s-zeile { display: flex; flex-direction: column; gap: 4px; align-items: stretch; }
.schiene .ub-s-oben { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
.schiene .ub-s-zeile i {
  flex: 1 1 auto; min-width: 0; width: auto; text-align: left;
  font-style: normal; font-size: .78em; line-height: 1.25; letter-spacing: .01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.schiene .ub-s-zeile u {
  flex: 0 0 auto; text-decoration: none; text-align: right;
  font-size: .78em; line-height: 1.25; font-weight: 600; font-variant-numeric: tabular-nums;
  min-width: 2.6em; color: var(--text);
}
/* 8 px, sichtbare Spur mit Innenrand — die Masse aus ui/style.css:266-271. BEI 0 %
   MUSS DIE SPUR SICHTBAR BLEIBEN: sonst ist „nichts verbraucht" von „hier fehlt
   etwas" nicht zu unterscheiden, und genau das war der Tadel am 08.08. */
.schiene .ub-s-bar {
  flex: 0 0 auto; width: 100%; min-width: 0; height: var(--balken-hoehe, 8px);
  border-radius: 99px; overflow: hidden;
  background: var(--balken-spur, color-mix(in srgb, var(--text) 16%, transparent));
  box-shadow: inset 0 0 0 var(--linie) var(--balken-spur-rand, color-mix(in srgb, var(--text) 10%, transparent));
}
/* NICHT GEMESSEN IST NICHT NULL. Eine leere Spur heisst „0 % verbraucht" — eine
   Behauptung. Wo nichts frisch gemessen ist, trägt die Spur eine Schraffur; daneben
   steht „—" statt einer Zahl (uebersicht.js → zeileStreifen). Eingeklappt ist die
   Schraffur das EINZIGE Unterscheidungsmerkmal, dort steht kein Wort mehr. */
.schiene .ub-s-bar.unbekannt {
  background: repeating-linear-gradient(135deg,
    var(--balken-spur, color-mix(in srgb, var(--text) 16%, transparent)) 0 3px,
    transparent 3px 6px);
}
/* ⚠️ AUCH DIESE DREI STEHEN AUF .76em (= 11,0 px) UND NICHT DARUNTER.
   Es ist verlockend, den erklärenden Text kleiner zu setzen als die Zahl — er ist ja
   „nur" die Begründung. Genau das war aber der Tadel: „Auslastung geht aktuell nicht"
   IST die Auskunft, wenn keine Zahl da ist, und der Massstab-Satz ist der einzige
   Grund, warum zwei Prozentzahlen nebeneinander nicht in die Irre führen. Beide
   standen auf .72em/.70em, also 10,4 und 10,2 px — gemessen mit dem Prüfstand
   (tools/agora-proben/abnahme.cjs, Abschnitt 10), der jede Schrift unter 11 px in der
   Schiene meldet. Wer hier spart, macht die Beschwerde vom 09.08., 15:10
   („dass man die Nutzung richtig lesen kann") rückgängig. Der Platz ist da: die
   Schiene ist 204 px breit, der Satz darf umbrechen. */
.schiene .ub-s-aus { font-size: .76em; line-height: 1.3; color: var(--warn); font-weight: 600; }
.schiene .ub-s-grund { font-size: .76em; line-height: 1.35; color: var(--gedaempft); }
.schiene .ub-s-note {
  font-size: .76em; line-height: 1.35; color: var(--gedaempft);
  padding-top: 8px; border-top: var(--linie) solid var(--rahmen);
}

/* ===========================================================================
   SCHIENE EINGEKLAPPT (body.schiene-schmal) UND LISTE ZU (body.liste-zu)
   ===========================================================================
   Dasselbe Muster wie in der heutigen Oberfläche (/work/ui/ → `body.side-min`,
   gemerkt in localStorage), nur mit zwei Achsen statt einer:
     · body.schiene-schmal — die Schiene behält ihre Symbole, verliert die Wörter und
       geht von 226 auf 64 px. Der Knopf dafür steht IN der Schiene, ganz unten.
     · body.liste-zu       — die Listenspalte fällt weg, das Detail bekommt den Platz.
       Der Knopf dafür steht im DETAILkopf und nicht im Listenkopf: sonst wäre er
       zusammen mit der Liste verschwunden und man käme nicht zurück.
   Geschaltet wird in agora.js (AGORA.klappUmschalten), gemerkt unter
   `agora_schiene_schmal` / `agora_liste_zu`. Der gemerkte Zustand wird von
   AGORA.klappWiederherstellen() gesetzt, und zwar auf oberster Ebene von agora.js —
   also lange vor AGORA.start(), damit die volle Leiste nicht kurz aufblitzt. Bis zum
   09.08.2026 wurde er GESCHRIEBEN und NIE GELESEN: nach jedem Neuladen stand die
   Schiene wieder breit da.

   BEIDES GILT NUR IN DER BREITEN ANORDNUNG. Schmal (≤860 px) liegt die Schiene als
   Leiste unten und Liste/Detail teilen sich ohnehin einen Platz — dort wäre Einklappen
   sinnlos, die Knöpfe sind ausgeblendet und die Klassen ohne Wirkung. Genau deshalb
   steht der ganze Block hinter `min-width: 861px`, wortgleich zur Abfrage weiter
   unten; die beiden dürfen sich nie überschneiden.
   =========================================================================== */
.nur-breit { display: grid; }

@media (min-width: 861px) {
  /* Die Schienenbreite steckt in der Rasterspalte der Schale — nur die lässt sich
     weich überblenden. `grid-template-columns` ist interpolierbar, solange die ZAHL
     der Spuren gleich bleibt (hier tut sie das: nur die erste Zahl ändert sich).
     Der globale prefers-reduced-motion-Block weiter unten schaltet sie wieder ab. */
  .schale { transition: grid-template-columns 220ms ease; }

  /* DIE SCHIENE SCROLLT SELBST. Sie trägt jetzt sechs beschriftete Knöpfe UND den
     Auslastungs-Streifen (zwei Konten, vier Balken, Name, Plan, Massstab-Satz —
     ausgeklappt rund 230 px). Auf einem 600 px hohen Fenster passt das nicht mehr;
     ohne diese Zeile fällt der Streifen unten aus der Schiene heraus und ist auf
     keinem Weg mehr erreichbar (`body { overflow: hidden }`). Dieselbe Massnahme
     wie bei Liste und Detail — jede Spalte scrollt in sich, nie die Seite —, und
     dieselbe wie in der heutigen Oberfläche (`ui/style.css` → `.side-nav`).
     Nur breit: schmal liegt die Schiene waagerecht unten und hat keine Höhe zu
     verteilen.
     `overflow-x: hidden` steht ausdrücklich dabei: sobald eine Achse nicht mehr
     `visible` ist, rechnet der Browser die andere auf `auto` — sonst käme unter der
     Schiene ein waagerechter Balken für Pixel, die niemand sehen will. Der Streifen
     am aktiven Knopf (::before, linke Kante bei x = 0) wird davon nicht beschnitten. */
  .schiene { overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scrollbar-width: thin; }

  /* ⚠️ BEIDE Variablen müssen HIER stehen, nicht nur --schiene: eine Variable wird an
     dem Element aufgelöst, an dem sie DEKLARIERT ist. Stünde --schiene-knopf allein in
     :root, behielte der Knopf (und mit ihm der Auslastungs-Streifen, uebersicht.css →
     `width: var(--schiene-knopf)`) seine 204 px in einer 64 px schmalen Schiene.
     Der Balken am aktiven Knopf rechnet mit (46 − 64) / 2 = −9 px und sitzt damit
     wieder genau auf der Schienenkante. */
  body.schiene-schmal { --schiene: 64px; --schiene-knopf: 46px; }

  body.schiene-schmal .schiene button { justify-content: center; gap: 0; padding: 9px 4px; }
  body.schiene-schmal .schiene-wort { display: none; }
  body.schiene-schmal .schiene-marke { justify-content: center; padding: 4px 0 0; }
  body.schiene-schmal .schiene-marke-wort { display: none; }
  /* Symbol wieder mittig → der Punkt zurück an seine Ecke. 50 % − 15 px ist dieselbe
     Rechnung wie in der schmalen Anordnung: halbe Knopfbreite minus halbe Symbolbreite
     minus die Punktbreite. */
  body.schiene-schmal .schiene .punkt { left: auto; right: calc(50% - 15px); top: 4px; }
  /* Die Pfeile zeigen jetzt nach RECHTS — derselbe Knopf klappt wieder aus. */
  body.schiene-schmal .schiene-klapp svg { transform: rotate(180deg); }

  /* ---- DIE NUTZUNG, EINGEKLAPPT ----------------------------------------
     Von 204 px bleiben 46 — für „5-Stunden" und „63 %" reicht das nicht, für einen
     Balken schon. Es bleibt also je Konto der BALKEN und sonst nichts: alles
     Geschriebene (Name, Plan, Wort, Zahl, Grund, Massstab-Satz) fällt weg.
     ⚠️ Der Balken selbst bleibt 8 px hoch und behält seine sichtbare Spur — ein
     verschwundener oder auf 2 px gequetschter Streifen sähe aus wie „kaputt", und
     genau das darf eingeklappt nicht passieren. Die Wörter sind nicht verloren:
     uebersicht.js schreibt sie vollständig in den `title` des Streifens.
     Nicht gemessene Balken tragen weiterhin ihre Schraffur (.unbekannt) — hier ist
     sie das einzige, was „weiss ich nicht" von „0 %" unterscheidet. */
  body.schiene-schmal .ub-streifen { padding: 7px 5px; gap: 7px; }
  body.schiene-schmal .schiene .ub-s-konto { gap: 5px; }
  body.schiene-schmal .schiene .ub-s-konto + .ub-s-konto { padding-top: 7px; }
  body.schiene-schmal .schiene .ub-s-kopf,
  body.schiene-schmal .schiene .ub-s-oben,
  body.schiene-schmal .schiene .ub-s-aus,
  body.schiene-schmal .schiene .ub-s-grund,
  body.schiene-schmal .schiene .ub-s-note { display: none; }

  /* Liste zu: dieselbe Zweispaltigkeit wie bei einem Bereich ganz ohne Liste. Die
     höhere Gewichtung (body.liste-zu .schale) schlägt auch die Regel für sehr breite
     Bildschirme weiter unten — sonst käme die Liste dort zurück. */
  /* ⚠️ TOT seit 10.08.2026: die Klasse wird nirgends mehr gesetzt (agora.js, Achse
     „liste" entfernt auf Owner-Order). Bewusst STEHENGELASSEN und nicht geloescht:
     ein Browser, der die alte Fassung noch im Zwischenspeicher hat, wuerde sonst mit
     gesetzter Klasse und ohne passende Regel eine halb gebaute Seite zeigen. Beim
     naechsten Aufraeumen darf der Block weg. */
  body.liste-zu .spalte-liste { display: none; }
  body.liste-zu .schale { grid-template-columns: var(--schiene) minmax(0, 1fr); }
  body.liste-zu #btn-liste-klapp { color: var(--akzent); border-color: var(--akzent-rand); }
  /* Ein Bereich OHNE Liste hat nichts auszublenden — ein Knopf, der nichts tut, ist
     schlimmer als keiner. */
  .schale[data-ohne-liste="1"] #btn-liste-klapp { display: none; }
}

/* ---------- Liste --------------------------------------------------------- */
.spalte-liste {
  display: flex; flex-direction: column; min-width: 0;
  border-right: var(--linie) solid var(--rahmen); background: var(--hintergrund);
}
.listen-kopf { display: flex; gap: 6px; padding: 8px; border-bottom: var(--linie) solid var(--rahmen); align-items: center; }
.listen-titel {
  flex: 1 1 auto; min-width: 0; font-family: var(--serif); font-weight: 600; font-size: 1em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.listen-titel small { font-weight: 400; color: var(--gedaempft); margin-left: .5em; }

/* min-height: 0 — damit der Scroll-Behälter wirklich schrumpfen DARF. In einer
   Spalten-Flexbox hat jedes Kind eine automatische Mindesthöhe in Höhe seines Inhalts;
   `overflow-y: auto` setzt sie zwar rechnerisch schon auf 0, aber diese Regel hängt an
   einer Feinheit der Spezifikation, die man beim Lesen nicht sieht. Ausgeschrieben ist
   sie eine Zeile und kostet nichts — und sie ist die zweite Hälfte der Reparatur oben. */
.liste { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* Hier stand bis zum 08.08.2026 `.liste:focus { outline: none }` — und das war der
   einzige Ort in der ganzen Oberfläche, an dem der Tastatur-Fokus UNSICHTBAR war.
   Gemessen: Tab-Reihenfolge Schiene → Suchfeld → Neu → LISTE, und beim Schritt auf die
   Liste änderte sich am Bildschirm gar nichts (outline "none", kein box-shadow, keine
   gerichtete Zeile). Wer mit der Tastatur arbeitet, wusste an dieser Stelle nicht, dass
   jetzt die Pfeiltasten wirken.
   :focus-visible statt :focus, weil ein KLICK in die Liste keinen Rahmen bekommen soll —
   dort sagt schon die angeklickte Zeile, wo man ist. outline-offset ist negativ: die
   Liste stösst rechts an die Trennlinie zur Detailspalte, ein äusserer Rahmen würde
   dort abgeschnitten. */
.liste:focus { outline: none; }
.liste:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
.liste-gruppe {
  padding: calc(var(--luft) * .9) 12px 4px; font-size: .74em; letter-spacing: .09em;
  text-transform: uppercase; color: var(--gedaempft); font-weight: 700;
  position: sticky; top: 0; background: var(--hintergrund); z-index: 1;
}
.zeile {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 8px;
  padding: var(--zeile-y) 12px; cursor: pointer; border: 0; width: 100%; text-align: left;
  background: transparent; border-radius: 0; border-left: 3px solid transparent;
  align-items: baseline;
}
/* Reihenfolge beachten: diese Regel und die Auswahl-Regel darunter haben dieselbe
   Gewichtung — die spätere gewinnt. Steht der Hover danach, verliert die gewählte
   Zeile beim Überfahren ihren linken Balken. */
@media (hover: hover) { .zeile:hover { background: var(--flaeche-hoch); border-color: transparent; } }
.zeile[aria-selected="true"] { background: var(--akzent-hauch); border-left-color: var(--akzent); }
.zeile.gerichtet { box-shadow: inset 0 0 0 var(--linie) var(--akzent-rand); }
/* 01.09.2026: nowrap + ellipsis schnitt Chat-Titel in der 204-px-Schiene
   auf ununterscheidbare Kürzel. Der Name bricht um, er wird nicht verstümmelt. */
.zeile-titel { font-weight: 550; overflow-wrap: anywhere; white-space: normal; }
/* DAS SYMBOL DES CHATS VOR DEM TITEL (19.08.2026, Owner: „damit man schnell den Chat
   am Icon finden kann"). Es sitzt IM Titel-Kasten und nicht in einer eigenen
   Rasterspur: eine dritte Spur hätte `.zeile` für JEDE Liste umgebaut — auch für die
   ohne Bild, und genau so eine `auto`-Spur hat am 11.08. an der Kachel dem Titel die
   Breite weggenommen.
   `vertical-align: -.28em` statt `middle`: die Zeile richtet sich an der Grundlinie aus
   (`.zeile { align-items: baseline }`), und `middle` zöge das Bild um seine halbe Höhe
   nach oben. Radius eine Spur enger als der Kasten-Radius, damit ein 26-px-Feld nicht
   rund wirkt. Gibt es kein Bild, entsteht dieses Element gar nicht erst. */
.zeile-bild {
  width: var(--chatbild); height: var(--chatbild); margin-right: 8px;
  vertical-align: -.28em; object-fit: cover; border-radius: calc(var(--radius) - 4px);
  border: var(--linie) solid var(--rahmen); background: var(--flaeche-tief);
}
.zeile-neben { font-size: .78em; color: var(--gedaempft); white-space: nowrap; }
.zeile-unten { grid-column: 1 / -1; font-size: .82em; color: var(--gedaempft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zeile-marken { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }

.listen-leer { padding: 26px 16px; color: var(--gedaempft); text-align: center; font-size: .9em; }
/* Deckel-Hinweis der Suche: vorhandenes `.hinweis`, Abstand aus --luft. */
.liste > .hinweis { margin: var(--luft); }
/* flex: 0 0 auto — DER FUSS DARF NICHT SCHRUMPFEN. Das waren die „restlichen 7 px", die
   nach der Reparatur der Grid-Zeile übrig blieben; gemessen am 08.08.2026 bei 1440×757
   waren es 16 px auf #/tools und 8 px auf #/projekte, und es war keine Zahl, sondern ein
   sichtbarer Schaden: der Fuss war 26 px hoch, sein Text brauchte 41 — die zweite Zeile
   von „12 Werkzeuge, die ein Modell aufrufen kann · 21 Einträge" wurde unterhalb des
   Fensterrands gemalt und war weg.
   URSACHE: in einer Spalten-Flexbox schrumpfen alle Kinder mit. Normalerweise schützt die
   automatische Mindesthöhe (min-height:auto = Inhaltshöhe) einen Kasten davor — aber das
   `min-height: 1.2em` in dieser Zeile ERSETZT sie durch einen kleineren Wert. Der Fuss war
   damit der einzige Kasten der Oberfläche, der unter seinen Inhalt gedrückt werden konnte,
   und das passierte genau dann, wenn die Liste länger als das Fenster ist. Zu schrumpfen
   hat er ohnehin nichts: die freie Höhe verwaltet die Liste darüber.
   min-height bleibt — es hält die Leiste in Form, solange kein Text darin steht. */
.listen-fuss { flex: 0 0 auto; padding: 7px 12px; border-top: var(--linie) solid var(--rahmen); font-size: .78em; color: var(--gedaempft); min-height: 1.2em; }

/* ---------- Detail -------------------------------------------------------- */
.spalte-detail { display: flex; flex-direction: column; min-width: 0; background: var(--hintergrund); }
.detail-kopf {
  display: flex; align-items: center; gap: 8px; padding: 8px 12px;
  border-bottom: var(--linie) solid var(--rahmen); min-height: 46px;
}
.detail-kopf h1 { margin: 0; font-family: var(--serif); font-size: var(--schrift-abschnitt); font-weight: 600; flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.detail-neben {
  display: flex; align-items: center; gap: calc(var(--luft) * .4);
  flex: 0 1 auto; min-width: 0;
}
.detail-neben:empty { display: none; }
.detail-neben select {
  width: auto; max-width: 100%; font-size: var(--schrift-klein);
  background: transparent; border-color: transparent;
  padding: calc(var(--luft) * .2) calc(var(--luft) * .5);
}

/* Wissen-Knopf über der Eingabe. Projekt-Chips sitzen im Chat-Kopf. */
.c-projekt-leiste {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: calc(var(--luft) * .5); padding: 0 var(--luft) calc(var(--luft) * .5);
  max-width: 100%;
}
.c-projekt-leiste[hidden] { display: none; }
#c-wissen {
  width: auto; max-width: 100%; flex: 0 0 auto;
  font-size: var(--schrift-klein);
}
#c-ab-huelle {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: calc(var(--luft) * .4); min-width: 0; max-width: 100%;
}
#c-proj-chips { max-width: 100%; }
.c-proj-chip { max-width: 100%; }
.c-proj-x {
  border: 0; background: transparent; color: inherit;
  padding: 0 calc(var(--luft) * .15); font: inherit; line-height: 1;
  min-width: calc(var(--tap) * 0.5); min-height: calc(var(--tap) * 0.5);
}
.c-proj-plus { font-size: var(--schrift-klein); padding: .16em .5em; }

.proj-menue-schicht { position: fixed; inset: 0; z-index: 80; pointer-events: none; }
.proj-menue {
  position: fixed; z-index: 81; pointer-events: auto;
  display: flex; flex-direction: column; gap: calc(var(--luft) * .35);
  min-width: 16em; max-width: min(28em, 92vw); max-height: 60vh;
  padding: calc(var(--luft) * .5);
  background: var(--flaeche-hoch); color: var(--text);
  border: var(--linie) solid var(--rahmen); border-radius: calc(var(--radius) * 1.6);
  overflow: auto;
}
.proj-menue-suche { width: 100%; }
.proj-menue-grp { display: flex; flex-direction: column; gap: calc(var(--luft) * .2); }
.proj-menue-grp-name { margin: calc(var(--luft) * .3) 0 0; }
.proj-menue-zeile {
  display: flex; align-items: center; gap: calc(var(--luft) * .4);
  padding: calc(var(--luft) * .35) calc(var(--luft) * .4);
  border-radius: var(--radius);
}
.proj-menue-satz, .proj-menue-stand { margin: 0; }

/* DIE CHAT-ZEILE IN DER SCHIENE (berichtigt 06.09.2026, Owner-Abzug)
   ------------------------------------------------------------------
   🔴 Was kaputt war, gemessen an der Kaskade, nicht geraten:
   `.schiene button` (weiter oben in dieser Datei) gibt JEDEM Knopf der Schiene
   `width: var(--schiene-knopf)` = 204 px. Das trifft auch die beiden Knöpfe IN
   der Chat-Zeile. Der alte Satz hier setzte `flex`, `min-width` und `padding`
   zurück — aber NIE `width`. Bei `flex-basis: auto` ist die Grundbreite die
   width-Eigenschaft, also 204 px:
     · `.schiene-ast-akt` stand auf `flex: 0 0 auto` → 204 px, nicht schrumpfbar.
       Der ⋯-Knopf war so breit wie die ganze Schiene.
     · `.schiene-ast-sprung` durfte als Einziger schrumpfen und ging auf 0 →
       Punkt, Titel und Zeit fielen aus ihrer Box heraus (overflow: visible)
       und wurden vom ⋯-Knopf überdeckt. Genau der Abzug des Owners:
       „⋯ vor 12 Std", kein Titel.
     · 0 + Lücke + 204 > 190 px Zeilenbreite → die Zeile lief waagerecht über,
       und weil `.schiene-ast` ein `overflow-y` ohne `overflow-x` trägt, macht
       der Browser daraus `overflow-x: auto` → der Rollbalken im Bild.
   Deshalb steht `width` hier jetzt an BEIDEN Knöpfen ausdrücklich.
   Nicht schrumpfbar sind nur noch Punkt und ⋯ — zusammen unter einem Viertel
   der Zeile, damit der Titel den Rest bekommt. */
.schiene .schiene-ast-zeile {
  display: flex; flex-direction: row; align-items: center;
  width: 100%; max-width: 100%; min-width: 0;
  position: relative;   /* Anker fuer den ⋯-Knopf, siehe unten */
}
.schiene .schiene-ast-sprung {
  display: flex; flex-direction: row; align-items: center;
  width: auto; flex: 1 1 auto; min-width: 0; min-height: 0; gap: inherit;
  background: transparent; border: 0; color: inherit; font: inherit;
  padding: 0; text-align: left; overflow: hidden;
}
/* Der ⋯-Knopf steht AUSSERHALB DES FLUSSES (position: absolute).
   Nachgerechnet an der Schiene (tools/test-letzte.js, Abschnitt 7): im Fluss
   nahm er dem Titel auch als kleiner Knopf noch 26 px von 175 px, und der Titel
   „Neuer Chat" passte damit immer noch nicht ganz hinein. Er ist aber keine
   Angabe, sondern eine Zugabe beim Überfahren — also darf er der Zeile keine
   Breite kosten. Er und die Zeit teilen sich denselben Platz rechts; deshalb
   weicht die Zeit, sobald er kommt (Regel darunter).
   0.6 × --tap = 26 px liegen über dem WCAG-2.2-Mindestziel von 24 px; am Finger
   steht die volle --tap-Kante, und dort bekommt der Sprung rechts Raum, damit
   Zeit und Knopf einander nicht überdecken. */
.schiene .schiene-ast-akt {
  position: absolute; right: calc(var(--luft) * 0.5); top: 50%;
  transform: translateY(-50%);
  width: calc(var(--tap) * 0.6); height: calc(var(--tap) * 0.6);
  min-width: 0; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0; color: var(--gedaempft);
  font: inherit; padding: 0; visibility: hidden;
}
.schiene .schiene-ast-zeile:hover .schiene-ast-akt,
.schiene .schiene-ast-zeile:focus-within .schiene-ast-akt,
.schiene .schiene-ast-akt[aria-expanded="true"] { visibility: visible; }
.schiene .schiene-ast-zeile:hover .schiene-ast-zeit,
.schiene .schiene-ast-zeile:focus-within .schiene-ast-zeit,
.schiene .schiene-ast-zeile:has(.schiene-ast-akt[aria-expanded="true"]) .schiene-ast-zeit {
  visibility: hidden;
}
@media (hover: none) {
  /* Kein Überfahren am Finger: der Knopf steht immer, und der Sprung macht ihm
     rechts Platz, statt die Zeit unter ihm verschwinden zu lassen. */
  .schiene .schiene-ast-akt { visibility: visible; width: var(--tap); height: var(--tap); }
  .schiene .schiene-ast-sprung { padding-right: var(--tap); }
  .schiene .schiene-ast-zeile:hover .schiene-ast-zeit { visibility: visible; }
}
.schiene-ast-umbenennen {
  flex: 1 1 auto; min-width: 0; width: 100%;
  font: inherit; color: var(--text); background: var(--flaeche);
  border: var(--linie) solid var(--rahmen); border-radius: var(--radius);
  padding: calc(var(--luft) * 0.2) calc(var(--luft) * 0.4);
}
.chat-kontext-menue {
  position: fixed; z-index: 82;
  display: flex; flex-direction: column; gap: 0;
  min-width: 12em; max-width: min(22em, 92vw);
  padding: calc(var(--luft) * .4);
  background: var(--flaeche-hoch); color: var(--text);
  border: var(--linie) solid var(--rahmen); border-radius: calc(var(--radius) * 1.6);
}
.chat-kontext-menue button {
  display: block; width: 100%; text-align: left;
  background: transparent; border-color: transparent; color: var(--text);
  padding: calc(var(--luft) * .55) calc(var(--luft) * .7);
  border-radius: var(--radius); font: inherit;
}
.projekt-treffer {
  display: flex; flex-direction: column; gap: calc(var(--luft) * .35);
  margin: calc(var(--luft) * .5) 0; max-width: 100%;
}
.projekt-treffer button { text-align: left; }
.detail-werkzeuge { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.detail-werkzeuge button { font-size: .86em; padding: .34em .7em; }
/* Der Weg zurück dorthin, wo man war (11.08.2026). Er steht links vor der
   Überschrift — dort sucht man einen Rückweg. `flex: 0 0 auto`, damit er dem Titel
   keine Breite abnimmt: genau dieser Fehler steckt in den Chat-Karten. */
#btn-woher { flex: 0 0 auto; font-size: .86em; padding: .3em .7em; white-space: nowrap; }
.detail { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; min-height: 0; }

/* ---------- Hereingleiten (Owner-Order 11.08.2026) ------------------------
   „soll animiert von links nach rechts gleiten" — die neue Seite kommt von links
   herein und wird dabei sichtbar. Nur bei einem gemerkten Sprung (agora.js →
   herkunftAnzeigen), nicht bei jedem Bereichswechsel: eine Oberfläche, die bei
   jedem Klick wandert, wirkt langsam, nicht lebendig.
   `prefers-reduced-motion` ist keine Höflichkeitsgeste: für wen Bewegung Übelkeit
   auslöst, ist das hier eine Zumutung. Der Sprung findet trotzdem statt. */
@keyframes detail-herein {
  from { opacity: 0; transform: translateX(-26px); }
  to   { opacity: 1; transform: translateX(0); }
}
.detail.gleitet-herein > * { animation: detail-herein .3s cubic-bezier(.22, .7, .3, 1) both; }
@media (prefers-reduced-motion: reduce) {
  .detail.gleitet-herein > * { animation: none; }
}
/* „voll" heisst: das Detail scrollt NICHT selbst, sein Inhalt verwaltet die Höhe.
   Der Chat braucht das — sonst wandert das Eingabefeld beim Tippen aus dem Bild. */
.detail.voll { overflow: hidden; display: flex; flex-direction: column; }
.detail.voll > .chat { flex: 1 1 auto; min-height: 0; }
/* DER LESE-DECKEL. 900 px sind rund 90 Zeichen je Zeile — darüber verliert das Auge
   beim Zeilenwechsel den Anschluss. Er gilt für FLIESSTEXT und bleibt dort stehen:
   „Lesbarkeit geht vor Dichte" (Owner 09.08.2026, 21:45, im selben Atemzug wie
   „der Platz wird effizient genutzt"). */
.detail-inhalt { padding: calc(var(--luft) * 1.5) clamp(14px, 4vw, 30px); max-width: var(--max); }
/* ---- ABER: EIN RASTER IST KEIN FLIESSTEXT ---------------------------------
   Owner 09.08.2026: „also ich will, dass der Platz effizient genutzt wird!" — auf
   1400 px stand das Kachel-Raster in Chats in einer 900-px-Spalte und rechts daneben
   war nichts. Ein Deckel, der Zeilenlänge begrenzen soll, hat an einem Gitter aus
   Kacheln keine Aufgabe: dort gibt es keine Zeile, die zu lang werden könnte.

   ZWEI WEGE, UND BEIDE STEHEN HIER MIT ABSICHT:
   · `:has(> .start-raster)` — der Deckel fällt von selbst, sobald ein Raster
     unmittelbar darin steht. Kostet keine Absprache mit den Dateien, denen das
     Markup gehört (bereiche.js, arbeitsbereich.js), und kann deshalb nicht
     auseinanderlaufen. Kennt ein Browser `:has()` noch nicht, verwirft er GENAU
     DIESE eine Regel und es bleibt beim heutigen Verhalten — deshalb steht sie
     allein und nicht in einer Selektorliste mit anderen.
   · `.detail-inhalt.breit` — der ausdrückliche Weg für alle anderen: wer eine
     Seite baut, die die volle Breite verdient, schreibt die Klasse ins Markup und
     ist von `:has()` unabhängig.
   Die Übersicht braucht keinen von beiden — sie ist `ohneListe` und hebt den Deckel
   schon über `.schale[data-ohne-liste="1"]` (siehe oben). */
.detail-inhalt:has(> .start-raster) { max-width: none; }
.detail-inhalt.breit { max-width: none; }
/* Der Zurueck-Knopf gehoert NUR in die schmale Anordnung. Bewusst mit zwei Klassen
   (.detail-kopf .nur-schmal): `button.rund` setzt display:grid und hat mit einer Klasse
   plus einem Element die hoehere Gewichtung als `.nur-schmal` allein — der Knopf stand
   deshalb auch auf dem breiten Bildschirm da, wo er nichts zu tun hat. Gemessen am
   08.08. im Browser (display: grid bei 1476 px), nicht vermutet. */
.detail-kopf .nur-schmal { display: none; }

/* ---------------------------------------------------------------------------
   CHATS: DIE LISTE GIBT ES ERST IM CHAT (Owner-Order 10.08.2026)
   ---------------------------------------------------------------------------
   `data-startbild="1"` setzt agora.js im Router (bereichWechseln), sobald der Bereich
   „chats" ohne geöffneten Chat dasteht. Dann gehört die Fläche den Kacheln.
   Gilt in JEDER Breite: schmal steht die Spalte ohnehin schon auf „detail", die
   Regel ist dort also folgenlos — aber sie macht die Absicht an einer Stelle
   lesbar, statt sie auf zwei Anordnungen zu verteilen. */

/* Einstellungen: durchlaufende Seite, Inhaltsverzeichnis springt, kein Umschalten. */
.e-seite {
  display: flex;
  gap: var(--luft);
  align-items: flex-start;
}
.e-inhalt {
  position: sticky;
  top: 0;
  flex: 0 1 12rem;
  max-width: 12rem;
  display: flex;
  flex-direction: column;
  gap: calc(var(--luft) * 0.5);
  padding: var(--karte-innen) 0;
}
.e-sprung {
  color: var(--gedaempft);
  font-size: var(--schrift-klein);
  padding: calc(var(--zeile-y) * 0.5) 0;
  border-left: 2px solid transparent;
  padding-left: 0.7em;
}
.e-sprung:target,
.e-block:target { scroll-margin-top: var(--luft); }
.e-alle {
  flex: 1;
  min-width: 0;
}
.e-alle .e-block { padding: var(--karte-innen); margin-bottom: var(--raster-abstand);
  background: var(--flaeche); border: var(--linie) solid var(--rahmen); border-radius: var(--radius); }
.e-alle .e-block > h2 { margin: 0; font-family: var(--serif); font-size: var(--schrift-abschnitt); }
.e-alle .e-block-unten { margin: .2em 0 .9em; }
.e-alle .e-block:target, .e-alle .e-block-inhalt:empty { scroll-margin-top: var(--luft); }
.e-schalter-reihe { flex-wrap: wrap; }
@media (max-width: 720px) {
  .e-seite { flex-direction: column; }
  .e-inhalt {
    position: static;
    max-width: none;
    flex: 1 1 auto;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--luft);
    padding: 0 0 var(--luft);
  }
  .e-sprung { border-left: none; padding-left: 0; }
}

/* Auf der Startseite gibt es kein „zurück" — sie IST oben. Schmal stand der Pfeil
   dort trotzdem (die Startseite läuft dort als Detailspalte) und führte ins Leere:
   ein Knopf, der nichts tut, ist schlimmer als keiner. Beim Durchklicken bei 390 px
   aufgefallen, nicht beim Lesen. 0-4-0 schlägt die Regel, die ihn schmal zeigt. */
.schale[data-startbild="1"] .detail-kopf .nur-schmal { display: none; }

/* ---------------------------------------------------------------------------
   EIN BEREICH OHNE LISTE — die Übersicht über die VOLLE BREITE
   ---------------------------------------------------------------------------
   agora.js setzt an der Schale `data-ohne-liste="1"`, sobald der offene Bereich
   `ohneListe: true` anmeldet (heute genau einer: die Übersicht). Bis zum
   09.08.2026 stand dazu in diesem Blatt NICHTS — agora.js räumte die Liste zwar
   leer, ihre 320 px (--listenbreite) standen aber weiter im Raster. Der Owner sah
   also links eine leere Spalte samt Kopf und Fuss: „ALTER ich will links das hier
   nicht haben!" · „ich will EINE UEBERSICHT". Drei Regeln, mehr braucht es nicht:

   · DIE SPALTE FÄLLT WEG, bei jeder Breite. Nicht nur breit: schmal entscheidet
     `data-spalte` zwischen Liste und Detail, und ein Zustand, der eine Spalte
     zeigt, die es in diesem Bereich gar nicht gibt, wäre ein leerer Bildschirm.
   · DAS RASTER HAT NUR NOCH SCHIENE + DETAIL — und zwar NUR BREIT. Schmal
     (≤ 860 px) ist die Schale einspaltig mit der Schiene als Leiste unten;
     diese Regel hier trüge mit ihrer höheren Gewichtung sonst genau dort die
     zwei Spalten wieder ein und schösse die Handy-Anordnung ab. Sie steht
     deshalb hinter `min-width: 861px` — der Gegenwert der einen Grenze, die
     dieses Blatt kennt.
   · DER LESE-DECKEL VON 900 px FÄLLT. Eine Übersicht IST die volle Breite; die
     Kacheln verteilen sich von selbst (auto-fit, uebersicht.css). Für alles mit
     Liste bleibt der Deckel: dort steht Fliesstext, und der wird ab etwa 90
     Zeichen je Zeile unlesbar.

   Der Zurück-Knopf ist schmal ebenfalls weg: AGORA.zurListe() kehrt für einen
   Bereich ohne Liste sofort zurück (agora.js), der Knopf wäre also sichtbar und
   ohne Wirkung. Ein toter Knopf ist schlimmer als keiner. Der Weg heraus ist die
   Schiene — sie steht schmal als Leiste unten und ist immer da. */
.schale[data-ohne-liste="1"] .spalte-liste { display: none; }
/* Der Ausklapper trägt die Chats (die mittlere Spalte ist weg, Owner 30.08.).
   Projekte haben seit 05.09. keinen Ast mehr. Damit die Schiene nicht länger
   wird als der Bildschirm, scrollt der Ast selbst. */
/* `overflow-x` MUSS hier stehen. Wird nur eine Achse gesetzt, rechnet der
   Browser die andere von `visible` auf `auto` hoch (CSS Overflow §3) — und
   genau daher kam der waagerechte Rollbalken im Owner-Abzug. Es ist kein
   Kaschieren: die Zeilen sind seit 06.09. `width: 100%` und laufen nicht mehr
   über (nachgerechnet in tools/test-letzte.js, Abschnitt 7). */
.schiene-ast {
  max-height: min(42vh, 420px);
  overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
}
.schale[data-ohne-liste="1"] .detail-inhalt { max-width: none; }
.schale[data-ohne-liste="1"] .detail-kopf .nur-schmal { display: none; }
@media (min-width: 861px) {
  .schale[data-ohne-liste="1"] { grid-template-columns: var(--schiene) minmax(0, 1fr); }
}
/* Offener Chat: Liste aus dem Raster, Zurück-Knopf bleibt. 0-5-0 schlägt die
   ohne-liste-Ausblendung (0-4-0) darüber. Gilt in jeder Breite.
   05.09.: dasselbe für die Projekt-Ansicht — ohne den Knopf gäbe es nur die
   Schiene als Weg zurück, und der Auftrag verlangt „Projekt-Ansicht mit Zurück". */
.schale[data-bereich="chats"][data-startbild="0"][data-ohne-liste="1"] .detail-kopf .nur-schmal { display: grid; }
.schale[data-bereich="projekte"][data-startbild="0"][data-ohne-liste="1"] .detail-kopf .nur-schmal { display: grid; }

/* Limits: der Schienen-Streifen ist tot (Owner 29.08.). Warnung nur, wenn sie zählt. */
.schiene .ub-streifen, #ub-streifen { display: none; }
.limit-warnung {
  padding: var(--luft) calc(var(--luft) * 1.5);
  background: var(--warn-grund);
  color: var(--text);
  border-bottom: var(--linie) solid var(--warn);
}
.limit-warnung[data-art="deutlich"] {
  background: var(--schlecht-grund);
  border-bottom-color: var(--schlecht);
}
.limit-warnung p { margin: 0; font-size: var(--schrift-klein); }
.limit-warnung p + p { margin-top: calc(var(--luft) * 0.5); }

.abschnitt { margin: 0 0 calc(var(--luft) * 2); }
.abschnitt > h2 {
  margin: 0 0 .5em; font-family: var(--serif); font-size: .95em;
  letter-spacing: 0; text-transform: none;
  color: var(--gedaempft); font-weight: 600;
}
.karte { background: var(--flaeche); border: var(--linie) solid var(--rahmen); border-radius: var(--radius); padding: var(--karte-innen); }
.karte + .karte { margin-top: var(--raster-abstand); }
.feldpaar { display: grid; grid-template-columns: minmax(90px, 26%) minmax(0, 1fr); gap: 4px var(--luft); font-size: .92em; }
.feldpaar dt { color: var(--gedaempft); }
.feldpaar dd { margin: 0; overflow-wrap: anywhere; }

.marke-chip {
  display: inline-flex; align-items: center; gap: 4px; font-size: .74em; font-weight: 600;
  padding: .16em .5em; border-radius: 99px; border: var(--linie) solid var(--rahmen);
  color: var(--gedaempft); background: var(--flaeche-tief); white-space: nowrap;
}
.marke-chip.gut { color: var(--gut); border-color: color-mix(in srgb, var(--gut) 45%, var(--rahmen)); }
.marke-chip.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, var(--rahmen)); }
.marke-chip.schlecht { color: var(--schlecht); border-color: color-mix(in srgb, var(--schlecht) 45%, var(--rahmen)); }
.marke-chip.akzent { color: var(--akzent); border-color: var(--akzent-rand); }

button.chip {
  font-size: .84em; padding: .28em .7em; border-radius: 99px;
  background: var(--flaeche-tief);
}
.chip-reihe { display: flex; flex-wrap: wrap; gap: 6px; }

.hinweis {
  border-left: 3px solid var(--warn); background: var(--flaeche); padding: var(--luft);
  border-radius: 0 var(--radius) var(--radius) 0; font-size: .9em;
}
.hinweis.info { border-left-color: var(--akzent); }
.hinweis.schlimm { border-left-color: var(--schlecht); }
.hinweis p:first-child { margin-top: 0; }
.hinweis p:last-child { margin-bottom: 0; }

/* ---------- Konto: Passwort, zweiter Faktor, Geräte (A4, 23.08.2026) -------
   Drei neue Klassen, mehr nicht — alles andere auf der Konto-Seite sind die
   vorhandenen `.karte`, `.chip-reihe`, `.marke-chip`, `.klein`, `.gedaempft`,
   `.fehler`, `.gut-text`. Kein eigener Farbwert, kein erfundener Abstand: die
   Zahlen unten sind entweder Vielfache von --luft oder die 44 px, die geraet.css
   überall als Fingerziel setzt. */
.k-meldung { margin: .6em 0 0; }

/* Das 2FA-Geheimnis. Dicktengleich, weil man es abtippt — in einer Proportional-
   schrift sind 0/O und 1/l genau die Zeichen, an denen das schiefgeht. Umbruch
   überall erlaubt: 32 Zeichen passen sonst schmal nicht in die Karte. */
.k-geheim {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 1.05em; letter-spacing: .08em; overflow-wrap: anywhere;
  color: var(--akzent); background: var(--akzent-hauch);
  border: var(--linie) solid var(--akzent-rand); border-radius: var(--radius);
  padding: calc(var(--luft) * .6) calc(var(--luft) * .8); margin: var(--luft) 0;
  user-select: all;
}

/* Eine Gerätezeile: Name + Beiwerk links, „Streichen" rechts. `wrap` statt fester
   Spalten — schmal rutscht der Knopf unter den Namen, statt ihn zu quetschen. */
.k-geraet {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--luft);
  padding: calc(var(--luft) * .8) 0;
}
.k-geraet + .k-geraet { border-top: var(--linie) solid var(--rahmen); }
.k-geraet:first-child { padding-top: 0; }
.k-geraet:last-child { padding-bottom: 0; }
.k-geraet-wer { flex: 1 1 12em; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.k-geraet-name { color: var(--text); font-weight: 600; overflow-wrap: anywhere; }
/* Das eigene Gerät hebt sich ab, ohne eine zweite Farbe zu erfinden. */
.k-geraet-hier .k-geraet-name { color: var(--akzent); }
.k-geraet > button { flex: 0 0 auto; min-height: 44px; }

/* ---------- Tickets (ui/support.js) — angeschlossen am 23.08.2026 ----------
   `grep -c "su-" ui/*.css` war an dem Tag in JEDEM Blatt 0: die Datei war nie
   eingebunden, also hatte auch nie jemand ihre Klassen gestaltet. Sie hier
   nachzuziehen gehoert zum Anschliessen — eine Ansicht, die zwar laedt, aber wie
   ein Rohentwurf aussieht, ist nicht angeschlossen, sondern nur sichtbar.
   Uebernommen ist die Bauform, die der Arbeitsbereich schon benutzt: Inhalt
   links, schmale Karte rechts, schmal untereinander. Keine neue Farbe. */
.su-start { display: block; }
.su-schreiben-zeile { display: flex; flex-wrap: wrap; align-items: center; gap: var(--luft); margin-top: var(--luft); }
.su-probe { margin-top: var(--raster-abstand); }

/* Zwei Spalten, aber erst wenn wirklich Platz ist. `--max` ist die Lesebreite
   des Fliesstextes; ein Ticket ist Verlauf UND Akte, das darf breiter. */
.su-blatt { display: flex; flex-direction: column; height: 100%; min-height: 0; gap: var(--raster-abstand); padding: var(--luft) clamp(10px, 3vw, 26px); }
.su-links { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; gap: var(--luft); }
.su-verlauf { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: flex; flex-direction: column; gap: var(--luft); }
.su-seite { flex: 0 0 auto; overflow-y: auto; }
@media (min-width: 1100px) {
  .su-blatt { flex-direction: row; }
  .su-links { flex: 1 1 auto; }
  .su-seite { flex: 0 0 clamp(280px, 30%, 380px); }
}

.su-post { background: var(--flaeche); border: var(--linie) solid var(--rahmen); border-radius: var(--radius); padding: var(--luft); }
/* Wer spricht, sieht man an der Kante — nicht an einer Fuellfarbe, die mit einer
   frei gewaehlten Palette unlesbar werden koennte. */
.su-post.kunde { border-left: 3px solid var(--rahmen); }
.su-post.owner { border-left: 3px solid var(--akzent); }
.su-post.ki { border-left: 3px solid var(--gut); }
.su-post-kopf { display: flex; flex-wrap: wrap; gap: var(--luft); font-size: var(--schrift-klein); color: var(--gedaempft); margin-bottom: .5em; }
.su-post-wer { color: var(--text); font-weight: 600; }
.su-post-text { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.su-post-trocken { margin: .5em 0 0; font-size: var(--schrift-klein); color: var(--warn); }

.su-schreiben { flex: 0 0 auto; }
.su-schreiben textarea { width: 100%; min-height: 5em; resize: vertical; }
.su-kartenkopf { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: var(--luft); }
.su-feld { margin-bottom: var(--luft); }
.su-feld .label { display: block; font-size: var(--schrift-klein); color: var(--gedaempft); margin-bottom: .25em; }
.su-vorschlag { white-space: pre-wrap; overflow-wrap: anywhere; background: var(--flaeche-tief); border: var(--linie) solid var(--rahmen); border-radius: var(--radius); padding: var(--luft); font-size: var(--schrift-klein); }
/* Dieselbe Skala wie `.marke-chip` daneben — hoch/mittel/niedrig sind schlecht/warn/gut. */
.su-dring { display: inline-flex; align-items: center; font-size: .74em; font-weight: 600; padding: .16em .5em; border-radius: 99px; border: var(--linie) solid var(--rahmen); background: var(--flaeche-tief); }
.su-dring.hoch { color: var(--schlecht); border-color: color-mix(in srgb, var(--schlecht) 45%, var(--rahmen)); }
.su-dring.mittel { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, var(--rahmen)); }
.su-dring.niedrig { color: var(--gut); border-color: color-mix(in srgb, var(--gut) 45%, var(--rahmen)); }

/* ---------- Chat ---------------------------------------------------------- */
.chat { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.chat-memory {
  flex: 0 0 auto;
  padding: calc(var(--luft) * .55) clamp(10px, 3vw, 26px);
  font-size: var(--schrift-klein);
  color: var(--gedaempft);
  border-bottom: var(--linie) solid var(--rahmen);
  background: var(--flaeche);
}
.chat-memory.neu { color: var(--warn); }
.nachricht.abgebrochen .nachricht-fuss { color: var(--warn); }
.chat-lauf { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: var(--luft) clamp(10px, 3vw, 26px); }
.nachricht { margin: 0 0 calc(var(--luft) * 1.4); display: flex; flex-direction: column; }
.nachricht.von-mir { align-items: flex-end; }
.blase {
  max-width: min(760px, 92%); padding: calc(var(--zeile-y) + 2px) var(--luft);
  border-radius: calc(var(--radius) * 1.4); border: var(--linie) solid var(--rahmen);
  background: var(--flaeche); overflow-wrap: anywhere;
}
.von-mir .blase { background: var(--akzent-hauch); border-color: var(--akzent-rand); }
.nachricht-fuss { font-size: .72em; color: var(--gedaempft); margin-top: 3px; padding: 0 4px; }
.blase p { margin: .5em 0; }
.blase p:first-child { margin-top: 0; }
.blase p:last-child { margin-bottom: 0; }
.blase pre {
  background: var(--flaeche-tief); border: var(--linie) solid var(--rahmen); border-radius: var(--radius);
  padding: var(--luft); overflow-x: auto; font-size: .88em;
}
.blase code { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; }
.blase :not(pre) > code { background: var(--flaeche-tief); padding: .1em .35em; border-radius: 4px; font-size: .9em; }
.blase ul, .blase ol { margin: .5em 0; padding-left: 1.4em; }
.blase h3, .blase h4 { margin: .8em 0 .3em; font-size: 1em; }
.blase img { max-width: 100%; border-radius: var(--radius); }
.blase table { border-collapse: collapse; font-size: .9em; }
.blase td, .blase th { border: var(--linie) solid var(--rahmen); padding: .3em .6em; }
.denken { font-size: .86em; color: var(--gedaempft); border-left: 2px solid var(--rahmen); padding-left: .8em; margin: 0 0 .6em; white-space: pre-wrap; max-height: 12em; overflow-y: auto; }
.spur { font-size: .8em; color: var(--gedaempft); margin: .4em 0 0; }
.chat-fehler, .chat-kontext, .chat-weiter {
  margin-top: var(--luft);
  padding: var(--luft);
  border: var(--linie) solid var(--warn);
  border-radius: var(--radius);
  background: var(--warn-grund);
}
.chat-fehler p, .chat-kontext p, .chat-weiter p { margin: 0 0 calc(var(--luft) * 0.5); }
.chat-fehler button, .chat-kontext button, .chat-weiter button { margin-top: calc(var(--luft) * 0.25); }

/* Live-Füllstand im Chat (Owner 29.08.): ab 50 % ein schmaler Balken neben der
   Prozentzahl, darunter unsichtbar. Farben nur aus den zehn Feldern. */
.chat-fuellstand {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--luft);
  max-width: 100%;
  padding: calc(var(--luft) * 0.25) 0 0;
  font-size: var(--schrift-klein);
  color: var(--gedaempft);
}
.chat-fuellstand-balken {
  flex: 1 1 8em;
  min-width: 5em;
  max-width: 12em;
  height: calc(var(--linie) * 4);
  border-radius: var(--radius);
  background: var(--rahmen);
  overflow: hidden;
}
.chat-fuellstand-balken > i {
  display: block;
  height: 100%;
  width: var(--stand, 0%);
  background: var(--gut);
  border-radius: var(--radius);
  transition: width var(--normal) var(--kurve);
}
.chat-fuellstand-text { white-space: nowrap; }
.chat-fuellstand--ruhig { color: var(--gedaempft); }
.chat-fuellstand--ruhig .chat-fuellstand-balken > i { background: var(--gut); }
.chat-fuellstand--gelb { color: var(--warn); }
.chat-fuellstand--gelb .chat-fuellstand-balken > i { background: var(--warn); }
.chat-fuellstand--rot { color: var(--schlecht); }
.chat-fuellstand--rot .chat-fuellstand-balken > i { background: var(--schlecht); }
.chat-fuellstand--unbekannt { color: var(--gedaempft); }
.cursor::after { content: "▌"; color: var(--akzent); animation: blinken 1.1s steps(2) infinite; }
@keyframes blinken { 50% { opacity: 0; } }

/* Eingabe: eine weiche Fläche, kein Kasten, kein Rahmen (Owner 29.08.).
   Der alte Regelsatz (border-top, flaeche-tief, Kasten im Kasten) ist gelöscht,
   nicht überschrieben. */
.chat { position: relative; }
.chat-schein {
  pointer-events: none; position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(ellipse at 50% 42%, var(--akzent-hauch), transparent 62%),
    radial-gradient(ellipse at 50% 100%, var(--akzent-weich), transparent 55%);
}
.chat-start, .chat-lauf, .verfasser, .chat-memory { position: relative; z-index: 1; }
.chat-start {
  display: none;
  padding: var(--luft);
  text-align: left;
}
.chat-start:has(#c-kc-folge:not(.versteckt)) { display: block; }
.chat.leer .chat-start {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  flex: 1 1 auto; min-height: 0; text-align: center;
  padding: calc(var(--luft) * 2) var(--luft);
}
.chat.leer .chat-lauf { flex: 0 0 0; min-height: 0; padding: 0; overflow: hidden; }
.chat-leer {
  display: flex; flex-direction: column; align-items: center; gap: var(--luft);
  max-width: min(var(--max), 100%); margin: 0 auto;
}
.chat-leer-zeichen {
  width: calc(var(--kopf-zeichen) * 1.8); height: calc(var(--kopf-zeichen) * 1.8);
  display: block;
}
.chat-leer-wort {
  margin: 0; font-family: var(--serif); font-size: var(--schrift-titel);
  font-weight: 600; color: var(--text); letter-spacing: 0.04em;
}
.chat-leer-stand { margin: 0; }
.chat-leer-karten {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--kachel-min)), 1fr));
  gap: var(--luft); width: 100%; max-width: min(var(--max), 100%);
  text-align: left;
}
.chat-leer-karte { width: 100%; }
.chat-start h2 {
  margin: 0 0 var(--luft);
  font-family: var(--serif); font-size: var(--schrift-titel); font-weight: 600;
  color: var(--text);
}
.verfasser {
  margin: 0 auto var(--luft);
  padding: var(--luft);
  width: calc(100% - var(--luft) * 2);
  max-width: min(var(--max), 100%);
  background: var(--flaeche);
  border: 0;
  border-radius: calc(var(--radius) * 2.2);
}
.verfasser-kopf {
  display: flex; align-items: center; gap: calc(var(--luft) * .4);
  flex: 1 1 auto; min-width: 0; margin: 0; flex-wrap: wrap;
}
.verfasser-kopf select {
  width: auto; max-width: 100%; font-size: var(--schrift-klein);
  background: transparent; border-color: transparent; padding: .2em .5em;
}
/* Der Knopf wächst mit dem Modellnamen. 12em + flex-shrink hat „Opu… 1…" erzeugt.
   flex: 0 0 auto und min-width: max-content, damit die Zeile den Namen nicht
   quetscht. Unter 420 px darf er umbrechen — dann min-width 0, sonst ragt er. */
.verfasser-kopf .mw,
.verfasser-kopf .wahl {
  flex: 0 0 auto;
  width: max-content; max-width: 100%; min-width: max-content;
  font-size: var(--schrift-klein);
}
.verfasser-zeile { display: flex; flex-direction: column; gap: calc(var(--luft) * .5); }
.verfasser textarea {
  resize: none; min-height: 2.8em; max-height: 40vh; line-height: 1.45; font-size: 1em;
  background: transparent; border: 0; padding: calc(var(--luft) * .25);
  color: var(--text);
}
.verfasser textarea:focus, .verfasser textarea:focus-visible {
  outline: none; border: 0;
}
.verfasser-fuss {
  display: flex; align-items: center; gap: calc(var(--luft) * .4);
}
.verfasser-fuss-rechts {
  margin-left: auto; display: flex; align-items: center; gap: calc(var(--luft) * .4);
}
.verfasser .senden {
  flex: 0 0 auto; background: var(--akzent); color: var(--akzent-text);
  border-color: transparent; width: 2.6em; height: 2.6em;
  display: grid; place-items: center; padding: 0; border-radius: 50%;
}
.verfasser .senden.stop { background: var(--schlecht); color: var(--akzent-text); }
.verfasser .senden.stoppt { opacity: .55; }
.verfasser.fallen {
  background: var(--akzent-weich);
  outline: var(--linie) dashed var(--akzent-rand);
  outline-offset: calc(var(--linie) * -2);
}
.verfasser-ablegen {
  display: none; text-align: center; color: var(--akzent);
  font-size: var(--schrift-klein); padding: calc(var(--luft) * .25);
}
.verfasser.fallen .verfasser-ablegen { display: block; }
.plus-ort { position: relative; }
.plus-menue {
  /* 30.08.2026, Owner: „mach es zur Not breiter, wenn es nicht gross genug ist — nicht
     so nach oben oder unten." Vorher 16-22em: „mehrere Agenten arbeiten zusammen" brach
     auf drei Zeilen um und das Menue wuchs in die Hoehe. Jetzt darf es breit werden und
     bleibt flach. 34em statt mehr, damit es auf 420 px nicht aus dem Fenster laeuft —
     die zweite Grenze (90vw) faengt schmale Fenster ab. */
  position: absolute; left: var(--luft); bottom: 100%; z-index: 8;
  min-width: 22em; max-width: min(34em, 90vw);
  padding: calc(var(--luft) * .5); margin-bottom: calc(var(--luft) * .4);
  background: var(--flaeche-hoch); border: 0;
  border-radius: calc(var(--radius) * 1.6);
}
.plus-menue[hidden] { display: none; }
.plus-menue button {
  display: flex; align-items: center; gap: calc(var(--luft) * .6);
  width: 100%; text-align: left; background: transparent; border-color: transparent;
  color: var(--text); padding: calc(var(--luft) * .55) calc(var(--luft) * .7);
  border-radius: var(--radius);
}
.plus-menue button[data-slash] { flex-wrap: wrap; }
.plus-menue button[data-slash] .klein { flex: 1 1 100%; }
.plus-menue button[aria-selected="true"] { background: var(--akzent-hauch); color: var(--akzent); }
@media (hover: hover) {
  /* Globales button:hover setzt --akzent-rand. Plus und Slash sind dieselbe
     Karte wie .wahl-liste — ohne Aussenlinie, Markierung nur Fläche. */
  .plus-menue button:hover:not(:disabled) {
    background: var(--flaeche);
    border-color: transparent;
    color: var(--text);
  }
  .plus-menue button[aria-selected="true"]:hover:not(:disabled) {
    background: var(--akzent-hauch);
    color: var(--akzent);
    border-color: transparent;
  }
}
.plus-menue .plus-leer { padding: calc(var(--luft) * .55) calc(var(--luft) * .7); }
#c-slash { font-weight: 700; }
.plus-menue .plus-trenn {
  height: var(--linie); background: var(--linie);
  background: color-mix(in srgb, var(--text) 12%, transparent);
  margin: calc(var(--luft) * .35) calc(var(--luft) * .4);
  border: 0;
}
.team-tafel {
  display: flex; flex-wrap: wrap; gap: var(--luft); align-items: center;
  max-width: 36em; padding: calc(var(--luft) * .4) 0;
}
.team-tafel select { max-width: 8em; }
.team-karte { margin-top: var(--luft); }
.team-spuren { margin: calc(var(--luft) * .3) 0 0; padding-left: calc(var(--luft) * 1.2); }
.recherche-karte { margin-top: var(--luft); }
.plus-unter {
  position: absolute; left: 100%; top: 0; z-index: 9;
  min-width: 14em; max-height: 16em; overflow: auto;
  padding: calc(var(--luft) * .5); margin-left: calc(var(--luft) * .35);
  background: var(--flaeche-hoch); border: 0;
  border-radius: calc(var(--radius) * 1.4);
}
.plus-unter[hidden] { display: none; }

/* Dunkle Ausklappliste (OSWahl) — dieselbe Karte wie .plus-menue.
   Native <select>-Popups sind nicht durchgestaltbar. */
.wahl { position: relative; display: inline-flex; max-width: 100%; vertical-align: middle; }
.wahl-ausloeser {
  display: inline-flex; align-items: center; gap: calc(var(--luft) * .4);
  max-width: 100%; width: max-content;
  background: transparent; border-color: transparent; color: var(--text);
  padding: calc(var(--luft) * .25) calc(var(--luft) * .5);
  font: inherit; font-size: var(--schrift-klein);
  border-radius: var(--radius);
}
.wahl-name { white-space: nowrap; overflow: visible; min-width: max-content; flex: 0 0 auto; }
.wahl-pfeil { flex: none; color: var(--gedaempft); }
.wahl-ausloeser[aria-expanded="true"] .wahl-pfeil { transform: rotate(.5turn); }
.wahl-ausloeser:focus { outline: none; }
.wahl-ausloeser:focus-visible {
  outline: var(--linie) solid var(--fokus);
  outline-offset: var(--linie);
}
.wahl-liste {
  position: fixed; z-index: 40;
  min-width: 10em; max-width: min(92vw, 36em);
  max-height: 60vh; overflow: auto;
  padding: calc(var(--luft) * .5);
  background: var(--flaeche-hoch); border: 0;
  border-radius: calc(var(--radius) * 1.6);
  color: var(--text);
}
.wahl-liste-koerper { display: flex; flex-direction: column; gap: var(--linie); }
.wahl-gruppenkopf {
  padding: calc(var(--luft) * .35) calc(var(--luft) * .7);
  color: var(--gedaempft); font-size: var(--schrift-klein);
  font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
.wahl-zeile {
  display: flex; align-items: center;
  width: 100%; text-align: left;
  background: transparent; border: 0;
  color: var(--text);
  padding: calc(var(--luft) * .55) calc(var(--luft) * .7);
  border-radius: var(--radius); cursor: pointer;
}
.wahl-zeile-name { white-space: nowrap; overflow: visible; min-width: max-content; flex: 0 0 auto; }
.wahl-zeile--aktiv,
.wahl-zeile--gewaehlt { background: var(--akzent-hauch); color: var(--akzent); }
.wahl-zeile[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.wahl-zeile:focus { outline: none; }
.wahl-zeile:focus-visible {
  outline: var(--linie) solid var(--fokus);
  outline-offset: var(--linie);
}
.wahl-leer {
  padding: calc(var(--luft) * .55) calc(var(--luft) * .7);
  color: var(--gedaempft); font-size: var(--schrift-klein);
}
@media (hover: hover) {
  .wahl-ausloeser:hover:not(:disabled) {
    background: var(--flaeche-hoch); color: var(--text); border-color: transparent;
  }
  .wahl-zeile:hover:not([aria-disabled="true"]):not(.wahl-zeile--aktiv) { background: var(--flaeche); }
}
@media (max-width: 420px) {
  .verfasser-kopf .mw,
  .verfasser-kopf .wahl { min-width: 0; }
  .wahl-ausloeser { flex-wrap: wrap; }
  .wahl-name { white-space: normal; min-width: 0; }
  .wahl-zeile-name { white-space: normal; min-width: 0; }
}

/* HIER STANDEN `.stufe-wort` und `.denken-schalter` — Denk-Stufe, Internet
   und „denken lassen" als eigene Leisten-Knöpfe. Die Eingabezeile trägt nur
   noch + (Dateien) und / (Optionen); die Felder #c-denken/#c-stufe sind
   hidden. Der alte Satz ist gelöscht, nicht überschrieben: sonst träfe er
   nichts, bliebe aber als tote Form stehen. */

/* ---------- Modellwahl (Combobox statt nacktem <select>) -------------------
   Farben, Radien, Abstände, Schrift, Bewegung: nur vorhandene Variablen.
   --tap ist die 44-px-Kante, die diese Datei in der schmalen Anordnung schon
   als Fingerziel führt. 16 px am Suchfeld ist dieselbe Schwelle wie weiter
   unten bei input/select (iOS zoomt sonst die Seite fest). */
.mw { position: relative; flex: 0 0 auto; width: max-content; min-width: max-content; max-width: 100%; }
.mw-ausloeser {
  display: flex; align-items: center; gap: var(--luft); width: max-content; max-width: 100%;
  min-height: var(--tap); padding: var(--zeile-y) var(--luft);
  text-align: left; font: inherit; font-size: max(16px, 1em);
  color: var(--text); background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen); border-radius: var(--radius);
}
.mw-ausloeser:focus { outline: none; }
.mw-ausloeser:focus-visible {
  outline: var(--linie) solid var(--fokus);
  outline-offset: var(--linie);
}
.mw-aktuell-name { font-weight: 600; flex: 0 0 auto; min-width: max-content; overflow: visible; white-space: nowrap; }
.mw-aktuell-info { margin-left: auto; color: var(--gedaempft); font-size: var(--schrift-klein); font-variant-numeric: tabular-nums; white-space: nowrap; }
.mw-pfeil { flex: none; color: var(--gedaempft); }
/* Die Auslastung am Modell-Knopf (Owner 30.08.: die Zahl gehoert dorthin, wo man
   das Modell waehlt — nicht in einen Streifen ueber der ganzen Seite). */
.mw-aktuell-info[data-last="hoch"] { color: var(--warn); }
.mw-aktuell-info[data-last="voll"] { color: var(--schlecht); font-weight: 600; }

/* Der Konto-Chip neben dem Modell. KEIN Gelb: der Owner am 30.08. — „andere Farbe,
   nicht so ein Gelb, ist kaum lesbar." Ruhig gedaempft, ab 75 % der Akzent (Orange,
   auf dunklem Grund gut lesbar), ab 90 % die Fehlerfarbe. */
.mw-limit {
  flex: none; margin-left: calc(var(--luft) * 0.5);
  padding: calc(var(--luft) * 0.25) calc(var(--luft) * 0.6);
  color: var(--gedaempft); background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen); border-radius: var(--radius);
  font-size: var(--schrift-klein); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.mw-limit[data-last="hoch"] { color: var(--akzent); border-color: var(--akzent); }
.mw-limit[data-last="voll"] { color: var(--schlecht); border-color: var(--schlecht); font-weight: 600; }

/* Die Karte zum Konto-Chip. Sitzt ueber der Zeile, nicht darunter: unter der
   Eingabe ist kein Platz, sie wuerde aus dem Fenster fallen. */
.mw-limit-karte {
  position: absolute; bottom: calc(100% + var(--luft)); left: 0; z-index: 50;
  min-width: 22em; max-width: min(30em, calc(100vw - var(--luft) * 4));
  padding: var(--luft);
  background: var(--flaeche-tief); color: var(--text);
  border: var(--linie) solid var(--rahmen); border-radius: var(--radius);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .5);
  font-size: var(--schrift-klein); line-height: 1.5;
}
.mw-lk-kopf { font-weight: 600; margin-bottom: calc(var(--luft) * 0.5); }
.mw-lk-zeile {
  display: flex; align-items: baseline; gap: var(--luft);
  padding: calc(var(--luft) * 0.3) 0;
}
.mw-lk-zeile + .mw-lk-zeile { border-top: var(--linie) solid var(--rahmen); }
.mw-lk-name { flex: 1 1 auto; }
.mw-lk-werte { flex: none; font-variant-numeric: tabular-nums; color: var(--gedaempft); }
.mw-lk-f { color: var(--gedaempft); font-size: .9em; }
.mw-lk-zeile.ist-frei .mw-lk-name { color: var(--gut); font-weight: 600; }
.mw-lk-zeile.ist-frei .mw-lk-werte { color: var(--text); }
.mw-lk-marke {
  flex: none; padding: 0 calc(var(--luft) * 0.4);
  color: var(--gut); border: var(--linie) solid var(--gut); border-radius: var(--radius);
  font-size: .85em;
}
.mw-lk-fuss {
  margin-top: calc(var(--luft) * 0.5); padding-top: calc(var(--luft) * 0.4);
  border-top: var(--linie) solid var(--rahmen); color: var(--gedaempft);
}
/* Der Chip traegt die Karte — deshalb ein eigener Bezugsrahmen. */
.verfasser-kopf { position: relative; }

/* Der Konto-Hinweis: schwebt, statt im Raster zu sitzen — ein Streifen im Raster
   hat am 30.08. die halbe Oberflaeche verdeckt. Wegklickbar, kommt bei 60/75/90 %. */
.limit-hinweis {
  /* Sitzt IN der Verfasser-Zeile, ueber der Eingabe (Owner 30.08.: „nur bei dem
     Chat ueber dem Input"). Kein position:fixed — ein schwebender Kasten in der
     Ecke war der zweite Fehlversuch, der Streifen oben der erste. */
  display: flex; flex-direction: column; gap: calc(var(--luft) * 0.5);
  margin: 0 0 calc(var(--luft) * 0.5);
  padding: calc(var(--luft) * 0.5) var(--luft);
  background: var(--warn-grund); color: var(--text);
  border: var(--linie) solid var(--warn); border-radius: var(--radius);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .45);
  font-size: var(--schrift-klein);
}
.limit-hinweis[data-art="voll"] { background: var(--schlecht-grund); border-color: var(--schlecht); }
.limit-hinweis-zeile { display: flex; align-items: center; gap: var(--luft); }
.limit-hinweis-zeile > span { flex: 1 1 auto; }
.limit-hinweis-zu {
  flex: none; min-width: calc(var(--tap) * 0.6); min-height: calc(var(--tap) * 0.6);
  color: var(--gedaempft); background: none; border: 0; border-radius: var(--radius);
  font: inherit; font-size: 1.1em; cursor: pointer;
}
.limit-hinweis-zu:hover { color: var(--text); }
.mw[aria-expanded="true"] .mw-pfeil,
.mw-ausloeser[aria-expanded="true"] .mw-pfeil { transform: rotate(.5turn); }
.mw-fenster {
  position: fixed; z-index: 40; display: flex; flex-direction: column;
  max-height: 60vh; min-width: 0;
  background: var(--flaeche); color: var(--text);
  border: var(--linie) solid var(--rahmen); border-radius: var(--radius);
}
.mw-fenster[hidden] { display: none; }
.mw-suche {
  flex: none; width: 100%; min-height: var(--tap);
  padding: var(--zeile-y) var(--luft);
  border: 0; border-bottom: var(--linie) solid var(--rahmen);
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--flaeche-tief); color: var(--text);
  font: inherit; font-size: max(16px, 1em);
}
.mw-koerper { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.mw-liste { padding: calc(var(--luft) * 0.5); }
.mw-gruppenkopf {
  position: sticky; top: 0; z-index: 1;
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--luft);
  padding: var(--zeile-y) var(--luft);
  background: var(--flaeche); color: var(--gedaempft);
  font-size: var(--schrift-klein); font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
.mw-anzahl { font-weight: 400; font-variant-numeric: tabular-nums; }
.mw-zeile {
  display: flex; flex-direction: column; justify-content: center; gap: calc(var(--linie) * 2);
  min-height: var(--tap); padding: var(--zeile-y) var(--luft);
  border-radius: var(--radius); cursor: pointer;
}
.mw-zeile-oben, .mw-zeile-unten { display: flex; align-items: center; gap: calc(var(--luft) * 0.5); min-width: 0; }
.mw-zeile-oben { flex-wrap: wrap; }
.mw-name { font-weight: 600; flex: 0 0 auto; min-width: max-content; overflow: visible; white-space: nowrap; }
.mw-kontext { margin-left: auto; flex: none; color: var(--gedaempft); font-size: var(--schrift-klein); font-variant-numeric: tabular-nums; }
.mw-zeile-unten { color: var(--gedaempft); font-size: var(--schrift-klein); }
.mw-preis--gratis { color: var(--gut); font-weight: 700; }
.mw-abzeichen {
  padding: 0 calc(var(--luft) * 0.5);
  border: var(--linie) solid var(--rahmen); border-radius: calc(var(--radius) * 2);
  font-size: var(--schrift-klein); white-space: nowrap;
}
.mw-abzeichen--gesperrt { color: var(--schlecht); border-color: var(--schlecht); font-weight: 700; }
.mw-zeile--aktiv { background: var(--akzent-hauch); color: var(--text); }
.mw-zeile--aktiv :is(.mw-kontext, .mw-preis) { color: inherit; }
.mw-zeile--gewaehlt .mw-name::after { content: " ✓"; color: var(--akzent); font-weight: 700; }
.mw-zeile--aktiv.mw-zeile--gewaehlt .mw-name::after { color: inherit; }
.mw-zeile--gesperrt { cursor: not-allowed; opacity: .45; }
.mw-hinweis {
  min-height: var(--tap); display: grid; place-content: center; justify-items: center;
  gap: var(--luft); padding: var(--luft); color: var(--gedaempft); text-align: center;
}
.mw-hinweis[hidden] { display: none; }
.mw-hinweis button { min-height: var(--tap); }
@media (max-width: 420px) {
  .mw { min-width: 0; width: 100%; }
  .mw-ausloeser { flex-wrap: wrap; width: 100%; }
  .mw-aktuell-name { white-space: normal; min-width: 0; }
  .mw-aktuell-info { margin-left: 0; flex: 1 0 100%; }
  .mw-name { white-space: normal; min-width: 0; }
  .mw-kontext { flex: 1 0 100%; margin-left: 0; }
}
.mw-fuss {
  display: flex; justify-content: space-between; gap: var(--luft);
  padding: var(--zeile-y) var(--luft);
  border-top: var(--linie) solid var(--rahmen);
  color: var(--gedaempft); font-size: var(--schrift-klein);
}
@media (hover: none) { .mw-kuerzel { display: none; } }
@media (hover: hover) {
  .mw-ausloeser:hover { border-color: var(--akzent-rand); }
  .mw-zeile:hover:not(.mw-zeile--gesperrt):not(.mw-zeile--aktiv) { background: var(--flaeche-hoch); }
}
/* Ebenso der Doc-Editor: sein font-size stand inline und schlug damit JEDE Regel,
   auch die 16-px-Regel der schmalen Anordnung (iOS zoomt sonst beim Antippen hinein). */
.doc-editor { font-family: ui-monospace, Consolas, monospace; font-size: .88em; }

/* ---------- Werkzeug-/Funktions-Karten ------------------------------------ */
.stufen-leiter { display: flex; gap: 4px; align-items: center; font-size: .78em; }
.stufen-leiter span { padding: .2em .6em; border-radius: 99px; border: var(--linie) solid var(--rahmen); color: var(--gedaempft); }
.stufen-leiter span[data-hier="ja"] { background: var(--akzent); color: var(--akzent-text); border-color: transparent; font-weight: 700; }

.farbgitter { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--luft); }
.farbzeile { display: flex; align-items: center; gap: 8px; }
.farbzeile input[type="color"] { flex: 0 0 44px; width: 44px; }
.farbzeile input[type="text"] { flex: 1 1 auto; font-family: ui-monospace, Consolas, monospace; font-size: .88em; }
.farbzeile-titel { font-size: .82em; color: var(--gedaempft); margin-bottom: 3px; }

/* `flex-wrap: wrap` seit 11.08.2026: seit die Abo-Gruppen nebeneinander stehen, ist
   eine Zeile nicht mehr fensterbreit. Ohne den Umbruch quetscht der Flex-Kasten Name
   und Knöpfe zusammen, bis beide unlesbar sind — mit ihm rutschen die Knöpfe eine
   Zeile tiefer. Auf breiten Zeilen ändert sich nichts: was passt, bricht nicht um. */
.tabzeile { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: var(--zeile-y) 0; border-bottom: var(--linie) solid var(--rahmen); }
.tabzeile:last-child { border-bottom: 0; }
/* 14em Grundbreite, damit der Name die Zeile aufspannt und die Knöpfe umbrechen —
   nicht umgekehrt. Bei `1 1 auto` schrumpft der Name zuerst, weil er der einzige
   schrumpffähige Kasten ist, und genau das war der abgeschnittene Kontoname. */
.tabzeile .wachs { flex: 1 1 14em; min-width: 0; }
.tabzeile .zweck { font-size: .8em; color: var(--gedaempft); }
/* Das Ankreuzfeld UND seine Beschriftung sind EIN Ziel: ein Tipp auf „Chats — alle
   Gespräche" schaltet den Tab an oder aus. Vorher war nur das 24 px grosse Kästchen
   selbst anzutippen — auf dem Handy das kleinste Ziel der ganzen Seite. */
.tab-schalter { display: flex; align-items: center; gap: 10px; margin: 0; min-width: 0;
  color: var(--text); font-size: 1em; cursor: pointer; }
.tab-schalter .zweck { display: block; }

.wahlreihe { display: flex; flex-wrap: wrap; gap: 6px; }
.wahlreihe button[aria-pressed="true"] { background: var(--akzent); color: var(--akzent-text); border-color: transparent; }

/* ---------- Abo-Gruppen: Inhalt bestimmt die Breite (01.09.2026) ----------
   GEMESSEN am lebenden Stand: vier Gruppen, Raster `minmax(30em, 1fr)`.
   `--max` ist 68rem, 30em×3 passt nicht — also genau zwei Spalten. Das leere
   OpenAI-Feld nahm den Platz neben Anthropic, xAI rutschte in die nächste
   Zeile. Owner 01.09.: „wenn das eine Claude aus ist, soll oben xAI neben
   Claude sein. Ich will nicht, dass es unnötig nach unten geht, lang."

   Deshalb KEIN Raster mit fester Untergrenze und KEIN `1fr` (das zieht eine
   leere Gruppe auf dieselbe Breite wie eine volle). Flex-Zeile, Gruppen so
   breit wie ihr Inhalt, Umbruch erst wenn `--karten-min` nicht mehr nebeneinander
   passt. Leere Anbieter liegen in `.abo-gruppen-leer` darunter — eine schmale
   Verbind-Zeile, keine Spalte, kein Loch.

   `margin: 0` an den Kindern: `.abschnitt` bringt sonst einen unteren Rand mit,
   und der würde zum `gap` addieren. Der Abstand steht EINMAL am Flex. */
.abo-gruppen {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: var(--luft) calc(var(--luft) * 2);
}
.abo-gruppen > .abo-gruppe {
  flex: 1 1 var(--karten-min);
  min-width: min(100%, var(--karten-min));
  margin: 0;
}
.abo-gruppen-leer {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: var(--luft);
  margin-top: var(--luft);
}
.abo-gruppen-leer > .abo-gruppe {
  flex: 0 1 auto;
  min-width: 0;
  margin: 0;
}
.abo-gruppe.leer > h2 { margin-bottom: calc(var(--luft) * .35); }

/* ---------- Toast und Dialog ---------------------------------------------- */
/* pointer-events:none — der Toast ist eine MELDUNG, kein Bedienelement. Gemessen am
   08.08.2026 bei 390×844: er lag mit [781,822] über der Schiene [789,844], und
   document.elementFromPoint() in der Mitte des „Tools"-Knopfs lieferte den Toast.
   Er kommt genau nach „Gespeichert · Gelöscht · Umbenannt" — also genau dann, wenn der
   Nächste Griff der Tab-Wechsel ist — und schluckte ihn 3,6 Sekunden lang.
   Zwei Massnahmen, weil eine allein zu wenig ist: er lässt Tipper durch UND er sitzt in
   der schmalen Anordnung über der Schiene, damit er sie auch nicht mehr VERDECKT. */
.toast {
  /* 🔴 30.08.2026, Owner: „das Popup ist nicht ueber den Nachrichten, sondern mitten im
     Weg — lass es von unten reinfliegen, also UEBER dieses Nachricht-Eingeben."
     bottom: 22px legte den Hinweis mitten auf die Eingabezeile: er verdeckte genau das
     Feld, in dem man gerade tippt. Jetzt raeumt er die Zeile und kommt von unten herein.
     --eingabe-hoehe setzt die Oberflaeche, wo sie die Zeile misst; 104px ist der
     gemessene Normalfall, falls sie es (noch) nicht tut. */
  position: fixed; left: 50%; bottom: calc(var(--eingabe-hoehe, 104px) + 14px);
  transform: translateX(-50%);
  background: var(--flaeche); color: var(--text); border: var(--linie) solid var(--rahmen);
  border-left: 3px solid var(--akzent);
  padding: .6em 1em; border-radius: var(--radius); max-width: 90vw; z-index: 96;
  pointer-events: none;
  animation: toast-herein .18s ease-out;
}
@keyframes toast-herein {
  from { opacity: 0; transform: translateX(-50%) translateY(14px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .toast { animation: none; }
}
.toast.err { border-left-color: var(--schlecht); }
.toast.warn { border-left-color: var(--warn); }
.toast.ok { border-left-color: var(--gut); }

.dialog-schicht {
  position: fixed; inset: 0; z-index: 95; display: grid; place-items: center; padding: 18px;
  background: color-mix(in srgb, var(--hintergrund) 72%, transparent);
}
/* Owner-Order 10.08.2026: „wenn ich auf meinem Ultra-Curved bin und das so klein ist -
   mach die groesser, damit die ganze Auflösung auch genutzt wird."
   420 px waren fuer JEDEN Schirm gleich - auf einem Ultrawide steht der Dialog als
   Briefmarke in der Mitte, waehrend links und rechts je 800 px leer bleiben.
   Gestaffelt statt prozentual: ein Dialog ist meistens ein Satz Text und ein Feld, und
   Fliesstext ueber ~90 Zeichen liest sich schlechter, nicht besser. Deshalb waechst er
   in Stufen bis 760 px und danach nicht weiter - `min()` deckelt zusaetzlich gegen die
   Fensterbreite, damit ein SCHMALES Fenster auf einem breiten Schirm nicht ueberlaeuft. */
.dialog { width: 100%; max-width: 420px; background: var(--flaeche); border: var(--linie) solid var(--rahmen);
  border-radius: calc(var(--radius) * 1.4); padding: var(--karte-innen); }
.dialog h3 { margin: 0 0 .4em; font-family: var(--serif); font-size: var(--schrift-abschnitt); }
.dialog-knoepfe { display: flex; gap: 8px; justify-content: flex-end; margin-top: var(--luft); }
@media (min-width: 1500px) { .dialog { max-width: min(560px, 90vw); } }
@media (min-width: 2100px) { .dialog { max-width: min(680px, 90vw); } }
@media (min-width: 2800px) { .dialog { max-width: min(760px, 90vw); } }

/* ---------- Ladebalken ---------------------------------------------------- */
.laedt { height: 2px; background: var(--akzent); animation: laufen 1s ease-in-out infinite; transform-origin: left; }
@keyframes laufen { 0% { transform: scaleX(.05); } 50% { transform: scaleX(1); } 100% { transform: scaleX(.05); } }

/* ===========================================================================
   SCHMAL — Handy und Tablet hoch
   ===========================================================================
   Liste und Detail teilen sich EINEN Platz und werden geschoben, statt gestapelt:
   data-spalte auf der Schale entscheidet, welche man sieht. Die Schiene wandert
   nach unten — auf einem Handy ist der Daumen unten, nicht links oben.
   Der Umschalter bleibt damit sichtbar, auch wenn das Detail offen ist: genau das
   ist der Punkt dieses Entwurfs, es gibt nie einen Seitenwechsel.
   =========================================================================== */
@media (max-width: 860px) {
  /* ---- DIE ZEILE STEHT AUCH SCHMAL, IN VOLLER BREITE --------------------
     ⚠️ HIER STAND BIS ZUM 09.08.2026 DER LUPEN-SCHALTER, und zwar noch, nachdem
     er in agora.js gelöscht worden war: vier Regeln auf `.nur-schmal-block` und
     `.kopf[data-offen="0"|"1"]`. Sichtbar war davon nichts — drei `!important`
     weiter unten im Blatt (`\.kopf .zeile-box { display: flex !important }`) haben
     sie betäubt. Betäubt ist aber nicht weg: `data-offen="0"` stand am <header>,
     ein `display: none` lauerte darauf, und wer die drei `!important` je für
     überflüssig hielte, hätte die Zeile auf 390 px ersatzlos ausgeblendet — ohne
     jeden Weg zurück, denn den Knopf, der sie aufklappte, gibt es nicht mehr.
     Der Owner wörtlich: „nix 0 oder 1, weg damit" und „baue das fuer keine
     backdoor um das wieder anzumachen". Eine tote Regel, die nur durch eine
     zweite Regel tot bleibt, IST diese Hintertür. Also gelöscht, nicht
     überschrieben — dasselbe, was agora.js mit dem Zustand gemacht hat.
     Was bleibt: die Zeile nimmt schmal die volle Kopfbreite, das Konto oben
     rechts weicht (siehe #kopf-konto unten), Zurück-Weg und Chat-Titel im
     Detailkopf behalten ihren Platz. */
  .zeile-box input { padding-right: 42px; }
  .zeile-leer { right: 6px; }
  #kopf-konto { display: none; }

  .schale {
    grid-template-columns: 100%;
    grid-template-rows: minmax(0, 1fr) auto;
  }
  .schiene {
    grid-row: 2; flex-direction: row; justify-content: space-evenly;
    border-right: 0; border-top: var(--linie) solid var(--rahmen);
    padding: 5px 4px calc(5px + env(safe-area-inset-bottom));
  }
  .schiene-marke { display: none; }
  .schiene-gruppe { flex-direction: row; width: auto; min-width: 0; }
  .schiene-unten { margin-top: 0; }
  /* HIER BLEIBT ALLES WIE ES WAR: Wort UNTER dem Symbol, Knopf nur so breit wie sein
     Wort. Breit stehen Symbol und Wort nebeneinander (`.schiene button`, oben) — das
     wird hier zurückgedreht, sonst frässe eine liegende Leiste mit fünf beschrifteten
     Knöpfen die halbe Bildschirmbreite.
     Fünf beschriftete Knöpfe müssen auf 390 px passen, ohne dass die Seite quer
     scrollt: die feste Knopfbreite fällt weg. Gemessen bei 390 px — sonst hätte
     „Einstellungen" die Schiene gesprengt. */
  .schiene button {
    width: auto; min-width: 44px; max-width: 33vw; min-height: 44px;
    flex-direction: column; align-items: center; gap: 2px;
    padding: 5px 5px 4px; text-align: center;
  }
  .schiene-wort { font-size: .6em; flex: 0 0 auto; max-width: 100%; }
  /* Symbol wieder mittig → Punkt an seine Ecke zurück (siehe „SCHIENE EINGEKLAPPT"). */
  .schiene .punkt { left: auto; right: calc(50% - 15px); top: 4px; }
  /* Einklappen sitzt in der Übersicht-Box (siehe .schiene-oben-box oben). Die
     alte Ausblendung `.schiene .schiene-klapp { display: none }` ist gelöscht:
     sie war für den Kopf-Knopf gebaut und traf ihn, sobald er in der Schiene
     wohnte. Auf 420 px bleibt der Knopf in der Box sichtbar und klappt. */

  /* DER AUSLASTUNGS-STREIFEN BLEIBT AUF DEM HANDY WEG. uebersicht.css blendet ihn hier
     schon aus (`.ub-streifen { display: none }`) — seit dieses Blatt den Streifen mit
     `.schiene .ub-streifen` (0-2-0) formt, verliert diese Regel aber gegen die eigene.
     Also steht die Ausblendung HIER noch einmal, mit derselben Gewichtung wie die
     Formgebung. Ohne sie stünden vier Balken samt Name, Plan und Massstab-Satz mitten
     in der liegenden Leiste am unteren Rand und schöben die Knöpfe vom Bildschirm.
     Auf dem Handy führt der Weg zur Auslastung über den Tab „Übersicht" — einen Tipp
     entfernt statt gequetscht. */
  .schiene .ub-streifen { display: none; }
  /* Hier stand bis zum 10.08.2026 die Sonderbehandlung für „Farben retten" auf 390 px
     (Symbol ohne Wort, damit sechs Knöpfe nebeneinander passen). Der Knopf ist weg —
     damit sind es fünf, und die passen ohne Kniff. */
  /* Liste und Detail teilen sich schmal EINEN Platz — es gibt nichts auszublenden.
     ⚠️ ZWEI SELEKTOREN, UND DER ZWEITE IST DER, DER WIRKT. `.nur-breit` allein wiegt
     0-1-0 und verliert gegen `button.rund { display: grid }` (0-1-1, Zeile 128) — der
     einzige Träger dieser Klasse ist `#btn-liste-klapp`, und der IST ein `button.rund`.
     Gemessen mit der Kaskaden-Attrappe: bei 390 px löste sich `display` auf `grid` auf,
     der Knopf „Liste ausblenden" stand also im Detailkopf eines Handys — wo er nichts
     tut, weil `body.liste-zu` nur hinter `min-width: 861px` überhaupt Regeln hat. Genau
     dieselbe Falle steckte in `.nur-schmal` und ist dort seit dem 08.08.2026 mit
     `.detail-kopf .nur-schmal` (0-2-0) behoben; hier fehlte die Gegenprobe.
     `.nur-breit` bleibt trotzdem stehen: es gilt für künftige Träger, die kein
     `button.rund` sind. */
  .nur-breit { display: none; }
  .detail-kopf .nur-breit { display: none; }
  .schiene button[data-bereich][aria-current="page"]::before,
  .schiene button[data-bereich].aktiv::before {
    left: 8px; right: 8px; top: auto; bottom: -5px; width: auto; height: 3px; border-radius: 3px 3px 0 0;
  }
  .spalte-liste, .spalte-detail { grid-row: 1; grid-column: 1; border-right: 0; }
  .schale[data-spalte="liste"] .spalte-detail { display: none; }
  .schale[data-spalte="detail"] .spalte-liste { display: none; }
  .detail-kopf .nur-schmal { display: grid; }
  .blase { max-width: 100%; }
  .detail-inhalt { padding: var(--luft) 14px calc(var(--luft) * 2); }

  /* ---- FINGERZIELE ------------------------------------------------------
     Gemessen am 08.08.2026 bei 390×844: „Zurück zur Liste" und „Neuer Chat" waren
     30×30, „Umbenennen"/„Löschen" 29 hoch, der Senden-Knopf 38, die Modellwahl 26,
     das Label „denken lassen" 20 und die drei Schieberegler 16. Die zwei WICHTIGSTEN
     Knöpfe des Handy-Betriebs — der Weg zurück zur Liste und der neue Chat — waren
     die kleinsten. WCAG 2.2 SC 2.5.8 verlangt 24×24; 44 ist das Mass, das Apple und
     Google seit Jahren für den Finger nennen, und dieser Entwurf ist auf dem Handy
     eine Ein-Hand-Oberfläche. Die Regel greift NUR hier — auf dem breiten Bildschirm
     würden 44er Knöpfe die Kopfzeile aufblähen, dort zielt eine Maus. */
  button, input, select, textarea { min-height: 44px; }
  button { min-width: 44px; }                /* „↑"/„↓" auf der Tabs-Seite waren 34 breit */
  button.rund { width: 44px; height: 44px; }
  .detail-werkzeuge { gap: 12px; }          /* „Löschen" klebte an „Umbenennen" */
  .detail-werkzeuge button { min-height: 44px; padding: .4em .9em; }
  .verfasser .senden { width: 44px; height: 44px; }
  input[type="range"] { height: 44px; }
  input[type="color"] { height: 44px; }
  /* Kästchen und Punkte bleiben klein — 44 px grosse Ankreuzfelder sehen aus wie
     Knöpfe. Ihr ZIEL ist die Zeile, in der sie stehen (.tabzeile), und die ist hoch
     genug; das Kästchen selbst wächst auf die 24 px der WCAG-Regel. */
  /* flex:0 0 auto — ohne das schrumpfen die Kästchen in einer flex-Zeile unter ihre
     eigene Breite. Gemessen in der Tabs-Liste: 15, 19, 20 und 23 px statt 24. */
  input[type="checkbox"], input[type="radio"] { width: 24px; height: 24px; min-height: 24px; flex: 0 0 auto; }
  .tabzeile { min-height: 44px; gap: 12px; }
  .verfasser textarea { min-height: 44px; }   /* schlägt das min-height: 2.6em von oben */

  /* ---- SCHRIFT IN EINGABEFELDERN ≥ 16 px --------------------------------
     Safari auf iOS zoomt die ganze Seite hinein, sobald ein angetipptes Feld unter
     16 px hat. Diese Oberfläche hat `body { overflow: hidden }` und `height: 100%` —
     aus dem hineingezoomten Zustand gäbe es keinen Weg zurück ausser Neuladen.
     Gemessen wurden 14,5 px (Suche, Chat), 12,47 px (Modellwahl) und 13,53 px in der
     Anmeldekarte. `max(16px, …)` statt fester 16 px: wer die Schriftgrösse hochstellt,
     soll grössere Felder bekommen, nicht kleinere.
     UNGEPRÜFT auf echtem iOS — hier ist kein Apple-Gerät. Gemessen ist nur die
     berechnete Schriftgrösse im Browser; die Safari-Regel selbst ist dokumentiert. */
  input, select, textarea { font-size: max(16px, 1em); }
  label > input, label > select, label > textarea { font-size: max(16px, 1.06em); }
  .verfasser-kopf select { font-size: max(16px, .86em); min-height: 44px; }
  .verfasser textarea { font-size: max(16px, 1em); }
  .farbzeile input[type="text"] { font-size: max(16px, .88em); }
  .doc-editor { font-size: max(16px, .88em); }

  /* Der Toast sitzt ÜBER der Schiene. Ihre Höhe ist nicht konstant (Dichte,
     Schriftgrösse, Sicherheitsabstand des Geräts), deshalb wird sie gemessen und von
     agora.js als --schiene-hoehe hinterlegt, statt geraten zu werden. Der Rückfall
     56px gilt nur, solange noch nichts gemessen wurde. */
  /* Schmal: Schiene UND Eingabezeile freihalten, nicht nur die Schiene. */
  .toast { bottom: calc(var(--schiene-hoehe, 56px) + var(--eingabe-hoehe, 104px) + 12px); }
}

/* Sehr breit: die Liste darf mitwachsen, das Detail bleibt lesbar begrenzt. */
@media (min-width: 1500px) {
  .schale { grid-template-columns: var(--schiene) calc(var(--listenbreite) * 1.15) minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::after { animation: none !important; transition: none !important; }
}


/* ===========================================================================
   DAS KACHEL-RASTER — heute im Bereich CHATS
   ===========================================================================
   Warum ein eigenes Raster und nicht `.karte`: eine Kachel ist ein KNOPF. Sie
   braucht Hover, sichtbaren Fokus und ein Fingerziel; `.karte` ist ein ruhiger
   Kasten ohne all das. Zwei Regeln fuer zwei verschiedene Dinge.

   ⚠️ NICHT LOESCHEN, WEIL karten.js WEG IST. Der Name stammt aus der Startseite,
   die agora von os3 uebernommen hatte (`ui-agora/karten.js`); die ist am 09.08.2026
   ersatzlos gestrichen — die Uebersicht ist seither vier Karten und sonst nichts,
   und die Datei ist geloescht. DIE REGELN HIER LEBEN WEITER: der Bereich Chats
   zeichnet damit sein Kachel-Raster („＋ Neuer Chat" und darunter die laufenden
   Gespraeche, bereiche.js → startbildHtml). Genau diese Anmutung hat der Owner am
   09.08. um 15:05 verlangt. Wer den Block mit karten.js mit entsorgt, macht aus dem
   Raster eine Reihe nackter Knoepfe untereinander — also die Zeilenliste, die er
   nicht wollte, und der Fehler saehe aus wie einer in fremdem Code.
   =========================================================================== */
.start-reiter { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 calc(var(--luft) * 1.4); }
.start-reiter-knopf { font-size: .86em; padding: .34em .9em; border-radius: 999px; }
.start-reiter-knopf[aria-pressed="true"] {
  background: var(--akzent); color: var(--akzent-text); border-color: var(--akzent);
}

/* DAS RASTER WÄCHST MIT — auto-FIT, nicht auto-fill (Owner 09.08.2026, 21:45:
   „also ich will, dass der Platz effizient genutzt wird!").
   Der Unterschied ist genau der, über den er sich beschwert hat: `auto-fill` legt so
   viele Spuren an, wie hineinpassen, AUCH LEERE — bei 1300 px sind das fünf Spuren zu
   260 px, und wer drei Chats hat, sieht drei Kacheln links und 520 px nichts rechts.
   `auto-fit` klappt die leeren Spuren zusammen, die vorhandenen Kacheln teilen sich
   die Breite. Keine feste Spaltenzahl in beiden Fällen — aber nur eine der beiden
   lässt keinen Rest stehen.
   270 px ist die Untergrenze einer Kachel, nicht ihre Breite: darunter passt „＋ Neuer
   Chat" samt Zusatzzeile nicht mehr in zwei Zeilen.
   🔴 VON 230 AUF 270 am 11.08.2026 (Owner: „Leiste breiter"). Gemessen bei 1440 px:
   bei 230 px legte auto-fit vier Spuren zu 283 px an, und davon frassen die Marken
   rechts („Wissen neu", „ControlHQ RMM") rund 170 px — dem Titel blieben 60, also
   stand da „Contr…". 270 px ändert die Spaltenzahl bei 1440 px NICHT (4 × 287), es
   hebt nur den Boden für schmalere Fenster; das Abschneiden behebt die Regel
   darunter. Beides zusammen, weil eines allein den Fall nur verschiebt. */
.start-raster { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--kachel-min)), 1fr)); gap: var(--raster-abstand); }

/* min-width: 0 — OHNE DIESE ZEILE SCHIEBT EIN LANGER CHAT-TITEL DIE SEITE SEITWAERTS.
   Ein Grid-Element hat als automatische Mindestgroesse seine min-content-Breite, und
   `.start-kachel-text b` traegt white-space: nowrap. Dieselbe Zeile steht in os3.css
   an `.mini`, und dort ist der Schaden gemessen: 08.08. bei 450 px Fenster, 68 Zeichen
   Titel — Kachel 648 px, scrollWidth 658 gegen innerWidth 450, 208 px seitwaerts. */
/* 🔴 ZWEI SPALTEN STATT DREI (11.08.2026, Owner: „Chat-Kartennamen abgeschnitten").
   Die dritte Spalte war `auto` — eine auto-Spur nimmt sich ihre volle Inhaltsbreite,
   und die einzige schrumpffähige Spur daneben war der Titel. Die Marken haben dem
   Namen also so lange Platz weggenommen, bis „ControlHQ RMM" zu „Contr…" wurde:
   nicht der Titel war zu lang, die Marken standen in seiner Zeile.
   Jetzt stehen sie eine Rasterzeile TIEFER, rechtsbündig unter dem Text — sichtbar
   bleiben sie (Owner-Order 10.08.: „Wissen neu, ControlHQ RMM soll da stehen"), aber
   sie zahlen nicht mehr mit der Breite des Namens dafür. */
.start-kachel {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start;
  gap: 2px 10px; min-width: 0; width: 100%; text-align: left; cursor: pointer;
  font: inherit; color: inherit; background: var(--flaeche);
  border: var(--linie) solid var(--rahmen); border-radius: var(--radius);
  padding: var(--karte-innen);
}
@media (hover: hover) {
  .start-kachel:hover { border-color: var(--akzent); background: var(--flaeche-hoch); }
  .start-kachel:hover .start-kachel-sym { color: var(--akzent); }
}
.start-kachel-sym { color: var(--gedaempft); display: grid; place-items: center; }
/* Das Chat-Symbol in der Kachel — hier ist es am meisten wert, denn die Kachel IST
   das, was der Owner „Icon" nennt. Es steht an der Stelle des allgemeinen Zeichens
   und ist so gross wie die Kachel es trägt, ohne die Textspalte zu drücken (Spalte 1
   ist `auto`, das Bild bestimmt sie also selbst — deshalb eine feste Breite). */
.kachel-bild {
  width: var(--chatbild-kachel); height: var(--chatbild-kachel); display: block;
  object-fit: cover; border-radius: var(--radius);
  border: var(--linie) solid var(--rahmen); background: var(--flaeche-tief);
}
.start-kachel-text { min-width: 0; }
.start-kachel-text b {
  display: block; font-family: var(--serif); font-weight: 600;
  overflow-wrap: anywhere; white-space: normal;
}
.start-kachel-text span {
  display: block; margin-top: 3px; font-size: .82em; color: var(--gedaempft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.start-kachel-neben { font-size: .78em; color: var(--gedaempft); white-space: nowrap; }
.start-kachel .marke-chip { align-self: center; }
/* Der Behaelter sitzt jetzt in der zweiten Spalte EINE ZEILE TIEFER (grid-column: 2),
   nicht mehr neben dem Titel. Er bricht weiter um, statt die Kachel aufzureissen —
   `min-width: 0` und `flex-wrap` sind das, was den Kasten haelt.
   Ohne `grid-column: 2` landete er unter dem SYMBOL in Spalte 1: das automatische
   Einsortieren fuellt die naechste freie Zelle, und das ist die linke. */
.start-kachel-marken { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end;
  grid-column: 2; margin-top: 5px; min-width: 0; }

/* Neuer Lauf: volle Breite des Hauptbereichs. Zeile bricht über flex-wrap,
   sobald Feld + Steuer nicht mehr nebeneinander passen — Grenze ist
   --kachel-min, kein freies px. */
[data-proj-lauf-karte] {
  display: flex; flex-direction: column; gap: var(--luft);
  width: 100%; max-width: none; box-sizing: border-box;
}
[data-proj-lauf-zeile] {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--luft);
  width: 100%;
}
[data-proj-fix-feld] {
  flex: 1 1 var(--kachel-min); min-width: min(100%, var(--kachel-min));
}
[data-proj-fix-feld] input { width: 100%; }
[data-proj-steuer] {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--luft);
  flex: 0 1 auto;
}
[data-proj-steuer] label.klein {
  display: flex; flex-direction: column; gap: calc(var(--luft) * 0.25);
  flex: 0 0 auto;
}
[data-proj-steuer] select { width: auto; }
[data-proj-lauf-karte] button.haupt,
[data-proj-lauf-karte] [data-proj-chat-los] {
  width: auto; flex: 0 0 auto; min-height: var(--tap);
}
[data-proj-meta] {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--kachel-min)), 1fr));
  gap: var(--luft);
}
[data-proj-meta] > .karte { margin-top: 0; }
[data-proj-lauf-stand][hidden] { display: none; }


/* ===========================================================================
   OWNER-ANSAGE 09.08.2026: die Such-Icons sind ERSATZLOS weg — ausdruecklich ohne
   Schalter, ohne Einstellung, ohne Weg zurueck ("nix 0 oder 1, weg damit").
   Der runde Aufklapp-Knopf ist damit auch fort. Damit die Suche auf schmalen
   Schirmen nicht unerreichbar wird, steht die Zeile dort jetzt IMMER offen —
   ein Knopf zum Aufklappen ist dann ueberfluessig, statt versteckt zu werden.

   DAS `!important` IST SEIT DEM 09.08.2026 EIN GUERTEL OHNE HOSENTRAEGER, und das
   ist Absicht: die Regeln, gegen die es sich stemmte (`.kopf[data-offen="0"]
   .zeile-box { display: none }` und Nachbarn), sind geloescht, ebenso das Attribut
   am <header>. Es zwingt jetzt nichts mehr nieder, sondern haelt nur noch fest,
   dass diese Zeile auf jeder Breite steht. Eine dritte Regel auf `[data-offen]`
   stand hier ebenfalls — sie traf nach dem Loeschen des Attributs nichts mehr und
   ist mit weg. Wer die verbliebenen zwei entfernt, aendert heute nichts; wer eine
   Regel schreibt, die die Zeile schmal versteckt, laeuft dagegen auf.
   =========================================================================== */
.listen-kopf .zeile-box { display: flex !important; }
@media (max-width: 640px) {
  .listen-kopf .zeile-box { display: flex !important; width: 100%; }
}


/* ===========================================================================
   BALKEN UND RINGE — sie wohnen in uebersicht.css, nicht hier.
   ===========================================================================
   Bis zum 09.08.2026 stand an dieser Stelle ein Block mit den Massen und
   Farben von .ub-bar/.ub-bett/.ub-bogen/.ub-s-bar. Er musste seine Gewichtung
   mit doppelt genannten Klassen anheben, weil uebersicht.css NACH diesem Blatt
   geladen wird. Beides ist weg: die Regeln stehen jetzt einmalig in
   ui-agora/uebersicht.css, im dortigen Block „BALKEN UND RINGE", zusammen mit
   dem Bauteil, das sie beschreiben. Wer die Balken ändert, ändert sie dort —
   und nur dort.
   =========================================================================== */


/* ===========================================================================
   STARTBILD UND BEWEGUNG (Owner-Wunsch 10.08.2026)
   ===========================================================================
   „Wie bei Riot" heisst: man wartet nicht vor einer leeren Seite, sondern sieht
   etwas, das offensichtlich schon arbeitet. Und es ist GEZEICHNET — SVG-Strich
   und Verlaeufe, kein Video, keine Bilddatei, keine Fremdbibliothek.

   Zwei Regeln, an die sich hier alles haelt:
   · Nichts blockiert. Das Startbild verschwindet, sobald die Oberflaeche steht —
     es haelt sie nie auf. Wer es laenger sieht, wartet auf echte Arbeit.
   · Wer keine Bewegung will, bekommt keine. `prefers-reduced-motion` ist kein
     Zusatz, sondern eine Zusage: unten steht EINE Regel, die alles stilllegt.
   =========================================================================== */

.startbild {
  position: fixed; inset: 0; z-index: 9000;
  display: grid; place-items: center;
  background: var(--hintergrund);
  /* Sichtbar ab der ersten Bildschirmzeile — nicht erst, wenn Skript laeuft. */
  opacity: 1; transition: opacity .5s ease, transform .5s ease;
}
.startbild.startbild-weg { opacity: 0; transform: scale(1.04); pointer-events: none; }

/* Der Schein dahinter: zwei sehr weiche Farbkreise, die langsam wandern.
   Sie liegen HINTER dem Zeichen und sind absichtlich kaum zu greifen — sie
   sollen Tiefe geben, nicht auffallen. */
.sb-schein {
  position: absolute; inset: -20%;
  /* 🔴 GEAENDERT 10.08.2026 (Owner: "danach ist das UI nicht wie die Animation,
     gar nicht dieses Farbschema"). Der zweite Kreis war GRUEN (--gut) — eine Farbe,
     die in der Oberflaeche nur fuer "in Ordnung" steht und sonst nirgends flaechig
     vorkommt. Dadurch sah das Startbild aus wie ein anderes Programm.
     Jetzt beide Kreise aus dem Akzent, der zweite nur schwaecher und waermer —
     dieselbe Familie wie die Oberflaeche, nur ruhiger. */
  /* 🔴 KEIN `filter: blur()` MEHR (Owner-Abzug 11.08.2026: „was ist denn hier los
     beim Ladescreen?" — grosse rote und blaue KLOETZE statt eines weichen Scheins).
     Ursache: ein Weichzeichner mit grossem Radius auf einer bildschirmfuellenden,
     ANIMIERTEN Ebene. Chromium rastert so eine Ebene stark herunter, zeichnet den
     Weichzeichner auf dem kleinen Abbild und skaliert es wieder hoch — daraus
     werden Bloecke, und die Farbabstufungen brechen sichtbar auf.
     Der Weichzeichner war hier ohnehin doppelt gemoppelt: ein `radial-gradient`
     IST bereits ein weicher Verlauf. Die Weichheit kommt jetzt allein aus den
     Farbstopps — dieselbe Anmutung, ohne die Rasterfalle.
     Zusaetzlich `will-change: transform`: so weiss der Browser vorher, dass sich
     nur die LAGE aendert, und muss die Flaeche nicht bei jedem Bild neu bewerten. */
  background:
    radial-gradient(52% 52% at 34% 32%,
      color-mix(in srgb, var(--akzent) 20%, transparent) 0%,
      color-mix(in srgb, var(--akzent) 9%, transparent) 42%,
      transparent 78%),
    radial-gradient(48% 48% at 66% 68%,
      color-mix(in srgb, var(--akzent) 11%, transparent) 0%,
      color-mix(in srgb, var(--akzent) 5%, transparent) 45%,
      transparent 78%);
  will-change: transform;
  animation: sbSchein 9s ease-in-out infinite alternate;
}
@keyframes sbSchein {
  from { transform: translate3d(-3%, -2%, 0) scale(1); }
  to   { transform: translate3d(3%, 2%, 0) scale(1.12); }
}

.sb-mitte { position: relative; display: grid; justify-items: center; gap: 16px; padding: 24px; }

.sb-zeichen { width: 84px; height: 84px; color: var(--akzent); display: block; }
/* DAS ZEICHEN ZEICHNET SICH SELBST — zwei versetzte Siebenecke, dann die
   Speichen, dann die Knoten, zuletzt atmet der Kern. Die Reihenfolge ist
   dieselbe wie im freigegebenen Zeichen von aussen nach innen: erst der
   Rahmen aus dunklem Metall, dann das, was darin gluht.
   Der Strichvorrat (200) ist groesser als der laengste Umfang (aussen 164,
   innen 118) — lieber zu viel als eine Luecke am Ende. */
.sb-ring {
  stroke-dasharray: 200; stroke-dashoffset: 200;
  animation: sbZeichnen 1.15s cubic-bezier(.65,.02,.28,1) forwards;
}
.sb-ring-i {
  animation-duration: 1s; animation-delay: .16s;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--akzent) 55%, transparent));
}
.sb-speichen {
  stroke-dasharray: 90; stroke-dashoffset: 90;
  animation: sbZeichnen .7s .8s ease-out forwards;
}
/* Die Knoten kommen AUS dem Kern heraus (transform-origin = Mitte), einer nach
   dem anderen. Das ist der Moment, in dem aus einem Umriss ein Netz wird. */
.sb-knoten {
  opacity: 0; transform: scale(0); transform-origin: 32px 32px;
  animation: sbKnotenAn .38s cubic-bezier(.2,1.5,.4,1) forwards;
  animation-delay: calc(1.02s + var(--k, 0) * .055s);
}
@keyframes sbKnotenAn { to { opacity: .92; transform: scale(1); } }
@keyframes sbZeichnen { to { stroke-dashoffset: 0; } }
/* Der Kern kommt NACH dem Umriss und atmet dann weiter — solange er atmet,
   arbeitet etwas. */
.sb-kern {
  transform-origin: 32px 32px; transform: scale(0); opacity: 0;
  filter: drop-shadow(0 0 7px color-mix(in srgb, var(--akzent) 70%, transparent));
  animation: sbKernAn .5s .95s cubic-bezier(.2,1.5,.4,1) forwards, sbAtmen 2.4s 1.5s ease-in-out infinite;
}
@keyframes sbKernAn { to { transform: scale(1); opacity: 1; } }
@keyframes sbAtmen { 0%,100% { opacity: 1; } 50% { opacity: .45; } }

/* Der Schriftzug laeuft Buchstabe fuer Buchstabe ein — jeder mit einem eigenen,
   aus seiner Nummer errechneten Versatz. Deshalb steht an jedem <i> ein --i. */
.sb-wort { display: flex; align-items: baseline; font-family: var(--serif); font-size: 26px; font-weight: 600; letter-spacing: .5px; color: var(--text); }
.sb-wort i {
  font-style: normal; opacity: 0; transform: translateY(9px);
  animation: sbBuchstabe .45s cubic-bezier(.2,.8,.3,1) forwards;
  animation-delay: calc(.72s + var(--i, 0) * .055s);
}
.sb-wort .sb-luecke { width: .38em; }
@keyframes sbBuchstabe { to { opacity: 1; transform: none; } }

/* Ein Streifen, der laeuft, ohne einen Fortschritt zu behaupten, den niemand
   kennt: ein Balken auf „63 %" waere gelogen. Er zeigt nur: es geht weiter. */
.sb-linie { width: 168px; height: 2px; border-radius: 2px; overflow: hidden; background: var(--rahmen); }
.sb-linie b { display: block; width: 38%; height: 100%; border-radius: 2px; background: var(--akzent); animation: sbLauf 1.35s ease-in-out infinite; }
@keyframes sbLauf { 0% { transform: translateX(-110%); } 100% { transform: translateX(320%); } }


/* ————— Anmeldung: hereinkommen statt erscheinen ————— */
.anmeldung:not(.versteckt) .anmeldekarte { animation: karteRein .5s cubic-bezier(.2,.8,.3,1) both; }
@keyframes karteRein { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
/* Die Felder folgen der Karte gestaffelt. `nth-child` statt einer Nummer je Feld:
   so gilt es auch fuer die Bloecke „Geraet" und „Code", ohne sie einzeln zu pflegen. */
.anmeldung:not(.versteckt) .anmeldekarte > div:not(.versteckt) > * {
  animation: feldRein .42s cubic-bezier(.2,.8,.3,1) both;
}
.anmeldekarte > div > *:nth-child(1) { animation-delay: .10s; }
.anmeldekarte > div > *:nth-child(2) { animation-delay: .16s; }
.anmeldekarte > div > *:nth-child(3) { animation-delay: .22s; }
.anmeldekarte > div > *:nth-child(4) { animation-delay: .28s; }
.anmeldekarte > div > *:nth-child(5) { animation-delay: .34s; }
.anmeldekarte > div > *:nth-child(n+6) { animation-delay: .40s; }
@keyframes feldRein { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ————— Der Wechsel zwischen Bereichen ————— */
.schale[data-bereich] .spalte-detail > *, .schale[data-bereich] .spalte-liste > * { animation: inhaltRein .3s ease-out both; }
@keyframes inhaltRein { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ————— DIE ZUSAGE —————
   Ein System, das sich nicht abschalten laesst, ist fuer manche Menschen nicht
   benutzbar (Schwindel, Migraene, Aufmerksamkeitsstoerung). Deshalb steht hier
   EINE Regel, die alles Obige stilllegt — und nicht je Animation ein Vermerk,
   den irgendwann jemand vergisst. */
@media (prefers-reduced-motion: reduce) {
  .startbild, .startbild * , .anmeldekarte, .anmeldekarte *,
  .schale[data-bereich] .spalte-detail > *, .schale[data-bereich] .spalte-liste > * {
    animation: none !important; transition: none !important;
  }
  .sb-ring, .sb-speichen { stroke-dashoffset: 0; }
  .sb-knoten { opacity: .92; transform: none; }
  .sb-kern { transform: scale(1); opacity: 1; }
  .sb-wort i { opacity: 1; transform: none; }
}


/* ————— DER ÜBERGANG (Owner 10.08.2026: „nicht einfach so cut, next site") —————
   Das Startbild weitet sich und verschwindet, die Oberfläche kommt aus derselben
   Mitte herauf. Gleiche Dauer, gleiche Kurve, gleichzeitig — deshalb liest es sich
   als EINE Bewegung. Zwei verschiedene Kurven würden hier sofort als Ruckler
   auffallen, auch wenn keiner sagen könnte warum. */
.startbild { transition: opacity .62s cubic-bezier(.4,0,.2,1), transform .62s cubic-bezier(.4,0,.2,1), filter .62s ease; }
/* Auch beim Ausblenden KEIN Weichzeichner mehr — dieselbe Rasterfalle wie oben,
   nur kuerzer sichtbar. Das Weiten allein traegt den Uebergang. */
.startbild.startbild-weg { opacity: 0; transform: scale(1.10); }

/* 🔴 AUCH DIE ANMELDUNG (11.08.2026). Der Uebergang hing an `#app` — wer nicht
   angemeldet ist, sieht aber die Anmeldung, und die kam bisher ohne jede Bewegung
   daher: das Startbild blendete gegen einen versteckten Kasten aus, das Anmeldefeld
   stand einfach da. Owner: „animiert, dann Login und dann halt die Uebersicht". */
#app.app-rein,
#anmeldung.app-rein { animation: appRein .62s cubic-bezier(.4,0,.2,1) both; }
@keyframes appRein {
  from { opacity: 0; transform: scale(.975); }
  to   { opacity: 1; transform: none; }
}
/* Die Spalten laufen leicht versetzt nach — zuerst die Schiene, dann Liste, dann
   Detail. Das ist der Unterschied zwischen „alles erscheint" und „es baut sich auf". */
#app.app-rein .schiene { animation: spalteRein .5s .04s cubic-bezier(.2,.8,.3,1) both; }
#app.app-rein .spalte-liste { animation: spalteRein .5s .10s cubic-bezier(.2,.8,.3,1) both; }
#app.app-rein .spalte-detail { animation: spalteRein .5s .16s cubic-bezier(.2,.8,.3,1) both; }
@keyframes spalteRein { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  #app.app-rein, #anmeldung.app-rein, #app.app-rein .schiene, #app.app-rein .spalte-liste, #app.app-rein .spalte-detail {
    animation: none !important;
  }
}


/* ————— DAS ECHTE ZEICHEN —————
   Anmeldung und Schiene laden es als Datei (/favicon.svg). Es ist dasselbe
   Zeichen, das auch im Browser-Reiter und auf dem Startbild der App steht —
   ein Produkt hat EIN Zeichen, nicht drei gezeichnete Annaeherungen. */
.marke-zeichen img { width: 100%; height: 100%; display: block; }
.schiene-marke img { width: 22px; height: 22px; display: block; flex-shrink: 0; }


/* ===========================================================================
   FORMENSPRACHE g-sv.eu (15.08.2026) — Haarlinie statt Schatten
   ===========================================================================
   Der A6-Block (Kantenlicht, Akzent-Schein, drop-shadow am Zeichen) ist
   geloescht, nicht ueberdeckt: Schatten gewaennen sonst gegen die Linie.
   Tiefe kommt aus Flaeche + einer Haarlinie aus --rahmen.
   =========================================================================== */

.ub-kachel-tor, .ub-punkt-tor {
  transition: border-color var(--schnell) var(--kurve),
              background-color var(--schnell) var(--kurve);
}
@media (hover: hover) {
  .ub-kachel-tor:hover, .ub-punkt-tor:hover {
    border-color: var(--akzent-rand);
    background: var(--akzent-weich);
  }
}

button.haupt {
  transition: background-color var(--schnell) var(--kurve),
              transform var(--schnell) var(--kurve);
}
@media (hover: hover) {
  button.haupt:hover:not(:disabled) { background: var(--akzent-hover); }
}
button.haupt:active { transform: translateY(1px); }

.schiene-marke img { width: 27px; height: 27px; }
.marke-zeichen { width: 40px; height: 40px; }
.marke { gap: 12px; }

/* ————— DIE GEMEINSAME KURVE —————
   Der Bereichswechsel lief mit `ease-out` und 300ms, das Startbild mit
   cubic-bezier(.2,.8,.3,1) und 500ms — zwei Rhythmen im selben Produkt. Jetzt
   einer: normal (200ms) fuer Inhalte, langsam (400ms) fuer den Seitenwechsel. */
.schale[data-bereich] .spalte-detail > *,
.schale[data-bereich] .spalte-liste > * {
  animation: inhaltRein var(--normal) var(--kurve) both;
}
.anmeldung:not(.versteckt) .anmeldekarte { animation: karteRein var(--langsam) var(--kurve) both; }
.anmeldung:not(.versteckt) .anmeldekarte > div:not(.versteckt) > * {
  animation: feldRein var(--normal) var(--kurve) both;
}


/* ===========================================================================
   MEDIEN IM CHAT — Bild und Video (A7, 13.08.2026)
   ===========================================================================
   Dieselbe Haltung wie im Rest des Blattes: kein fester Farbwert, alles aus den
   zehn Variablen gemischt. Und dieselben Zeiten wie ueberall (M6).
   =========================================================================== */
.med-videobox { margin: 10px 0; border: var(--linie) solid var(--rahmen); border-radius: var(--radius); overflow: hidden; background: var(--flaeche-tief); }
.med-video { display: block; width: 100%; max-height: 62vh; background: var(--hintergrund); }
.med-zeile { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 8px 10px; }
.med-knoepfe { display: flex; gap: 6px; margin-left: auto; }
.med-lade { padding: 14px 12px; display: grid; gap: 8px; }
/* Ein Balken, der einen ECHTEN Wert zeigt — er kommt aus /api/videos/:id/stand.
   Solange nichts bekannt ist, steht er auf 0 und der Text sagt, was laeuft. */
.med-balken { height: 4px; border-radius: 3px; background: var(--rahmen); overflow: hidden; }
.med-balken i { display: block; height: 100%; background: var(--akzent); border-radius: 3px; transition: width var(--normal) var(--kurve); }
.med-fehler { padding: 12px; color: var(--schlecht); }
.med-pruefung { padding: 10px 12px; border-top: var(--linie) solid var(--rahmen); display: grid; gap: 6px; }
.med-pruef-kopf { font-weight: 650; font-size: .92em; }
.med-pruef-liste { margin: 0; padding-left: 1.1em; display: grid; gap: 3px; font-size: .92em; }

/* Ein Bild, das man anfassen kann, sagt das auch. */
.med-klickbar { cursor: zoom-in; transition: outline-color var(--schnell) var(--kurve); }
@media (hover: hover) {
  .med-klickbar:hover { outline: var(--linie) solid var(--akzent-rand); outline-offset: 2px; }
}

/* ————— Die Grossansicht ist der Werkzeugkasten —————
   Sie liegt ueber allem, schliesst mit Escape und mit einem Klick daneben. */
.med-schicht { position: fixed; inset: 0; z-index: 90; background: color-mix(in srgb, var(--hintergrund) 82%, transparent); display: grid; place-items: center; padding: 3vh 3vw; animation: medRein var(--normal) var(--kurve) both; }
@keyframes medRein { from { opacity: 0; } to { opacity: 1; } }
.med-fenster { width: min(1100px, 96vw); max-height: 94vh; overflow: auto; background: var(--flaeche); border: var(--linie) solid var(--rahmen); border-radius: calc(var(--radius) + 2px); padding: var(--karte-innen); display: grid; gap: var(--raster-abstand); }
/* min-width: 0 ist hier kein Feinschliff, sondern die Bedingung dafuer, dass
   „…" ueberhaupt erscheinen kann. Ohne sie ist die Mindestbreite eines Kindes
   sein ganzer Inhalt, und das Fenster laeuft aus. */
.med-fenster > * { min-width: 0; }
.med-kopf { display: flex; align-items: center; gap: 12px; min-width: 0; }
.med-kopf h3 { margin: 0; min-width: 0; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* align-items ergänzt 18.08.: in der Kopfzeile steht jetzt zwischen den Blätter-Pfeilen
   der Galerie ein Zählertext („2 / 5"). Ohne diese Zeile streckt flex ihn auf volle Höhe
   und die Schrift klebt oben an den Knöpfen. Geändert statt danebengesetzt. */
.med-kopf-knoepfe { display: flex; gap: 6px; margin-left: auto; flex-shrink: 0; align-items: center; }
.med-werkzeuge { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.med-trenner { width: 1px; height: 1.4em; background: var(--rahmen); margin: 0 2px; }
.med-meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.med-gross { display: block; max-width: 100%; max-height: 70vh; margin: 0 auto; border-radius: var(--radius); background: var(--flaeche-tief); }
/* Ein <a>, der wie ein Knopf aussieht — fuer „Herunterladen": ein echter Knopf
   kann keine Datei laden, und ein nackter Verweis sieht neben Knoepfen falsch aus. */
.knopf-wie-link { display: inline-flex; align-items: center; padding: .3em .7em; border: var(--linie) solid var(--rahmen); border-radius: 7px; color: var(--text); text-decoration: none; background: var(--flaeche-hoch); }
@media (hover: hover) { .knopf-wie-link:hover { border-color: var(--akzent-rand); } }

/* DATEI-KARTE — ein grosser Code-Block als Datei statt als Textwand. */
.datei-karte {
  margin: var(--luft) 0;
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  background: var(--flaeche-tief);
  overflow: hidden;
  display: grid;
  gap: calc(var(--luft) * .5);
  padding: var(--luft);
}
.datei-karte[data-stand="abgeschnitten"],
.datei-karte[data-stand="zu-gross"],
.datei-karte[data-stand="fehler"],
.datei-karte[data-stand="abgelaufen"] {
  border-color: color-mix(in srgb, var(--warn) 55%, var(--rahmen));
  background: var(--warn-grund);
}
.datei-kopf { display: flex; align-items: center; gap: var(--luft); min-width: 0; }
/* Das Art-Zeichen vor dem Namen. Es folgt der Akzentfarbe, damit die Kachel auf
   einen Blick als Datei erkennbar ist — genau die Rolle, die beim Bild die
   Miniatur übernimmt. */
.datei-zeichen {
  flex: 0 0 auto;
  color: var(--akzent);
  font-size: var(--schrift-titel);
  line-height: 1;
}
.datei-name {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--flaeche);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  color: var(--text);
  font: inherit;
  padding: calc(var(--luft) * .4) calc(var(--luft) * .7);
}
.datei-meta { flex: 0 0 auto; }
.datei-vorschau, .datei-voll {
  margin: 0;
  max-height: 16em;
  overflow: auto;
  background: var(--hintergrund);
  border-radius: var(--radius);
  padding: calc(var(--luft) * .7);
  font-size: var(--schrift-klein);
}
.datei-knoepfe { display: flex; flex-wrap: wrap; gap: calc(var(--luft) * .5); }
.datei-lade { color: var(--gedaempft); }

/* ---------------------------------------------------------------------------
   DIE VORSCHAU IN DER KACHEL (T1-B, 25.08.2026)
   ---------------------------------------------------------------------------
   Owner 19.08.: „die Datei wie ein Artefakt dargestellt — wie als würde ich eine
   Datei reinschicken, aber nur andersrum." Also dieselbe Anmutung wie bei einem
   Bild im Chat: erst sehen, dann entscheiden.
   Alle Werte kommen aus den Variablen oben. Der einzige NEUE Wert ist `--blatt`
   und er steht in :root, nicht hier — Begründung dort.
   --------------------------------------------------------------------------- */

/* PDF: die erste Seite. `contain` statt `cover` — eine beschnittene erste Seite
   wäre eine Vorschau, die etwas anderes zeigt als die Datei. */
.datei-blatt { margin: 0; display: grid; gap: calc(var(--luft) * .35); }
.datei-blatt img {
  display: block;
  width: 100%;
  max-height: 22em;
  object-fit: contain;
  object-position: top center;
  background: var(--blatt);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
}

/* HTML: die Seite selbst. Der Rahmen ist im Markup gesandkastet (kein Skript,
   keine eigene Origin); hier bekommt er nur seine Grösse und einen weissen
   Grund, damit eine Seite ohne eigenen Hintergrund nicht durchsichtig wirkt. */
.datei-rahmen {
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  background: var(--blatt);
  overflow: hidden;
}
.datei-rahmen iframe { display: block; width: 100%; height: 20em; border: 0; }

/* Keine Vorschau möglich: ein ehrliches Zeichen und der Grund — nie ein
   kaputtes Bild und nie ein leerer Kasten, der wie ein Ladefehler aussieht. */
.datei-ohne {
  display: flex;
  align-items: center;
  gap: var(--luft);
  padding: calc(var(--luft) * .9);
  border: var(--linie) dashed var(--rahmen);
  border-radius: var(--radius);
  background: var(--hintergrund);
}
.datei-ohne-zeichen { color: var(--gedaempft); font-size: var(--schrift-titel); line-height: 1; }
.datei-ablauf { justify-self: end; }

/* Grossansicht in der Dialog-Schicht. */
.dialog-gross { width: min(96vw, 72rem); max-width: none; }
.dialog-kopf { display: flex; align-items: center; justify-content: space-between; gap: var(--luft); }
.datei-gross {
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  background: var(--blatt);
  overflow: hidden;
}
.datei-gross iframe { display: block; width: 100%; height: min(78vh, 52rem); border: 0; }

/* Atelier (Bereich Bild & Video). */
.med-atelier { display: grid; gap: var(--raster-abstand); }
.med-form { display: grid; gap: var(--luft); }
.med-form textarea,
.med-form select {
  width: 100%;
  background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  color: var(--text);
  font: inherit;
  padding: calc(var(--luft) * .5);
}
.med-opts { display: flex; flex-wrap: wrap; gap: var(--luft); }
.med-opts label { min-width: 10em; }
.med-raster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--kachel-min), 1fr));
  gap: var(--raster-abstand);
}
.med-kachel {
  display: grid;
  gap: calc(var(--luft) * .5);
  padding: 0;
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  background: var(--flaeche-tief);
  color: inherit;
  text-align: left;
  overflow: hidden;
  cursor: pointer;
}
.med-kachel img,
.med-kachel video {
  display: block;
  width: 100%;
  height: 10em;
  object-fit: cover;
  background: var(--hintergrund);
}
.med-kachel span { padding: 0 var(--luft) var(--luft); }

/* ————— AUSWÄHLEN UND LÖSCHEN IN DER GALERIE (19.08.2026) —————
   Owner: „ich will bei Medien auch Dinge löschen können". „Dinge" heisst
   Mehrfachauswahl, und die braucht ein Kästchen je Kachel.
   Die Kachel ist deshalb kein <button> mehr, sondern eine Hülle; der Öffnen-Bereich
   ist der Knopf darin. Die Regeln oben zielen auf `.med-kachel img/video/span`, also
   auf NACHFAHREN — sie greifen unverändert weiter. Alle Werte kommen aus den
   Variablen; eigene Farben gibt es hier keine. */
.med-kachel { position: relative; }
.med-oeffnen {
  display: grid;
  gap: calc(var(--luft) * .5);
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
/* Kästchen und Weg-Knopf liegen ÜBER dem Bild. Ohne eigenen Grund wären sie auf einem
   hellen Bild unsichtbar — der Grund ist die Flächenfarbe, nicht eine neue. */
.med-wahl,
.med-kachel .med-weg {
  position: absolute;
  top: calc(var(--luft) * .5);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 1.9em;
  min-height: 1.9em;
  padding: 0;
  border-radius: var(--radius);
  background: var(--flaeche);
  border: var(--linie) solid var(--rahmen);
}
.med-wahl { left: calc(var(--luft) * .5); cursor: pointer; }
.med-kachel .med-weg { right: calc(var(--luft) * .5); }
.med-wahl input { margin: 0; cursor: pointer; accent-color: var(--akzent); }
.med-kachel.gewaehlt { border-color: var(--akzent-rand); background: var(--akzent-weich); }
/* Die kurze Angabenzeile unter dem Titel — je nach Art andere Felder (ui/medien.js).
   ZWEI Klassen mit Absicht: `.med-kachel span` oben ist (0,1,1) und schlüge ein blosses
   `.med-kurz` (0,1,0) — die Zeile bekäme dann die volle Kachel-Polsterung ein zweites
   Mal, obwohl sie INNERHALB des gepolsterten Titel-Spans liegt. `.med-kachel .med-kurz`
   ist (0,2,0) und gewinnt. */
.med-kachel .med-kurz { display: block; padding: 0; opacity: .8; }

/* Die Leiste über dem Raster: nur sichtbar, wenn etwas ausgewählt ist. */
.med-leiste {
  display: flex;
  align-items: center;
  gap: var(--luft);
  flex-wrap: wrap;
  margin-bottom: var(--raster-abstand);
  padding: calc(var(--luft) * .75) var(--luft);
  border: var(--linie) solid var(--akzent-rand);
  border-radius: var(--radius);
  background: var(--akzent-weich);
}
.med-leiste[hidden] { display: none; }

/* Angaben je Medium als Paare — Bezeichnung, Wert. Ein Feld, das es nicht gibt,
   erzeugt gar kein Paar (ui/medien.js: angaben()). */
.med-angaben {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: calc(var(--luft) * .25) var(--luft);
  margin: 0;
  font-size: var(--schrift-klein);
}
.med-angaben dt { color: var(--gedaempft); }
.med-angaben dd { margin: 0; overflow-wrap: anywhere; }

/* Ein Medium, das es nicht mehr gibt — im Verlauf und in der Galerie.
   Ruhig, nicht rot: gelöscht ist kein Fehler. */
.med-weggefallen {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--luft) * .5);
  padding: calc(var(--luft) * .75) var(--luft);
  border: var(--linie) dashed var(--rahmen);
  border-radius: var(--radius);
  background: var(--flaeche-tief);
}

/* Der Kopier-Knopf zeigt sich erst, wenn man die Nachricht ansieht — er soll den
   Verlauf nicht mit zehn gleichen Knoepfen tapezieren. Auf Finger-Geraeten ist er
   immer da: dort gibt es kein „ansehen". */
.nachricht-kopie { margin-left: 8px; padding: 0 .4em; }
@media (hover: hover) {
  .nachricht-kopie { opacity: 0; transition: opacity var(--schnell) var(--kurve); }
  .nachricht:hover .nachricht-kopie, .nachricht-kopie:focus-visible { opacity: 1; }
}


/* ————— DAS VIDEO IM STARTBILD (13.08.2026) —————
   Dieselben Masse wie in der App (app/src/startbild.js): quadratisch, mittig,
   55 % der kuerzeren Bildschirmseite, gedeckelt bei 75 %. Es liegt UEBER dem
   gezeichneten Zeichen — das bleibt sichtbar, bis das Video wirklich laeuft, und
   tritt dann zurueck. So gibt es keine Luecke und kein Aufblitzen. */
.sb-video {
  /* VOLL BILD (Owner 13.08.: „keiner macht den Browser Vollbild"). Die Animation
     ist quadratisch, das Fenster ist es nie — `cover` fuellt die Flaeche und
     schneidet oben/unten ab. Zeichen und Schriftzug liegen mittig und bleiben
     vollstaendig; abgeschnitten wird nur Rauch und Hintergrund.
     `background: transparent`: ohne das legt der Browser eine SCHWARZE Flaeche
     in der Groesse des Videos an, bevor das erste Einzelbild da ist — bei einem
     Quadrat war das ein dunkler Kasten, ueber die ganze Seite waere es ein
     schwarzer Schlag. */
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; background: transparent;
  opacity: 0; pointer-events: none;
  transition: opacity var(--langsam, 400ms) var(--kurve, ease);
}
.startbild.sb-mit-video .sb-video { opacity: 1; }
/* Das Video traegt Zeichen UND Schriftzug selbst — beides doppelt zu zeigen
   waere Unruhe. Es bleibt aber im Baum: wer den Ton verweigert bekommt und das
   Video haengt, sieht immer noch etwas. */
.startbild.sb-mit-video .sb-mitte { opacity: 0; transition: opacity var(--normal, 200ms) var(--kurve, ease); }
@media (prefers-reduced-motion: reduce) {
  /* Wer Bewegung abgeschaltet hat, bekommt kein Video — und zwar gar keins. */
  .sb-video { display: none; }
  .startbild.sb-mit-video .sb-mitte { opacity: 1; }
}


/* ===========================================================================
   APP-TITELZONE — nur in der AGORA-OS-App. Im Browser greift hier NICHTS.
   ===========================================================================
   Owner 13.08.2026: „nix zum Draggen da!" — und tatsaechlich hatte agora keine
   einzige `app-region`-Regel, waehrend das Fenster rahmenlos laeuft.

   Die alte Oberflaeche loeste es mit einem eigenen Streifen (#app-drag) ueber
   allem. agora braucht den nicht: es HAT bereits eine Leiste ganz oben quer ueber
   die volle Breite — die Kopfzeile mit der Such-/Befehlszeile. Die ist zu 90 %
   leere Flaeche und damit die natuerliche Titelleiste. Ein zweiter Streifen
   darueber waere genau der doppelte Balken, den der Owner am 27.07. abgeschafft
   hat.

   ZWEI DINGE MUESSEN DABEI STIMMEN, sonst ist die Reparatur eine neue Falle:
     1. Was in einer Ziehflaeche liegt, ist sonst NICHT MEHR BEDIENBAR. Deshalb
        steht `no-drag` pauschal auf allem Anklickbaren — auch auf dem, was erst
        spaeter dazukommt (Dialoge, Trefferlisten, die Grossansicht).
     2. Die Systemknoepfe liegen oben rechts UEBER der Seite. Ohne freien Platz
        laege das Konto darunter. Der Wert kommt gemessen aus agora.js, nicht geraten.
   =========================================================================== */
body[data-titelzone] .kopf {
  -webkit-app-region: drag; app-region: drag;
  /* Mindestens so hoch wie die Ueberlagerung, sonst ragen die Knoepfe darunter. */
  min-height: var(--cos-titel-h, 0px);
  padding-right: calc(10px + var(--cos-titel-rechts, 0px));
  padding-left: calc(10px + var(--cos-titel-links, 0px));
}
/* Vollbild: die Ueberlagerung ist weg, die Zone auch — dann zieht die Leiste
   trotzdem weiter (das ist unter Windows das gewohnte Verhalten), aber der
   reservierte Platz faellt weg. */
body[data-titelzone].titel-frei .kopf { padding-right: 10px; padding-left: 10px; }

/* Die klassische Falle: alles Anklickbare muss sich ausdruecklich ausnehmen. */
body[data-titelzone] button,
body[data-titelzone] a,
body[data-titelzone] input,
body[data-titelzone] select,
body[data-titelzone] textarea,
body[data-titelzone] label,
body[data-titelzone] summary,
body[data-titelzone] [role="button"],
body[data-titelzone] [role="tab"],
body[data-titelzone] [contenteditable="true"],
body[data-titelzone] .zeile-box,
body[data-titelzone] .liste-zeile,
body[data-titelzone] .schiene-knopf,
body[data-titelzone] .dialog,
body[data-titelzone] .med-fenster,
body[data-titelzone] .nachricht {
  -webkit-app-region: no-drag; app-region: no-drag;
}

/* Das Startbild liegt ueber allem und ist in der App die erste Flaeche, die man
   sieht — auch daran soll man das Fenster schieben koennen. */
body[data-titelzone] .startbild { -webkit-app-region: drag; app-region: drag; }


/* ————— KONTO-ZEILE UNTEN IN DER SCHIENE (C7.6 / C7.9) —————
   Wie die grosse Nachrichten-Bar (.verfasser): weiche Radien, ruhige Fläche,
   klare Trennung. Alter Satz (border-top + freie px) ist gelöscht. */
.schiene-konto {
  display: flex; align-items: center;
  gap: calc(var(--luft) * 0.25);
  width: var(--schiene-knopf);
  padding: calc(var(--luft) * 0.55) calc(var(--luft) * 0.5);
  margin-top: calc(var(--luft) * 0.5);
  background: var(--flaeche);
  border: var(--linie) solid var(--rahmen);
  border-radius: calc(var(--radius) * 2.2);
  position: relative;
}
.konto-kuerzel {
  flex: 0 0 auto; order: 1;
  width: var(--chatbild); height: var(--chatbild); border-radius: 50%;
  display: grid; place-items: center; line-height: 1;
  font-size: var(--schrift-klein); font-weight: 700;
  background: var(--akzent-hauch); color: var(--akzent);
  border: var(--linie) solid var(--akzent-rand);
  background-size: cover; background-position: center; overflow: hidden;
}
.konto-kuerzel.hat-bild { color: transparent; border-color: var(--rahmen); }
.schiene .konto-name,
.konto-name {
  order: 2;
  flex: 0 1 auto; min-width: 0; width: auto;
  color: var(--text);
  font-size: var(--schrift-abschnitt);
  font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: calc(var(--luft) * 0.15) 0;
  background: transparent; border-color: transparent;
  text-align: left; min-height: 0;
  gap: 0;
}
.schiene-konto .rund { width: 1.8em; height: 1.8em; flex: 0 0 auto; }
.schiene-konto #btn-konto-einstellungen {
  order: 4; flex: none; margin-left: auto; margin-right: 0;
}
.schiene-konto #btn-konto-neu {
  order: 3; flex: none; margin-left: auto;
}
.schiene-konto:has(> #btn-konto-neu) #btn-konto-einstellungen { margin-left: 0; }
.schiene-konto .konto-menue { order: 5; }
@media (hover: hover) {
  .schiene-konto .rund:hover { color: var(--text); background: var(--flaeche-hoch); }
  #btn-konto-ab:hover { color: var(--schlecht); }
}
body.schiene-schmal .schiene-konto {
  flex-wrap: wrap; justify-content: center; width: var(--schiene-knopf);
  gap: calc(var(--luft) * 0.35);
}
body.schiene-schmal .konto-name { display: none; }
body.schiene-schmal .schiene-konto #btn-konto-neu,
body.schiene-schmal .schiene-konto #btn-konto-einstellungen { margin-left: 0; }

/* 🔴 HIER STAND BIS ZUM 23.08.2026 EINE REGEL, DIE DIE KONTO-ZEILE UNTER 861 px
   AUSGEBLENDET HAT (Medienabfrage auf die 860er-Schwelle, display none auf
   `.schiene-konto`). Sie ist geloescht, nicht auskommentiert — und sie wird hier
   BEWUSST NICHT WOERTLICH ZITIERT: eine Abnahme, die per grep nach dem Selektor
   sucht, darf nicht an einem Kommentar haengenbleiben, der ihn wiederholt. Dieselbe
   Falle steht weiter oben schon einmal beschrieben (Farbwert im Kommentar).
   Begruendung damals: „schmal liegt die Schiene unten als Leiste — dort ist fuer
   die Zeile kein Platz, und Abmelden steht in den Einstellungen."

   Beides gilt nicht mehr, und die Regel war zuletzt eine SCHEINTOTE:
     · Seit dem Redesign Teil 2 gibt es ui/geraet.css. Das Blatt setzt fuer
       768–1023 px `.schiene-konto { display: flex }` (geraet.css:397) — gleiche
       Gewichtung (0-1-0), aber spaeter geladen, also gewinnt es. Die Regel hier
       hat auf dem iPad hochkant seit dem Tag KEINE Wirkung mehr.
     · Unter 768 px blendet geraet.css die ganze Schiene hinter dem Griff aus
       (`#schale:not([data-ebene="leiste"]) #schiene > :not(#btn-leiste-griff)`,
       0-2-1) und zeigt die Konto-Zeile in der aufgerufenen Leiste ausdruecklich
       WIEDER (geraet.css:226). Auch dort entschied diese Regel nichts.

   Eine Regel, die nur deshalb nichts kaputtmacht, weil ein zweites Blatt sie bei
   gleicher Gewichtung ueberstimmt, ist genau die Hintertuer, die in diesem Blatt
   schon zweimal Schaden angerichtet hat (siehe `.nur-schmal-block` weiter oben).
   Wer geraet.css spaeter einmal frueher einbindet, umbenennt oder aufteilt,
   haette den Griff zu den Einstellungen auf dem iPad ohne eine Zeile Absicht
   verloren. Deshalb GELOESCHT statt ueberschrieben — die Geraetefrage gehoert
   ganz nach ui/geraet.css, so wie es dessen Kopf seit dem Redesign ankuendigt.
   Gemessen vorher/nachher bei 767/768/820/860/861/1024/1180 px: identisches
   Ergebnis (tools/abzug-konto-ipad.js, Abschnitt „Breiten-Reihe"). */


/* ===========================================================================
   DER KOPF IST EINE TITELLEISTE (13.08.2026)
   ===========================================================================
   Owner: „bei der App oben das Suchen raus … das AGORA OS kann nach oben in die
   Leiste wo auch die Buttons sind." Die Befehlszeile ist deshalb in den
   LISTENKOPF gezogen — sie filtert die Liste, dort gehoert sie hin. Oben stehen
   Zeichen und Name; rechts daneben malt Windows seine drei Knoepfe.
   =========================================================================== */
a.kopf-marke { color: inherit; text-decoration: none; }
.kopf-marke { display: flex; align-items: center; gap: var(--luft); min-width: 0; }
.kopf-marke img {
  display: block; width: var(--kopf-zeichen); height: var(--kopf-zeichen); flex: 0 0 auto;
}
.kopf-wort {
  font-family: var(--serif); font-size: var(--schrift-abschnitt); font-weight: 600; letter-spacing: -.02em; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* In der App traegt der Kopf denselben Grund wie das, was das SYSTEM daneben malt
   (titleBarOverlay color: #0a0909 = --hintergrund, app/src/main.js). Vorher war er
   --flaeche-tief und damit heller — dann sitzt oben rechts ein Rechteck in einem
   anderen Schwarz, genau das, wovor der Kommentar in main.js warnt.
   ⚠️ Wer die Farbe --hintergrund umstellt, verschiebt diesen Gleichstand: die Farbe
   der Knopfflaeche steckt in der gebauten App und kann nur mit einer neuen Fassung
   nachziehen. */
body[data-titelzone] .kopf { background: var(--hintergrund); border-bottom-color: transparent; }

/* ————— Der Listenkopf traegt jetzt zwei Zeilen ————— */
.listen-kopf { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
.listen-kopf-oben { display: flex; align-items: center; gap: 8px; }
.listen-kopf .zeile-box { max-width: none; margin: 0; }
/* Der Leeren-Knopf sass 60 px vom rechten Rand, weil rechts im Kopf noch das Konto
   stand. In der Liste ist rechts nichts mehr — sonst schwebt er mitten im Feld. */
.listen-kopf .zeile-box input { padding-right: 40px; }
.listen-kopf .zeile-leer { right: 8px; }


/* ————— ANHÄNGE IM VERFASSER (A7, 13.08.2026) ————— */
.anhaenge { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 0 8px; }
.anhang {
  position: relative; display: flex; flex-direction: column; justify-content: center;
  border: var(--linie) solid var(--rahmen); border-radius: 9px; background: var(--flaeche-tief);
  overflow: hidden;
}
.anhang img { display: block; width: 64px; height: 64px; object-fit: cover; cursor: zoom-in; }
.anhang.datei { padding: 6px 26px 6px 9px; max-width: 240px; min-width: 0; }
.anhang-n { font-size: .88em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.anhang-s { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Was das Modell nicht lesen kann, sagt das mit der Warnfarbe — vor dem Senden. */
.anhang.warn { border-color: color-mix(in srgb, var(--warn) 55%, var(--rahmen)); }
.anhang.warn .anhang-s { color: var(--warn); }
.anhang-x {
  position: absolute; top: 2px; right: 2px; width: 20px; height: 20px;
  display: grid; place-items: center; cursor: pointer; border-radius: 6px;
  background: color-mix(in srgb, var(--hintergrund) 70%, transparent);
  color: var(--gedaempft); font-size: 12px; line-height: 1;
}
@media (hover: hover) { .anhang-x:hover { color: var(--schlecht); } }
/* Solange der Upload läuft, pulst ein Punkt — kein Balken, der einen Fortschritt
   behauptet, den niemand kennt. */
.anhang.laeuft { min-width: 64px; min-height: 64px; align-items: center; }
.anhang-punkt {
  width: 10px; height: 10px; border-radius: 50%; background: var(--akzent);
  animation: anhangPuls 1.1s ease-in-out infinite;
}
@keyframes anhangPuls { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
/* Datei über den Verfasser ziehen: die Fläche sagt, dass sie sie nimmt. */

@media (prefers-reduced-motion: reduce) { .anhang-punkt { animation: none; } }

/* Anhänge in einer gesendeten Nachricht: Download, nicht nur der Name.
   Maße wie die Chips im Verfasser — kein zweiter Satz Werte. */
.nachricht-anhaenge {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 0 6px;
  max-width: min(72ch, 100%);
}
.nachricht.von-mir .nachricht-anhaenge { justify-content: flex-end; }
.nachricht-anhaenge a.anhang { color: inherit; text-decoration: none; cursor: pointer; }


/* Denk-Regler: native Breite ist weg. OSWahl zeichnet den Knopf (max-content).
   Der alte 12em-Deckel (und 9em unter 860 px) schnitt „xhigh" nicht, aber
   erzwang dieselbe Enge wie die Modellwahl — gelöscht, nicht überschrieben. */


/* ###########################################################################
   REDESIGN DES CHAT-BEREICHS — VON GROK 4.6 (xhigh), 13.08.2026
   ###########################################################################
   Owner: „Grok soll hier nen ganzen Redesign machen, er soll etwas machen, was zu
   einem AGORA OS passt — oben die Leiste bleibt aber wie sie ist" und generell:
   „Styling bitte nur von Grok machen lassen."

   Grok hat den ECHTEN Stand bekommen, nicht eine Beschreibung davon: die Token aus
   :root, die betroffenen Regeln wörtlich aus dieser Datei und das Markup, das
   bereiche.js erzeugt. Auftrag und vollständige Antwort liegen in
   docs/grok/redesign-chat-2026-08-13.md.

   Sein Bild dazu: die Schiene ist die Zarge, die Liste die Indexplatte auf der Tür,
   der Verlauf der Hohlraum dahinter, der Verfasser die Schlossplatte — dasselbe
   Gerät wie im Startbild.

   NACHGEMESSEN, bevor es hier steht (die Auflagen aus dem Auftrag):
     · kein einziger fester Farbwert — nur Token und color-mix
     · `.kopf`, `.kopf-marke`, `.kopf-wort` unangetastet (Titelleiste der App)
     · keine :hover-Regel ausserhalb von @media (hover: hover)
     · @media (prefers-reduced-motion: reduce) vorhanden
     · keine eigenen Zeiten — nur --schnell/--normal/--kurve
     · die schmale Anordnung (860 px) ist berücksichtigt
   Es steht als BLOCK am Ende: was hier drin ist, ist Groks Handschrift, und es
   lässt sich in einem Stück zurücknehmen.
   ########################################################################### */
/* ============================================================
   Chat-Bereich — Tresor (an ui/agora.css ANHÄNGEN)
   Überschreibt Schiene, Liste, Verlauf, Blasen, Verfasser.
   .kopf / .kopf-marke / .kopf-wort: unangetastet.
   ============================================================ */

.liste,
.chat-lauf {
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--akzent) 35%, var(--rahmen)) transparent;
}

/* --- Liste ----------------------------------------------- */
.spalte-liste {
  background: var(--flaeche-tief);
  border-right: var(--linie) solid var(--rahmen);
}
.listen-kopf {
  background: var(--flaeche);
  border-bottom: var(--linie) solid var(--rahmen);
}
.listen-titel { color: var(--text); letter-spacing: -.01em; }
.listen-titel small { color: var(--gedaempft); }
.liste { background: transparent; }
.liste-gruppe {
  background: var(--flaeche-tief);
  color: var(--gedaempft);
  letter-spacing: .1em;
}
.listen-leer { color: var(--gedaempft); }
.listen-fuss {
  background: color-mix(in srgb, var(--flaeche-tief) 70%, var(--hintergrund));
  border-top-color: var(--rahmen);
  color: var(--gedaempft);
}
.liste-zeile {
  background: transparent;
  border-color: transparent;
  color: var(--text);
  transition:
    background var(--schnell) var(--kurve),
    color var(--schnell) var(--kurve);
}
.liste-zeile[aria-current="page"],
.liste-zeile[aria-selected="true"],
.liste-zeile.aktiv {
  background: var(--akzent-hauch);
  color: var(--text);
  border-left-color: var(--akzent);
}

/* --- Verlauf: Hohlraum ------------------------------------ */
.spalte-detail { background: var(--hintergrund); }
.detail-kopf {
  background: var(--flaeche);
  border-bottom: var(--linie) solid var(--rahmen);
}
.detail-kopf h1 { color: var(--text); }
.detail { background: var(--hintergrund); }
.chat-lauf { background: var(--hintergrund); }
.nachricht { margin: 0 0 calc(var(--luft) * 1.5); }
.blase {
  background: var(--flaeche);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  padding: calc(var(--zeile-y) + 2px) var(--luft);
}
.nachricht.von-mir .blase {
  background: var(--akzent-weich);
  border-color: var(--akzent-rand);
}
.nachricht-fuss { color: var(--gedaempft); }
.blase pre {
  background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen);
}
.blase :not(pre) > code {
  background: color-mix(in srgb, var(--hintergrund) 55%, var(--flaeche));
}
.blase img,
.blase .md-bild {
  border: var(--linie) solid var(--rahmen);
}
.med-videobox {
  background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  overflow: hidden;
}
.denken {
  color: var(--gedaempft);
  border-left-color: color-mix(in srgb, var(--warn) 70%, var(--rahmen));
  background: color-mix(in srgb, var(--warn) 6%, transparent);
}
.spur { color: var(--gedaempft); }
.cursor::after { color: var(--akzent); }

/* Verfasser-Optik steht einmal oben. Hier nur Hover der vorhandenen Klassen. */
.anhang {
  background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen);
}
.anhang.warn {
  border-color: color-mix(in srgb, var(--warn) 55%, var(--rahmen));
}
.anhang-x {
  background: color-mix(in srgb, var(--hintergrund) 70%, transparent);
  color: var(--gedaempft);
}
.anhang-punkt { background: var(--akzent); }

/* --- Hover nur mit echtem Zeiger -------------------------- */
@media (hover: hover) {
  .liste-zeile:hover {
    background: color-mix(in srgb, var(--flaeche-hoch) 40%, transparent);
  }
  .liste-zeile[aria-current="page"]:hover,
  .liste-zeile[aria-selected="true"]:hover,
  .liste-zeile.aktiv:hover {
    background: color-mix(in srgb, var(--akzent) 20%, transparent);
  }
  .nachricht-kopie { opacity: 0; transition: opacity var(--schnell) var(--kurve); }
  .nachricht:hover .nachricht-kopie { opacity: 1; }
  .verfasser .senden:hover { background: var(--akzent-hover); }
  .verfasser .senden.stop:hover { background: color-mix(in srgb, var(--schlecht) 78%, var(--text)); }
  .anhang-x:hover { color: var(--text); }
}

.nachricht-kopie:focus-visible { opacity: 1; }

/* --- Schmal: Schiene unten, nichts zerlegen --------------- */
@media (max-width: 860px) {
  .spalte-liste,
  .spalte-detail { border-right: 0; }
  .blase { max-width: 100%; }
  .chat-lauf { background: var(--hintergrund); }
}

/* --- Bewegung aus, wenn gewünscht ------------------------- */
@media (prefers-reduced-motion: reduce) {
  .schiene button,
  .schiene-klapp svg,
  .liste-zeile,
  .blase,
  .verfasser textarea,
  .verfasser .senden,
  .nachricht-kopie {
    transition: none;
  }

}


/* ============================================================
   Einstellungen + Admin-Modus — Tresor (13.08.2026)
   Lange Seite mit Rhythmus; Abo-Karten mit Zustand;
   Admin-Liste wie die Chat-Liste, Detail als ruhige Fläche.
   .kopf / .kopf-marke / .kopf-wort: unangetastet.
   ============================================================ */

/* --- Die Kammer: derselbe Hohlraum wie der Chat-Verlauf ---- */
.schale[data-bereich="einstellungen"] .spalte-detail,
.schale[data-bereich="admin"] .spalte-detail {
  background: var(--hintergrund);
}
.schale[data-bereich="einstellungen"] .detail,
.schale[data-bereich="admin"] .detail {
  background: var(--hintergrund);
}
.schale[data-bereich="einstellungen"] .detail-kopf,
.schale[data-bereich="admin"] .detail-kopf {
  background: var(--flaeche);
  border-bottom: var(--linie) solid var(--rahmen);
}

/* Reiter-Liste der Einstellungen gelöscht (04.09.2026): Inhaltsverzeichnis
   in .e-inhalt springt, schaltet nicht. Admin-Liste bleibt, falls der Bereich
   je wiederkommt. */
.schale[data-bereich="admin"] .zeile {
  background: transparent;
  border-color: transparent;
  color: var(--text);
  padding: calc(var(--zeile-y) + 2px) var(--luft);
  transition:
    background var(--schnell) var(--kurve),
    color var(--schnell) var(--kurve);
}
.schale[data-bereich="admin"] .zeile[aria-selected="true"] {
  background: var(--akzent-hauch);
  color: var(--text);
  border-left-color: var(--akzent);
}
.schale[data-bereich="admin"] .zeile-marken {
  gap: 6px;
  margin-top: 5px;
}
.schale[data-bereich="admin"] .zeile-marken .marke-chip {
  letter-spacing: .03em;
  padding: .22em .62em;
}
.marke-chip.ruhig {
  color: var(--gedaempft);
  background: transparent;
  border-style: dashed;
  border-color: color-mix(in srgb, var(--rahmen) 70%, var(--gedaempft));
}

/* --- Einstellungen: Abschnitte als eingelassene Platten ---- */
.e-alle {
  display: flex;
  flex-direction: column;
  gap: calc(var(--luft) * 1.75);
  padding-bottom: calc(var(--luft) * 2);
}
.e-alle .e-block {
  background: var(--flaeche);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  padding: var(--karte-innen);
  margin-bottom: 0;
}
.e-alle .e-block > h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: var(--schrift-abschnitt);
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--text);
  padding-left: .7em;
  border-left: 2px solid var(--akzent);
}
.e-alle .e-block-unten {
  margin: .35em 0 calc(var(--luft) * 1.15);
  padding-left: calc(.7em + 2px);
}
.e-alle .e-block .karte {
  background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen);
}
.e-alle .e-block .abschnitt > h2 {
  margin: 0 0 .55em;
  font-family: var(--serif);
  font-size: .95em;
  letter-spacing: 0;
  text-transform: none;
  color: var(--gedaempft);
  font-weight: 600;
}

/* Abo-Gruppen: je Anbieter eine Kammer, nicht ein weiterer gleicher Kasten.
   Aussenabstand trägt `.abo-gruppen` (gap), nicht die Kammer selbst. */
.abo-gruppe > h2 {
  margin: 0 0 .45em;
}
.abo-gruppe .karte {
  padding: calc(var(--zeile-y) * .4) var(--luft);
}

/* Abo-Zeile: Zustand, Plan, drei Griffe — Entfernen sichtbar, nicht schreiend */
.abo-zeile {
  align-items: center;
  gap: 8px var(--luft);
  padding: calc(var(--zeile-y) + 2px) 2px;
  border-bottom-color: color-mix(in srgb, var(--rahmen) 80%, transparent);
  transition:
    opacity var(--normal) var(--kurve),
    background var(--schnell) var(--kurve);
}
.abo-zeile:last-child { border-bottom: 0; }
/* Aus: eine schmale Zeile, kein zweiter voller Konto-Block. Die Höhe einer
   ausgeschalteten Zeile darf die Gruppe nicht nach unten treiben — sonst rutscht
   der nächste Anbieter unter den Knöpfen weg. */
.abo-zeile.aus {
  opacity: .58;
  padding-top: calc(var(--zeile-y) * .35);
  padding-bottom: calc(var(--zeile-y) * .35);
}
.abo-zeile .abo-zustand { margin-left: 8px; }
.abo-zeile button.gefahr {
  background: var(--schlecht-grund);
  color: var(--schlecht);
  border-color: color-mix(in srgb, var(--schlecht) 38%, var(--rahmen));
}
.abo-zeile button.still {
  color: var(--gedaempft);
}

/* 5h- und 7d-Balken in der Abo-Verwaltung (Owner 01.09.: beide Fenster, mit Reset).
   Nebeninander, nicht untereinander. Masse und Farben nur aus den Token-Variablen
   der Übersicht (`--balken-hoehe`, `--balken-spur`) — keine freien px, kein #hex. */
.abo-fenster {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  gap: var(--luft);
  max-width: min(100%, 36em);
  min-width: 0;
}
.abo-fenster-teil {
  flex: 1 1 10rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.abo-fenster-oben {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
  font-size: .78em;
  line-height: 1.25;
}
.abo-fenster-oben i {
  flex: 1 1 auto;
  min-width: 0;
  font-style: normal;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.abo-fenster-oben u {
  flex: 0 0 auto;
  text-decoration: none;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.abo-fenster-bar {
  height: var(--balken-hoehe, 8px);
  border-radius: 99px;
  overflow: hidden;
  background: var(--balken-spur, color-mix(in srgb, var(--text) 16%, transparent));
  box-shadow: inset 0 0 0 var(--linie) var(--balken-spur-rand, color-mix(in srgb, var(--text) 10%, transparent));
}
.abo-fenster-bar > b {
  display: block;
  height: 100%;
  background: var(--gut, var(--akzent));
  border-radius: inherit;
}
.abo-fenster-teil.warn .abo-fenster-bar > b { background: var(--warn); }
.abo-fenster-teil.schlecht .abo-fenster-bar > b { background: var(--schlecht); }
.abo-fenster-teil.gut .abo-fenster-bar > b { background: var(--gut, var(--akzent)); }
.abo-fenster-bar.unbekannt {
  background: repeating-linear-gradient(135deg,
    var(--balken-spur, color-mix(in srgb, var(--text) 16%, transparent)) 0 3px,
    transparent 3px 6px);
}

/* Verteilung fällt von den Abo-Kammern ab — Haarlinie, mehr Luft, kein zweiter Kasten */
.abo-verteilung {
  margin-top: calc(var(--luft) * 1.4);
  padding-top: calc(var(--luft) * 1.2);
  border-top: var(--linie) solid var(--rahmen);
}
.abo-verteilung .wahlreihe {
  gap: 8px;
}
.abo-verteilung .wahlreihe button[aria-pressed="true"] {
  border-color: var(--akzent-rand);
}

/* Oberflächen-Kästen (Farben, Größe, Leiste …) sitzen in .e-block —
   der Hinweis darunter tritt zurück, damit er nicht wie ein fünfter Kasten wirkt. */
.e-alle .hinweis {
  background: var(--flaeche-tief);
  border-left-color: var(--akzent);
}

/* --- Admin: Detail als ruhige Fläche ---------------------- */
.admin-leer {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 42vh;
  max-width: 28em;
}
.admin-leer-wort {
  margin: 0 0 .35em;
  font-family: var(--serif);
  font-size: var(--schrift-titel);
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--text);
}
.admin-leer .gedaempft { max-width: 22em; }

.admin-blatt {
  max-width: 36em;
}
.admin-blatt .stufen-leiter {
  gap: 6px;
  font-size: .8em;
}
.admin-blatt .stufen-leiter span {
  padding: .28em .75em;
  background: var(--flaeche-tief);
}
.admin-blatt .stufen-leiter span[data-hier="ja"] {
  background: var(--akzent);
  color: var(--akzent-text);
  border-color: transparent;
}
.stufen-pfeil {
  border: 0;
  padding: 0 .15em;
  color: var(--gedaempft);
  background: transparent;
}
.admin-zweck {
  margin: 0;
  font-size: 1.05em;
  line-height: 1.45;
}
.admin-blatt .karte {
  background: var(--flaeche-tief);
}
.admin-ausrollen {
  width: auto;
  transition: background var(--schnell) var(--kurve);
}
.admin-blatt .hinweis {
  background: var(--flaeche-tief);
  border-left-color: var(--akzent);
  color: var(--gedaempft);
}

/* --- Hover nur mit echtem Zeiger -------------------------- */
@media (hover: hover) {
  .schale[data-bereich="admin"] .zeile:hover {
    background: color-mix(in srgb, var(--flaeche-hoch) 40%, transparent);
  }
  .schale[data-bereich="admin"] .zeile[aria-selected="true"]:hover {
    background: color-mix(in srgb, var(--akzent) 20%, transparent);
  }
  .e-sprung:hover { color: var(--text); border-left-color: var(--akzent); }
  .abo-zeile button.gefahr:hover:not(:disabled) {
    border-color: var(--schlecht);
    background: color-mix(in srgb, var(--schlecht) 14%, transparent);
  }
  .admin-ausrollen:hover:not(:disabled) { background: var(--akzent-hover); }
}

/* --- Schmal: Kammer bleibt Kammer ------------------------- */
@media (max-width: 860px) {
  .schale[data-bereich="einstellungen"] .detail,
  .schale[data-bereich="admin"] .detail {
    background: var(--hintergrund);
  }
  .e-alle { gap: var(--raster-abstand); }
  .admin-leer { min-height: 28vh; }
}

/* --- Bewegung aus, wenn gewünscht ------------------------- */
@media (prefers-reduced-motion: reduce) {
  .schale[data-bereich="admin"] .zeile,
  .abo-zeile,
  .admin-ausrollen {
    transition: none;
  }
}

/* ===========================================================================
   KLAPP-LISTEN — Mitglieder und Werkzeuge (16.08.2026)
   Dieselbe Anordnung auf beiden Seiten: Raster aus aufklappbaren Gruppen.
   Alle Abstände aus --luft, Spaltenbreite aus --karten-min. Alter .mgl-Satz
   (eine volle Spalte, kein Raster) ist gelöscht, nicht überschrieben.
   =========================================================================== */
.klapp-raster {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--karten-min)), 1fr));
  gap: var(--luft);
  align-items: start;
}
.klapp {
  background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  min-width: 0;
}
.klapp-innen { background: var(--flaeche); }
.klapp-kopfzeile {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: calc(var(--luft) / 2);
}
.klapp-kopf {
  flex: 1 1 12em;
  display: flex;
  align-items: center;
  gap: calc(var(--luft) / 2);
  min-width: 0;
  width: auto;
  padding: calc(var(--luft) / 2) var(--luft);
  text-align: left;
  color: var(--text);
}
.klapp-wer {
  display: flex;
  flex-direction: column;
  gap: 0.1em;
  min-width: 0;
}
.klapp-wer strong { font-weight: 600; overflow-wrap: anywhere; }
.klapp-zahl { display: block; }
.klapp-pfeil {
  flex: 0 0 auto;
  color: var(--gedaempft);
  width: 1em;
  text-align: center;
}
.klapp-tun {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--luft) / 2);
  /* 16.08.: vorher nur padding-right - die Knoepfe klebten links und unten am
     Kartenrand. Jetzt seitlich derselbe Abstand wie .klapp-kopf darueber. */
  padding: 0 var(--luft) calc(var(--luft) / 2);
}
.klapp-tun button {
  padding: calc(var(--luft) / 3) calc(var(--luft) * .6);
  font-size: var(--schrift-klein);
}
.klapp-tun button.haupt { width: auto; }
.klapp[data-offen="0"] > .klapp-rumpf { display: none; }
.klapp-rumpf { padding: 0 var(--luft) var(--luft); }
.klapp-chips {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(var(--karten-min) / 2)), 1fr));
  gap: calc(var(--luft) / 2);
}
.mgl-modell {
  display: flex;
  align-items: center;
  gap: calc(var(--luft) / 2);
  margin: 0;
  padding: calc(var(--luft) / 4) calc(var(--luft) / 2);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  color: var(--text);
  font-size: var(--schrift-klein);
  cursor: pointer;
  min-width: 0;
}
.mgl-modell > input { margin: 0; font-size: inherit; }
.mgl-stand:empty { display: none; }
.mgl-stand { margin: 0; padding: 0 var(--luft) calc(var(--luft) / 2); }

/* GRENZEN je Mitglied (18.08.) — Tageslimit und Internet-Schalter im Rumpf der Karte.
   Erbt Aussehen und Abstände von .klapp-leiste/.klapp-einladen; hier stehen nur die zwei
   Dinge, die dort nicht passen: eine Zahl braucht kein 12em breites Feld (die Regel
   .klapp-einladen input ist auf E-Mail-Adressen ausgelegt), und das Internet-Häkchen
   gehört auf eine eigene Zeile, weil sein Erklärtext sonst die Zeile sprengt. */
.mgl-grenzen .mgl-cap-feld { flex: 0 0 7em; max-width: 7em; }
.mgl-grenzen .mgl-web-feld { flex: 1 1 100%; flex-wrap: wrap; }
.klapp-liste { display: flex; flex-direction: column; }
.klapp-zeile {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: calc(var(--luft) / 2) var(--luft);
  padding: calc(var(--luft) / 3) 0;
  border-top: var(--linie) solid var(--rahmen);
  font-size: var(--schrift-klein);
}
.klapp-zeile:first-child { border-top: 0; }
.klapp-zeile .wachs { flex: 1 1 10em; min-width: 0; }
.klapp-zeile .zweck { display: block; color: var(--gedaempft); }
.klapp-zeile button.still { width: auto; }
.klapp-mehr { padding: calc(var(--luft) / 2) 0 var(--luft); }
.klapp-mehr ul { margin: 0.3em 0; padding-left: 1.2em; }
.klapp-mehr p { margin: 0.35em 0; }
.klapp-fuss { margin: 0 0 var(--luft); }
.werk-abschnitt-satz { margin: 0 0 calc(var(--luft) / 2); }
.klapp-leiste {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--luft);
  margin-bottom: var(--luft);
  padding: var(--luft);
  background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
}
.klapp-leiste .klapp-wer { flex: 1 1 12em; }
.klapp-einladen {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--luft) / 2);
  flex: 1 1 16em;
  align-items: stretch;
}
.klapp-einladen input { flex: 1 1 12em; min-width: 0; }
.klapp-einladen button.haupt { width: auto; flex: 0 0 auto; }
.klapp-leiste .mgl-einladen-stand:empty { display: none; }
.klapp-leiste .mgl-einladen-stand,
.klapp-leiste #mgl-einladen-daten { flex: 1 1 100%; margin: 0; }
@media (hover: hover) {
  .mgl-modell:hover { border-color: var(--akzent-rand); }
}
@media (max-width: 860px) {
  .klapp-kopf, .mgl-modell, .klapp-zeile { min-height: 44px; }
}

/* ===========================================================================
   16.08.2026 — DIE KOSTEN-ANSICHT GING "EWIG NACH UNTEN" (Owner)
   Zwei lange Blocke standen untereinander in EINER schmalen Spalte: die Tabelle
   "Nach Projekt" (10 Zeilen) und darunter "Die juengsten Posten" (12 Zeilen),
   jede Zeile dreizeilig umgebrochen. Auf einem breiten Fenster blieb rechts
   alles leer, waehrend man unten weiterscrollte.
   Jetzt: beide Blocke fuellen die Breite, die da ist. Reine Anordnung - keine
   Zahl, keine Zeile faellt weg. Werte aus den Token.
   =========================================================================== */
.ub-kosten-raster,
.ub-kosten .karte + h3 { margin-top: var(--luft); }

/* Die Posten-Liste bricht in Spalten um, sobald Platz ist. */
.karte:has(> .ub-posten) {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: calc(var(--luft) / 2);
  align-items: start;
}
.ub-posten {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: calc(var(--luft) / 3);
  padding: calc(var(--luft) / 3) 0;
}
/* Zeit/Dauer rutscht unter den Titel statt eine eigene Zeile zu erzwingen. */
.ub-posten-t { min-width: 0; overflow-wrap: anywhere; }
.ub-posten-n { grid-column: 2; font-size: var(--schrift-klein); }
.ub-posten-g { grid-column: 3; grid-row: 1 / span 2; align-self: center; white-space: nowrap; }

/* Die Projekt-Tabelle: Zahlen rechtsbuendig, Name darf umbrechen, keine
   dreifach umgebrochenen Euro-Spalten mehr. */
table.ub-projekte { width: 100%; border-collapse: collapse; }
table.ub-projekte th, table.ub-projekte td { padding: calc(var(--luft) / 4) calc(var(--luft) / 3); }
table.ub-projekte th:not(:first-child),
table.ub-projekte td:not(:first-child) { text-align: right; white-space: nowrap; }
table.ub-projekte td:first-child { overflow-wrap: anywhere; }


/* ===========================================================================
   C7 — Not-Aus, Einklappen neben Übersicht, Wissens-Fläche
   Alter Schienen-/Konto-Satz steht oben (gelöscht + neu, keine Kopie).
   Hooks gemessen in ui/notaus.js: .notaus-knopf, data-zustand=frei|gesperrt,
   .notaus-wort/.notaus-titel/.notaus-neben, #notaus-platz, [data-host="notaus"],
   .notaus-knopf-host. Klasse .laeuft setzt notaus.js nicht; Selektor liegt
   bereit, falls A17 sie nachzieht. Fallback #btn-notaus aus bereiche.js.
   =========================================================================== */

/* C7.4 Einklappen sitzt in .schiene-oben-box (siehe oben, nach .schiene-kopf).
   Die alten :has(#btn-schiene-klapp)-Regeln für #schiene-haupt sind gelöscht:
   der Knopf wohnt nicht mehr in der Gruppe, die schieneZeichnen() wischt. */

/* C7.3 Not-Aus in der Schiene.
   Spezifität .schiene .notaus-knopf[data-zustand] (0-3-0) schlägt den
   injizierten Satz aus notaus.js (0-2-0), ohne !important. */
.schiene #notaus-platz,
.schiene #schiene-notaus,
.schiene .notaus-knopf-host,
.schiene [data-host="notaus"] {
  width: var(--schiene-knopf);
  flex-shrink: 0;
  padding: calc(var(--luft) * 0.25) 0 0;
}
.schiene .notaus-knopf,
.schiene #btn-notaus {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: calc(var(--luft) * 0.55);
  width: var(--schiene-knopf);
  min-height: calc(var(--tap) - var(--luft) * 0.35);
  padding: calc(var(--luft) * 0.65) calc(var(--luft) * 0.7);
  margin: 0;
  background: transparent;
  color: var(--gedaempft);
  border: var(--linie) solid transparent;
  border-radius: var(--radius);
  font: inherit;
  font-weight: 650;
  text-align: left;
  cursor: pointer;
  transition:
    background var(--schnell) var(--kurve),
    color var(--schnell) var(--kurve),
    border-color var(--schnell) var(--kurve);
}
.schiene .notaus-knopf svg,
.schiene #btn-notaus svg { flex-shrink: 0; }
.schiene .notaus-knopf .notaus-wort {
  display: flex; flex-direction: column; min-width: 0; line-height: 1.2;
}
.schiene .notaus-knopf .notaus-titel { font-size: var(--schrift-klein); }
.schiene .notaus-knopf .notaus-neben {
  font-size: var(--schrift-klein); font-weight: 500;
  color: var(--gedaempft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.schiene .notaus-knopf[data-zustand="frei"],
.schiene #btn-notaus:not(.laeuft) {
  background: transparent;
  color: var(--gedaempft);
  border-color: transparent;
}
.schiene .notaus-knopf[data-zustand="gesperrt"],
.schiene .notaus-knopf.laeuft,
.schiene .notaus-knopf[data-zustand="laeuft"],
.schiene #btn-notaus.laeuft {
  background: var(--schlecht-grund);
  color: var(--schlecht);
  border-color: var(--rahmen);
  min-height: var(--tap);
  padding: calc(var(--luft) * 0.85) var(--luft);
  font-size: var(--schrift-abschnitt);
}
.schiene .notaus-knopf[data-zustand="gesperrt"] .notaus-titel,
.schiene .notaus-knopf.laeuft .notaus-titel {
  font-size: var(--schrift-abschnitt);
  color: inherit;
}
.schiene .notaus-knopf[data-zustand="gesperrt"] .notaus-neben,
.schiene .notaus-knopf.laeuft .notaus-neben { color: inherit; }
.schiene .notaus-knopf:disabled { opacity: .65; cursor: wait; }
@media (hover: hover) {
  .schiene .notaus-knopf[data-zustand="frei"]:hover,
  .schiene .notaus-knopf[data-zustand="frei"]:focus-visible,
  .schiene #btn-notaus:not(.laeuft):hover {
    background: var(--flaeche-hoch);
    color: var(--text);
    border-color: transparent;
  }
  .schiene .notaus-knopf[data-zustand="gesperrt"]:hover,
  .schiene .notaus-knopf[data-zustand="gesperrt"]:focus-visible,
  .schiene .notaus-knopf.laeuft:hover,
  .schiene #btn-notaus.laeuft:hover {
    background: color-mix(in srgb, var(--schlecht) 28%, var(--hintergrund));
    color: var(--schlecht);
    border-color: var(--rahmen);
  }
}
body.schiene-schmal .schiene #notaus-platz,
body.schiene-schmal .schiene #schiene-notaus {
  padding: calc(var(--luft) * 0.25) 0 0;
  width: var(--schiene-knopf);
}
body.schiene-schmal .schiene .notaus-knopf,
body.schiene-schmal .schiene #btn-notaus {
  justify-content: center;
  padding: calc(var(--luft) * 0.45) calc(var(--luft) * 0.3);
}
body.schiene-schmal .schiene .notaus-knopf .notaus-wort { display: none; }
body.schiene-schmal .schiene .notaus-knopf[data-zustand="gesperrt"],
body.schiene-schmal .schiene .notaus-knopf.laeuft {
  min-height: var(--tap);
}

@media (max-width: 860px) {
  .schiene-konto {
    width: auto;
    margin-top: 0;
    padding: calc(var(--luft) * 0.2);
    background: transparent;
    border-color: transparent;
  }
  .schiene .notaus-knopf,
  .schiene #btn-notaus {
    width: auto;
    min-width: var(--tap);
    min-height: var(--tap);
    max-width: none;
    flex-direction: column;
    align-items: center;
    gap: calc(var(--luft) * 0.15);
    padding: calc(var(--luft) * 0.35);
  }
  .schiene .notaus-knopf .notaus-wort { display: none; }
  .schiene #notaus-platz,
  .schiene #schiene-notaus,
  .schiene .notaus-knopf-host { width: auto; padding: 0; }
}


/* ===========================================================================
   WISSEN-DIALOG (04.09.2026) — der alte Kachelwand-Regelsatz (.wissen-flaeche,
   .wi-liste Raster, .wi-zeile Karten) ist gelöscht, nicht ausgeblendet.
   Chips und Dialog nutzen vorhandene .dialog / .chip-reihe / .marke-chip.
   =========================================================================== */
.dialog[data-wissen-dialog] .chip-reihe {
  max-height: var(--karten-min);
  overflow: auto;
  overscroll-behavior: contain;
  margin: calc(var(--luft) * .4) 0;
}
.dialog[data-wissen-dialog] .marke-chip {
  white-space: normal;
  overflow-wrap: anywhere;
  max-width: 100%;
}
.dialog[data-wissen-dialog] .marke-chip input { margin: 0; }

/* ===========================================================================
   BEREICH „PROJEKTE" (ui/wissensprojekte.js) — Projekte der Wissensbank
   verwalten. Nur Variablen, kein Hex, keine freien px.
   =========================================================================== */
.wp-karte { margin-bottom: var(--luft); }
.wp-kopf { display: flex; align-items: center; gap: calc(var(--luft) * .6); flex-wrap: wrap; }
.wp-luecke { flex: 1 1 auto; }
.wp-auf { font-weight: 600; }

.wp-docs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--kachel-min), 1fr));
  gap: calc(var(--luft) * .3);
  margin-top: var(--luft);
}
.wp-doc {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: calc(var(--luft) * .5);
  padding: calc(var(--luft) * .35) calc(var(--luft) * .5);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  background: var(--flaeche-tief);
  cursor: pointer;
}
.wp-doc:hover { background: var(--flaeche-hoch); border-color: var(--akzent-rand); }
.wp-doc input { margin: 0; accent-color: var(--akzent); cursor: pointer; }
.wp-doc:has(input:checked) { background: var(--akzent-hauch); border-color: var(--akzent-rand); }
.wp-doc-titel { color: var(--text); overflow-wrap: anywhere; }
.wp-doc-slug { grid-column: 2; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.wp-fuss { margin-top: var(--luft); }

/* ---------- Wächter (01.09.2026) ------------------------------------------
   Nur vorhandene Token. Kein eigenes #hex, keine freien px: Abstände aus
   --luft/--raster-abstand/--zeile-y, Radius aus --radius, Farben aus der
   Palette. Felder bleiben unter calc(--karten-min * 1.75) (unter 600 px). */
.wa-blatt {
  display: grid;
  gap: var(--raster-abstand);
  max-width: var(--max);
}
.wa-raster {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--karten-min)), 1fr));
  gap: var(--raster-abstand);
  align-items: start;
}
.wa-karte h2 {
  margin: 0 0 var(--luft);
  font-size: var(--schrift-abschnitt);
}
.wa-zahlen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(var(--karten-min) / 2)), 1fr));
  gap: var(--luft);
}
.wa-zahl { min-width: 0; }
.wa-zahl strong {
  display: block;
  font-size: var(--schrift-titel);
  font-weight: 600;
}
.wa-vorschau-bild {
  display: block;
  width: 100%;
  max-width: 100%;
  max-height: calc(var(--tap) * 8);
  object-fit: contain;
  background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
}
.wa-vergleich {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--schrift-klein);
  overflow-wrap: anywhere;
  margin: calc(var(--luft) * 0.5) 0 0;
}
.wa-vergleich p { margin: 0 0 calc(var(--luft) * 0.35); }
.wa-vergleich mark {
  background: var(--schlecht-grund);
  color: var(--schlecht);
  padding: 0;
}
.wa-start {
  display: grid;
  gap: var(--luft);
  max-width: min(100%, calc(var(--karten-min) * 1.75));
}
.wa-start label {
  display: grid;
  gap: calc(var(--luft) * 0.35);
  font-size: var(--schrift-klein);
  color: var(--gedaempft);
}
.wa-zeile {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--luft);
  align-items: baseline;
  width: 100%;
  max-width: 100%;
  text-align: left;
  padding: var(--zeile-y) 0;
  border: 0;
  border-bottom: var(--linie) solid var(--rahmen);
  border-radius: 0;
  background: transparent;
}
.wa-zeile.ist-offen { background: var(--akzent-hauch); }
.wa-proto {
  max-height: calc(var(--tap) * 10);
  overflow: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--schrift-klein);
  background: var(--flaeche-tief);
  border: var(--linie) solid var(--rahmen);
  border-radius: var(--radius);
  padding: var(--luft);
}
.wa-proto p { margin: 0 0 calc(var(--luft) * 0.35); }
