<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Los Santos – Responsive & Breite Bubbles</title>
  <style>
    :root {
      --primary-color: #1784c8;
      --primary-dark: #014772;
      --night-sky: #0a0a2a;
      --night-sky-dark: #1a1a3a;
    }

    html, body {
      margin: 0;
      padding: 0;
      font-family: Arial, sans-serif;
      background: var(--night-sky);
      color: #fff;
      /* Wir wollen möglichst keine Scrollbars -> overflow hidden in .scene */
    }

    /* Die Haupt-Szene füllt den kompletten Viewport, kein Scrollen */
    .scene {
      position: relative;
      width: 100%;
      height: 100vh; /* volle Höhe */
      overflow: hidden; /* kein Scrollen mehr */
      background: linear-gradient(to bottom, var(--night-sky) 0%, var(--night-sky-dark) 100%);
    }

    /* Himmel, Sterne, Mond */
    .sky {
      position: absolute;
      width: 100%;
      height: 100%;
      z-index: 1;
    }
    .stars {
      position: absolute;
      width: 100%;
      height: 100%;
      z-index: 2;
    }
    .star {
      position: absolute;
      width: 0.3vmin;
      height: 0.3vmin;
      background: white;
      border-radius: 50%;
      animation: twinkle 1.5s infinite alternate;
    }
    @keyframes twinkle {
      0% { opacity: 0.2; }
      100% { opacity: 1; }
    }
    .shooting-star {
      position: absolute;
      width: 0.5vmin;
      height: 0.5vmin;
      background: white;
      border-radius: 50%;
      animation: shoot 1s linear forwards;
    }
    @keyframes shoot {
      0% {
        transform: translate(0, 0);
        opacity: 1;
      }
      100% {
        transform: translate(200px, 200px);
        opacity: 0;
      }
    }
    .moon {
      position: absolute;
      top: 5vmin;
      right: 5vmin;
      width: 10vmin;
      height: 10vmin;
      background: radial-gradient(circle at 30% 30%, #fff 0%, rgba(255,255,255,0.9) 50%, rgba(255,255,255,0.8) 100%);
      border-radius: 50%;
      box-shadow: 0 0 3vmin rgba(255, 255, 255, 0.5);
      z-index: 3;
      animation: moonGlow 4s infinite alternate;
      cursor: pointer;
    }
    @keyframes moonGlow {
      0% {
        box-shadow: 0 0 3vmin rgba(255,255,255,0.5);
      }
      100% {
        box-shadow: 0 0 5vmin rgba(255,255,255,0.7);
      }
    }

    /* Stadt-Hintergrund */
    .city-background {
      position: absolute;
      bottom: 10vmin;
      width: 100%;
      height: 20vmin;
      background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 200'><path d='M0,200 L0,150 L50,160 L100,140 L150,170 L200,130 L250,150 L300,120 L350,160 L400,110 L450,140 L500,100 L550,150 L600,120 L650,170 L700,130 L750,160 L800,110 L850,140 L900,120 L950,150 L1000,130 L1000,200 Z' fill='%23131C2E'/></svg>");
      background-repeat: repeat-x;
      background-size: 1000px 200px;
      opacity: 0.7;
      z-index: 4;
    }

    /* Straße / Boden */
    .ground {
      position: absolute;
      bottom: 0;
      width: 100%;
      height: 10vmin;
      background: linear-gradient(to bottom, #1a1a2a 0%, #2a2a4a 100%);
      z-index: 4;
    }

    /* Charaktere (Stick-Figuren) */
    .character {
      position: absolute;
      bottom: 10vmin;
      width: 7vmin;
      height: 11vmin;
      transition: all 0.5s ease;
      z-index: 5;
    }
    .character .character-name {
      position: absolute;
      bottom: -3vmin;
      left: 50%;
      transform: translateX(-50%);
      background: var(--primary-color);
      color: #fff;
      padding: 0.3vmin 1vmin;
      border-radius: 10px;
      font-size: 1.8vmin;
      white-space: nowrap;
      box-shadow: 0 2px 5px rgba(0,0,0,0.3);
    }
    .stick-figure svg {
      width: 100%;
      height: 100%;
    }

    /* Sprechblasen (noch breiter) */
    .dialog-bubble {
      position: absolute;
      top: -18vmin; /* höher über dem Kopf */
      left: 50%;
      transform: translateX(-50%);
      background: linear-gradient(-45deg, var(--primary-color) -50%, var(--primary-dark));
      padding: 1.2vmin 1.8vmin;
      border-radius: 1vmin;
      min-width: 15vmin;
      max-width: 60vmin; /* viel breiter */
      opacity: 0;
      transition: opacity 0.3s ease;
      z-index: 6;
      color: #fff;
      font-size: 2vmin;
      line-height: 1.4;
      white-space: pre-wrap;
    }
    .dialog-bubble::after {
      content: '';
      position: absolute;
      bottom: -1vmin;
      left: 50%;
      transform: translateX(-50%);
      border-width: 1vmin 1vmin 0;
      border-style: solid;
      border-color: var(--primary-dark) transparent;
    }

    /* Garage + Fly-away */
    .garage {
      position: absolute;
      bottom: 10vmin;
      right: 5vmin;
      width: 20vmin;
      height: 15vmin;
      background: linear-gradient(-45deg, var(--primary-color) -50%, var(--primary-dark));
      border: 2px solid rgba(255,255,255,0.1);
      transform: scale(0);
      transition: transform 0.5s ease;
      z-index: 4;
    }
    .garage.visible {
      transform: scale(1);
    }
    .construction-site {
      position: relative;
      width: 100%;
      height: 100%;
    }
    .crane {
      position: absolute;
      top: 0;
      left: 0;
      width: 6vmin;
      height: 10vmin;
      background: rgba(255,255,255,0.2);
    }
    .construction-progress {
      position: absolute;
      bottom: 0;
      right: 2vmin;
      width: 2vmin;
      height: 5vmin;
      opacity: 0;
      background: #2ecc71;
      transition: opacity 0.3s ease;
    }
    .blueprint {
      position: absolute;
      bottom: 1vmin;
      left: 7vmin;
      width: 10vmin;
      height: 8vmin;
      background: #3498db;
      opacity: 0.2;
    }
    .fly-away {
      animation: garageFlyAway 2s forwards ease-in;
    }
    @keyframes garageFlyAway {
      0% {
        transform: scale(1) translate(0,0);
        opacity: 1;
      }
      100% {
        transform: scale(0.2) translate(-80vmin, -80vmin);
        opacity: 0;
      }
    }

    /* Story-Titel */
    .scene-title {
      position: relative;
      font-size: 2.5vmin;
      font-weight: bold;
      text-align: center;
      color: #fff;
      text-shadow: 0 0 1vmin rgba(255,255,255,0.3);
      margin: 1vmin auto;
      width: 90%;
      opacity: 0;
      transition: opacity 1s ease;
      z-index: 9;
    }

    /* Animation gehender Character */
    @keyframes walking {
      0%, 100% { transform: translateY(0); }
      50% { transform: translateY(-1vmin); }
    }
    .walking {
      animation: walking 0.5s infinite;
    }

    /* Auto-Gimmick */
    .car {
      position: absolute;
      bottom: 11.5vmin;
      width: 6vmin;
      height: 3vmin;
      background: red;
      border-radius: 1vmin;
      z-index: 8;
      box-shadow: inset 0 0 0.5vmin rgba(0,0,0,0.5);
    }
    .car::before {
      content: '';
      position: absolute;
      bottom: -1vmin;
      left: 1vmin;
      width: 1vmin;
      height: 1vmin;
      background: black;
      border-radius: 50%;
    }
    .car::after {
      content: '';
      position: absolute;
      bottom: -1vmin;
      right: 1vmin;
      width: 1vmin;
      height: 1vmin;
      background: black;
      border-radius: 50%;
    }
  </style>
</head>
<body>
  <div class="scene">
    <!-- Himmel, Sterne, Mond -->
    <div class="sky">
      <div class="stars"></div>
      <div class="moon" title="Klick mich!"></div>
    </div>
    <!-- Stadt-Hintergrund und Boden -->
    <div class="city-background"></div>
    <div class="ground"></div>

    <!-- Garage (verschwindet am Ende) -->
    <div class="garage">
      <div class="construction-site">
        <div class="crane"></div>
        <div class="construction-progress"></div>
        <div class="blueprint"></div>
      </div>
    </div>

    <!-- Titel & Charakter-Container -->
    <div class="scene-title"></div>
    <div id="charactersContainer"></div>
  </div>

  <script>
    /****************************************************
     *   CHARAKTER-REGISTRY + ERSTELLUNG               *
     ****************************************************/
    const existingCharacters = {};

    /**
     * Erzeugt oder aktualisiert eine Figur an einer prozentualen Position:
     * @param {string} name - Name (unique)
     * @param {string} color - z.B. "#e67e22"
     * @param {number} xPercent - z.B. 10 => 10% von links
     */
    function getOrCreateCharacter(name, color, xPercent) {
      if (existingCharacters[name]) {
        existingCharacters[name].style.left = xPercent + '%';
        return existingCharacters[name];
      }

      const charWrapper = document.createElement('div');
      charWrapper.classList.add('character', 'stick-figure');
      charWrapper.style.left = xPercent + '%';

      const svg = document.createElement('div');
      svg.innerHTML = `
        <svg viewBox="0 0 50 80" xmlns="http://www.w3.org/2000/svg">
          <circle cx="25" cy="10" r="8" fill="${color}" />
          <line x1="25" y1="18" x2="25" y2="45" stroke="${color}" stroke-width="3" />
          <line x1="25" y1="30" x2="15" y2="40" stroke="${color}" stroke-width="3" />
          <line x1="25" y1="30" x2="35" y2="40" stroke="${color}" stroke-width="3" />
          <line x1="25" y1="45" x2="15" y2="70" stroke="${color}" stroke-width="3" />
          <line x1="25" y1="45" x2="35" y2="70" stroke="${color}" stroke-width="3" />
        </svg>
      `;
      charWrapper.appendChild(svg);

      const nameTag = document.createElement('div');
      nameTag.className = 'character-name';
      nameTag.textContent = name;
      charWrapper.appendChild(nameTag);

      document.getElementById('charactersContainer').appendChild(charWrapper);
      existingCharacters[name] = charWrapper;
      return charWrapper;
    }

    function showDialog(characterElement, text) {
      const bubble = document.createElement('div');
      bubble.className = 'dialog-bubble';
      bubble.textContent = text;
      characterElement.appendChild(bubble);
      setTimeout(() => { bubble.style.opacity = '1'; }, 50);
    }

    function hideAllDialogBubbles(characterElement) {
      const bubbles = characterElement.querySelectorAll('.dialog-bubble');
      bubbles.forEach(bubble => bubble.remove());
    }

    /****************************************************
     *   DIALOG-QUEUE (kein Durcheinander)              *
     ****************************************************/
    function playDialogQueue(queue, index = 0, onFinish) {
      if (index >= queue.length) {
        if (onFinish) onFinish();
        return;
      }
      const item = queue[index];
      let lineIndex = 0;

      function showNextLine() {
        if (lineIndex >= item.lines.length) {
          setTimeout(() => {
            hideAllDialogBubbles(item.char);
            playDialogQueue(queue, index + 1, onFinish);
          }, 500);
          return;
        }
        const line = item.lines[lineIndex];
        hideAllDialogBubbles(item.char);
        showDialog(item.char, line);
        lineIndex++;

        setTimeout(() => {
          hideAllDialogBubbles(item.char);
          showNextLine();
        }, 3000);
      }
      showNextLine();
    }

    /****************************************************
     *   SPEZIELLE VISUELLE EFFEKTE                    *
     ****************************************************/
    function createSpecialEffects() {
      // Sterne generieren
      const starsContainer = document.querySelector('.stars');
      for (let i = 0; i < 100; i++) {
        const star = document.createElement('div');
        star.className = 'star';
        star.style.top = Math.random() * 100 + '%';
        star.style.left = Math.random() * 100 + '%';
        star.style.animationDelay = (Math.random() * 5) + 's';
        starsContainer.appendChild(star);
      }

      // Sternschnuppen
      setInterval(() => {
        if (Math.random() < 0.3) {
          const star = document.createElement('div');
          star.className = 'shooting-star';
          star.style.left = `${Math.random() * 100}%`;
          star.style.top = `${Math.random() * 30}%`;
          document.querySelector('.sky').appendChild(star);
          setTimeout(() => star.remove(), 1000);
        }
      }, 3000);

      // Mond-Effekt
      setInterval(() => {
        const moon = document.querySelector('.moon');
        moon.style.boxShadow = Math.random() < 0.5
          ? '0 0 10vmin rgba(255, 255, 255, 0.8)'
          : '0 0 15vmin rgba(255, 255, 255, 0.6)';
      }, 4000);
    }

    function enableMoonEasterEgg() {
      const moon = document.querySelector('.moon');
      moon.addEventListener('click', () => {
        alert("Du hast den Mond berührt! Gibt's jetzt Mond-Kekse?");
      });
    }

    function spawnRandomCar() {
      const car = document.createElement('div');
      car.className = 'car';
      car.style.left = '-15vmin'; // Start ganz links
      const colors = ['red', 'green', 'blue', 'orange', 'purple'];
      car.style.background = colors[Math.floor(Math.random() * colors.length)];
      document.body.appendChild(car);

      let position = -15;
      const target = 150;
      const speed = 0.3 + Math.random() * 0.5; 
      const drive = setInterval(() => {
        position += speed;
        car.style.left = position + 'vmin';
        if (position > target) {
          clearInterval(drive);
          car.remove();
        }
      }, 20);
    }

    /****************************************************
     *   STORY-DATEN (Dieselbe Story mit %-Positions)   *
     ****************************************************/
    const sceneTitle = document.querySelector('.scene-title');

    const storySequences = [
      {
        title: "Willkommen in Los Santos",
        action: () => {
          // Elias bei ~10%
          const elias = getOrCreateCharacter('Elias', '#ffd700', 10);
          const queue = [
            {
              char: elias,
              lines: [
                "Puh... endlich in Los Santos gelandet! Das wird ein Abenteuer!"
              ]
            }
          ];
          playDialogQueue(queue, 0, playNextSequence);
        }
      },
      {
        title: "Ein Admin in der City",
        action: () => {
          // Elias 10%, Ryan 60%
          const elias = getOrCreateCharacter('Elias', '#ffd700', 10);
          const ryan = getOrCreateCharacter('Ryan', '#3498db', 60);
          const queue = [
            {
              char: elias,
              lines: [
                "Wow, diese Hochhäuser sind echt krass!",
                "Hey, du in Blau! Was geht hier so ab?"
              ]
            },
            {
              char: ryan,
              lines: [
                "Moin, bin Ryan, der Admin. Kümmer mich drum, wenn was explodiert oder brennt.",
                "Und ja, das passiert ständig!"
              ]
            }
          ];
          playDialogQueue(queue, 0, playNextSequence);
        }
      },
      {
        title: "Technik im Admin-Büro",
        action: () => {
          // Elias 10%, Nudy 40%, Paul 70%
          const elias = getOrCreateCharacter('Elias', '#ffd700', 10);
          const nudy = getOrCreateCharacter('Nudy', '#e74c3c', 40);
          const paul = getOrCreateCharacter('Paul', '#9b59b6', 70);
          const queue = [
            {
              char: nudy,
              lines: [
                "Heyhey, ich bin Nudy. Bei mir ist alles 'Feature', nie 'Bug'!"
              ]
            },
            {
              char: paul,
              lines: [
                "Und ich bin Paul. Ich dokumentier Nudys 'Features', falls mal wer die Wahrheit wissen will, haha!"
              ]
            }
          ];
          playDialogQueue(queue, 0, playNextSequence);
        }
      },
      {
        title: "Die never-ending Garage",
        action: () => {
          // Elias 10%, Corazon 40%, Geck 75%
          const elias = getOrCreateCharacter('Elias', '#ffd700', 10);
          const corazon = getOrCreateCharacter('Corazon', '#e67e22', 40);
          const geck = getOrCreateCharacter('Geck', '#2ecc71', 75);

          const queue = [
            {
              char: corazon,
              lines: [
                "Willkommen in meiner Werkstatt! Hier fliegt öfter mal Öl und Werkzeug durch die Gegend."
              ]
            },
            {
              char: elias,
              lines: [
                "Sieht auch noch 'n bisschen unfertig aus, oder?"
              ]
            },
            {
              char: geck,
              lines: [
                "Unfertig? Ach was, wir messen nur jeden Millimeter dreimal nach!"
              ]
            }
          ];
          playDialogQueue(queue, 0, playNextSequence);
        }
      },
      {
        title: "Ein chaotischer Held: Hannes",
        action: () => {
          // Elias 30%, Hannes 60%
          const elias = getOrCreateCharacter('Elias', '#ffd700', 30);
          const hannes = getOrCreateCharacter('Hannes', '#f1c40f', 60);
          const queue = [
            {
              char: hannes,
              lines: [
                "Hannes am Start! *verspritzt Kaffee* Oops, egal, Party on!"
              ]
            },
            {
              char: elias,
              lines: [
                "Kaffeeverschwendung?! Egal, du siehst eh nach Dauerparty aus!"
              ]
            }
          ];
          playDialogQueue(queue, 0, playNextSequence);
        }
      },
      {
        title: "Nächtliches Abenteuer",
        action: () => {
          // Elias 20%, Lilly 70%
          const elias = getOrCreateCharacter('Elias', '#ffd700', 20);
          const lilly = getOrCreateCharacter('Lilly', '#e84393', 70);
          const queue = [
            {
              char: lilly,
              lines: [
                "Hey, Fremder! Nächte in Los Santos sind legendary, pass auf!"
              ]
            },
            {
              char: elias,
              lines: [
                "Perfekt, ich mag's verrückt! Immer her mit dem Chaos!"
              ]
            }
          ];
          playDialogQueue(queue, 0, playNextSequence);
        }
      },
      {
        title: "Alles in geordneten Bahnen?",
        action: () => {
          // Elias 20%, Abdi 50%, Frank 80%
          const elias = getOrCreateCharacter('Elias', '#ffd700', 20);
          const abdi = getOrCreateCharacter('Abdi', '#00cec9', 50);
          const frank = getOrCreateCharacter('Frank', '#a8e6cf', 80);
          const queue = [
            {
              char: abdi,
              lines: [
                "Willkommen in der Verwaltung. Formulare, Formulare und nochmal Formulare!"
              ]
            },
            {
              char: frank,
              lines: [
                "Und ich sortiere sie. Manchmal finde ich sie sogar wieder! *grinst*"
              ]
            }
          ];
          playDialogQueue(queue, 0, playNextSequence);
        }
      },
      {
        // Finale: Garage verschwindet
        title: "Ein Blick über Los Santos",
        action: () => {
          // Elias 30%, Corazon 70%
          const elias = getOrCreateCharacter('Elias', '#ffd700', 30);
          const corazon = getOrCreateCharacter('Corazon', '#e67e22', 70);

          const queue = [
            {
              char: elias,
              lines: [
                "So viele Leute, so viel Chaos – I love it!",
                "Hey Corazon, was geht eigentlich mit deiner Garage? Ist die schon fertig?"
              ]
            },
            {
              char: corazon,
              lines: [
                "Garage? Welche Garage? *zündet spontan was an*",
                "Ups... war wohl der falsche Hebel, haha!"
              ]
            },
            {
              char: elias,
              lines: [
                "Ääääh, was war das grad? Sieht aus, als würd sie abheben?!"
              ]
            }
          ];

          // Garage wegfliegen lassen, dann "ENDE"
          playDialogQueue(queue, 0, () => {
            document.querySelector('.garage').classList.add('fly-away');
            setTimeout(() => {
              sceneTitle.innerHTML = "ENDE";
              sceneTitle.style.opacity = '1';
            }, 2000);
          });
        }
      }
    ];

    let currentSequenceIndex = 0;
    function playNextSequence() {
      if (currentSequenceIndex >= storySequences.length) return;
      const seq = storySequences[currentSequenceIndex++];
      sceneTitle.innerHTML = seq.title;
      sceneTitle.style.opacity = '1';
      seq.action();
    }

    document.addEventListener('DOMContentLoaded', () => {
      createSpecialEffects();
      enableMoonEasterEgg();

      // Garage nach 1s sichtbar machen
      setTimeout(() => {
        document.querySelector('.garage').classList.add('visible');
      }, 1000);

      // Ab und zu ein Auto spawnen
      setInterval(() => {
        if (Math.random() < 0.4) {
          spawnRandomCar();
        }
      }, 12000 + Math.random() * 8000);

      // Story starten
      playNextSequence();
    });
  </script>
</body>
</html>
