/* Dunkles Theme, mobile zuerst. Die Kommentare markieren die Stellen, die
   ausschliesslich wegen iOS Safari oder Android Chrome so aussehen. */

:root {
  --hg:        #14161a;
  --hg-erhoben:#1d2027;
  --hg-karte:  #23272f;
  --rand:      #2a2e37;
  --text:      #e6e8ec;
  --text-leise:#8a90a0;
  --akzent:    #7dd3fc;
  --akzent-hg: #2b4a63;
  --eigen:     #2b4a63;
  --fehler:    #f08a8a;
  --radius:    14px;
}

* { box-sizing: border-box; }

/* MUSS vor allen Regeln mit display stehen — und braucht !important.
   [hidden] { display: none } kommt nur aus dem Standard-Stylesheet des
   Browsers; jede eigene display-Regel schlaegt es, weil die Kaskade die
   Herkunft hoeher wertet als die Spezifitaet. Ohne diese Zeile bleibt der
   Anmeldebildschirm nach dem Login stehen. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--hg);
  color: var(--text);
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* Verhindert, dass iOS beim Drehen die Schrift eigenmaechtig vergroessert */
  -webkit-text-size-adjust: 100%;
}

/* 100dvh statt 100vh: In iOS Safari ist 100vh groesser als der sichtbare
   Bereich, weil die Adressleiste nicht mitgerechnet wird. Mit 100vh
   verschwindet das Eingabefeld unter der Leiste. svh/dvh loesen das. */
body { height: 100dvh; overflow: hidden; }
@supports not (height: 100dvh) { body { height: 100vh; } }

button, input { font: inherit; color: inherit; }

/* --- Anmeldung ------------------------------------------------------- */

.anmeldung {
  height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.anmeldekarte {
  width: 100%; max-width: 340px;
  background: var(--hg-karte);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  padding: 24px 20px;
  display: flex; flex-direction: column; gap: 6px;
}
.anmeldekarte h1 { margin: 0 0 14px; font-size: 20px; }
.anmeldekarte label { font-size: 13px; color: var(--text-leise); margin-top: 8px; }

/* WICHTIG: mindestens 16px. Bei kleinerer Schrift zoomt iOS Safari beim
   Antippen eines Eingabefelds automatisch in die Seite hinein — und zoomt
   danach nicht wieder heraus. */
.anmeldekarte input, .eingabe input {
  font-size: 16px;
  background: var(--hg);
  border: 1px solid var(--rand);
  border-radius: 10px;
  padding: 11px 12px;
  width: 100%;
}
.anmeldekarte input:focus, .eingabe input:focus {
  outline: 2px solid var(--akzent); outline-offset: 1px;
}
.anmeldekarte button {
  margin-top: 18px;
  background: var(--akzent-hg); color: var(--akzent);
  border: 1px solid var(--akzent);
  border-radius: 10px; padding: 12px;
  font-weight: 600; cursor: pointer;
}
.anmeldekarte button:disabled { opacity: .6; cursor: default; }
.fehler { color: var(--fehler); font-size: 13.5px; margin: 12px 0 0; }

/* --- Anwendung ------------------------------------------------------- */

.anwendung { height: 100%; display: flex; flex-direction: column; }

.kopf {
  display: flex; align-items: center; gap: 10px;
  background: var(--hg-erhoben);
  border-bottom: 1px solid var(--rand);
  padding: 10px 12px;
  /* Unter dem Notch bzw. der Statusleiste nicht verschwinden */
  padding-top: calc(10px + env(safe-area-inset-top));
}
.kopftitel { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.kopftitel strong { font-size: 15px; }
.gedaempft { color: var(--text-leise); font-size: 12px;
             white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 44px ist die kleinste Flaeche, die sich auf einem Touchscreen zuverlaessig
   treffen laesst — Apples eigene Empfehlung. */
.symbolknopf {
  min-width: 44px; height: 44px;
  background: none; border: none; font-size: 20px;
  cursor: pointer; border-radius: 10px;
}
.symbolknopf:disabled { opacity: .35; cursor: default; }

.seitenleiste {
  position: fixed; z-index: 3; top: 0; bottom: 0; left: 0;
  /* Geschlossen ausgefahren statt versteckt: so laesst sie sich animieren,
     und auf dem Desktop hebt die Media-Query das einfach auf. */
  transform: translateX(-100%);
  transition: transform .18s ease-out;
  width: 78%; max-width: 300px;
  background: var(--hg-erhoben);
  border-right: 1px solid var(--rand);
  padding: calc(16px + env(safe-area-inset-top)) 14px 16px;
  display: flex; flex-direction: column;
}
.seitenleiste h2 { font-size: 13px; color: var(--text-leise);
                   text-transform: uppercase; letter-spacing: .05em; margin: 0 0 10px; }
.seitenleiste ul { list-style: none; margin: 0; padding: 0; flex: 1; }
.seitenleiste li {
  padding: 11px 10px; border-radius: 10px;
  display: flex; align-items: center; gap: 8px; cursor: pointer;
}
/* Kanalnamen duerfen Leerzeichen und Emoji enthalten — ein langer Name soll
   die Leiste trotzdem nicht auseinanderziehen. */
.seitenleiste li span:first-child {
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.seitenleiste li[aria-current="true"] { background: var(--akzent-hg); color: var(--akzent); }
.zaehler {
  margin-left: auto; background: var(--akzent); color: #0e1013;
  border-radius: 999px; padding: 1px 8px; font-size: 12px; font-weight: 700;
}
.installhinweis {
  font-size: 12px; line-height: 1.45; color: var(--text-leise);
  background: var(--hg-karte); border: 1px solid var(--rand);
  border-radius: 10px; padding: 9px 10px; margin: 12px 0 0;
}
.installhinweis strong { color: var(--text); font-weight: 600; }

/* Klein und gedaempft an unauffaelliger Stelle (§ 12) */
.version { font-size: 11px; color: var(--text-leise); margin: 14px 0 0;
           user-select: all; -webkit-user-select: all; }

.anwendung.menue-offen .seitenleiste { transform: none; }

.abdunkeln { position: fixed; z-index: 2; inset: 0; background: #0009; }

@media (prefers-reduced-motion: reduce) {
  .seitenleiste { transition: none; }
}

.verlauf {
  flex: 1; overflow-y: auto;
  /* Traegheitsscrollen auf iOS */
  -webkit-overflow-scrolling: touch;
  padding: 14px 12px; display: flex; flex-direction: column; gap: 8px;
}

.nachricht { max-width: 82%; background: var(--hg-karte);
             border-radius: var(--radius); padding: 8px 11px; }
.nachricht.eigen { align-self: flex-end; background: var(--eigen); }
.nachricht .absender { font-size: 12px; color: var(--akzent); font-weight: 600; }
.nachricht .zeit { font-size: 11px; color: var(--text-leise); margin-left: 6px; }
/* Eine lange URL ohne Leerzeichen sprengt sonst das Layout */
.nachricht .rumpf { overflow-wrap: anywhere; }
.nachricht a { color: var(--akzent); }

.nachricht.system {
  align-self: center; max-width: 90%; background: none;
  color: var(--text-leise); font-size: 12.5px; text-align: center; padding: 2px;
}

.eingabe {
  display: flex; gap: 8px; padding: 10px 12px;
  background: var(--hg-erhoben); border-top: 1px solid var(--rand);
  /* Home-Indicator-Bereich auf dem iPhone freihalten */
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
}
.eingabe button {
  min-width: 48px; border-radius: 10px;
  background: var(--akzent-hg); color: var(--akzent);
  border: 1px solid var(--akzent); cursor: pointer; font-size: 18px;
}

.verbindungshinweis {
  background: #4a3a1c; color: #e6cfae;
  text-align: center; font-size: 13px; padding: 7px;
}

/* --- Video-Raum ------------------------------------------------------ */

.videobereich {
  display: flex; flex-direction: column;
  background: #0b0d10; border-bottom: 1px solid var(--rand);
  /* Fester Anteil der Fensterhoehe, nicht die Hoehe des Inhalts: die Kacheln
     leiten ihre Groesse aus dem Bereich ab, der Bereich darf sie also nicht
     seinerseits aus den Kacheln ableiten — sonst faellt er auf ein paar
     Dutzend Pixel zusammen und jedes Bild wird zum Streifen.
     Der Chat bleibt darunter sichtbar: auf dem Handy ist das der einzige Weg,
     waehrend eines Gespraechs etwas mitzuschreiben. */
  flex: 0 0 46dvh; min-height: 0;
}
@supports not (height: 1dvh) { .videobereich { flex-basis: 46vh; } }
/* Teilt jemand seinen Bildschirm, braucht er die Flaeche */
.anwendung.teilt .videobereich { flex-basis: 62dvh; }

.kacheln {
  flex: 1; min-height: 0;
  display: grid; gap: 6px; padding: 6px;
  /* Spaltenzahl und Kachelmass rechnet layout.js aus und setzt sie hier als
     Inline-Stil. Diese Werte sind die Rueckfallebene, falls das Skript nicht
     laeuft — untereinander, das funktioniert in jeder Fensterform. */
  grid-auto-flow: row; grid-auto-rows: 1fr;
  justify-items: center; align-items: center;
  justify-content: center; align-content: center;
}

/* Sprecheransicht: einer gross, die uebrigen als Streifen darunter (§ 4.3) */
.kacheln.sprecher {
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 1fr 24%;
  grid-auto-rows: 24%;
}
.kacheln.sprecher .kachel { grid-row: 2; }
.kacheln.sprecher .kachel.gross { grid-row: 1; grid-column: 1 / -1; }

.vollbildknopf {
  position: absolute; top: 6px; right: 6px;
  min-width: 40px; min-height: 40px;
  display: none; align-items: center; justify-content: center;
  border: none; border-radius: 10px;
  background: #000000b0; color: var(--text); cursor: pointer;
}
.vollbildknopf svg {
  width: 20px; height: 20px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
/* Im Raster hat ihn jede Kachel: dort sind alle gleich wichtig, und ein Knopf,
   der mit dem lautesten Sprecher von Kachel zu Kachel springt, waere nicht zu
   treffen. In der Sprecheransicht nur auf der grossen und auf geteilten
   Bildschirmen — auf den Streifenkacheln waere er groesser als ihr Inhalt. */
.kacheln:not(.sprecher) .vollbildknopf,
.kacheln.sprecher .kachel.gross .vollbildknopf,
.kachel.schirm .vollbildknopf { display: inline-flex; }

/* Auf sehr kleinen Kacheln wuerde er das Bild verdecken */
.kachel.klein .vollbildknopf { display: none; }

/* Im Vollbild gilt das Seitenverhaeltnis der Kachel nicht mehr — sonst bliebe
   der groesste Teil des Bildschirms schwarz. */
.kachel:fullscreen {
  aspect-ratio: auto;
  width: 100%; height: 100%; max-width: none; max-height: none;
  border-radius: 0;
}
.kachel:fullscreen video { object-fit: contain; }
.kachel:fullscreen .vollbildknopf { display: inline-flex; }

/* Ein geteilter Bildschirm wird NIE beschnitten — bei Text waere genau die
   Zeile weg, auf die es ankommt. Schwarze Raender sind das kleinere Uebel. */
.kachel.schirm video { object-fit: contain; background: #000; }
.kachel.schirm .name { background: var(--akzent-hg); color: var(--akzent); }

/* Angetippte Kachel bleibt gross, bis das Gespraech endet (§ 4.3) */
.kachel.gepinnt { outline: 2px solid var(--akzent); outline-offset: -2px; }
.kachel.spricht { box-shadow: 0 0 0 2px var(--akzent) inset; }

/* Das feste Seitenverhaeltnis ist der Kern: ohne es folgt die Breite dem
   Fenster, waehrend die Hoehe gedeckelt bleibt — die Kachel wird zum Streifen
   und object-fit schneidet alles ausser dem Kinn weg. Mit aspect-ratio ergibt
   sich die eine Kantenlaenge aus der anderen; max-width und max-height sorgen
   dafuer, dass die jeweils knappere Richtung gewinnt. */
.kachel {
  aspect-ratio: 16 / 9;
  width: auto; height: 100%;
  max-width: 100%; max-height: 100%;
  position: relative; background: #000; border-radius: 10px;
  overflow: hidden; min-height: 0;
}
.kacheln video {
  width: 100%; height: 100%; display: block; background: #000;
  /* Ohne object-fit verzerrt ein Hochkant-Handybild die Kachel */
  object-fit: cover;
}
.kachel .name {
  position: absolute; left: 6px; bottom: 6px;
  font-size: 11px; background: #0009; padding: 2px 7px; border-radius: 6px;
}

/* wrap ist keine Kosmetik: ohne es laufen die Knoepfe auf einem schmalen
   Display seitlich aus dem Bild, ohne dass etwas darauf hinweist. */
.videoleiste {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 8px; justify-content: center;
  padding-bottom: calc(8px + env(safe-area-inset-bottom));
}

.videoknopf {
  /* 44px in beide Richtungen — die kleinste Flaeche, die sich auf einem
     Touchscreen zuverlaessig treffen laesst. */
  min-width: 44px; min-height: 44px; padding: 0 10px;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border-radius: 12px;
  background: var(--hg-karte); border: 1px solid var(--rand);
  color: var(--text); cursor: pointer; font-size: 14px;
}
.videoknopf svg {
  width: 22px; height: 22px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Der Querstrich erscheint nur im abgeschalteten Zustand */
.videoknopf .strich { display: none; }
.videoknopf[aria-pressed="true"] .strich { display: inline; }
.videoknopf[aria-pressed="true"] {
  background: #4a1f1f; border-color: #7a3030; color: #f3c3c3;
}
.videoknopf.verlassen { background: #4a1f1f; border-color: #7a3030; color: #f3c3c3; }
.videoknopf:disabled { opacity: .4; cursor: default; }

/* Auf dem Handy nur die Symbole. Die Beschriftung bleibt im Markup — ein
   Vorlesegeraet liest weiterhin das aria-label, und ab Tablet ist sie da. */
.videoknopf .beschriftung { display: none; }
@media (min-width: 600px) {
  .videoknopf .beschriftung { display: inline; }
}
.videohinweis { margin: 0; padding: 7px 10px; font-size: 12.5px;
                color: #e6cfae; background: #4a3a1c; }

/* Ab Tablet die Seitenleiste dauerhaft zeigen */
@media (min-width: 760px) {
  .anwendung { display: grid; grid-template-columns: 260px 1fr;
               grid-template-rows: auto 1fr auto; height: 100%; }
  /* Dauerhaft sichtbar — die Schublade gibt es hier nicht mehr */
  .seitenleiste { position: static; width: auto; max-width: none;
                  grid-row: 1 / 4; border-right: 1px solid var(--rand);
                  transform: none; }
  .kopf, .videobereich, .verlauf, .eingabe { grid-column: 2; }
  /* Nur bei laufendem Gespraech eine eigene Zeile — sonst bekaeme der
     Verlauf die falsche und das Eingabefeld saesse in der Mitte.
     minmax(0, …) ist noetig, weil eine Grid-Zeile sonst nie kleiner wird als
     ihr Inhalt und der Verlauf das Fenster nach unten schoebe. */
  /* Waehrend eines Gespraechs ist das Video die Hauptsache; der Verlauf
     behaelt genug Platz fuer die letzten Nachrichten. */
  .anwendung.video-offen {
    grid-template-rows: auto minmax(0, 1.7fr) minmax(0, 1fr) auto;
  }
  .anwendung.video-offen.teilt {
    grid-template-rows: auto minmax(0, 3.4fr) minmax(0, 1fr) auto;
  }
  /* Hier bestimmt die Grid-Zeile die Hoehe, nicht der Flex-Anteil von oben */
  .videobereich { flex: initial; height: 100%; }
  #menueknopf, .abdunkeln { display: none; }
}

/* Ab einem breiten Monitor steht der Chat waehrend eines Gespraechs NEBEN dem
   Video statt darunter. Uebereinander haengt die Kachelgroesse an der Hoehe:
   auf 3440x1440 blieben so zwei Drittel der Flaeche ungenutzt, waehrend die
   Gesichter klein blieben. Darunter (Laptop, Tablet) bleibt es gestapelt — dort
   waere eine dritte Spalte fuer beides zu schmal. */
@media (min-width: 1200px) {
  .anwendung.video-offen {
    grid-template-columns: 260px minmax(0, 1fr) minmax(320px, 24%);
    grid-template-rows: auto minmax(0, 1fr) auto;
  }
  .anwendung.video-offen .kopf { grid-column: 2 / 4; grid-row: 1; }
  .anwendung.video-offen .videobereich {
    grid-column: 2; grid-row: 2 / 4; height: 100%;
    border-bottom: none; border-right: 1px solid var(--rand);
  }
  .anwendung.video-offen .verlauf { grid-column: 3; grid-row: 2; }
  .anwendung.video-offen .eingabe { grid-column: 3; grid-row: 3; }
}

/* Handy quer waehrend eines Gespraechs: uebereinander bleiben vom Video keine
   100 px, weil die Hoehe schon vom Kopf, der Leiste und dem Eingabefeld
   aufgebraucht ist. Nebeneinander bekommt das Video die volle Hoehe. */
@media (orientation: landscape) and (max-height: 560px) {
  .anwendung.video-offen {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto;
  }
  .anwendung.video-offen .kopf { grid-column: 1 / 3; grid-row: 1; }
  .anwendung.video-offen .videobereich {
    grid-column: 1; grid-row: 2 / 4;
    flex: initial; height: 100%;
    border-bottom: none; border-right: 1px solid var(--rand);
  }
  .anwendung.video-offen .verlauf { grid-column: 2; grid-row: 2; }
  .anwendung.video-offen .eingabe { grid-column: 2; grid-row: 3; }

  /* Quer ist das Fenster breit, die Videospalte aber schmal — beschriftete
     Knoepfe braechen dort um und fraessen die knappe Hoehe. */
  .videoknopf .beschriftung { display: none; }
}
