/* ============================================================================
 * tc-sprechblase — Wenn eine Figur etwas sagt (03.10.2026, #828)
 * ----------------------------------------------------------------------------
 * Renderer: js/ui/sprechblase.js (TC.Sprechblase.figur / .zeige)
 * Demonstriert in: library-community.html („Die Sprechblase")
 *
 * Noswads Wunsch: Der Anfeuern-Knopf soll einen Spruch loslassen. Tims
 * Ergaenzung: Der Stadtschreier kommentiert an der Karte, wie viele schon
 * angefeuert haben. Entschieden „1A 2A 3B 4A" (Ticket #828, 01.10.2026).
 *
 * ⚠️ WARUM HIER EIN ZIPFEL STEHT, OBWOHL DIE WIRTE KEINEN HABEN.
 * Die Wirt-Rede (tc-wirt__rede, tc-lampe__rede) ist eine kursive Zeile mit
 * Randstrich — mit Absicht ohne Zipfel (css/untergrund.css: „bei fuenf
 * Wirten mit sehr unterschiedlichen Textlaengen wird der Zipfel zur
 * Fummelei"). Dort steht die Figur gross daneben und spricht fuer den Raum.
 * Hier spricht sie in eine fremde Karte hinein, mit einem 28-px-Gesicht:
 * Ohne Zipfel laese sich der Satz wie eine Zeile der Karte, nicht wie
 * jemandes Rede. Die Schrift bleibt die der Wirte (Lato kursiv, warm), damit
 * es dieselbe Familie bleibt.
 *
 * Zwei Formen, eine Familie (Heuristik 3, Modifier statt zweiter Komponente):
 *
 *   --figur   Gesicht + Blase mit Zipfel, steht IN einer Karte.
 *             Stufen --stufe-1 … --stufe-4: Sie waechst mit (Tim, 1A) —
 *             das Gesicht wird groesser, der Rahmen waermer, bei der
 *             vierten Stufe leuchtet er. Die Stufe sagt die Erzaehlung,
 *             nicht die Daten: Die Zahl steht im Text.
 *
 *   --knopf   Ein kurzer Spruch ueber dem Knopf, der gerade gedrueckt wurde
 *             (Tim, 3B). Schwebt am <body> (position: absolute, scrollt mit
 *             der Seite), geht nach ein paar Sekunden von selbst. Kein
 *             Bedienelement: Ein Tipp irgendwohin nimmt ihn weg, eine
 *             kleine Trefferflaeche gibt es also nicht.
 *
 * Struktur --figur:
 *   <div class="tc-sprechblase tc-sprechblase--figur tc-sprechblase--stufe-N">
 *     <img class="tc-sprechblase__gesicht" src="…/avatare/schreier.webp" alt="">
 *     <p class="tc-sprechblase__blase">
 *       <span class="tc-sprechblase__wer">Der Stadtschreier</span>
 *       <strong>Drei</strong> feuern an. Satz aus dem Baukasten.
 *     </p>
 *   </div>
 *
 * Struktur --knopf (setzt TC.Sprechblase.zeige):
 *   <div class="tc-sprechblase tc-sprechblase--knopf [tc-sprechblase--unten]"
 *        aria-hidden="true" style="--tc-sprechblase-zipfel: 40px">
 *     <span class="tc-sprechblase__icon">👏</span><span>Spruch</span>
 *   </div>
 *   Vorgelesen wird ueber eine unsichtbare Ansage (__ansage, role=status) —
 *   ein Element, das MIT Inhalt eingefuegt wird, sagen Screenreader oft
 *   nicht an.
 *
 * Reduced-Motion: kein Aufspringen, kein Gleiten (siehe unten).
 * ========================================================================== */

.tc-sprechblase {
  /* Groesse des Gesichts; die Stufen setzen sie neu. Der Zipfel richtet sich
     danach, damit er immer auf die Mitte des Gesichts zeigt. */
  --tc-sprechblase-gesicht: 28px;
  font-family: var(--tc-font-body);
}

/* ---- Die Figur in der Karte (--figur) ------------------------------------ */

.tc-sprechblase--figur {
  display: flex;
  /* Gesicht unten, Blase daneben nach oben gewachsen — wie ein Comic, in
     dem der Sprecher unten steht. Der Zipfel sitzt deshalb unten. */
  align-items: flex-end;
  gap: var(--tc-space-2);
  margin-top: var(--tc-space-2);
}

.tc-sprechblase__gesicht {
  flex: none;
  display: block;
  width: var(--tc-sprechblase-gesicht);
  height: var(--tc-sprechblase-gesicht);
  border-radius: var(--tc-radius-full);
  /* Die Avatare zeigen den Kopf im oberen Drittel (wie tc-wirt__portrait). */
  object-fit: cover;
  object-position: 50% 20%;
  border: 1px solid var(--tc-deco-warm-border);
  background: var(--tc-bg-surface-2);
  transition: width var(--tc-motion-normal), height var(--tc-motion-normal);
}

.tc-sprechblase__blase {
  position: relative;
  flex: 1 1 auto;
  /* ⚠️ Ohne min-width sprengt ein langer Satz die Zeile: Flex-Kinder haben
     min-width: auto, und der Inhalt gewinnt gegen den Behaelter. */
  min-width: 0;
  margin: 0;
  padding: var(--tc-space-2) var(--tc-space-3);
  background: var(--tc-bg-surface-2);
  border: 1px solid var(--tc-deco-warm-border);
  border-radius: var(--tc-radius-md);
  /* Die Ecke am Zipfel ist spitz — sonst haengt er an einer Rundung. */
  border-bottom-left-radius: var(--tc-radius-xs);
  font-style: italic;
  font-size: var(--tc-text-sm);
  line-height: var(--tc-leading-snug);
  color: var(--tc-deco-warm-text);
  overflow-wrap: break-word;
}

/* Der Zipfel: ein auf die Spitze gestelltes Quadrat mit zwei Kanten.
   `background: inherit` nimmt die Flaeche der Blase mit, auch die getoente
   der hoeheren Stufen. */
.tc-sprechblase__blase::before {
  content: '';
  position: absolute;
  left: -5px;
  bottom: calc(var(--tc-sprechblase-gesicht) / 2 - 5px);
  width: 9px;
  height: 9px;
  background: inherit;
  border-left: 1px solid;
  border-bottom: 1px solid;
  border-color: inherit;
  transform: rotate(45deg);
}

/* Wer spricht. Klein, aber da: Wer das Gesicht noch nicht kennt, soll nicht
   raten muessen, und der Screenreader liest so „Der Stadtschreier: …". */
.tc-sprechblase__wer {
  display: block;
  margin-bottom: 2px;
  font-family: var(--tc-font-display);
  font-style: normal;
  font-size: var(--tc-text-2xs);
  letter-spacing: 0.04em;
  color: var(--tc-text-muted);
}

/* Die Zahl, die der Erzeuger einsetzt — nicht kursiv, damit man sie findet. */
.tc-sprechblase__blase strong {
  font-style: normal;
  font-weight: var(--tc-weight-semibold);
  color: var(--tc-text-strong);
}

/* ---- Sie waechst mit (Stufen 1 · 2–3 · 4–5 · 6+) ------------------------- */

/* Stufe 1, „einer feuert an": Der Stadtschreier laestert ueber die Runde.
   Die Blase ist kuehl — kein warmer Rand, gedaempfte Schrift. */
.tc-sprechblase--stufe-1 .tc-sprechblase__blase {
  border-color: var(--tc-border-default);
  color: var(--tc-text-default);
}

/* Stufe 2, „zwei, drei": die warme Grundform von oben. */
.tc-sprechblase--stufe-2 { --tc-sprechblase-gesicht: 32px; }

/* Stufe 3, „vier, fuenf": Er lobt — der Rand nimmt den Ton des Systems an. */
.tc-sprechblase--stufe-3 { --tc-sprechblase-gesicht: 36px; }
.tc-sprechblase--stufe-3 .tc-sprechblase__blase {
  border-color: rgba(var(--tc-highlight-rgb), 0.4);
  background:
    linear-gradient(rgba(var(--tc-highlight-rgb), 0.07), rgba(var(--tc-highlight-rgb), 0.07)),
    var(--tc-bg-surface-2);
}
.tc-sprechblase--stufe-3 .tc-sprechblase__gesicht { border-color: rgba(var(--tc-highlight-rgb), 0.5); }

/* Stufe 4, „sechs und mehr": begeistert. Der Rand leuchtet, die Zahl auch. */
.tc-sprechblase--stufe-4 { --tc-sprechblase-gesicht: 40px; }
.tc-sprechblase--stufe-4 .tc-sprechblase__blase {
  border-color: var(--tc-highlight);
  background:
    linear-gradient(rgba(var(--tc-highlight-rgb), 0.10), rgba(var(--tc-highlight-rgb), 0.10)),
    var(--tc-bg-surface-2);
  box-shadow: 0 0 16px var(--tc-highlight-glow);
}
.tc-sprechblase--stufe-4 .tc-sprechblase__gesicht {
  border-color: var(--tc-highlight);
  box-shadow: 0 0 12px var(--tc-highlight-glow);
}
.tc-sprechblase--stufe-4 .tc-sprechblase__blase strong { color: var(--tc-highlight); }

/* ---- Der Spruch am Knopf (--knopf) --------------------------------------- */

.tc-sprechblase--knopf {
  /* Wo der Zipfel sitzt, rechnet TC.Sprechblase.zeige aus der Mitte des
     Knopfes — die Blase selbst wird am Bildrand festgehalten. */
  --tc-sprechblase-zipfel: 50%;
  position: absolute;
  z-index: var(--tc-z-tooltip);
  box-sizing: border-box;
  max-width: min(280px, calc(100vw - 2 * var(--tc-space-3)));
  padding: var(--tc-space-2) var(--tc-space-3);
  display: flex;
  align-items: baseline;
  gap: var(--tc-space-2);
  background: var(--tc-bg-surface-2);
  border: 1px solid var(--tc-highlight);
  border-radius: var(--tc-radius-md);
  box-shadow: var(--tc-shadow-lg), 0 0 14px var(--tc-highlight-glow);
  font-style: italic;
  font-size: var(--tc-text-sm);
  line-height: var(--tc-leading-snug);
  color: var(--tc-text-strong);
  cursor: default;
  transform-origin: var(--tc-sprechblase-zipfel) 100%;
  animation: tc-sprechblase-auf var(--tc-motion-elegant) both;
}

.tc-sprechblase--knopf::after {
  content: '';
  position: absolute;
  left: var(--tc-sprechblase-zipfel);
  bottom: -6px;
  width: 10px;
  height: 10px;
  margin-left: -5px;
  background: inherit;
  border-right: 1px solid var(--tc-highlight);
  border-bottom: 1px solid var(--tc-highlight);
  transform: rotate(45deg);
}

/* Kein Platz ueber dem Knopf (er steht ganz oben im Bild): Die Blase haengt
   darunter, der Zipfel zeigt nach oben. */
.tc-sprechblase--knopf.tc-sprechblase--unten { transform-origin: var(--tc-sprechblase-zipfel) 0; }
.tc-sprechblase--knopf.tc-sprechblase--unten::after {
  bottom: auto;
  top: -6px;
  border-right: 0;
  border-bottom: 0;
  border-left: 1px solid var(--tc-highlight);
  border-top: 1px solid var(--tc-highlight);
}

.tc-sprechblase__icon {
  flex: none;
  font-style: normal;
}

/* Mit Verweis (#948, „Im Stadtbuch"): Der Link steht in einer eigenen Zeile
   unter dem Satz, aufrecht und unterstrichen, damit er als Weg erkennbar ist.
   Trefferflaeche 36 px (Heuristik 5) ueber Innenabstand, nicht Schriftgroesse. */
.tc-sprechblase--mehr {
  flex-wrap: wrap;
  cursor: auto;
}
.tc-sprechblase__text { flex: 1 1 0; min-width: 0; }
.tc-sprechblase__mehr {
  flex-basis: 100%;
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  margin: calc(-1 * var(--tc-space-1)) 0 calc(-1 * var(--tc-space-2));
  font-style: normal;
  font-size: var(--tc-text-xs);
  font-weight: 600;
  color: var(--tc-highlight);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.tc-sprechblase__mehr:hover { color: var(--tc-text-strong); }
.tc-sprechblase__mehr:focus-visible {
  outline: 2px solid var(--tc-highlight);
  outline-offset: 2px;
  border-radius: var(--tc-radius-sm);
}

/* ---- Der Begriff im Text (tc-begriff, #948) -------------------------------
 * Ein Wort aus der Wortschatz-Kartei, das sich beim Antippen erklaert.
 * Erzeugt von TC.Wortschatz.begriff(id[, text]); die Sprechblase oeffnet der
 * Kartei-Zuhoerer selbst (ein Zuhoerer je Seite, auch fuer spaeter
 * gezeichnete Begriffe). Struktur:
 *   <button type="button" class="tc-begriff" data-begriff="schmelze">Schmelze</button>
 * Steht mitten im Satz: erbt Schrift, Farbe und Groesse vom Text drumherum;
 * erkennbar nur an der gepunkteten Linie. Die Trefferflaeche waechst
 * unsichtbar ueber ::after (Heuristik 5), ohne die Zeile aufzureissen.
 * ------------------------------------------------------------------------- */
.tc-begriff {
  appearance: none;
  position: relative;
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: inherit;
  cursor: help;
  text-decoration: underline dotted;
  text-decoration-color: var(--tc-highlight);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  transition: color var(--tc-motion-fast), text-decoration-color var(--tc-motion-fast);
}
.tc-begriff::after {
  content: '';
  position: absolute;
  inset: -10px -4px;
}
.tc-begriff:hover { color: var(--tc-highlight); }
.tc-begriff:focus-visible {
  outline: 2px solid var(--tc-highlight);
  outline-offset: 2px;
  border-radius: var(--tc-radius-sm);
}

/* Geht: leiser aus als herein. */
.tc-sprechblase--knopf.is-geht {
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--tc-motion-slow), transform var(--tc-motion-slow);
}

@keyframes tc-sprechblase-auf {
  from { opacity: 0; transform: translateY(6px) scale(0.92); }
  to   { opacity: 1; transform: none; }
}

/* Vorgelesen, nicht gesehen: die Ansage fuer Screenreader. */
.tc-sprechblase__ansage {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .tc-sprechblase--knopf,
  .tc-sprechblase--knopf.is-geht,
  .tc-sprechblase__gesicht {
    animation-duration: 0.01ms;
    transition-duration: 0.01ms;
  }
  .tc-sprechblase--knopf.is-geht { transform: none; }
  .tc-begriff { transition-duration: 0.01ms; }
}

/* ===========================================================================
 * RUTGER, DER ZEUGWART (#1164) — TC.Zeugwart.html (js/ui/zeugwart.js)
 * ---------------------------------------------------------------------------
 * Dieselbe Figur-Blase wie der Stadtschreier und Krenk, nur mit Abstand nach
 * unten: Rutger steht ÜBER dem, wozu er etwas sagt (Konto, Systeme, Listen,
 * die Antwort nach der Zusage). Ohne TC.Sprechblase auf der Seite steht sein
 * Satz als Zeile (`--zeile`). Library: library-community.html#zeugwart.
 * ======================================================================== */
.tc-zeugwart { margin: 0 0 var(--tc-space-3); }
.tc-zeugwart > .tc-sprechblase { margin-top: 0; }
.tc-zeugwart--zeile {
  font-size: var(--tc-text-sm);
  color: var(--tc-text-default);
  line-height: var(--tc-leading-snug);
}
