/* ============================================
   messages.css — Bereich: messages
   ============================================ */
.message {
  /* --media-cap teilt max-width UND die inline gesetzte min-width der
       Medien-Bubble (min(Wpx, var(--media-cap)) im _message-Partial).
       --media-max-w deckelt die Anzeigebreite einzelner Bilder/Videos:
       große Uploads (z.B. 1024px) blasen die Bubble sonst auf. */
  --media-cap: 70%;
  --media-max-w: 480px;
  /* Absolutes Bubble-Maximum neben den 70%: Auf breiten Bildschirmen wäre
     70% eine riesige Bubble (langtextige Nachrichten laufen in EINER Zeile).
     min() cappt zusätzlich auf lesbare Zeilenlänge (~80 Zeichen). */
  max-width: min(var(--media-cap), 600px);
  padding: 12px 16px;
  border-radius: 16px;
  font-size: 15px;
  line-height: 1.4;
  position: relative;
  margin-bottom: 12px;
  width: fit-content;
}

.message.sent {
  align-self: flex-end;
  background: var(--primary);
  color: var(--inverse-text);
  border-bottom-right-radius: 4px;
}

.message.received {
  align-self: flex-start;
  background: var(--surface);
  color: var(--text);
  border-bottom-left-radius: 4px;
  border: 1px solid lightgrey;
}

[data-theme="dark"] .message.received {
  background: #253154;
  border: none;
}

/* Sender-Avatar in Gruppen-/Kanal-Chats */
.message-row {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  /* Volle Breite statt fit-content: die max-width:70% der .message braucht
     eine definite Prozent-Basis. In der shrink-to-fit Row resolved die
     Prozentangabe zirkulär (Row-Breite hängt von der Message ab, deren
     max-width von der Row) → Bubble kollabiert unter die Textbreite,
     Text wrapped, Höhe driftet (Scroller-Korrektur-Fehler). */
  width: 100%;
}

.message-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--inverse-text);
  flex-shrink: 0;
  align-self: flex-end;
}

.message-avatar__img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

.message-sender-name {
  font-size: 12px;
  font-weight: 600;
  margin-bottom: 2px;
  cursor: pointer;
}

.message-sender-name:hover {
  text-decoration: underline;
}

.message-avatar[role="button"] {
  cursor: pointer;
}

.chat-date-sticky {
  /* Sticky-Datums-Badge (Telegram-Stil): klebt am oberen Rand des
   Chat-Scrollers und zeigt den Tag der obersten sichtbaren Nachricht.
   Wird serverseitig in die Liste eingefügt (kein data-message-id,
   damit die Virtual-Scroll-Logik es ignoriert). */
  position: sticky;
  top: 0;
  z-index: 30;
  align-self: center;
  background: rgba(31, 42, 68, 0.82);
  /* Text IMMER Weiß: der Badge-Hintergrund ist bewusst themenunabhängig
     dunkles Navy — var(--text) wäre im Dark-Theme hell und der Text
     damit nicht lesbar. */
  color: #fff;
  border-radius: 14px;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin: 4px 0;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
  user-select: none;
  pointer-events: none;
}

.chat-date-sticky[hidden] {
  display: none;
}

.message-time {
  font-size: 11px;
  opacity: 0.7;
  margin-top: 4px;
}

.message-system {
  /* Zentrierte System-Meldung (Telegram-Stil), z.B. "Dada hat die Gruppe
   verlassen". Keine Bubble, keine Actions — dezente Pille mit Icon + Zeit.
   Höhe deckt sich mit VIRTUAL_SYSTEM_HEIGHT (30px) im virtuellen Scroller. */
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  padding: 3px 12px;
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.07);
  border: 1px solid rgba(0, 0, 0, 0.06);
  color: #8a8a8a;
  font-size: 12.5px;
  line-height: 1.4;
  max-width: 70%;
  word-break: break-word;
}

.message-system__icon {
  font-size: 10px;
  opacity: 0.55;
}

.message-system__time {
  font-size: 10px;
  opacity: 0.5;
  white-space: nowrap;
}

.message-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 2px;
}

.message-meta__pin {
  font-size: 10px;
  opacity: 0.8;
}

.message-meta .message-time {
  margin-top: 0;
}

.message-tick {
  font-size: 11px;
  opacity: 0.8;
}

.message-tick--read {
  opacity: 1;
  color: #53bdeb;
}

.message-tick--delivered {
  opacity: 1;
}

.message-reactions {
  /* Reactions (Telegram/WhatsApp-Stil) */
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}

.message-reactions:empty {
  display: none;
}

.message-reaction {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 24px;
  padding: 0 6px;
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.06);
  font-size: 14px;
  line-height: 1;
  user-select: none;
  border: 1px solid transparent;
}

.message.sent .message-reaction {
  background: rgba(255, 255, 255, 0.2);
}

.message-reaction--mine {
  background: rgba(83, 189, 235, 0.25) !important;
  border: 1px solid #53bdeb;
  cursor: pointer;
}

.message-reaction__avatar {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  font-size: 10px;
  line-height: 16px;
  text-align: center;
  color: var(--inverse-text);
  flex-shrink: 0;
  margin-right: 2px;
}

.message-reaction__avatar--placeholder {
  overflow: hidden;
}

.message-reaction-picker[hidden] {
  /* Reaction-Picker (Popup über der Nachricht) */
  display: none;
}

.message-reaction-picker {
  /* geändert von absolute */
  position: fixed;
  bottom: 100%;
  left: 0;
  padding: 4px;
  margin-bottom: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  z-index: 1100;
  margin: 0;
}

.message.sent .message-reaction-picker {
  /* Bei rechtsbündigen (sent) Nachrichten den Picker rechts ausrichten. */
  left: auto;
  right: 0;
}

.message-reaction-picker__quick {
  /* Quick-Palette (8 Emojis + "+") */
  display: flex;
  align-items: center;
  gap: 2px;
}

.message-reaction-picker__emoji {
  border: none;
  background: none;
  font-size: 18px;
  padding: 2px 4px;
  border-radius: 50%;
  cursor: pointer;
  line-height: 1;
}

.message-reaction-picker__emoji:hover {
  background: rgba(0, 0, 0, 0.08);
}

.message-reaction-picker__more {
  border: none;
  background: none;
  color: var(--text-muted);
  width: 26px;
  height: 26px;
  border-radius: 50%;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
}

.message-reaction-picker__more:hover {
  background: rgba(0, 0, 0, 0.08);
}

.message-reaction-picker__search[hidden] {
  /* Such-Panel ("+"-View) */
  display: none;
}

.message-reaction-picker__search {
  display: flex;
  flex-direction: column;
  width: 220px;
  max-height: 260px;
}

.message-reaction-picker__search-input {
  width: 100%;
  box-sizing: border-box;
  font-size: 13px;
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: 12px;
  margin-bottom: 4px;
}

.message-reaction-picker__search-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  overflow-y: auto;
  max-height: 210px;
  padding: 2px;
}

.message-reaction-picker__search-grid .message-reaction-picker__emoji {
  font-size: 20px;
  padding: 3px;
}

.message-reaction-picker__empty {
  color: var(--text-muted);
  font-size: 13px;
  padding: 8px;
  text-align: center;
}

.message-reaction-picker--drop-down {
  bottom: auto;
  top: 100%;
  margin-bottom: 0;
  margin-top: 6px;
}

.message-media {
  /* 100% statt fit-content: fit-content kollabiert in Firefox auf den
       Inhalt (ungeladenes Lazy-Bild trägt 0 bei) → die Medien-Box verschwindet
       und poppt beim Laden. Die Breite verankert die Bubble (min-width) — hier
       füllen wir sie; die eigentliche Medienbreite setzt die Item-Div inline. */
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
  width: 100%;
}

.message-media__frame {
  /* Medien-Box-Frame: Die Höhe wird inline als feste px gesetzt ("fit within"
   aus den Blob-Metadaten, nie hochskalieren). width kommt aus width:100%.
   Damit ist die Box genauso deterministisch wie height:260px im
   Safari-Standalone — beide Maße hängen nie vom Ladezustand oder vom Layout
   ab → kein Layout-Shift beim Laden, kein ResizeObserver-Jitter. Nötig,
   weil ein <video> ohne Metadaten keine intrinsische Größe hat. */
  position: relative;
  overflow: hidden;
  width: 100%;
  border-radius: 10px;
}

.message-media__frame video {
  /* Schwarzer Letterbox-Hintergrund NUR für Videos (Player-Standard);
     Bilder letterboxen stattdessen in der Bubble-Farbe — keine schwarzen
     Balken, wenn Frame- und Bild-Ratio minimal abweichen. */
  background: #000;
}

.message-media__frame img,
.message-media__frame video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.message-media__frame img {
  cursor: zoom-in;
}

.message-media__more {
  position: absolute;
  inset: 0;
  border: none;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.55);
  color: var(--inverse-text);
  font-size: 22px;
  font-weight: 700;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
}

.message-media__more:hover {
  background: rgba(0, 0, 0, 0.65);
}

.message-media audio {
  max-width: 100%;
}

.message:has(.message-media img),
.message:has(.message-media video) {
  /* Bubble mit Bild/Video: feste Breite statt shrink-to-fit. Sonst hängt die
   Bubble-Breite vom Bildinhalt ab (fit-content) und width:100% des Mediums
   kollabiert auf die intrinsische Breite — beim ungeladenen lazy-Bild ist
   die 0, die reservierte Box verschwindet und das Bild poppt beim Laden auf. */
  width: fit-content;
}

.message-file {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  color: var(--text);
  text-decoration: none;
  max-width: 260px;
}

.message-file i {
  font-size: 22px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.message-file__name {
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.message-file__size {
  font-size: 12px;
  color: var(--text-muted);
}

.message-media__item {
  /* Die Breite wird inline als feste px gesetzt ("fit within", ≤480px):
       Der max-content der Bubble hängt dann NICHT vom Medien-Ladezustand ab.
       Ein prozentuales width:100% des Items wäre zirkulär — die Bubble
       würde beim Laden wachsen (Höhen-Sprung). max-width:100% deckelt die
       Anzeigebreite auf die Bubble-Content-Breite in schmalen Fenstern
       (die Frame-Höhe bleibt dabei konstant, das Medium letterboxt).
       min-width:0 lässt Flex-Items unter die Content-Breite schrumpfen. */
  position: relative;
  min-width: 0;
  width: 100%;
}

/* Nur Sprachnachrichten-Stacks kompakt stapeln (enge Gaps); Bilder/Videos
   behalten den normalen Gap. */
.message-media:has(.voice-message) {
  gap: 2px;
}

/* Mehrere Sprachnachrichten in einer Nachricht: Bubble-Breite auf kompakte
   Player-Breite deckeln. Nötig, weil die Items width:100% tragen — die
   max-content-Messung des flex-wrap-Containers legt sie in EINE Zeile
   (Summe aller Items) und bläst die fit-content-Bubble damit auf volle
   verfügbare Breite auf. Einzelne Sprachnachrichten bleiben unverändert. */
.message-media:has(.message-media__item + .message-media__item .voice-message) {
  max-width: 270px;
}

.message-media__remove {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  color: var(--inverse-text);
  display: none;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 12px;
  z-index: 3;
}

.message:hover .message-media__remove {
  display: flex;
}

.message-media__remove:hover {
  background: rgba(0, 0, 0, 0.85);
}

.message--text-empty {
  position: relative;
  border: 1px dashed transparent;
  transition: border-color 0.15s ease;
  cursor: text;
}

.message--text-empty:hover {
  border-color: var(--primary);
}

.message-text-empty__hint {
  display: none;
  position: absolute;
  top: -11px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--primary);
  color: var(--inverse-text);
  font-size: 12px;
  padding: 4px 12px;
  border-radius: 12px;
  white-space: nowrap;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
  z-index: 5;
  cursor: pointer;
}

.message--text-empty:hover .message-text-empty__hint {
  display: block;
}

.message.is-editing .message-text-empty__hint {
  display: none;
}

.message.is-editing .message-text:empty::before {
  content: "Text eingeben...";
  color: var(--text-muted);
  pointer-events: none;
}

.voice-message {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 44px;
  padding: 0 6px;
}

.voice-message__play {
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 50%;
  background: var(--primary);
  color: var(--inverse-text);
  font-size: 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.voice-message__play:hover {
  background: var(--primary-dark);
}

.voice-message.is-playing .voice-message__play {
  background: var(--danger);
}

.voice-message__duration {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  white-space: nowrap;
}

.message.sent .voice-message__duration {
  color: rgba(255, 255, 255, 0.92);
}

.voice-message__wave {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  align-items: center;
  gap: 2px;
  overflow: hidden;
}

.voice-message__bar {
  flex: 1;
  min-width: 2px;
  height: 20%;
  border-radius: 1px;
  background: var(--primary);
  opacity: 0.3;
  transition: opacity 0.15s ease;
}

.message.sent .voice-message__bar {
  background: rgba(255, 255, 255, 0.9);
}

.voice-message__bar.is-played {
  opacity: 1;
}

.voice-message__audio {
  display: none;
}

[contenteditable],
.message-text {
  /* Erlaubt normales Umbrechen an Wortgrenzen */
  /* Verhindert das Sprengen der Box bei langen Zeichenketten */
  border: 1px solid transparent;
  white-space: pre-wrap !important;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.message-text {
  font-family: "Twemoji", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  white-space: pre-wrap !important;
  word-break: break-word;
  overflow-wrap: anywhere;
  outline: none;
}

.message-text a {
  /* Links im Nachrichtentext (Autolink): auf der weißen Bubble ein kräftiges
   Blau, auf der lila Bubble ein heller Lavendel-Ton (weißer Text hat dort
   Priorität, Links müssen sich davon abheben). .message-file (Medien-
   Anhang) hat eigene Styles und bleibt unberührt. */
  color: #1a73e8;
  font-weight: 500;
  text-decoration: underline;
}

.message.sent .message-text a {
  color: #cdc0ff;
}

.message.sent .message-text a:hover {
  color: #e0d8ff;
}

.message-mention {
  background: rgba(108, 92, 231, 0.12);
  color: var(--primary-dark);
  border-radius: 4px;
  padding: 0 2px;
  border: none;
  font: inherit;
  cursor: pointer;
}

.message.sent .message-mention {
  /* Mention-Chips auf der lila Bubble: dunkellila Text ist dort unsichtbar —
   stattdessen heller Transparenz-Hintergrund mit weißem Text. */
  background: rgba(255, 255, 255, 0.18);
  color: var(--inverse-text);
}

.message-mention--self {
  background: var(--primary);
  color: var(--inverse-text);
  border: none;
  font: inherit;
  cursor: pointer;
}

[contenteditable]:focus {
  border: 1px dashed white;
  padding: 0px;
}

.message-meta .edited {
  font-size: 11px;
  opacity: 0.7;
  color: inherit;
}

.message-actions {
  position: absolute;
  top: -32px;
  right: 8px;
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.15s ease;
  z-index: 1100;
}

.message.received .message-actions {
  right: auto;
  left: 8px;
}

.message:hover .message-actions,
.message:focus-within .message-actions {
  opacity: 1;
}

.message-actions__button {
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-muted);
  font-size: 13px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.message-actions__button:hover {
  color: #e53935;
  background: var(--border-light);
}

/* Gepinnt: Pin rotiert (Kopf nach unten) + Akzentfarbe, damit der
   Unpin-Zustand im Hover-Menu sofort erkennbar ist. */
.message-actions__button--pinned {
  color: var(--primary);
}

.message-actions__button--pinned i {
  transform: rotate(180deg);
}

.message.is-editing {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.message.dragover {
  outline: 2px dashed var(--primary);
  outline-offset: 2px;
}

.message-edit {
  margin-top: 8px;
}

.message-edit[hidden] {
  display: none;
}

.message-edit__attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 8px;
}

.message-edit__row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.message-edit__attach {
  width: 30px;
  height: 30px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.message-edit__attach:hover {
  color: var(--primary);
  background: var(--border-light);
}

.message-edit__attach.is-listening {
  background: var(--danger);
  color: var(--inverse-text);
  animation: mic-pulse 1.4s ease-in-out infinite;
}

.message-edit .dictation-hint,
.message-edit .voice-recorder {
  margin-bottom: 8px;
}

.message-edit__save,
.message-edit__cancel {
  border: none;
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 13px;
  cursor: pointer;
}

.message-edit__save {
  background: var(--primary);
  color: var(--inverse-text);
}

.message-edit__cancel {
  background: var(--border-light);
  color: var(--text);
}

.message-edit__error {
  font-size: 12px;
  color: #e74c3c;
}

.message-edit__error[hidden] {
  display: none;
}

.message-edit-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
}

.message-edit-progress[hidden] {
  display: none;
}

.message-edit-progress__track {
  flex: 1;
  height: 6px;
  border-radius: 3px;
  background: var(--border-light);
  overflow: hidden;
}

.message-edit-progress__bar {
  height: 100%;
  width: 0%;
  border-radius: 3px;
  background: var(--primary);
  transition: width 0.15s ease;
}

.message-edit-progress__label {
  font-size: 12px;
  color: var(--text-muted);
  min-width: 32px;
  text-align: right;
}

.message-edit-progress__cancel {
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 50%;
  background: var(--border-light);
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.message-edit-progress__cancel:hover {
  background: var(--border);
  color: var(--text);
}

.message-reply {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 8px;
  padding: 6px 10px;
  border-left: 3px solid currentColor;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.08);
  font-size: 13px;
  line-height: 1.35;
}

.sent .message-reply {
  background: rgba(255, 255, 255, 0.2);
}

.message-reply__name {
  font-weight: 600;
}

.message-reply__text {
  opacity: 0.85;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.message-reply__label {
  font-style: italic;
  opacity: 0.7;
}

.message-forward {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  font-size: 12px;
  opacity: 0.8;
}

.message-forward i {
  font-size: 11px;
}

.message-reply__quote {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
  font: inherit;
}

.message-reply__quote:hover .message-reply__name,
.message-reply__quote:hover .message-reply__text {
  text-decoration: underline;
}

/* Jump-to-Message-Hervorhebung: 2 kurze Aufblink-Pulse (statt langsamem
   Background-Fade, der im Dark-Theme schlecht sichtbar war und zum falschen
   Endwert --surface statt #253154 blendete). Der semitransparente Gelb-Overlay
   (inset box-shadow) liegt ÜBER dem Bubble-Hintergrund und bleibt auf allen
   Basisfarben (weiß, dunkelblau, primary) gleich gut sichtbar — ohne die echte
   Bubble-Farbe zu ersetzen bzw. am Ende hart zurückspringen zu müssen. */
.message--focused {
  animation: message-focus-blink 1.3s ease-in-out;
}

@keyframes message-focus-blink {
  0%,
  22%,
  56%,
  100% {
    box-shadow: none;
  }

  /* Blink 1 */
  11% {
    box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--accent) 55%, transparent);
  }

  /* Blink 2 */
  45% {
    box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--accent) 55%, transparent);
  }
}

.message-location {
  position: relative;
  z-index: 0;
  border-radius: 10px;
  margin-bottom: 8px;
}

.message-location .leaflet-container {
  border-radius: 10px;
}