/* Die linke Leiste — Stil von Claude, Farben von janevim.
 *
 * WARUM SIE NEU IST
 * -----------------
 * Der janevim-Chat hat an dieser Stelle eine Schublade, die über die
 * Seite fährt: gut fürs Handy, aber am Schreibtisch verschenkt sie
 * die ganze linke Seite. Claude macht daraus eine feste Spalte mit
 * drei Bereichen, und genau die soll es werden.
 *
 * AUFBAU (Ricos Vorgabe)
 * ----------------------
 *   oben        Chat        — neuer Chat, Liste der Gespräche
 *   darunter    Projekt     — die Projekte
 *   unten       Einstellungen — fest am Boden, wandert nicht mit
 *
 * Der mittlere Bereich ist der einzige, der wächst und scrollt. Kopf
 * und Fuß bleiben stehen, damit "Neuer Chat" und die Einstellungen
 * immer an derselben Stelle sind — bei einer Liste, die über Wochen
 * wächst, ist das der Unterschied zwischen Griffbereit und Suchen.
 *
 * WAS HIER NICHT PASSIERT
 * -----------------------
 * Kein Hex-Wert. Alle Farben kommen aus tokens.css. Und keine ID aus
 * chat.js wird umbenannt: #konv-liste, #btn-drawer-new,
 * #btn-drawer-close, #drawer-backdrop und #chat-drawer heißen weiter
 * so, sonst greift die kopierte Datei ins Leere.
 */

/* ── Der Rahmen: Leiste links, Chat rechts ─────────────────── */

#chat-screen {
  display: none;              /* chat.js schaltet auf flex */
  flex-direction: row !important;
  height: 100dvh;
  overflow: hidden;
}

#chat-rechts {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  /* Anker fuer die Datei-Tafel (D-488): sie liegt UEBER dem Chat,
   * nicht daneben. Ohne diese Zeile suchte sie sich den naechsten
   * positionierten Vorfahren und landete am Fenster. */
  position: relative;
}

/* ── Die Leiste selbst ─────────────────────────────────────── */

#chat-drawer {
  position: static;
  transform: none;
  width: var(--leiste-breite);
  max-width: var(--leiste-breite);
  flex-shrink: 0;
  height: 100dvh;
  background: var(--bg-secondary);
  border-right: 1px solid var(--border);
  box-shadow: none;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* ── Kopf: Marke ───────────────────────────────────────────── */

.leiste-kopf {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 14px 14px 10px;
  flex-shrink: 0;
}
.leiste-logo { width: 24px; height: 24px; color: var(--teal); flex-shrink: 0; }
.leiste-marke {
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  color: var(--teal-dark);
}

/* ── Zeilen: eine Form für alles Anklickbare ───────────────── */

/* ACHTUNG, zweite Stelle: die Chat-Einträge in der Liste darüber
 * tragen dieselben Maße, stehen aber in style.css bei .konv-titel
 * und .konv-item (D-482). Wer hier Größe, Farbe oder Polster
 * ändert, ändert sie dort mit — sonst stehen Chats und Projekte
 * wieder verschieden untereinander, und genau das war der Anlass. */
.leiste-zeile {
  display: flex;
  align-items: center;
  gap: 10px;
  width: calc(100% - 16px);
  margin: 1px 8px;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  color: var(--text-secondary);
  text-align: left;
  transition: var(--transition);
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
}
.leiste-zeile:hover { background: var(--bg-hover); color: var(--text); }
.leiste-zeile svg { width: 16px; height: 16px; flex-shrink: 0; opacity: 0.75; }
.leiste-zeile .beschriftung {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.leiste-zeile[aria-current="true"] {
  background: var(--teal-dim);
  color: var(--teal-darker);
  font-weight: 600;
}
.leiste-zeile[aria-current="true"] svg { opacity: 1; }

/* ── Abschnitts-Überschriften ──────────────────────────────── */

.leiste-abschnitt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px 4px;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  user-select: none;
}
/* Das Plus je Abschnitt — "Neuer Chat" und "Neues Projekt" sitzen
 * damit an derselben Stelle in derselben Form. Zwei Bedienelemente,
 * die dasselbe tun, sollen auch gleich aussehen; ein herausgehobener
 * Knopf für das eine und ein Plus für das andere wäre nur eine
 * Sonderregel, die man sich merken muss. */
.leiste-abschnitt button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 4px;
  color: var(--text-muted);
  line-height: 1;
  font-size: 1.05rem;
  transition: var(--transition);
  background: none; border: none; cursor: pointer;
}
.leiste-abschnitt button:hover {
  background: var(--bg-hover);
  color: var(--teal-darker);
}

/* ── Mitte: der einzige Teil, der scrollt ──────────────────── */

.leiste-mitte {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
  padding-bottom: 8px;
}

/* Ein leerer Bereich sagt, dass er leer ist — sonst sieht ein
 * kaputter Ladevorgang genauso aus wie "noch nichts da". */
.leiste-leer {
  padding: 6px 18px 10px;
  font-size: 0.78rem;
  color: var(--text-muted);
  line-height: 1.5;
}

/* Die Gesprächsliste, die chat.js füllt. Die Klassen darin
 * (.konv-item, .konv-titel …) kommen aus style.css und bleiben. */
/* Die Liste zeigt hoechstens FUENF Chats, danach wird gescrollt
 * (D-487). Sonst schiebt ein vielbenutzter Tag die Projekte und die
 * Einstellungen aus dem Bild.
 *
 * Die Zeilenhoehe wird NICHT geraten: leiste.js misst die erste Zeile
 * und schreibt sie in --konv-zeile. Der Wert hier ist nur der
 * Rueckfall fuer den Augenblick vor der ersten Messung — waere er die
 * Wahrheit, zeigte die Liste nach der naechsten Schriftaenderung
 * still 4,8 Zeilen. */
#konv-liste {
  --konv-zeile: 44px;
  --konv-sichtbar: 5;
  padding: 0;
  max-height: calc(var(--konv-zeile) * var(--konv-sichtbar));
  overflow-y: auto;
  /* Nicht wachsen: die Hoehe folgt dem Inhalt bis zur Grenze.
   * style.css setzt hier "flex: 1" fuer die alte Schublade. */
  flex: 0 1 auto;
}

/* ── Fuß: Einstellungen, fest am Boden ─────────────────────── */

.leiste-fuss {
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  padding: 6px 0 8px;
  background: var(--bg-secondary);
}

.leiste-konto {
  display: flex;
  align-items: center;
  gap: 9px;
  width: calc(100% - 16px);
  margin: 4px 8px 0;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  transition: var(--transition);
  background: none; border: none; cursor: pointer;
  font-family: inherit;
  text-align: left;
}
.leiste-konto:hover { background: var(--bg-hover); }
.konto-kreis {
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--teal-light);
  color: var(--teal-darker);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.72rem; font-weight: 600;
  flex-shrink: 0;
}
.konto-name {
  font-size: 0.82rem; color: var(--text); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.konto-zusatz { font-size: 0.72rem; color: var(--text-muted); }

/* ── Sprache in der Eingabezeile ───────────────────────────── */
/*
 * Mikrofon und Lautsprecher sassen bis zum 27.08. oben rechts in der
 * Kopfzeile. Rico braucht sie zum Chatten im Auto — dort ist der
 * Daumen unten am Bildschirm, nicht oben. Muster aus claude.ai: ein
 * Knopf fuer die haeufige Handlung, ein schmaler Pfeil daneben fuer
 * alles Weitere.
 */

.sprach-gruppe {
  position: relative;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

/* Der Pfeil ist absichtlich schmal und blass: er ist die seltene
 * Handlung neben der haeufigen. */
.sprach-pfeil {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 32px;
  margin-left: -4px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  transition: var(--transition);
  background: none; border: none; cursor: pointer;
}
.sprach-pfeil:hover { background: var(--bg-hover); color: var(--text); }
.sprach-pfeil[aria-expanded="true"] {
  background: var(--bg-hover);
  color: var(--teal-darker);
}

.sprach-menue {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  z-index: 50;
  min-width: 196px;
  padding: 5px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}
.sprach-menue[hidden] { display: none; }

.sprach-eintrag {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  color: var(--text);
  text-align: left;
  transition: var(--transition);
  background: none; border: none; cursor: pointer;
  font-family: inherit;
}
.sprach-eintrag:hover { background: var(--bg-hover); }
.sprach-eintrag svg { flex-shrink: 0; opacity: 0.75; }
.sprach-eintrag .beschriftung { flex: 1; }

/* Der Haken zeigt an, ob vorgelesen wird. Er ist immer da und nimmt
 * immer denselben Platz ein — sonst ruckt die Zeile beim Umschalten. */
.sprach-eintrag .haken {
  color: var(--teal-dark);
  visibility: hidden;
  font-size: 0.9rem;
}
.sprach-eintrag[aria-checked="true"] .haken { visibility: visible; }
.sprach-eintrag[aria-checked="true"] svg { opacity: 1; color: var(--teal-dark); }

/* Ein Trenner ist vorgesehen, aber noch ungenutzt: das Menue hat
 * heute genau einen Eintrag. Kommt ein zweiter dazu, ist die Regel
 * schon da. */
.sprach-trenner {
  height: 1px;
  margin: 5px 8px;
  background: var(--border);
}

/* Aufnahme laeuft: das muss man sehen, ohne hinzusehen. */
#btn-voice.recording {
  background: var(--danger);
  color: var(--bg);
  animation: aufnahme-puls 1.4s ease-in-out infinite;
}
@keyframes aufnahme-puls {
  0%, 100% { box-shadow: 0 0 0 0 var(--danger-dim); }
  50%      { box-shadow: 0 0 0 6px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  #btn-voice.recording { animation: none; }
}

/* ── Tastatur-Bedienung sichtbar lassen ────────────────────── */

.leiste-zeile:focus-visible,
.leiste-konto:focus-visible,
.leiste-abschnitt button:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: -2px;
}

/* ── Schmale Fenster: zurück zur Schublade ─────────────────── */

@media (max-width: 900px) {
  #chat-drawer {
    position: fixed;
    top: 0; left: 0;
    z-index: 40;
    width: 82%;
    max-width: 320px;
    transform: translateX(-100%);
    box-shadow: var(--shadow-md);
    transition: transform 0.2s ease;
  }
  #chat-drawer.open { transform: translateX(0); }
}

/* Am Schreibtisch braucht die Leiste keinen Abdunkler dahinter — sie
 * verdeckt nichts, sie steht daneben. */
@media (min-width: 901px) {
  #drawer-backdrop { display: none !important; }
  .nur-schublade { display: none; }
}

/* ── Ein- und Ausklappen ───────────────────────────────────── */

/* Am Schreibtisch verschwindet die Leiste nicht hinter dem Rand,
 * sondern schrumpft auf Null und gibt ihren Platz frei — sonst
 * bliebe eine leere Spalte stehen und das Einklappen haette keinen
 * Zweck. */
@media (min-width: 901px) {
  #chat-drawer {
    transition: width 0.18s ease, opacity 0.12s ease;
  }
  body.leiste-zu #chat-drawer {
    width: 0;
    max-width: 0;
    opacity: 0;
    border-right: none;
    overflow: hidden;
    pointer-events: none;
  }
}

/* Der Knopf zum Zuklappen sitzt im Leisten-Kopf, der zum Aufklappen
 * in der Kopfzeile daneben. Immer nur einer von beiden ist zu sehen:
 * zwei Knoepfe fuer dieselbe Sache an zwei Stellen sind eine Sache
 * mehr, die man suchen muss. */
#btn-leiste-zu { margin-left: auto; }

@media (min-width: 901px) {
  #btn-menu { display: inline-flex; }
  body:not(.leiste-zu) #btn-menu { display: none; }
}
@media (max-width: 900px) {
  /* Auf dem Handy uebernimmt die Schublade — der Zuklapp-Knopf
   * waere dort das Kreuz, das es schon gibt. */
  #btn-leiste-zu { display: none; }
  body.leiste-zu #chat-drawer { width: 82%; max-width: 320px; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  #chat-drawer { transition: none; }
}

@media (prefers-reduced-motion: reduce) {
  #chat-drawer { transition: none; }
}

/* Video in der Ansicht (D-534).
 *
 * Volle Breite, Seitenverhaeltnis 16:9 — sonst steht der Abspieler
 * entweder gequetscht oder mit schwarzen Balken da. Der Rahmen bekommt
 * keine eigene Umrandung: der Abspieler bringt seine eigene mit. */
.vorschau-video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: 8px;
  background: var(--video-bett);
}

/* Die Video-Bühne (D-673).
 *
 * Ein Platz, der nie geräumt wird. Vorher wohnte der Abspieler in der
 * Datei-Vorschau, und die wird bei jeder Aktualisierung geleert — jede
 * neue Antwort mit Videos hat die laufende Musik abgewürgt.
 *
 * WARUM DREI KLASSEN UND KEIN UMHÄNGEN: ein <iframe>, das im DOM an
 * eine andere Stelle wandert, lädt neu. Die Bühne bleibt deshalb, wo
 * sie ist; nur die Klasse wechselt.
 *
 * Kein Hex-Wert (D-456), alles aus tokens.css. */
#video-buehne {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
#video-buehne[hidden] { display: none; }

/* GROSS — eine eigene Spalte rechts.
 *
 * D-685: EIGENE Breite, nicht die der Datei-Tafel. Vorher stand hier
 * `body.buehne-breit { --tafel-breite: 560px }` — die Bühne verstellte
 * damit die Breite der Tafel. Rico: „vielleicht solltest du es trennen
 * voneinander … im Programm zwei eigene Themen." Genau so: zwei
 * Bereiche, zwei Zahlen, keine gemeinsame Schraube. */
body { --buehne-breite: 560px; }

/* Der Chat macht Platz — für die Bühne, für die Tafel, für beide. */
body.buehne-breit #messages,
body.buehne-breit #input-area {
  padding-right: calc(var(--buehne-breite) + 16px);
}
body.buehne-breit.dateien-offen #messages,
body.buehne-breit.dateien-offen #input-area {
  padding-right: calc(var(--buehne-breite) + var(--tafel-breite) + 16px);
}

#video-buehne.buehne-gross {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: var(--buehne-breite);
  max-width: 92vw;
  z-index: 70;
  border-radius: 0;
  border-top: 0;
  border-right: 0;
  border-bottom: 0;
}

/* Ist die Datei-Tafel offen, rückt die Bühne daneben statt darüber.
 * Eine CSS-Regel statt zweier Funktionen, die sich gegenseitig
 * zurechtschieben (D-685) — die eine kennt die andere nicht, sie
 * gehen sich nur aus dem Weg. */
body.dateien-offen #video-buehne.buehne-gross {
  right: var(--tafel-breite);
}

/* KLEIN — schwebt über dem Chat, das „Bild im Bild". Über der
 * Eingabezeile, damit es das Tippen nicht verdeckt. */
/* z-index 90: ueber allem, was die Seite sonst hat — Tafel (20),
 * Schublade, Eingabezeile. Rico: „es sollte immer vorn sein."
 * Zusammen mit dem Platz am <body> (D-674) liegt es damit in keinem
 * fremden Stapel-Zusammenhang mehr. */
#video-buehne.buehne-klein {
  position: fixed;
  right: 18px;
  /* D-704: OBEN rechts, nicht unten. Rico, 01.09., vom Handy: „es ist
   * praktischer, wenn es oben rechts waere."
   *
   * Unten sass es genau dort, wo man liest und tippt: auf einem
   * Telefon verdeckte das Fenster die letzten Antworten und reichte
   * fast bis ans Eingabefeld. Oben verdeckt es aelteren Text, den man
   * ohnehin weggescrollt hat.
   *
   * Der Abstand rechnet mit der Kopfzeile statt sie zu raten —
   * dieselbe Marke und derselbe Rueckfallwert wie in style.css. */
  top: calc(var(--kopf-hoehe, 63px) + 12px);
  width: min(340px, 80vw);
  z-index: 90;
  border-radius: var(--radius);
}

/* NUR TON — unsichtbar, läuft weiter.
 *
 * ACHTUNG: NICHT display:none und NICHT visibility:hidden. Beides
 * hält den Abspieler an, und genau das soll hier nicht passieren.
 * Ein Punkt in der Ecke mit opacity 0 bleibt für den Browser ein
 * laufendes Bild. */
#video-buehne.buehne-ton {
  position: fixed;
  right: 0;
  bottom: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
  border: 0;
  box-shadow: none;
  /* D-675: bewusst DERSELBE z-index wie in den anderen Zuständen.
   * Hier stand 0 — mit dem Wert war die Bauart nicht mehr die, die am
   * 01.09. gegen fünf Alternativen gemessen wurde und als einzige
   * Firefox' Bild-in-Bild überlebt hat. Ein unsichtbarer Punkt kostet
   * nichts, egal in welcher Lage er liegt; die Abweichung war ein
   * unnötiges Risiko. */
  z-index: 90;
}

.buehne-kopf {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 5px 6px 5px 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.buehne-name {
  flex: 1;
  min-width: 0;
  font-size: 0.78rem;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.buehne-video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  background: var(--video-bett);
}
.buehne-mitte { flex-shrink: 0; }

/* D-678: die Trefferliste unter dem Video. Der Platz war ohnehin leer
 * — das Video ist 16:9, die Bühne so hoch wie die Tafel. Ein Klick
 * wechselt zum nächsten Stück. */
.buehne-liste {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 6px;
  border-top: 1px solid var(--border);
}
/* Im kleinen Fenster und beim Ausblenden ist kein Platz dafür. */
#video-buehne.buehne-klein .buehne-liste,
#video-buehne.buehne-ton .buehne-liste { display: none; }

/* Was gerade läuft, ist zu erkennen. */
.video-karte.laeuft {
  background: var(--teal-dim);
}
.video-karte.laeuft .video-titel {
  color: var(--teal-darker);
  font-weight: 600;
}

/* Der Video-Zettel oben — gebaut wie der für Dateien. */
#btn-videos { position: relative; }
#btn-videos.nur-ton { color: var(--teal); }

/* Die Videoliste in der Tafel (D-669).
 *
 * Gebaut wie die Dateiliste daneben — kein Kasten, nur eine Zeile, die
 * sich beim Ueberfahren zeigt. Der Unterschied ist das Vorschaubild
 * links: bei Musik ist es das, woran man den Titel wiedererkennt.
 *
 * Kein Hex-Wert hier drin (D-456), alles aus tokens.css. */
.video-karte {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  padding: 8px;
  border-radius: var(--radius-sm);
  text-align: left;
  text-decoration: none;
  color: inherit;
  transition: var(--transition);
}
.video-karte:hover { background: var(--bg-hover); }

.video-bild {
  flex-shrink: 0;
  width: 96px;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--video-bett);
}
.video-bild img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Sammel-Listen haben kein eigenes Vorschaubild — statt einer leeren
 * schwarzen Flaeche steht dort ein Abspiel-Zeichen. */
.video-bild.ohne-bild {
  display: grid;
  place-items: center;
  background: var(--bg-tertiary);
  border: 1px solid var(--border);
}
.video-bild.ohne-bild::after {
  content: "";
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 7px 0 7px 12px;
  border-color: transparent transparent transparent var(--text-muted);
}

.video-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.video-titel {
  font-size: 0.82rem;
  line-height: 1.35;
  color: var(--text);
  /* Lange Titel laufen nicht aus der Tafel heraus. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.video-marke {
  align-self: flex-start;
  font-size: 0.68rem;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--neutral-flaeche);
  border: 1px solid var(--neutral-rahmen);
  color: var(--text-muted);
}

/* ── Kleines Fenster (Bild-in-Bild) ──────────────────────────────────
   Die Android-Huelle setzt beim Schrumpfen body.kompakt. Dann zaehlt
   nur noch das Video: der Abspieler legt sich randlos ueber das ganze
   Fenster, alles andere liegt darunter (Rico, 05.09.: im kleinen
   Fenster standen Kopfzeile und Textfetzen statt des Videos). Die
   [hidden]-Ausnahme haelt auch den Nur-Ton-Fall am Bild: dort ist die
   Buehne versteckt, das Video laeuft aber weiter. */
body.kompakt #video-buehne,
body.kompakt #video-buehne[hidden] {
  display: block !important;
  position: fixed !important;
  inset: 0 !important;
  z-index: 99998;
}
body.kompakt #video-buehne > :not(.buehne-mitte) { display: none !important; }
body.kompakt .buehne-mitte,
body.kompakt .buehne-video {
  position: fixed !important;
  inset: 0 !important;
  width: 100vw !important;
  height: 100vh !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  z-index: 99999;
}
body.kompakt { overflow: hidden !important; }
