/* ==========================================================================
   Taktgeber - Beamer-/TV-Ansicht (WP11)

   Der EINZIGE Bildschirm im Projekt, der aus mehreren Metern funktionieren
   muss. Deshalb: Groessen ueber `vmin`/`vw` statt fester rem-Werte, viel
   Weissraum, hoher Kontrast auf `--tg-bg-abyss` - und keinerlei
   Bedienelemente.

   Warum `vmin` und nicht die `--tg-fs-*`-Tokens: die hoeren bei 4 rem auf
   (docs/DESIGN.md, §5). Auf 1920x1080 aus fuenf Metern ist das eine
   Fussnote. Die Tokens bleiben trotzdem die Quelle fuer ALLES andere -
   Farben, Abstaende, Radien, Schatten, Dauern.
   ========================================================================== */

.tv {
  /* Der aeusserste Rand der Nacht-Palette. Der Aurora-Verlauf aus base.css
     bleibt darueber liegen - er gibt der Flaeche Tiefe, ohne Kontrast zu
     kosten. */
  background-color: var(--tg-bg-abyss);
  /* Ein Beamerbild scrollt nicht. Was nicht passt, wird kleiner. */
  overflow: hidden;
  height: 100dvh;
}

.tv-buehne {
  display: flex;
  flex-direction: column;
  gap: clamp(var(--tg-space-4), 2vmin, var(--tg-space-6));
  height: 100dvh;
  min-width: 0;
  padding: clamp(var(--tg-space-5), 3vmin, var(--tg-space-8));
}

/* ------------------------------------------------------------------- Kopf */

.tv-kopf {
  display: flex;
  align-items: center;
  gap: clamp(var(--tg-space-3), 1.5vmin, var(--tg-space-5));
  flex: none;
  min-width: 0;
}

.tv-kopf > * {
  min-width: 0;
}

.tv-kopf__feier {
  font-size: clamp(1.25rem, 2vmin, 2.25rem);
  font-weight: var(--tg-fw-bold);
  letter-spacing: var(--tg-tracking-tight);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* `white-space: nowrap` OHNE `overflow: hidden` war der einzige Grund fuer den
   waagerechten Overflow der Leinwand bei 320/390 px (gemessen: Seitenbreite
   368 statt 320, obwohl kein Element sichtbar ueber den Rand ragte - der
   nicht umbrechende Phasenname schob die Layout-Breite). Der Beamer laeuft im
   Querformat, aber der Probelauf am Handy soll die Seite nicht verziehen. */
.tv-kopf__phase {
  margin-inline-start: auto;
  color: var(--tg-accent-3);
  font-size: clamp(1rem, 1.7vmin, 1.9rem);
  font-weight: var(--tg-fw-medium);
  letter-spacing: var(--tg-tracking-wide);
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Das Emblem kommt aus shared/base.css. Auf der Leinwand waechst es nur
   mit - Farbe, Takt und Aufbau bleiben dieselben wie ueberall. */
.tv .tg-mark {
  --tg-mark-h: clamp(1.5rem, 2.6vmin, 3rem);
  --tg-mark-w: max(3px, 0.55vmin);
  gap: 0.35vmin;
}

/* -------------------------------------------------------------- Großmeldung */

.tv-meldung {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--tg-space-4);
  min-height: 0;
  text-align: center;
  animation: tg-fade-in var(--tg-dur-slow) var(--tg-ease-out) both;
}

.tv-meldung[hidden] {
  display: none;
}

/* KEIN VERLAUFSTEXT. Die Grossmeldung ist die eine Zeile, die aus zehn
   Metern treffen muss - "Diese Feier gibt es nicht", "Danke fürs Feiern".
   Ein Verlauf senkt am hellen Ende den Kontrast gegen den dunklen Grund,
   und genau dort steht oft das entscheidende Wort. Volltonfarbe. */
.tv-meldung__zeile {
  color: var(--tg-text);
  font-size: clamp(2.5rem, 7vmin, 7rem);
  font-weight: var(--tg-fw-bold);
  line-height: var(--tg-lh-tight);
  letter-spacing: var(--tg-tracking-tight);
  text-wrap: balance;
}

.tv-meldung__text {
  max-width: 40ch;
  color: var(--tg-text-muted);
  font-size: clamp(1.1rem, 2.4vmin, 2.25rem);
  line-height: var(--tg-lh-snug);
}

/* ----------------------------------------------------------------- Raster
   Links die Musik, rechts der Weg hinein, unten die Widmungen. */

.tv-raster {
  display: grid;
  flex: 1 1 auto;
  gap: clamp(var(--tg-space-4), 2.5vmin, var(--tg-space-7));
  /* S5: Die Saeule bemisst sich jetzt an der BILDBREITE (vw), nicht an der
     kleineren Kante (vmin). Auf einem 16:9-Beamer ist die Hoehe die knappe
     Groesse - der QR-Code aber konkurriert um Breite. Vorher blieb er bei
     1080p auf 173 px = 9 % der Bildbreite haengen; auf einem 2-m-Bild sind
     das rund 18 cm, scannbar aus etwa 1,8 m. Die Gaeste stehen 3-6 m weg. */
  grid-template-columns: minmax(0, 1fr) clamp(17rem, 26vw, 34rem);
  /* "Laeuft gerade" nimmt, was es braucht; die Liste bekommt den Rest und
     schneidet ab, statt in die Widmung zu laufen; die Widmung sitzt unten.
     Mit drei `fr`-Zeilen ueberlappten die Bloecke, sobald ein Titel zweizeilig
     wurde - auf einer Leinwand ist das nicht "etwas eng", sondern unlesbar. */
  grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-areas:
    'jetzt     mitmachen'
    'naechste  mitmachen'
    'widmung   widmung';
  min-height: 0;
  min-width: 0;
}

.tv-raster[hidden] {
  display: none;
}

.tv-raster > * {
  min-width: 0;
  min-height: 0;
}

/* Hochkant: kein Beamer, sondern der Probelauf am Handy. Hier wird gestapelt
   UND gescrollt - vier Bloecke untereinander passen in kein Hochformat, und
   ein Raster, das sie hineinzwingt, schiebt sie uebereinander. Die Regel
   "ein Beamerbild scrollt nicht" gilt fuer das Querformat, in dem er haengt. */
@media (max-aspect-ratio: 1/1) {
  .tv {
    height: auto;
    overflow: visible;
  }

  .tv-buehne {
    height: auto;
    min-height: 100dvh;
  }

  .tv-raster {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto auto;
    grid-template-areas:
      'jetzt'
      'mitmachen'
      'naechste'
      'widmung';
  }

  .tv-naechste {
    overflow: visible;
  }

  .tv-mitmachen {
    align-self: stretch;
  }
}

/* S6: TOTER RAUM BEI GENAU DER ZIELAUFLOESUNG.
   Bei 1920x1080 stand ein leerer Streifen von rund 1600x215 px zwischen der
   QR-Karte und dem Widmungsband, waehrend die Nächstes-Titel bei 24 px
   klemmten. Ursache: `.tv-mitmachen` war `align-self: center` (die Karte
   schrumpfte auf ihren Inhalt und liess den Rest der zwei Zeilen leer), und
   die Nächstes-Liste stapelte oben, statt ihre Zeile auszufuellen.

   Zwei Aenderungen, keine Sonderregel je Aufloesung:
     - die QR-Saeule fuellt ihre beiden Zeilen aus (`stretch`) und zentriert
       ihren Inhalt darin selbst - sie tut das schon, siehe `justify-content`;
     - die Nächstes-Liste verteilt ihre Zeilen ueber die verfuegbare Hoehe.
   Damit waechst die Schrift nicht, aber der Raum wird benutzt - und die
   Komposition sitzt bei 1280x720 genauso wie bei 1920x1080. */
.tv-mitmachen {
  align-self: stretch;
}

.tv-naechste__liste {
  /* Die Liste fuellt ihre Rasterzeile aus. BEWUSST OHNE `space-evenly`:
     gemessen fuellten vier Zeilen die Zeile auf 1920x1080 bereits exakt aus -
     es gab keinen freien Platz zu verteilen, wohl aber Rundungsfehler, und die
     kosteten eine ganze Zeile. Der tote Streifen aus S6 kam ohnehin nicht von
     hier, sondern von der QR-Saeule, die auf Inhaltshoehe schrumpfte
     (`align-self` weiter oben).

     `overflow: hidden` ist nur das Netz; wer entscheidet, wie viele Zeilen
     passen, ist `beschneideNaechste()` in tv.js - eine halbe Karte ist auf
     einer Leinwand kein "etwas eng", sondern sieht aus wie ein Defekt. */
  flex: 1 1 auto;
  justify-content: flex-start;
  overflow: hidden;
}

/* Kleine Beschriftung ueber jedem Block. Die einzige Stelle mit
   Versalien - sie ordnet, ohne zu konkurrieren. */
/* S5: Die Untergrenze lag bei 0,85 rem - gemessen 15 px auf 1080p. Aus drei
   bis sechs Metern ist das keine Beschriftung mehr, sondern ein Strich.
   Untergrenze und Steigung angehoben; `--tg-text-faint` wird ausserdem zu
   `--tg-text-muted`, weil die Marke jetzt gelesen werden soll. */
.tv-rubrik {
  margin-bottom: clamp(var(--tg-space-2), 1vmin, var(--tg-space-4));
  color: var(--tg-text-muted);
  font-size: clamp(1.15rem, 1.9vmin, 2rem);
  font-weight: var(--tg-fw-medium);
  letter-spacing: var(--tg-tracking-wide);
  text-transform: uppercase;
}

/* -------------------------------------------------------------- Läuft gerade */

.tv-jetzt {
  grid-area: jetzt;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}

.tv-jetzt__titel {
  font-size: clamp(2.25rem, 6.4vmin, 6.5rem);
  font-weight: var(--tg-fw-bold);
  line-height: var(--tg-lh-tight);
  letter-spacing: var(--tg-tracking-tight);
  overflow-wrap: anywhere;
  text-wrap: balance;
  animation: tv-einblenden var(--tg-dur-slow) var(--tg-ease-out) both;
}

.tv-jetzt__kuenstler {
  margin-top: clamp(var(--tg-space-1), 0.8vmin, var(--tg-space-3));
  color: var(--tg-accent-strong);
  font-size: clamp(1.35rem, 3.4vmin, 3.5rem);
  font-weight: var(--tg-fw-medium);
  line-height: var(--tg-lh-snug);
  overflow-wrap: anywhere;
  animation: tv-einblenden var(--tg-dur-slow) var(--tg-ease-out) both;
  animation-delay: var(--tg-dur-fast);
}

@keyframes tv-einblenden {
  from {
    opacity: 0;
    transform: translateY(0.5em);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.tv-balken {
  height: clamp(0.5rem, 1vmin, 1rem);
  margin-top: clamp(var(--tg-space-4), 2vmin, var(--tg-space-6));
  overflow: hidden;
  border-radius: var(--tg-radius-pill);
  background: var(--tg-bg-sunken);
  box-shadow: var(--tg-shadow-inset);
}

/* Der Balken waechst ueber `transform: scaleX()`, nicht ueber `width`.
   Auf dem Beamer laeuft er die ganze Nacht sekuendlich weiter; ueber `width`
   waere das jede Sekunde ein neues Layout auf dem meist schwaechsten Rechner
   im Haus. `transform` bleibt im Compositor. */
.tv-balken__fuellung {
  display: block;
  width: 100%;
  height: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  border-radius: var(--tg-radius-pill);
  background: var(--tg-grad-brand);
  box-shadow: var(--tg-glow-live);
  transition: transform var(--tg-dur-slower) linear;
}

.tv-balken[hidden] {
  display: none;
}

/* Ueberzogen: der Balken ist voll, aber er misst nichts mehr. Die Farbe
   wechselt zur Warnung - der TEXT daneben sagt es ohnehin. */
.tv-balken[data-ueber='ja'] .tv-balken__fuellung {
  background: var(--tg-warn, var(--tg-accent-3));
  box-shadow: none;
}

/* Die enge Live-Region um Titel, Künstler und Lage. */
.tv-jetzt__ansage {
  min-width: 0;
}

/* "läuft länger als geplant" / "gerade Pause". Aus fuenf Metern lesbar -
   dieser Satz erklaert, warum der Titel oben stehen bleibt. */
/* S11: DIESER ZUSTAND WAR AUF DISTANZ NUR FARBE.

   "laeuft laenger als geplant" stand in 21,6 px grauem Text neben einem
   amberfarbenen Balken. Auf die Betrachtungsdistanz einer Leinwand (25 %
   Skalierung ~ vierfache Entfernung) sind das 5,4 px - unlesbar. Uebrig blieb
   die Farbe des Balkens, und genau das verbietet docs/DESIGN.md 1.5.

   Jetzt: Amber wie im Regiepult und auf jeder anderen Flaeche, eigene
   Flaeche, und dieselbe Groessenordnung wie der Gäste-Code darunter
   (gemessen 34,5 px), der aus derselben Entfernung abgelesen wird. */
.tv-jetzt__lage {
  /* Eine Marke, kein Balken: sie ist so breit wie ihr Text. Ueber die ganze
     Bildbreite gezogen laese sie sich als zweiter Fortschrittsbalken. */
  width: fit-content;
  align-self: flex-start;
  margin-top: clamp(var(--tg-space-2), 1vmin, var(--tg-space-4));
  padding: clamp(var(--tg-space-1), 0.8vmin, var(--tg-space-3))
    clamp(var(--tg-space-3), 1.6vmin, var(--tg-space-5));
  border-radius: var(--tg-radius-pill);
  background: var(--tg-warn-soft);
  color: var(--tg-warn);
  font-size: clamp(1.4rem, 3.2vmin, 3.2rem);
  font-weight: var(--tg-fw-bold);
  line-height: var(--tg-lh-tight);
}

.tv-jetzt__lage[hidden] {
  display: none;
}

/* ------------------------------------------------------------- Kommt danach */

.tv-naechste {
  grid-area: naechste;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  /* Lieber einen Titel weniger zeigen als in den Block darunter laufen. */
  overflow: hidden;
}

.tv-naechste__liste {
  display: flex;
  flex-direction: column;
  gap: clamp(var(--tg-space-2), 1.2vmin, var(--tg-space-4));
  margin: 0;
  padding: 0;
  list-style: none;
  min-height: 0;
}

.tv-naechst {
  display: flex;
  align-items: baseline;
  gap: clamp(var(--tg-space-3), 1.6vmin, var(--tg-space-5));
  padding: clamp(var(--tg-space-2), 1vmin, var(--tg-space-4))
    clamp(var(--tg-space-3), 1.4vmin, var(--tg-space-5));
  border: 1px solid var(--tg-line);
  border-radius: var(--tg-radius-md);
  background: var(--tg-glass);
  box-shadow: var(--tg-shadow-1), var(--tg-shadow-inset);
  animation: tg-fade-in var(--tg-dur-slow) var(--tg-ease-out) both;
  animation-delay: calc(var(--tg-i, 0) * 90ms);
}

.tv-naechst > * {
  min-width: 0;
}

.tv-naechst__zeit {
  flex: none;
  color: var(--tg-accent-2);
  font-family: var(--tg-font-mono);
  font-size: clamp(1.25rem, 2.4vmin, 2.2rem);
  font-weight: var(--tg-fw-bold);
}

.tv-naechst__text {
  flex: 1 1 auto;
  overflow: hidden;
}

.tv-naechst__titel {
  display: block;
  font-size: clamp(1.5rem, 2.8vmin, 2.6rem);
  font-weight: var(--tg-fw-medium);
  line-height: var(--tg-lh-snug);
  overflow-wrap: anywhere;
}

/* S5: gemessen 17 px auf 1080p, 16,8 px auf 1280x720. Der Künstler ist die
   halbe Auskunft der Zeile - er muss aus derselben Entfernung lesbar sein
   wie der Titel darueber. */
.tv-naechst__kuenstler {
  display: block;
  color: var(--tg-text-muted);
  font-size: clamp(1.15rem, 2vmin, 2rem);
  overflow-wrap: anywhere;
}

/* S11: DAS UNTERE VIERTEL DARF NICHT LEER STEHEN.

   Gemessen bei 1920x1080 ohne geplante Titel: die Spalte "Kommt als Nächstes"
   war ein leerer Block, und der einzige Satz darin ("Gleich geht es weiter.")
   stand als 21,6-px-Zeile oben links darin - aus der Betrachtungsdistanz einer
   Leinwand nichts. Jetzt fuellt der Satz die Flaeche, die er ohnehin belegt,
   und ist so gross wie die Titel, die er vertritt. Ein bewusst leerer Bereich
   liest sich als Ruhe; ein zufaellig leerer als Defekt. */
.tv-naechste__leer {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  color: var(--tg-text-muted);
  font-size: clamp(1.2rem, 3vmin, 3rem);
  text-wrap: balance;
}

.tv-naechste__leer[hidden] {
  display: none;
}

/* Steht kein Titel in der Liste, soll der Ersatzsatz den Platz bekommen -
   sonst draengt ihn die leere, aber immer noch flexende Liste an den unteren
   Rand, und dazwischen steht das leere Viertel aus S11. */
.tv-naechste__liste:empty {
  display: none;
}

/* ----------------------------------------------------------------- QR-Code */

.tv-mitmachen {
  grid-area: mitmachen;
  /* Die Saeule reicht ueber zwei Zeilen und fuellt sie aus (siehe S6 oben);
     dass der QR-Code darin nicht "im Nichts schwimmt", besorgt
     `justify-content: center` weiter unten - der Inhalt sitzt mittig, die
     Karte selbst aber laesst keinen toten Streifen daneben stehen. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(var(--tg-space-2), 1vmin, var(--tg-space-4));
  min-width: 0;
  padding: clamp(var(--tg-space-4), 2vmin, var(--tg-space-6));
  border: 1px solid var(--tg-line);
  border-radius: var(--tg-radius-xl);
  background: var(--tg-grad-night);
  box-shadow: var(--tg-shadow-3), var(--tg-shadow-inset);
  text-align: center;
}

/* Heller Grund um den Code herum. Ein QR auf dunklem Grund ist fuer viele
   Kameras nicht invertierbar - die Norm sieht dunkel auf hell vor. Als
   "hell" dient `--tg-text` (#f3f2fb): der hellste Ton der Palette, damit
   auch hier kein Farbwert ausserhalb der Tokens steht. Dieselben zwei Toene
   bekommt qr.js fuer das SVG, sonst haette der Rahmen eine andere Farbe als
   die Ruhezone im Bild. */
/* S5: Der QR-Code ist die EINZIGE Aufgabe, die die Leinwand fuer Gaeste hat.
   Er bekommt jetzt die volle Breite seiner Saeule statt eines vmin-Deckels,
   der ihn auf 1080p bei 173 px festhielt. Rechnung fuer 1920x1080: Saeule
   26vw = 499 px, abzueglich Innenabstand bleiben rund 420 px - gut 22 % der
   Bildbreite, auf einem 2-m-Bild etwa 44 cm. Das ist aus 4-5 m scannbar.
   Bei 1280x720 sind es rund 300 px statt vorher 128. */
.tv-qr {
  width: 100%;
  max-width: clamp(13rem, 24vw, 30rem);
  padding: clamp(var(--tg-space-2), 1vmin, var(--tg-space-3));
  border-radius: var(--tg-radius-md);
  background: var(--tg-text);
  box-shadow: var(--tg-shadow-2);
}

.tv-qr svg {
  display: block;
  width: 100%;
  height: auto;
}

.tv-code {
  font-family: var(--tg-font-mono);
  font-size: clamp(1.5rem, 3.2vmin, 3.25rem);
  font-weight: var(--tg-fw-bold);
  letter-spacing: 0.12em;
  overflow-wrap: anywhere;
}

/* S5: gemessen 16 px. Das ist die Gebrauchsanweisung fuer den QR-Code -
   sie steht direkt darunter und wird aus derselben Entfernung gelesen. */
.tv-mitmachen__text {
  color: var(--tg-text-muted);
  font-size: clamp(1.1rem, 1.9vmin, 1.9rem);
  line-height: var(--tg-lh-snug);
  text-wrap: pretty;
}

/* ---------------------------------------------------------------- Widmungen */

/* S10: Innenabstand. Gemessen 17x22 px bei 1920x1080 - bei einer Schrift von
   30 px klebt der Text damit am Rahmen. Das hier ist der Satz, den ein Gast an
   die Wand schreiben laesst; er bekommt Luft. */
.tv-widmung {
  grid-area: widmung;
  min-width: 0;
  padding: clamp(var(--tg-space-4), 2.4vmin, var(--tg-space-7))
    clamp(var(--tg-space-5), 3vmin, var(--tg-space-8));
  border-left: 0.4vmin solid var(--tg-accent-4);
  border-radius: var(--tg-radius-md);
  background: var(--tg-accent-4-soft);
}

.tv-widmung[hidden] {
  display: none;
}

.tv-widmung__text {
  margin: 0;
  font-size: clamp(1.2rem, 2.8vmin, 2.9rem);
  font-weight: var(--tg-fw-medium);
  line-height: var(--tg-lh-snug);
  overflow-wrap: anywhere;
  text-wrap: pretty;
}

/* S5: gemessen 18 px. Wer gewidmet hat und wem, ist der halbe Reiz des
   Bandes - das darf keine Fussnote sein. */
.tv-widmung__von {
  margin-top: clamp(var(--tg-space-1), 0.6vmin, var(--tg-space-2));
  color: var(--tg-text-muted);
  font-size: clamp(1.2rem, 2.1vmin, 2.1rem);
  overflow-wrap: anywhere;
}

/* Der Wechsel zwischen zwei Widmungen. Ohne ihn wirkt der Sprung wie ein
   Darstellungsfehler. */
.tv-widmung--wechsel .tv-widmung__text,
.tv-widmung--wechsel .tv-widmung__von {
  animation: tv-einblenden var(--tg-dur-slow) var(--tg-ease-out) both;
}
