/* ============================================================
   APPICS Webversion — LIVE-1 UI-Modul (isoliert)
   Contract: design/SPEC-LIVE-1-20260719.md §UI-Modul (todoroki)

   Alles unter `.lv` gescoped, damit das Modul die App-Styles
   nicht berührt. Sandro-Sprache: Panels #1b1d2a, keine Borders,
   weiße Buttons, Lucide-Icons, hell + dunkel (.lv-light).
   ============================================================ */
.lv {
  /* Dunkel = Standard (App-Welt) */
  --lv-panel: #1b1d2a;
  --lv-panel2: #232537;
  --lv-input: #2d2e40;
  --lv-ink: #eef0f6;
  --lv-muted: #8e92b2;
  --lv-teal: #35d0c5;
  --lv-red: #ff5d6c;
  --lv-gold: #f5c451;
  --lv-gold-deep: #b8862b;
  --lv-btn-bg: #ffffff;
  --lv-btn-ink: #14141e;
  --lv-radius: 16px;
  --lv-radius-s: 11px;
  --lv-shadow: 0 8px 30px rgba(0, 0, 0, .35);
  font-family: 'Inter', system-ui, sans-serif;
  color: var(--lv-ink);
  box-sizing: border-box;
}
.lv *, .lv *::before, .lv *::after { box-sizing: border-box; }

.lv.lv-light {
  --lv-panel: #ffffff;
  --lv-panel2: #f2f3f8;
  --lv-input: #eceef5;
  --lv-ink: #1a1c26;
  --lv-muted: #6b6f8e;
  --lv-btn-bg: #14141e;
  --lv-btn-ink: #ffffff;
  --lv-gold-deep: #9a6c17;
  --lv-shadow: 0 8px 30px rgba(20, 22, 40, .12);
  /* Teal als TEXT/Icon auf hellen Panel-Flächen abdunkeln. Das Dunkel-Teal
     #35d0c5 trägt auf Weiß nur ~1.9:1 Kontrast (WCAG AA fordert 4.5:1) — im
     Hell-Theme sitzt es aber auf weißem Chat-Panel / weißer Tip-Card und
     färbt tip-amt, me-User, Agent-Text + tip-ic. #0b7a72 auf Weiß = ~5.2:1
     (AA erfüllt). Nur die Panel-gebundenen Teal-Stellen erben das; der
     join-ic sitzt auf DUNKLEM Glas und bleibt separat hell (s.u.). */
  --lv-teal: #0b7a72;
}

.lv .lv-ic { width: 18px; height: 18px; display: block; }

/* Weiße (Sandro-)Buttons — in hell invertiert (dunkler Chip). */
.lv .lv-btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--lv-btn-bg); color: var(--lv-btn-ink);
  border: 0; border-radius: 999px; cursor: pointer;
  width: 38px; height: 38px; flex: 0 0 auto;
  transition: transform .12s ease, opacity .12s ease;
}
.lv .lv-btn:hover { transform: translateY(-1px); }
.lv .lv-btn:active { transform: translateY(0); opacity: .85; }
.lv .lv-btn .lv-ic { width: 17px; height: 17px; }

/* ---------- LIVE-Badge ---------- */
.lv-badge {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--lv-red); color: #fff;
  font: 700 10.5px/1 'Inter', system-ui, sans-serif;
  letter-spacing: .08em; padding: 5px 9px; border-radius: 7px;
  text-transform: uppercase;
}
.lv-badge-lg { font-size: 12.5px; padding: 7px 12px; border-radius: 9px; }
.lv-badge-dot {
  width: 6px; height: 6px; border-radius: 50%; background: #fff;
  animation: lv-pulse 1.6s ease-in-out infinite;
}
.lv-badge-lg .lv-badge-dot { width: 7px; height: 7px; }
@keyframes lv-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* ---------- Chat-Panel ---------- */
.lv-chat {
  display: flex; flex-direction: column;
  background: var(--lv-panel); border-radius: var(--lv-radius);
  overflow: hidden; min-height: 0;
}
.lv-chat-head {
  display: flex; align-items: center; gap: 8px;
  padding: 13px 15px; font-weight: 600; font-size: 13.5px;
  flex: 0 0 auto;
}
.lv-live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--lv-red);
  animation: lv-pulse 1.6s ease-in-out infinite; }
.lv-chat-title { flex: 1 1 auto; }
.lv-chat-count {
  background: var(--lv-panel2); color: var(--lv-muted);
  font-size: 11.5px; font-weight: 600; padding: 3px 8px; border-radius: 999px; min-width: 22px;
  text-align: center;
}
/* Bis zur ersten Nachricht verborgen (Parität zu .lv-viewers/.lv-caption): das
   gefüllte Capsule soll kein leeres Geister-Pill im Kopf zeigen. Explizit, damit
   ein späteres display auf .lv-chat-count den UA-[hidden]-Default nicht aushebelt. */
.lv-chat-count[hidden] { display: none; }
.lv-chat-scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: 4px 15px 8px; display: flex; flex-direction: column; gap: 11px;
  scrollbar-width: thin; scrollbar-color: var(--lv-panel2) transparent;
}
.lv-chat-scroll::-webkit-scrollbar { width: 7px; }
.lv-chat-scroll::-webkit-scrollbar-thumb { background: var(--lv-panel2); border-radius: 6px; }
.lv-msg { display: flex; flex-direction: column; gap: 2px; }
.lv-msg-head { display: flex; align-items: center; gap: 7px; }
/* min-width:0 + overflow-wrap: ein langer, leerzeichenloser Anzeigename (per
   Gateway-Push, JS-seitig auf MAX_NAME_LEN gedeckelt) bricht innerhalb seiner
   Box um statt die Kopfzeile horizontal aufzureißen (mobil 390px). */
.lv-msg-user { font-size: 12.5px; font-weight: 600; color: var(--lv-muted); min-width: 0; overflow-wrap: anywhere; }
.lv-msg-me .lv-msg-user { color: var(--lv-teal); }
.lv-msg-ts { font-size: 11px; color: var(--lv-muted); opacity: .7; margin-left: auto; }
/* Umbruch der Chat-Body-Zeile über das STANDARD `overflow-wrap: anywhere` —
   Parität zu den übrigen fremd-Push-Textflächen (.lv-msg-user/.lv-tip-user/
   .lv-join-user). Diese Zeile trug als einzige das NICHT-standardisierte
   `word-break: break-word` (MDN: non-standard, Legacy-Alias) — sie hält aber
   den LÄNGSTEN Fremd-Push-Text (chatAdd-Body, JS-Deckel MAX_MSG_LEN=600). Ein
   langer leerzeichenloser Token (URL/Blob) muss auf 390px innerhalb der Box
   brechen statt die Zeile aufzureißen; `anywhere` erzwingt das standardkonform
   UND zählt als Soft-Wrap für die min-content-Breite (Legacy-Alias tat das nicht
   garantiert). min-width:0, damit die Flex-Box unter die Token-Breite schrumpfen
   darf. */
.lv-msg-text { font-size: 14px; line-height: 1.4; min-width: 0; overflow-wrap: anywhere; }
.lv-agent-tag {
  display: inline-flex; align-items: center; gap: 3px;
  background: rgba(53, 208, 197, .16); color: var(--lv-teal);
  font-size: 10.5px; font-weight: 700; padding: 2px 7px 2px 5px; border-radius: 999px;
  letter-spacing: .03em;
}
.lv-agent-tag .lv-ic { width: 12px; height: 12px; }
.lv-msg-agent .lv-msg-text { color: var(--lv-teal); }
.lv-chat-bar { display: flex; gap: 8px; padding: 11px 13px; flex: 0 0 auto; }
.lv-chat-in {
  flex: 1 1 auto; background: var(--lv-input); color: var(--lv-ink);
  border: 0; outline: none; border-radius: 999px; padding: 0 15px; height: 38px; font-size: 13.5px;
  font-family: inherit;
}
.lv-chat-in::placeholder { color: var(--lv-muted); opacity: .8; }
/* Sichtbarer Tastatur-Fokus (WCAG 2.4.7 Focus Visible). Der Chat-Input setzt
   oben `outline: none` für die rahmenlose Sandro-Ruhe — OHNE Ersatz sah ein
   Tastatur-/AT-Nutzer beim Tabben ins Nachrichtenfeld gar keinen Fokus (der
   Send-Button trug nur den inkonsistenten UA-Default-Ring). `:focus-visible`
   (NICHT `:focus`) zeigt den Ring NUR bei Tastatur-/Programm-Fokus, nie beim
   Mausklick — Normal- und Maus-Zustand bleiben unverändert rahmenlos. `outline`
   (kein `border`) erzeugt keinen Reflow; outline-offset legt ihn in den Panel-
   Spalt, damit er in BEIDEN Themes kontraststark gegen Input- UND Panel-Fläche
   sitzt (Teal ≥ 3:1, WCAG 1.4.11 Non-Text-Kontrast). Alt-Safari (< 15.4) ohne
   :focus-visible fällt auf den rahmenlosen Ruhezustand zurück — kein Regress. */
.lv .lv-chat-in:focus-visible,
.lv .lv-btn:focus-visible {
  outline: 2px solid var(--lv-teal);
  outline-offset: 2px;
}

/* ---------- Overlay-Ebene ---------- */
.lv-overlay {
  position: relative; width: 100%; height: 100%;
  pointer-events: none; overflow: hidden;
  display: flex; flex-direction: column;
}
/* Viewer-Chip oben rechts — LIVE-Badge sitzt konventionell oben links. */
.lv-ov-top { position: absolute; top: 14px; left: 14px; right: 14px; display: flex; justify-content: flex-end; }
.lv-viewers {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(20, 20, 30, .62); color: #fff;
  /* -webkit-Präfix zuerst: iOS Safari greift unpräfixiertes backdrop-filter erst
     ab v18 — ohne Präfix bleibt das dunkle Glas auf mobil (390px-Ziel) ohne Blur. */
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  font-size: 12.5px; font-weight: 600; padding: 6px 11px; border-radius: 999px;
  pointer-events: auto;
}
.lv-viewers .lv-ic { width: 15px; height: 15px; }
.lv-viewers[hidden] { display: none; }
/* Nur-Screenreader: visuell entfernt, aber im Accessibility-Tree erhalten.
   Der Viewer-Chip zeigt sichtbar nur die Zahl (+ Auge-Icon, aria-hidden); dieses
   Label ("Zuschauer") gibt der Zahl für assistive Technik einen Sinn. Standard-
   Clip-Muster — NICHT display:none/visibility:hidden, die den Text ganz aus dem
   Accessibility-Tree nähmen. */
.lv-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.lv-ov-stack {
  position: absolute; top: 54px; left: 14px; right: 14px;
  display: flex; flex-direction: column; gap: 9px; align-items: flex-start;
}

/* Tip-Card */
.lv-tip {
  display: flex; align-items: center; gap: 11px;
  background: var(--lv-panel); color: var(--lv-ink);
  border-radius: 14px; padding: 11px 15px 11px 12px; box-shadow: var(--lv-shadow);
  pointer-events: auto; max-width: 300px;
  animation: lv-in .32s cubic-bezier(.2, .8, .2, 1) both;
}
.lv-tip.lv-out { animation: lv-out .3s ease forwards; }
.lv-tip-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 11px; flex: 0 0 auto;
  background: var(--lv-panel2); color: var(--lv-teal);
}
.lv-tip-line { display: flex; align-items: baseline; gap: 8px; min-width: 0; flex-wrap: wrap; }
.lv-tip-user { font-weight: 600; font-size: 13.5px; min-width: 0; overflow-wrap: anywhere; }
.lv-tip-amt { font-weight: 800; font-size: 14px; color: var(--lv-teal); }
.lv-tip-target { font-size: 11.5px; color: var(--lv-muted); margin-top: 1px; }
/* Gold ab 1000 APX */
.lv-tip-gold {
  background: linear-gradient(135deg, #2a2410, #1f1a0a);
  box-shadow: 0 8px 34px rgba(245, 196, 81, .28), inset 0 0 0 1px rgba(245, 196, 81, .32);
}
.lv-tip-gold .lv-tip-ic { background: rgba(245, 196, 81, .18); color: var(--lv-gold); }
.lv-tip-gold .lv-tip-amt { color: var(--lv-gold); }
.lv-tip-gold .lv-tip-user, .lv-tip-gold .lv-tip-target { color: #f3ead0; }
.lv-light .lv-tip-gold {
  background: linear-gradient(135deg, #fff5d8, #ffedb8);
  box-shadow: 0 8px 34px rgba(184, 134, 43, .22), inset 0 0 0 1px rgba(184, 134, 43, .34);
}
.lv-light .lv-tip-gold .lv-tip-user { color: #4a3a10; }
.lv-light .lv-tip-gold .lv-tip-amt { color: var(--lv-gold-deep); }
.lv-light .lv-tip-gold .lv-tip-target { color: #7a5f1c; }

/* Join-Ticker */
.lv-join {
  display: inline-flex; align-items: center; gap: 7px;
  background: rgba(20, 20, 30, .62); color: #fff;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); /* iOS Safari < 18 */
  font-size: 12.5px; padding: 6px 12px 6px 8px; border-radius: 999px;
  pointer-events: auto; animation: lv-in .3s ease both; max-width: 100%;
}
.lv-join.lv-out { animation: lv-out .3s ease forwards; }
/* Bewusst festes Hell-Teal statt var(--lv-teal): der Join-Ticker sitzt in BEIDEN
   Themes auf dunklem Glas (rgba(20,20,30,.62)). Würde er das Light-Theme-Teal
   (#0b7a72, für weiße Panels abgedunkelt) erben, verschwände das Icon auf dem
   dunklen Glas. Auf dunklem Grund ist #35d0c5 der kontraststarke Ton. */
.lv-join-ic { display: inline-flex; color: #35d0c5; flex: 0 0 auto; }
.lv-join-ic .lv-ic { width: 15px; height: 15px; }
.lv-join-user { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.lv-join-txt { color: rgba(255, 255, 255, .7); }

/* Caption-Leiste (2 Zeilen, unten) */
.lv-caption {
  position: absolute; left: 14px; right: 14px; bottom: 14px;
  background: rgba(12, 12, 20, .68);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); /* iOS Safari < 18 */
  border-radius: 12px; padding: 9px 13px; pointer-events: auto;
}
.lv-caption[hidden] { display: none; }
.lv-cap-lines { display: flex; flex-direction: column; gap: 2px; }
.lv-cap-line {
  color: #fff; font-size: 14px; line-height: 1.35; font-weight: 500;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .4); overflow-wrap: break-word;
}
/* Die untere Zeile (lv-cap-cur) ist die AKTUELLE Caption — voll sichtbar, 14px.
   Eine bereits gesprochene, nach oben gerollte Zeile (lv-cap-prev) wird gedimmt.
   Explizit per Klasse statt :first-child: eine EINZELNE Zeile ist die aktive
   Caption und darf NICHT matt sein (als lone :first-child wäre sie es sonst). */
.lv-cap-prev { opacity: .62; font-size: 13px; }

@keyframes lv-in { from { opacity: 0; transform: translateY(-8px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes lv-out { to { opacity: 0; transform: translateY(-6px) scale(.97); } }

@media (prefers-reduced-motion: reduce) {
  .lv-badge-dot, .lv-live-dot { animation: none; }
  .lv-tip, .lv-join { animation: none; }
  /* Auch die AUS-Animation stilllegen: `.lv-tip.lv-out`/`.lv-join.lv-out`
     (Spezifität 0,2,0) schlägt sonst das `.lv-tip { animation: none }` (0,1,0)
     oben — die Karte würde beim Auto-Out trotz reduzierter Bewegung noch faden.
     Entfernen der Karte läuft per JS-Timer (removeChild), unabhängig von der
     CSS-Animation; ohne Fade verschwindet sie einfach sofort (korrektes
     reduced-motion-Verhalten). Gleiche Spezifität, später in der Quelle → gewinnt. */
  .lv-tip.lv-out, .lv-join.lv-out { animation: none; }
  /* Auch die Button-TRANSITION stilllegen: `.lv .lv-btn { transition: transform
     .12s, opacity .12s }` (Zeile 51) animiert das :hover-translateY(-1px) und den
     :active-Dip (translateY(0) + opacity .85) — das ist getweente Bewegung, genau
     die Klasse, die reduced-motion abschalten soll. Der reduced-motion-Block nullt
     bislang nur `animation`, nicht `transition`, sodass diese Mikro-Bewegung durch-
     rutschte. Selektor `.lv .lv-btn` (Spezifität 0,2,0) MUSS die Basis-Regel gleicher
     Spezifität matchen; @media hebt die Spezifität nicht — nur die spätere Quell-
     Position gewinnt. Der Button reagiert weiter auf :hover/:active (translateY/opacity
     GELTEN weiter), nur SOFORT statt getweent — korrektes reduced-motion-Verhalten,
     Contract (weiße Sandro-Buttons) unverändert. */
  .lv .lv-btn { transition: none; }
}
