/* ===========================================================================
   OS4 — 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.

   Die drei Dichten und die Zusatzregler (Schriftgrösse, Listenbreite, Ecken)
   hängen ebenfalls nur an Variablen; data-dichte setzt os4.js auf <html>.
   =========================================================================== */

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

     DAS THEMA (Owner 09.08.2026: „was für ein theme mach es passend") ist die
     warme Palette des lebenden Produkts — Fundstellen in ui/style.css:
     --bg 11 · --panel-solid 13 · --text 22 · --muted 24 · --accent 28 ·
     Tinte auf dem Akzent 145 · --ok 38 · --warn 39 · --err 40. `rahmen` hat dort
     keine deckende Entsprechung (--border-2 ist rgba(255,240,234,.12)); der Wert
     hier ist genau diese Linie auf --hintergrund gerechnet.

     ⚠️ ZWEITE KOPIE, ZEICHENGLEICH: dieselben zehn Werte stehen als VORGABE_FARBEN
     in os4.js:565-569. Das ist Absicht und darf NICHT wegoptimiert werden — dieses
     Blatt ist der Ausgangszustand für das ERSTE BILD, bevor JavaScript läuft;
     OS4.farbenAnwenden() (os4.js:667ff) schreibt danach Inline-Styles auf <html>,
     und die schlagen :root. Nur hier ändern wäre wirkungslos, nur dort ändern
     liesse die alte Farbe beim Laden aufblitzen. Wer eine ändert, ändert beide. */
  --hintergrund: #0a0909;
  --flaeche:     #151213;
  --text:        #f3efec;
  --gedaempft:   #a49d9a;
  --akzent:      #e0715a;
  --akzent-text: #1a0f0c;
  --rahmen:      #272524;
  --gut:         #4ec99a;
  --warn:        #e5b567;
  --schlecht:    #e8697a;

  /* 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));

  /* 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;

  --zeile-y: 10px;
  --luft: 12px;
  --schrift: 14.5px;

  /* ————— 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 os4". Damit ist os4 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);
}

html[data-dichte="kompakt"] { --zeile-y: 6px;  --luft: 8px;  --schrift: 13.2px; }
html[data-dichte="normal"]  { --zeile-y: 10px; --luft: 12px; --schrift: 14.5px; }
html[data-dichte="luftig"]  { --zeile-y: 15px; --luft: 18px; --schrift: 15.6px; }

* { box-sizing: border-box; }

html, body {
  margin: 0; height: 100%;
  background: var(--hintergrund); color: var(--text);
  font: calc(var(--schrift) * var(--skala))/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}
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: .86em; }
.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(--akzent); outline-offset: 2px; }

/* ---------- Knöpfe und Felder ---------------------------------------------- */
button {
  font: inherit; cursor: pointer; color: var(--text);
  background: var(--flaeche-hoch); border: 1px 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; }

input, select, textarea {
  font: inherit; color: var(--text); background: var(--flaeche-tief);
  border: 1px solid var(--rahmen); border-radius: var(--radius); padding: .45em .6em;
  width: 100%;
}
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: 1px solid var(--rahmen); border-radius: calc(var(--radius) * 1.6); padding: 26px;
}
.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-size: 1.15em; }

/* ---------- 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;
  grid-template-rows: auto minmax(0, 1fr);
  height: 100%;
}

.kopf {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px calc(6px) 10px;
  border-bottom: 1px solid var(--rahmen); background: var(--flaeche-tief);
  padding-top: calc(6px + env(safe-area-inset-top));
}
/* `.kopf-marke` stand hier bis zum 09.08.2026 und war tot: das Element gibt es
   seit dem Umbau des Kopfes nicht mehr (kein Treffer in index.html, os4.js,
   bereiche.js, karten.js). Eine Regel ohne Element ist kein Vorrat, sondern eine
   Falle — der Nächste hält sie für ein Bauteil und sucht das Element. */
.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: 1px 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: 3px;
  padding: 12px 0; background: var(--flaeche-tief);
  border-right: 1px solid var(--rahmen);
}
/* 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: 12px; opacity: .9;
}
.schiene-marke-wort {
  font-size: .98em; font-weight: 700; letter-spacing: -.02em; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.schiene-gruppe { display: flex; flex-direction: column; gap: 3px; width: 100%; align-items: center; }
.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: 9px 10px;
  display: flex; flex-direction: row; align-items: center; gap: 11px;
  background: transparent; border-color: transparent; color: var(--gedaempft);
  text-align: left; min-height: 40px;
}
.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); } }
/* aria-current="page" statt aria-selected: die Schiene ist eine <nav> mit Knöpfen und
   KEINE Tabliste (siehe os4.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. */
.schiene button[aria-current="page"] { background: var(--akzent-hauch); color: var(--akzent); }
.schiene button[aria-current="page"] .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[aria-current="page"]::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);
}

/* ---------- DER URTEILSKASTEN AUF DER FARBSEITE ----------------------------
   DAS EINZIGE ELEMENT DIESER OBERFLÄCHE MIT FESTEN FARBWERTEN — und zwar mit Absicht.
   Er sagt beim AUSWÄHLEN, welches Farbpaar unter 4,5:1 liegt, und trägt den Knopf,
   der die Vorschau zurücknimmt (bereiche.js → urteilZeichnen). Würde er aus der
   gerade gewählten Palette gemalt, wäre er genau dann unlesbar, wenn man ihn braucht:
   ein Urteil in den Farben, vor denen es warnt, ist eine schwarze Fläche mit einem
   Geheimnis darin. Die Werte sind gegeneinander geprüft (#ffe4dc auf #2b1512 ≈ 12:1)
   und hängen an keiner Variablen.

   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: #2b1512; color: #ffe4dc; border: 1px solid #e0715a;
  border-radius: var(--radius, 10px); padding: 12px 14px;
}
.farb-urteil .farb-urteil-kopf { margin: 0 0 .5em; 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: .86em; color: #f0c9bf; margin: 0 0 .6em; }
.farb-urteil button {
  width: auto; font-size: .9em;
  background: #4a221c; color: #fff2ee; border: 1px solid #f0917d;
}
@media (hover: hover) {
  .farb-urteil button:hover { background: #5e2c24; border-color: #ffb3a1; }
}

/* ---------- 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: 4px; font-size: .84em; }
.schiene-klapp svg { transition: transform 220ms ease; }

/* ===========================================================================
   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: 1px 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: 1px 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;
}
/* 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 1px 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/os4-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: 1px 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 os4.js (OS4.klappUmschalten), gemerkt unter
   `os4_schiene_schmal` / `os4_liste_zu`. Der gemerkte Zustand wird von
   OS4.klappWiederherstellen() gesetzt, und zwar auf oberster Ebene von os4.js —
   also lange vor OS4.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 (os4.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: 1px solid var(--rahmen); background: var(--hintergrund);
}
.listen-kopf { display: flex; gap: 6px; padding: 8px; border-bottom: 1px solid var(--rahmen); align-items: center; }
.listen-titel {
  flex: 1 1 auto; min-width: 0; font-weight: 600; font-size: .95em;
  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 1px var(--akzent-rand); }
.zeile-titel { font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.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; }
/* 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: 1px 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: 1px solid var(--rahmen); min-height: 46px;
}
.detail-kopf h1 { margin: 0; font-size: 1.02em; font-weight: 600; flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.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 (os4.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: 900px; }
/* ---- 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 os4.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 sind EINE Seite (Owner-Order 10.08.2026, s. bereiche.js →
   alleSeiten): alle acht Abschnitte stehen untereinander, die Sachgebiet-Liste
   daneben waere danach eine zweite Navigation zu denselben Inhalten. */
.e-alle .e-block { padding: calc(var(--luft) * 1.1); margin-bottom: var(--luft);
  background: var(--flaeche); border: 1px solid var(--rahmen); border-radius: var(--radius); }
.e-alle .e-block > h2 { margin: 0; font-size: 1.05em; }
.e-alle .e-block-unten { margin: .2em 0 .9em; }
.e-alle .e-block:target, .e-alle .e-block-inhalt:empty { scroll-margin-top: 12px; }

/* 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; }

@media (min-width: 861px) {
  /* Der Zurück-Knopf ist bisher NUR schmal da (Regel darüber). Im offenen Chat ist
     er breit jetzt der einzige Weg zurück auf die Startseite — die Liste, die diesen
     Weg früher getragen hat, steht dort nicht mehr.
     Vier Klassen/Attribute (0-4-0) schlagen sowohl `.detail-kopf .nur-schmal` (0-2-0)
     als auch `button.rund { display: grid }` (0-1-1) — dieselbe Kaskaden-Falle, die
     am 08.08. schon einmal zugeschnappt ist, deshalb hier gleich mitgerechnet. */
  .schale[data-bereich="chats"][data-startbild="0"] .detail-kopf .nur-schmal { display: grid; }
}

/* ---------------------------------------------------------------------------
   EIN BEREICH OHNE LISTE — die Übersicht über die VOLLE BREITE
   ---------------------------------------------------------------------------
   os4.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 — os4.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: OS4.zurListe() kehrt für einen
   Bereich ohne Liste sofort zurück (os4.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; }
.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); }
}

.abschnitt { margin: 0 0 calc(var(--luft) * 2); }
.abschnitt > h2 {
  margin: 0 0 .5em; font-size: .78em; letter-spacing: .09em; text-transform: uppercase;
  color: var(--gedaempft); font-weight: 700;
}
.karte { background: var(--flaeche); border: 1px solid var(--rahmen); border-radius: var(--radius); padding: var(--luft); }
.karte + .karte { margin-top: 8px; }
.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: 1px 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; }

/* ---------- Chat ---------------------------------------------------------- */
.chat { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.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: 1px 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: 1px 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: 1px 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; }
.cursor::after { content: "▌"; color: var(--akzent); animation: blinken 1.1s steps(2) infinite; }
@keyframes blinken { 50% { opacity: 0; } }

.verfasser { border-top: 1px solid var(--rahmen); padding: var(--luft) clamp(10px, 3vw, 26px); background: var(--flaeche-tief); }
.verfasser-kopf { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.verfasser-kopf select { width: auto; max-width: 100%; font-size: .86em; padding: .3em 1.6em .3em .5em; }
.verfasser-zeile { display: flex; gap: 8px; align-items: flex-end; }
.verfasser textarea { resize: none; min-height: 2.6em; max-height: 40vh; line-height: 1.45; font-size: 1em; }
.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; }
/* „denken lassen" stand als Inline-Stil im Quelltext von bereiche.js und war damit für
   jede Regel unerreichbar — auf dem Handy ein 114×20-Ziel. Jetzt eine Klasse, damit die
   schmale Anordnung unten daran kommt. */
.denken-schalter { display: inline-flex; gap: 5px; align-items: center; margin: 0; }
/* 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: 1px 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: 1px 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: der Platz, den es gibt (11.08.2026) --------------
   GEMESSEN am 11.08. bei 1440 px: die drei Anbieter standen untereinander, jede
   Kontozeile über die volle Breite — zwischen der E-Mail und den vier Knöpfen lag
   ein Loch von rund 700 px, und „xAI-Abo" kam erst nach dem Scrollen. Owner:
   „Einstellungen: Platz besser nutzen."

   `auto-fit` statt einer festen Spaltenzahl: die vierte Abo-Art (OpenRouter) reiht
   sich damit von selbst ein, ohne dass jemand hier eine 3 in eine 4 ändern muss.
   `min(100%, 30em)` ist die Untergrenze — schmaler wird eine Kontozeile mit Name,
   Plan-Chip und drei Knöpfen unleserlich, also bricht das Raster vorher um. Auf dem
   Handy bleibt es dadurch von selbst einspaltig.

   `align-items: start` ist kein Beiwerk: ohne diese Zeile zieht das Raster alle
   Gruppen auf die Höhe der höchsten, und unter einer Gruppe mit einem Konto klaffte
   dann die Lücke, die gerade verschwinden soll. */
.abo-gruppen {
  display: grid; gap: 0 22px; align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 30em), 1fr));
}
/* Die Gruppen sitzen im Raster, also trägt das Raster den Abstand — der eigene
   Aussenabstand des Abschnitts würde ihn ein zweites Mal setzen. */
.abo-gruppen > .abo-gruppe { min-width: 0; }

/* ---------- 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 {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
  background: var(--flaeche); color: var(--text); border: 1px solid var(--rahmen);
  border-left: 3px solid var(--akzent);
  padding: .6em 1em; border-radius: var(--radius); max-width: 90vw; z-index: 60;
  box-shadow: 0 6px 24px color-mix(in srgb, var(--hintergrund) 70%, transparent);
  pointer-events: 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: 70; 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: 1px solid var(--rahmen);
  border-radius: calc(var(--radius) * 1.4); padding: var(--luft); }
.dialog h3 { margin: 0 0 .4em; font-size: 1.05em; }
.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 os4.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 os4.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: 1px 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 gibt es nur, wo die Schiene auch steht. Hier liegt sie und der Knopf
     wäre ohne Wirkung — ein toter Knopf ist schlimmer als keiner. Dasselbe tut die
     heutige Oberfläche (/work/ui/style.css → `.side-min-btn { display: none }`).
     ⚠️ `.schiene ` MUSS DAVOR STEHEN. `.schiene-klapp` allein wiegt 0-1-0 und verliert
     gegen `.schiene button { display: flex }` (0-1-1) weiter oben — der Knopf blieb
     dadurch bis zum 09.08.2026 auch auf 390 px stehen und stand als sechstes Element
     in einer liegenden Leiste, in der schon sechs Knöpfe knapp sind. Gemessen mit der
     Kaskaden-Attrappe, nicht vermutet: `display` löste sich auf `flex` auf.
     Eine Medienabfrage ändert an der Gewichtung NICHTS — sie entscheidet nur, ob eine
     Regel überhaupt mitzählt. */
  .schiene .schiene-klapp { display: none; }

  /* 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[aria-current="page"]::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; }
  .denken-schalter { min-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
     os4.js als --schiene-hoehe hinterlegt, statt geraten zu werden. Der Rückfall
     56px gilt nur, solange noch nichts gemessen wurde. */
  .toast { bottom: calc(var(--schiene-hoehe, 56px) + 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 os4 von os3 uebernommen hatte (`ui-os4/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(270px, 1fr)); gap: 8px; }

/* 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: 1px solid var(--rahmen); border-radius: var(--radius);
  padding: calc(var(--luft) * .75);
}
@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; }
.start-kachel-text { min-width: 0; }
.start-kachel-text b {
  display: block; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.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; }


/* ===========================================================================
   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.
   =========================================================================== */
.kopf .zeile-box { display: flex !important; }
@media (max-width: 640px) {
  .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-os4/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, #0a0909);
  /* 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, #e0715a) 20%, transparent) 0%,
      color-mix(in srgb, var(--akzent, #e0715a) 9%, transparent) 42%,
      transparent 78%),
    radial-gradient(48% 48% at 66% 68%,
      color-mix(in srgb, var(--akzent, #e0715a) 11%, transparent) 0%,
      color-mix(in srgb, var(--akzent, #e0715a) 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, #e0715a); 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, #e0715a) 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, #e0715a) 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-size: 26px; font-weight: 700; letter-spacing: .5px; color: var(--text, #f3efec); }
.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, #272524); }
.sb-linie b { display: block; width: 38%; height: 100%; border-radius: 2px; background: var(--akzent, #e0715a); 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; }


/* ===========================================================================
   A6 — DIE OBERFLAECHE AUF DIE ANIMATIONEN ABGESTIMMT (13.08.2026)
   ===========================================================================
   Owner: „ueberlege dir was passt zu den Oeffnen- und Reload-Screens, es muss
   stimmig sein". Die beiden freigegebenen Videos setzen damit den Massstab, und
   der besteht nicht aus Farben allein — die stimmten schon (--hintergrund
   #0a0909, --akzent #e0715a). Was fehlte, zeigen die Abzuege vom 13.08.:

     · Im Video ist jede Kante ein LICHT. In der Oberflaeche war jede Kante eine
       LINIE (1px --rahmen, sonst nichts). Flaechen ohne Kantenlicht wirken
       aufgeklebt, nicht aus Metall.
     · Im Video glueht der Kern. In der Oberflaeche glueht nichts — auch der
       Hauptknopf nicht, obwohl er die Akzentfarbe traegt.
     · Im Video bewegt sich alles schwer und ruhig. In der Oberflaeche gab es
       eine einzige Zeit (140ms) und keine gemeinsame Kurve.

   Deshalb hier drei Dinge, und bewusst nur drei: Kantenlicht, Gluehen am
   Akzent, und die gemeinsame Kurve. KEINE neuen Farben — die Palette ist
   freigegeben, und der Farbregler des Kontos (os4.js farbenAnwenden) muss
   weiter alles umfaerben koennen. Deshalb steht unten kein einziger fester
   Farbwert: jedes Licht ist aus --text oder --akzent gemischt.
   =========================================================================== */

/* ————— KANTENLICHT —————
   Ein Streifen Licht auf der Oberkante, ein Schatten darunter. Das ist der
   ganze Unterschied zwischen „Flaeche" und „Koerper". 7 % Text auf der Kante
   ist bewusst wenig: man soll es nicht sehen, man soll es merken. */
.karte, .ub-kachel, .anmeldekarte {
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--text) 7%, transparent),
    0 1px 2px color-mix(in srgb, var(--hintergrund) 70%, transparent),
    0 8px 24px -18px color-mix(in srgb, var(--hintergrund) 90%, transparent);
}

/* Was anklickbar ist, antwortet auch: die Kante nimmt die Akzentfarbe an und
   darunter liegt ein warmer Schein — nicht als Rahmen, sondern als Licht, das
   aus der Karte kommt. 120ms, weil der Finger es angestossen hat. */
.ub-kachel-tor, .ub-punkt-tor {
  transition: border-color var(--schnell) var(--kurve),
              box-shadow var(--schnell) var(--kurve),
              transform var(--schnell) var(--kurve);
}
@media (hover: hover) {
.ub-kachel-tor:hover, .ub-punkt-tor:hover {
  border-color: var(--akzent-rand);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--text) 10%, transparent),
    0 0 0 1px color-mix(in srgb, var(--akzent) 22%, transparent),
    0 10px 30px -20px var(--akzent);
}
}

/* ————— DAS GLUEHEN AM AKZENT —————
   Im Video ist der Akzent immer eine Lichtquelle. Ein Knopf in Akzentfarbe ohne
   Schein ist ein Aufkleber. Der Schein sitzt UNTER dem Knopf (negativer Radius),
   damit er nicht als zweiter Rand gelesen wird. */
button.haupt {
  box-shadow: 0 6px 20px -12px var(--akzent),
              inset 0 1px 0 color-mix(in srgb, #fff 22%, transparent);
  transition: box-shadow var(--schnell) var(--kurve),
              transform var(--schnell) var(--kurve),
              filter var(--schnell) var(--kurve);
}
button.haupt:hover { box-shadow: 0 10px 28px -12px var(--akzent),
              inset 0 1px 0 color-mix(in srgb, #fff 28%, transparent); filter: brightness(1.04); }
button.haupt:active { transform: translateY(1px); }

/* ————— DAS ZEICHEN —————
   Im Abzug war es 22 px gross und damit ein oranger Punkt: die zwei Ringe und
   die sechs Knoten sind bei der Groesse nicht mehr zu unterscheiden. 27 px in
   der Schiene, 40 px auf der Anmeldekarte — dazu derselbe warme Schein, den es
   im Video auch wirft. */
.schiene-marke img { width: 27px; height: 27px; }
.schiene-marke img, .marke-zeichen img {
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--akzent) 35%, transparent));
}
.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;
}
