  /* Szene: alles in "em", 1em = 1% der Szenenbreite (bei 16:9) -> skaliert von selbst.
     Dieses File enthaelt Geometrie + Funktion (Screen, Figuren, Bedienknoepfe). Das Aussehen der Karte (Himmel, Skyline, Terrasse, Pflanzen, Licht,
     Ambient-Animationen) steht in css/map.css + css/map-art.css (BarselVibe Default Map V1 "Rooftop After Dark"). */
  .scene { flex: 1; min-height: 0; position: relative; container-type: size; overflow: hidden; }
  .backdrop { position: absolute; inset: 0; font-size: min(1cqw, 1.7778cqh); }
  #stars { position: absolute; top: 0; left: 0; width: 1px; height: 1px; }

  /* "Welt" = feste 16:9-Buehne, mittig unten */
  .world { position: absolute; left: 50%; bottom: 0; width: 100em; height: 56.25em; transform: translateX(-50%); }
  .world > * { position: absolute; }

  /* Video-Screen */
  .screen {
    left: 32.5em; top: .5em; width: 35.5em; height: 20em;
    border: .25em solid #4d3bff; background: #000; overflow: hidden;
    display: grid; place-items: center; text-align: center;
  }
  .screen iframe { width: 100%; height: 100%; border: 0; }
  /* YouTube-Vorgaben (Required Minimum Functionality, Stand 2026-09): Player-Viewport mind. 200x200 px, und nichts darf VOR dem Player liegen
     (auch nicht unsichtbar: sonst kommen Klicks nicht bei den Player-Bedienelementen an). Deshalb: ueber allen Figuren/Blasen/Emojis (z-index)
     und Figuren-Ebene ohne eigene Klickflaeche (nur die Figuren selbst sind klickbar, siehe #crowd). Details: docs/PRELAUNCH_COMPLIANCE.md */
  .screen { z-index: 40; min-width: calc(200px + .5em); min-height: calc(200px + .5em); }    /* + Rahmen (2 x .25em): der Player-Viewport selbst soll >= 200x200 sein */
  /* Schmal/Hochformat (Handy): die Buehne ist nur 16:9 hoch -> der Screen wird an den oberen Rand der Szene gesetzt (volle Breite, ueber den Himmel; die Figuren stehen unten und bleiben frei) */
  @container (max-width: 700px) or (max-aspect-ratio: 1/1) {
    .screen { left: 0; width: max(100em, calc(200px + .5em)); top: calc(56.25em - 100cqh); height: max(56.25em, calc(200px + .5em)); }
  }

  /* Publikum */
  #crowd { inset: 0; pointer-events: none; }          /* die Ebene selbst faengt keine Klicks ab (sonst liegt sie unsichtbar ueber dem YouTube-Player) */
  #crowd .av, #dj.av { pointer-events: auto; }
  /* Figuren: css/characters.css */
  /* Namensschild (Rollen-Badge + Name): bei wenigen Figuren immer, sonst nur eigene Figur / Hover. Sprechblase sitzt darueber. */
  .av .tag { position: absolute; left: 50%; bottom: 100%; transform: translateX(-50%); z-index: 20; pointer-events: none; white-space: nowrap;
             background: #0d0b20cc; color: #ece9ff; padding: .15em .6em; border-radius: 1em; font: 700 calc(max(11px, .95em) / var(--s, 1))/1.3 system-ui; opacity: 0; transition: opacity .2s; }   /* durch Figuren-Massstab geteilt: Schrift bleibt gleich gross */
  #dj .tag, .av.me .tag, .av:hover .tag { opacity: 1; }
  @container (min-width: 560px) { #crowd[data-lod=high] .av .tag { opacity: 1; } }        /* alle Namen nur bei genug Platz (nicht auf dem Handy) */
  .av.me .tag { background: #1f6b4a; color: #fff; }
  .av.me::after { content: ""; position: absolute; left: 12%; right: 12%; bottom: -.15em; height: .9em; border: .2em solid #7bd0a0; border-radius: 50%; opacity: .85; pointer-events: none; }
  .av:hover { filter: brightness(1.12); }
  .av .bub { bottom: calc(100% + 1.8em); }

  /* Reaction ueber dem Character (nicht als Ansammlung im Raum): eine je Figur, klickdurchlaessig, entfernt sich selbst (js/scene.js reactionEmoji).
     Schriftgroesse geteilt durch --s, damit sie unabhaengig vom Figuren-Massstab (DJ 1.5, Crowd .78-1.45) gleich wirkt, wie beim Namensschild. */
  .av .reactfx { position: absolute; left: 70%; bottom: calc(100% + 1.6em); transform: translateX(-50%); z-index: 25; pointer-events: none;
                 font-size: calc(1.7em / var(--s, 1)); line-height: 1; animation: reactpop 1.8s ease-out forwards; }
  @keyframes reactpop {
    0%   { opacity: 0; transform: translateX(-50%) translateY(0) scale(.4); }
    18%  { opacity: 1; transform: translateX(-50%) translateY(-.3em) scale(1.2); }
    30%  { transform: translateX(-50%) translateY(-.5em) scale(1); }
    72%  { opacity: 1; transform: translateX(-50%) translateY(-1.7em) scale(1); }
    100% { opacity: 0; transform: translateX(-50%) translateY(-2.6em) scale(.85); }
  }
  @media (prefers-reduced-motion: reduce) { .av .reactfx { animation: none; } }   /* zeigt sich kurz statisch (wie .float); JS entfernt sie trotzdem nach 2,2 s */

  /* Leben in der Szene: ruhig im Leerlauf, wilder sobald ein Song laeuft (Figuren: characters.css; Karte: map.css) */
  .world { --beat: .55s; }                      /* Tempo der tanzenden Figuren (Sekunden pro Schlag) */
  .world.hype { --beat: .3s; }
  .float { position: absolute; font-size: 1.8em; pointer-events: none; z-index: 6; animation: floatup 1.2s ease-out forwards; }
  @keyframes floatup {
    from { opacity: 1; transform: translateY(0) scale(.8); }
    to   { opacity: 0; transform: translateY(-10em) scale(1.4); }
  }
  @media (prefers-reduced-motion: reduce) { .float { animation: none !important; } }

  /* DJ-Pult: Position/Groesse/Stapelung hier, Aussehen in map.css */
  .booth { left: 38em; bottom: 2.4em; width: 24em; height: 5em; }
  #dj { left: 46.8em; bottom: 4.2em; z-index: 2; --s: 1.5; }      /* steht HINTER dem Pult (Pult z-index 3) */
  .booth { z-index: 3; }

  /* Warteliste + Votes: Position/Groesse/Funktion (Aussehen der Huelle: map.css) */
  .queue {
    left: 21em; bottom: 2.8em; width: 18em; height: 4.3em; display: flex; background: #2a2c36cc;
  }
  .queue span { flex: none; width: 4.3em; display: grid; place-items: center; background: #3a3d4a; font-size: 1.8em; }
  .queue button { flex: 1; background: none; font-size: .95em; padding: 0 .6em; }
  .queue button:hover { background: #ffffff14; }

  .votes { right: 20em; bottom: 2.8em; width: 18em; height: 4.3em; display: flex; }
  .vote { flex: 1; display: flex; flex-direction: column; background: #262933; font-size: 1.05em; }
  .vote.woot { flex: 1.25; background: #8fb02b; }
  .vote b { flex: 1; display: grid; place-items: center; }
  .vote em { font-style: normal; font-size: .8em; text-align: center; padding: .25em 0; background: #0004; }
  .vote.grab em { background: #a56cff; }
  .vote.meh  em { background: #c72f3c; }
  .vote.woot em { background: #6f8a1b; }
  .vote:hover { filter: brightness(1.15); }
  .vote.on { outline: .15em solid #fff; outline-offset: -.15em; }
  .vote.woot.on { background: #b3dd35; }
  .vote.grab.on { background: #a56cff; }
  .vote.meh.on  { background: #e03a4a; }
  .vote:active { transform: scale(.96); }
