-- ══════════════════════════════════════════════════════════════
-- MODULE: WhatsNew — Timeline-Style Changelog Popup
-- Zeigt Versionshistorie als vertikale Timeline an.
-- Automatisches Popup bei neuem Versionsupdate.
-- ══════════════════════════════════════════════════════════════

local addonName, addon = ...
local GDL = _G["GuildDeathLog"]

local WhatsNew = {}

-- ── DISCORD ──────────────────────────────────────────────────
local DISCORD_INVITE = "yHA6SKZPEv"
local DISCORD_URL    = "discord.gg/" .. DISCORD_INVITE

-- ── FARBEN ───────────────────────────────────────────────────
local C_GOLD       = {0.96, 0.83, 0.36}
local C_TITLE      = {1.00, 0.84, 0.00}
local C_TEXT       = {0.85, 0.78, 0.65}
local C_DIM        = {0.55, 0.48, 0.38}
local C_HIGHLIGHT  = {1.00, 0.92, 0.60}
local C_GREEN      = {0.40, 0.90, 0.40}
local C_RED        = {0.90, 0.30, 0.30}
local C_BLUE       = {0.40, 0.70, 1.00}
local C_PURPLE     = {0.70, 0.50, 0.90}
local C_LINE       = {0.45, 0.35, 0.20, 0.7}
local C_NODE_MAJOR = {1.00, 0.78, 0.20}
local C_NODE_MINOR = {0.65, 0.55, 0.35}
-- Wurden in TIMELINE referenziert, existierten aber nie -> Eintraege fielen
-- still auf C_NODE_MINOR (grau) zurueck.
local C_FEATURE    = C_GOLD
local C_IMPROVE    = C_BLUE

-- ── TIMELINE DATA ────────────────────────────────────────────
-- Nur die wichtigsten Meilensteine — kein Vollstaendiges Changelog.
-- tag: "major" | "feature" | "fix" | "current"
local TIMELINE = {
    {
        version = "4.5 – 4.9",
        title   = "Die Grundsteine",
        tag     = "major",
        color   = C_DIM,
        items   = {
            "Erste Todes-Erkennung & Popup",
            "Talent-Spec Tracking",
            "Grundlegendes Gilden-Tracking",
        },
    },
    {
        version = "5.4",
        title   = "Episches Todes-Popup",
        tag     = "feature",
        color   = C_PURPLE,
        items   = {
            "Cinematic Death Overlay eingefuehrt",
            "Geisterhafter Sound-Effekt",
            "Performance-Optimierungen",
        },
    },
    {
        version = "5.9",
        title   = "Lokalisierung & Stabilität",
        tag     = "fix",
        color   = C_DIM,
        items   = {
            "Russische Lokalisierung",
            "Persistente Blacklist",
            "Multi-Client Fix",
        },
    },
    {
        version = "6.3 – 6.5",
        title   = "Das Grosse Buch-Update",
        tag     = "major",
        color   = C_BLUE,
        items   = {
            "Buch-UI eingefuehrt (erstes Design)",
            "Gilden-Sync & Member-Tracking",
            "Berufe-Erkennung & Statistiken",
        },
    },
    {
        version = "7.0",
        title   = "Immersions-Update",
        tag     = "major",
        color   = C_GOLD,
        items   = {
            "Supporter+ Integration",
            "Epische Meilensteine & Titel-System",
            "Verbesserte Toderkennung",
        },
    },
    {
        version = "7.12",
        title   = "Narcissus-Redesign",
        tag     = "major",
        color   = C_GOLD,
        items   = {
            "Komplettes Buch-Redesign (Narcissus/DialogueUI-Stil)",
            "Chronik der Gefallenen: Immersiv-Redesign",
            "Charakter-Isolation fuer Achievements",
        },
    },
    {
        version = "7.15 – 7.16",
        title   = "Live Map & Premium UI",
        tag     = "feature",
        color   = C_GREEN,
        items   = {
            "Live Map Tracking auf der Weltkarte",
            "Kalender Delete-Push Sync",
            "UI Premium Refresh (Lesbarkeit & Meilensteine)",
        },
    },
    {
        version = "8.0",
        title   = "Cinematic Animation Overhaul",
        tag     = "major",
        color   = C_GOLD,
        items   = {
            "\"Absolute Bombe\" — komplett neue Animationen",
            "Das Lebendige Grimoire (v8.3)",
            "Custom Death Popup Artwork (v8.7)",
        },
    },
    {
        version = "8.10 – 8.11",
        title   = "Death Popup Perfektioniert",
        tag     = "feature",
        color   = C_GREEN,
        items   = {
            "Vertikale Karte (Forschungs-basiert)",
            "Guild Leave ≠ Tod Fix (kritisch!)",
            "Icon-Rahmen & Lesbarkeits-Feinschliff",
        },
    },
    {
        version = "8.12",
        title   = "Abenteurer der Gilde",
        tag     = "feature",
        color   = C_BLUE,
        items   = {
            "GRM-Style Member Profiles",
            "C_Club Communities API Integration",
            "Rasse, Geschlecht, Berufe pro Mitglied",
        },
    },
    {
        version = "8.14",
        title   = "Kondolenzenbuch Live-Sync",
        tag     = "feature",
        color   = C_GREEN,
        items   = {
            "Kondolenzen per Guild-Sync verteilt",
            "Schwarzes Brett Sync",
            "Chronik & Gedenkhalle zusammengefuehrt",
        },
    },
    {
        version = "9.0",
        title   = "Architektur-Refactor",
        tag     = "major",
        color   = C_GOLD,
        items   = {
            "Modular Immersive Context UI Framework",
            "Config.lua, AnimationHelper, SlashCommands ausgelagert",
            "Core von 930 auf 531 Zeilen reduziert (-43%)",
        },
    },
    {
        version = "9.1",
        title   = "UI-Split: Das Monster zerlegt",
        tag     = "major",
        color   = C_GOLD,
        items   = {
            "UI.lua (7292 Zeilen) in 5 Module aufgeteilt",
            "addon._UI Bridge-Pattern",
            "Keine externen Breaking Changes",
        },
    },
    {
        version = "9.2",
        title   = "What's New Timeline",
        tag     = "feature",
        color   = C_FEATURE,
        items   = {
            "Dieses Fenster! Timeline-Changelog",
            "Automatisches Popup bei Updates",
            "Offizieller Discord: " .. DISCORD_URL,
        },
    },
    {
        version = "9.3",
        title   = "Fake 3D: Das Buch lebt",
        color   = C_FEATURE,
        items   = {
            "Parallax-Effekt: Staubmoten folgen der Maus",
            "Tiefer Buchfalz-Schatten (Multi-Layer)",
            "Lichtreflex auf rechter Buchseite",
            "Gedenkhalle: Datum nicht mehr abgeschnitten",
            "Statistiken: Zonen-Layout korrigiert",
            "Kill-Stats: Umgebungsschaden aufgewertet",
            "Kondolenzbuch: Alternating Rows",
        },
    },
    {
        version = "9.4 – 9.5",
        title   = "DeathNotificationLib & UI-Polish",
        color   = C_IMPROVE,
        items   = {
            "DeathNotificationLib (DNL) Integration",
            "Survival-Streak System",
            "Todes-Heatmap auf Weltkarte",
            "3D Killer-Portrait im Overlay",
            "UI Lesbarkeit & Kontrast verbessert",
        },
    },
    {
        version = "9.6",
        title   = "Gilden-Wettbewerb & Leaderboard",
        tag     = "minor",
        items   = {
            "Neues Punktesystem: Kills = Punkte (1-50 pro Gegner)",
            "Cross-Guild Leaderboard via Addon-Sync",
            "7 Gegnerkategorien (Normal bis Weltboss)",
            "Gildenmitglied-Tod = -500 Strafpunkte",
            "Buch-Kapitel: Kill-Statistiken → Gilden-Wettbewerb",
            "Spieler-Rangliste mit persoenlicher Jagdstatistik",
        },
    },    {
        version = "9.7",
        title   = "Kalender-Toast Redesign & RSVP",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Kalender-Toast: Pergament-Design passend zum Buch",
            "RSVP direkt im Toast: Ja / Vielleicht / Nein",
            "RSVP wird sofort per Gilde synchronisiert",
            "Toast-Groesse passt sich dynamisch an (mit/ohne RSVP)",
            "Trennlinie und saubere Typografie im Toast",
        },
    },    {
        version = "9.7.4",
        title   = "Stabilitaet & Code-Audit",
        tag     = "fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Nameplate-Titel-Hook gegen Fehler-Spam gehaertet (pcall-gekapselt)",
            "Doppelte Tod-Verarbeitung behoben: Live-Feed nur noch via DNLBridge",
            "Achievement-Helfer Forward-Deklaration (3 Gilden-Erfolge triggerten nie)",
            "UTF-8 BOM aus 3 Modulen entfernt",
            "5 tote Patch-/Scratch-Dateien aus dem Paket entfernt",
        },
    },    {
        version = "9.7.5",
        title   = "Lesbarkeit & Buch-Kontrast",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Navigations-Ueberschriften: kraeftiges Sepia statt blasser Buntfarben",
            "Kleiner Akzent-Balken pro Kategorie behaelt die Struktur",
            "Seitentitel dunkler + staerkerer Schatten = besser lesbar",
            "Ruhmeshallen-Banner & Texte entblasst (kein Off-Theme-Gruen mehr)",
            "Schrift der Kapitel-Gruppen leicht groesser (8 -> 9)",
        },
    },    {
        version = "9.7.6",
        title   = "Buch-Politur: Reiter & saubere Kanten",
        tag     = "fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Werkzeug-Icons unten rechts: ausklappbarer Reiter statt dunklem Balken",
            "Dunkle 'Striche' an den Buchecken entschaerft (warme Risskante)",
            "Buch-Hintergrund auf saubere Power-of-Two-Textur (weniger VRAM)",
            "Versions-Anzeige liest jetzt aus der TOC -> Debug zeigt korrekte Version",
        },
    },    {
        version = "9.7.7",
        title   = "Saubere Kanten & ruhiges Buch",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Flackernde Partikel & Parallax-Glanz am Buchrand entfernt",
            "Buchfalz-Schatten sauber auf die Seitenflaeche begrenzt (keine Streifen)",
            "Leader-Striche zwischen den Kapiteln raus -> ruhigere Liste",
            "Roemische Zahlen links deutlich besser lesbar",
            "Werkzeug-Icons ohne schwarzen Rand, Reiter standardmaessig eingeklappt",
            "Zwei Dauer-Ticker eliminiert (ruhiger + weniger Last)",
        },
    },    {
        version = "9.7.8",
        title   = "Aufgeraeumtes Inhaltsverzeichnis",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Kapitel-Kategorien jetzt ein-/ausklappbar (Klick auf die Gruppe)",
            "Aktive Gruppe ist offen, der Rest zu -> kein gequetschtes Listen-Gefuehl",
            "Plus/Minus-Knopf zeigt den Zustand, Auswahl wird gemerkt",
            "Aus 21 Zeilen werden ~9 - viel Luft statt randvoll",
        },
    },    {
        version = "9.7.9",
        title   = "Inhaltsverzeichnis: Klapp-Fix",
        tag     = "fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Aktive Gruppe laesst sich jetzt auch wieder zuklappen (Toggle-Bug weg)",
            "Liste beginnt tiefer - klarer Abstand zum Buchtitel",
            "Standardmaessig nur die aktive Gruppe offen",
        },
    },    {
        version = "9.8.0",
        title   = "Serverweite Praesenz (BETA)",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Neu: serverweite Zaehlung der Addon-Nutzer (Heartbeat ueber versteckten Channel)",
            "Debug zeigt: serverweit online + davon in deiner Gilde",
            "Verpasste eigene Gildentode werden jetzt periodisch aus den Deathlog/DNL-Daten nachgezogen",
            "Backfill bleibt strikt auf die eigene Gilde gefiltert",
            "Hinweis: die Netz-Funktion ist BETA und braucht einen Ingame-Test",
        },
    },    {
        version = "9.8.1",
        title   = "TBC 2.5.5 Kompatibilitaet",
        tag     = "fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Expansion-Erkennung in Milestones/Achievements repariert (war auf TBC blind)",
            "TBC: Level-70-Cap, TBC-Milestones & korrekte Texte (kein 'Level 60 UNSTERBLICH' mehr)",
            "GuildRoster gegen Nil-Fehler auf TBC abgesichert",
            "HC-Channel bleibt korrekt auf Classic Era beschraenkt",
        },
    },    {
        version = "9.8.2",
        title   = "Neuer Name: Guild Chronicle",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Das Addon heisst ab jetzt 'Guild Chronicle'",
            "Neue Slash-Befehle: /chronicle und /gc (/gdl funktioniert weiter)",
            "Ordner & gespeicherte Daten bleiben kompatibel - nichts geht verloren",
        },
    },    {
        version = "9.8.3",
        title   = "Buch aufgeraeumt: weg mit den Kaesten",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Harte Eck-Rechtecke entfernt (die komischen Kaestchen oben)",
            "Gold-Quadrate an den Ornament-Linien raus",
            "Sauberere, ruhigere Buch-Optik - Textur bleibt erhalten",
        },
    },    {
        version = "9.8.4",
        title   = "Meilenstein-Popups: Fix + huebscher",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Streak-Toasts poppen nur noch EINMAL (nicht mehr bei jedem Login)",
            "Popup im warmen Pergament-Look statt schwarzem Balken",
            "Grelle Kategoriefarben gedaempft, passend zum Buch",
        },
    },    {
        version = "9.8.5",
        title   = "Popup jetzt echt im Pergament-Look",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Meilenstein-Popup mit echtem Pergament-Hintergrund + dunkler Schrift",
            "Dedup-Guard direkt am Toast: jeder Meilenstein nur EINMAL pro Char",
            "Falls weiterhin alt: bitte AddOn-Ordner ersetzen + /reload",
        },
    },    {
        version = "9.8.6",
        title   = "Performance-Grossputz unter der Haube",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Frame-Pooling fuer ALLE Effekte: kein Frame-Leak mehr pro Popup/Buch",
            "Todespopup-Textur: 24 MB -> 4 MB VRAM, 7 MB tote Texturen entfernt",
            "Mob-Kill-Zaehler im Abschiedsjournal zaehlt jetzt wirklich",
            "Dauerhafte OnUpdate-Poller durch echte Timer ersetzt",
        },
    },    {
        version = "9.8.7",
        title   = "Buchsatz-Ueberarbeitung: Eine Tinte, ein Buch",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Ueber 30 Streu-Brauntoene auf eine 7-stufige Tinten-Palette vereinheitlicht",
            "Klarere Hierarchie: dunkle Tinte fuer Titel, Gold fuer Akzente & Nummern",
            "Blaue/lila/neongruene Fremdfarben aus dem Pergament entfernt",
            "Scrollbalken, Banner & Listenzeilen in warme Buch-Optik gebracht",
        },
    },    {
        version = "9.8.8",
        title   = "Inhaltsverzeichnis neu gesetzt + Fehlerjagd",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Neue Gliederung: 4 Kategorien statt 5, beide Karten vereint",
            "Gold-Chevrons statt gruener +/- Buttons, Kapitelzahl am Rand",
            "Seitenzahl (Folio) am Blattrand, wechselnde Zitate im Fussbereich",
            "5 versteckte Fehler gefunden & behoben (u.a. Crash-Pfade)",
        },
    },    {
        version = "9.8.9",
        title   = "Gilden-Wettbewerb: Sync-Fix + Redesign",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Kill-Explosion behoben: Eigen-Echo liess Zaehler exponentiell wachsen",
            "Punkte der Gildenkollegen ueberleben jetzt den Relog (vorher 0)",
            "Kapitel neu gesetzt: Medaillen-Raenge, Gold-Fortschrittslinien",
            "Vergiftete Altdaten heilen sich beim naechsten Login selbst",
        },
    },    {
        version = "9.9.0",
        title   = "Sync-Hygiene: Praesenz, Pings & Broadcasts",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "ServerNet-Praesenz laeuft jetzt auch ueber GUILD (Channel-Limit-sicher)",
            "PING-Salven bei Roster-Updates debounced (3x-PONG-Spam weg)",
            "Berufe-Broadcasts gebuendelt: kein Dauerfeuer mehr beim Farmen",
            "Debug-Fenster: Memory-Anzeige repariert, Zaehlungen klar beschriftet",
        },
    },    {
        version = "9.9.1",
        title   = "Das neue Buch: episches Artwork",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Fotorealistisches Buch: Leder, zerrissener Falz, verbrannte Raender",
            "Allianz/Horde-Wasserzeichen & Blutspritzer im Pergament",
            "Seiten in die hellen Kernzonen gerueckt, Textzonen aufgehellt",
            "Inhaltsverzeichnis als Akkordeon: eine Sektion offen, wie ein Register",
        },
    },    {
        version = "9.9.2",
        title   = "Ledergebundenes Tagebuch & Quest-Log-Schrift",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Neues Buch: helles Pergament im Ledereinband, kaum Verzerrung",
            "Seiten nutzen jetzt fast die volle Buchflaeche (448px hoch)",
            "Verzeichnis entlang der linken Seite, Schrift auf 11px angehoben",
            "Quest-Log-Typografie: MORPHEUS-Titel, klare FRIZQT-Eintraege",
        },
    },    {
        version = "9.9.3",
        title   = "Verzeichnis: immer offenes Register",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Kein Akkordeon mehr: alle 16 Kapitel dauerhaft sichtbar",
            "Kategorien als schlanke Trennzeilen mit Gold-Linie",
            "Passt komplett auf die linke Seite, nichts klappt oder springt",
        },
    },    {
        version = "9.9.4",
        title   = "Death-Banner, Gilden-Pushes & Trauer-Text",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Episches GuildChronicle-Banner als Todes-Benachrichtigung",
            "Meilensteine & Titelwechsel als Einzeiler im Gildenchat",
            "Persoenliche Trauer-Nachricht: /gdl trauer <Text mit {name}>",
            "DeathBell-Crash gefixt, Online-Liste ueberlappt nicht mehr",
        },
    },    {
        version = "9.9.5",
        title   = "FPS-Rettung: Buch laeuft wieder fluessig",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Kapitel-Renderer recyceln Widgets statt endlos neue zu bauen",
            "Glut-Ambience auf 30 Hz gedrosselt, Anker-Verschwendung beseitigt",
            "GPU-fressender Atem-Glow hinter dem Buch entfernt",
            "Memory-Anzeige im Debug-Fenster zappelt nicht mehr",
        },
    },    {
        version = "9.9.6",
        title   = "Todes-Popup: GuildChronicle-Banner",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Das grosse Todes-Popup traegt jetzt das GuildChronicle-Artwork",
            "Kompakter: 520x320 statt 660x460, Banner-Satz statt Formular",
            "Name, Zone und Uhrzeit elegant zentriert im Lederfeld",
            "Skalieren wie gehabt: Shift+Ziehen, Position per Drag",
        },
    },    {
        version = "9.9.7",
        title   = "Banner-Feinjustierung & Zaehlfix",
        tag     = "fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Text sitzt jetzt exakt im Lederfeld, nichts ragt mehr raus",
            "Eine elegante Zeile: Stufe, Klasse, Zone, Uhrzeit",
            "Schwebendes Killer-Symbol entfernt",
            "Gilden-Zaehlung: Karteileichen raus, Duplikate erkannt",
        },
    },    {
        version = "9.9.8",
        title   = "Zeichensatz-Politur",
        tag     = "fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Kapitel-Tooltip: verstuemmeltes Zeichen vor 'Level' bereinigt (·)",
            "Korrupte Debug-Texte (Gedankenstriche) repariert",
            "Datei-Integritaet: Null-Byte-Padding entfernt, Code unveraendert",
        },
    },    {
        version = "9.9.9",
        title   = "Stabilitaet: Doppel-Popup, Fraktionen & FPS",
        tag     = "fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Doppeltes Todes-Popup behoben: zentrale Sperre + Namens-Normalisierung",
            "Gilden-Broadcast-Sturm gedaempft (kein N-fach-Relay fremder Tode mehr)",
            "Wettbewerb: Chars getrennt nach Fraktion+Gilde - keine Twinks der Gegenseite",
            "Grosser FPS-Fix: Kapitel werden gecacht, Wechsel baut nicht mehr alles neu",
            "Neu: /gdl status (Diagnose) und /gdl dedupe (raeumt Doppel-Eintraege)",
        },
    },    {
        version = "9.10.0",
        title   = "Teilbare Grabstein-Karte",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Neu: /gdl card [Name] - oeffnet eine Gedenk-Karte des Gefallenen",
            "Sauberer Screenshot-Knopf (Bedienelemente blenden sich kurz aus)",
            "Discord-Text-Knopf: fertig formatiert, ein Klick zum Kopieren",
            "Buch-Look: Klassen-Icon, Name in Klassenfarbe, Zone, Killer, letzte Worte",
        },
    },    {
        version = "9.11.0",
        title   = "Grabsteine auf der Karte",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Grabstein-Marker am Todesort: Weltkarte, Gebietskarten UND Minimap",
            "Marker halten 30 Tage; eigene Grabstein-Grafik mit Klassen-Aura",
            "Memorial-Fix: Gefallene werden NICHT mehr nach 30 Tagen aus dem Buch geloescht",
            "Die 30-Tage-Grenze gilt jetzt nur noch fuer die Karten-Marker",
        },
    },    {
        version = "9.11.1",
        title   = "Minimap-Button neu gestaltet",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Neues Icon: lederner Foliant statt Totenkopf (passt zum Buch der Gefallenen)",
            "Sanft atmender goldener Glow-Ring statt roter Dauer-Aura",
            "Ruhiger Look und performant (AnimationGroup statt Per-Frame-Code)",
        },
    },    {
        version = "9.12.0",
        title   = "Logbuch",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Neu: persistentes, zeitgenaues Logbuch (ueberlebt Reloads)",
            "/gdl log [n|export|clear] - Eintraege ansehen, kopieren, leeren",
            "Protokolliert was/warum/Fehler -> Probleme spaeter leicht nachvollziehbar",
            "Deutsch + Englisch (automatische Client-Erkennung)",
        },
    },    {
        version = "9.13.0",
        title   = "Gilden-Isolation + Ausdauernde gildenweit",
        tag     = "feature",
        color   = C_HIGHLIGHT,
        items   = {
            "Kalender & Schwarzes Brett: streng pro Gilde getrennt (nichts ausserhalb sichtbar)",
            "Neuer Brett-Eintrag erzeugt eine einmalige Push-Benachrichtigung",
            "Die Ausdauernden: jetzt GILDENWEIT synchronisiert (nur Mitglieder mit Addon)",
            "Unsere Kaempfer: zeigt nur noch Gildenmitglieder, die das Addon nutzen",
            "Fehlende Icons ergaenzt (Classic-sichere Pfade)",
        },
    },    {
        version = "9.13.1",
        title   = "Lokalisierung: Memorial-Karte DE/EN",
        color   = C_HIGHLIGHT,
        items   = {
            "Die teilbare Grabstein-Karte ist jetzt zweisprachig (Deutsch/Englisch)",
            "Sauber ueber das Locale-System mit automatischer Client-Erkennung",
            "Weitere Strings folgen im selben Muster",
        },
    },    {
        version = "9.13.2",
        title   = "Buch: schwarzer Rand entfernt",
        color   = C_HIGHLIGHT,
        items   = {
            "Der schwarze Rahmen um das Buch ist jetzt transparent",
            "Buch-Textur bereinigt - Falz, Schatten und Lederbund bleiben erhalten",
        },
    },    {
        version = "9.14.2",
        title   = "Neues Buch-Design",
        color   = C_HIGHLIGHT,
        items   = {
            "Neues mittelalterliches Buch: gealtertes Leder, Messing-Eckbeschlaege",
            "Ruhige, gleichmaessige Alt-Beige Seiten (nicht mehr grell)",
            "Buch standardmaessig kleiner - Feinjustage per Strg+Mausrad",
        },
    },    {
        version = "9.14.3",
        title   = "Die Ausdauernden: Sync-Fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Eigene Streak taucht jetzt zuverlaessig in der Gilden-Bestenliste auf",
            "Gilde wird nach Login korrekt nachgezogen (Timing-Bug behoben)",
            "Nur Gildenmitglieder mit Addon, gildenweit gesynct + gespeichert",
        },
    },    {
        version = "9.14.4",
        title   = "Doppel-Popup/Push behoben",
        color   = C_HIGHLIGHT,
        items   = {
            "DeathNotificationLib feuerte pro Tod mehrfach -> jetzt genau 1x",
            "Pipeline-Dedup an der Wurzel: ein Overlay, eine Gildenmeldung pro Tod",
            "Gilden-Announce nutzt jetzt dieselbe Sperre wie das Popup",
        },
    },    {
        version = "9.15.0",
        title   = "4 neue Mehrwert-Features",
        color   = C_HIGHLIGHT,
        items   = {
            "Waehrend du weg warst: Login-Digest der Tode seit letztem Besuch",
            "Toedlichste-Stufe-Warnung beim Aufstieg (aus echten Gildendaten)",
            "/gdl threats: Hallen der Furcht - toedlichste Gebiete & Stufen",
            "Gilden-Meilenstein-Toast: Die Chronik zaehlt nun N Gefallene",
        },
    },    {
        version = "9.15.2",
        title   = "Statistiken erweitert",
        color   = C_HIGHLIGHT,
        items   = {
            "Haeufigste Todesursachen jetzt direkt in der Statistiken-Seite",
            "Doppeltes Kapitel 'Hallen der Furcht' wieder entfernt (redundant)",
            "/gdl threats bleibt als schneller Chat-Befehl erhalten",
        },
    },    {
        version = "9.15.3",
        title   = "Killer-Namen statt Kreatur-IDs",
        color   = C_HIGHLIGHT,
        items   = {
            "Addon lernt NPC-Namen aus dem Kampflog (persistent)",
            "Todesursachen zeigen jetzt Namen statt 'Kreatur #ID'",
            "Nutzt Deathlog-Namensdatenbank mit, falls installiert",
        },
    },    {
        version = "9.15.5",
        title   = "Doppel-Popup endgueltig behoben",
        color   = C_HIGHLIGHT,
        items   = {
            "Overlay-Backstop: jeder Tod erscheint garantiert nur EINMAL",
            "Eigenes Broadcast-Echo wird nicht mehr erneut verarbeitet",
            "Popup + Gildenmeldung gehen wieder zuverlaessig raus",
        },
    },    {
        version = "9.15.6",
        title   = "Loeschen trifft jetzt den richtigen Eintrag",
        color   = C_HIGHLIGHT,
        items   = {
            "Loeschen im Buch ging nach Anzeige-Index -> falscher Char flog",
            "Jetzt per Identitaet (Name + Zeitstempel) - immer der richtige",
            "Gilt fuer Buch-Liste und Todes-Overlay (mit/ohne Passwort)",
        },
    },    {
        version = "9.16.8",
        title   = "English localization",
        color   = C_HIGHLIGHT,
        items   = {
            "The book is now English on English clients (auto-detected)",
            "Manual switch any time: /gdl lang en | de | auto",
            "Spotted a leftover German string? Let me know and it gets fixed",
        },
    },    {
        version = "9.16.9",
        title   = "Milestones follow /gdl lang",
        color   = C_HIGHLIGHT,
        items   = {
            "All ~126 milestones already showed English on English clients",
            "Now /gdl lang en|de switches them live too (was load-time only)",
            "Reuses the built-in translations - no duplicate text, no bloat",
        },
    },    {
        version = "9.16.10",
        title   = "Titles follow /gdl lang",
        color   = C_HIGHLIGHT,
        items   = {
            "~80 titles now switch live with /gdl lang en|de too",
            "French clients keep French in auto mode - no regression",
            "Override only kicks in when you explicitly force a language",
        },
    },    {
        version = "9.16.11",
        title   = "Professions in English",
        color   = C_HIGHLIGHT,
        items   = {
            "Guild Professions window + book chapter fully translated",
            "Filter buttons localized (internal logic untouched)",
            "Bonus: milestone row tooltips were still German - fixed",
        },
    },    {
        version = "9.16.12",
        title   = "Map chapters in English",
        color   = C_HIGHLIGHT,
        items   = {
            "Map of the Fallen page, heatmap legend & pin tooltips translated",
            "Completes the full English pass across every book chapter",
            "Found German somewhere? Hit the thumbs-down or ping me",
        },
    },    {
        version = "9.17.0",
        title   = "Fully English — every window & command",
        color   = C_HIGHLIGHT,
        items   = {
            "Side windows, tooltips, toasts & all /gdl command output translated",
            "~135 leftover strings across 28 files - verified three ways",
            "Switch anytime: /gdl lang en | de | auto",
        },
    },    {
        version = "9.17.1",
        title   = "Lighter Deathlog scan + solo sync test",
        color   = C_HIGHLIGHT,
        items   = {
            "Deathlog scan now dense right after login, relaxed afterwards",
            "New: /gdl synctest fakes a received peer death - test sync solo",
            "/gdl synctest clear removes the fake peer + test entries",
        },
    },    {
        version = "9.17.2",
        title   = "Death popup/chat fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Background scan no longer 'steals' fresh deaths from the live feed",
            "Deaths < 90s old stay with the live feed -> popup + guild chat fire",
            "Still silent? /reload, then /gdl pipetest + /gdl log to pinpoint",
        },
    },    {
        version = "9.17.3",
        title   = "No more double death popup",
        color   = C_HIGHLIGHT,
        items   = {
            "Overlay + DeathBell flash both popped a window - now just one",
            "With the overlay on, DeathBell is sound-only (its flash is a fallback)",
            "Prefer the centered flash? Turn the overlay off in settings",
        },
    },    {
        version = "9.17.4",
        title   = "QA fixes: memory leak, double bell, map data",
        color   = C_HIGHLIGHT,
        items   = {
            "Stats/Memorial/Leader windows now pool rows - no more frame leak",
            "Received deaths no longer double the bell sound/banner",
            "Map of the Fallen + world heatmap read the right data again",
        },
    },    {
        version = "9.17.5",
        title   = "New book design: worn WoW tome",
        color   = C_HIGHLIGHT,
        items   = {
            "Redrawn open-tome artwork: aged parchment, frayed worn edges, brass corner fittings",
            "Thin worn leather edge instead of the thick dark border",
            "Book proportions + page anchors retuned to the new art",
        },
    },    {
        version = "9.17.6",
        title   = "Photoreal book, muted pages",
        color   = C_HIGHLIGHT,
        items   = {
            "Replaced the cartoonish tome with a realistic aged-leather book photo",
            "Toned the bright page centers down to muted warm parchment",
            "Frame height retuned to the new art; text stays readable",
        },
    },    {
        version = "9.17.7",
        title   = "Clean elegant book (your pick)",
        color   = C_HIGHLIGHT,
        items   = {
            "Swapped in the clean, evenly-toned parchment book you chose",
            "Kept the source transparency; no more grungy stained edges",
            "Frame + page anchors remeasured to the new art",
        },
    },    {
        version = "9.18.0",
        title   = "Book polish: wax seal & ornaments",
        color   = C_HIGHLIGHT,
        items   = {
            "Close button is now a raven wax seal instead of the red X",
            "Removed the clunky scrollbar arrows - slim warm scrollbar only",
            "Filigree flourishes + a faint guild seal watermark on the pages",
        },
    },    {
        version = "9.18.1",
        title   = "Smaller book by default",
        color   = C_HIGHLIGHT,
        items   = {
            "Book scales a bit smaller by default (0.9 -> 0.8)",
            "Removed the right-page bottom flourish",
        },
    },    {
        version = "9.18.2",
        title   = "Cleaner left page",
        color   = C_HIGHLIGHT,
        items   = {
            "Removed the left-page flourish and seal watermark",
        },
    },    {
        version = "9.18.3",
        title   = "Bigger book text",
        color   = C_HIGHLIGHT,
        items   = {
            "Shared text builders + index + condolence list enlarged",
        },
    },    {
        version = "9.18.4",
        title   = "Text now fills the book naturally",
        color   = C_HIGHLIGHT,
        items   = {
            "Real font point sizes raised across index, chronicle & condolences",
            "Book scaled down (0.85) so text fills the page, not floats in it",
            "Death list line spacing rebuilt to match the larger fonts",
        },
    },    {
        version = "9.19.5",
        title   = "Your title on character & target",
        color   = C_HIGHLIGHT,
        items   = {
            "Chosen guild title shows as a readable header line in your character window",
            "Target a guildmate and their title shows under their name",
            "Gender-correct; free feature like nameplate titles",
        },
    },    {
        version = "9.20.0",
        title   = "Merit badges in the tooltip",
        color   = C_HIGHLIGHT,
        items   = {
            "Badges tied to existing milestones & achievements - no duplicates",
            "Hover a guildmate to see their earned badges + count",
            "Synced like titles (full-state, no desync); free to view",
        },
    },    {
        version = "9.21.0",
        title   = "Prestige rank + early badges",
        color   = C_HIGHLIGHT,
        items   = {
            "Prestige rank from badge count: Bronze -> Silver -> Gold -> Platinum -> Diamond",
            "Added 9 early badges so even a fresh char sees progress",
            "29 badges total, still one per real feat",
        },
    },    {
        version = "9.21.1",
        title   = "Sync hardening (QA pass)",
        color   = C_HIGHLIGHT,
        items   = {
            "Death packets length-capped - no more silent truncation",
            "Full sync logging for milestones & streaks",
        },
    },    {
        version = "9.21.2",
        title   = "Stricter QA - honest fixes",
        color   = C_HIGHLIGHT,
        items   = {
            "Rolled back milestone over-engineering (dead storage + packet storm)",
            "Badges: clean ID-boundary chunking + live supporter unlock",
            "Fixed a German text leak; hardened book scale",
        },
    },    {
        version = "9.21.3",
        title   = "Deep QA - crash fix",
        color   = C_HIGHLIGHT,
        items   = {
            "Fixed a crash when sorting the guild-leader list by 'last online'",
            "Deep audit confirmed the death pipeline is leak/dupe-free",
        },
    },    {
        version = "9.22.0",
        title   = "Guild community update",
        color   = C_FEATURE,
        items   = {
            "Guild Nemesis: the creature that slew the most guildmates - take revenge!",
            "Guild Vows: swear a public pledge, break it by dying. /gdl vow",
            "Both fully synced & localized (DE/EN)",
        },
    },    {
        version = "9.23.0",
        title   = "Days Without a Loss",
        tag     = "current",
        color   = C_FEATURE,
        items   = {
            "Guild-wide safety streak: days since the last loss + all-time record",
            "Milestones announced automatically; /gdl safedays",
        },
    },
}

-- ══════════════════════════════════════════════════════════════
-- UI CREATION
-- ══════════════════════════════════════════════════════════════

local frame       -- Main frame
local scrollFrame -- ScrollFrame
local content     -- ScrollChild

local FRAME_W = 480
local FRAME_H = 560
local TIMELINE_X = 38   -- X-Offset der Timeline-Linie
local NODE_RADIUS = 6
local CONTENT_PAD_TOP = 16
local CONTENT_PAD_BOT = 20

-- ── TAG LABELS ───────────────────────────────────────────────
local TAG_LABELS = {
    major   = {"|cffFFD100MAJOR|r",   {1.00, 0.82, 0.00, 0.15}},
    feature = {"|cff55DD55FEATURE|r", {0.33, 0.87, 0.33, 0.15}},
    fix     = {"|cffAAAAFFFIX|r",     {0.67, 0.67, 1.00, 0.15}},
    current = {"|cff00FF88NEU|r",     {0.00, 1.00, 0.53, 0.20}},
}

local function CreateTimelineFrame()
    if frame then return frame end

    -- ── MAIN FRAME ───────────────────────────────────────────
    frame = CreateFrame("Frame", "GDLWhatsNew", UIParent, "BackdropTemplate")
    frame:SetSize(FRAME_W, FRAME_H)
    frame:SetPoint("CENTER", 0, 20)
    frame:SetFrameStrata("DIALOG")
    frame:SetFrameLevel(100)
    frame:SetMovable(true)
    frame:EnableMouse(true)
    frame:RegisterForDrag("LeftButton")
    frame:SetScript("OnDragStart", frame.StartMoving)
    frame:SetScript("OnDragStop", frame.StopMovingOrSizing)
    frame:Hide()

    frame:SetBackdrop({
        bgFile   = "Interface\\ACHIEVEMENTFRAME\\UI-Achievement-Parchment-Horizontal",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
        tile     = false,
        tileSize = 256,
        edgeSize = 32,
        insets   = { left = 8, right = 8, top = 8, bottom = 8 },
    })
    frame:SetBackdropColor(0.95, 0.90, 0.80, 1)
    frame:SetBackdropBorderColor(0.80, 0.70, 0.50, 1)

    -- ── DARK OVERLAY fuer Tiefe ──────────────────────────────
    local darkOverlay = frame:CreateTexture(nil, "BACKGROUND", nil, 1)
    darkOverlay:SetColorTexture(0.05, 0.03, 0.01, 0.25)
    darkOverlay:SetPoint("TOPLEFT", 8, -8)
    darkOverlay:SetPoint("BOTTOMRIGHT", -8, 8)

    -- ── TITLE BAR ────────────────────────────────────────────
    local titleBar = CreateFrame("Frame", nil, frame, "BackdropTemplate")
    titleBar:SetHeight(32)
    titleBar:SetPoint("TOPLEFT", 12, -12)
    titleBar:SetPoint("TOPRIGHT", -12, -12)
    titleBar:SetBackdrop({
        bgFile   = "Interface\\ACHIEVEMENTFRAME\\UI-Achievement-Parchment-Horizontal",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        edgeSize = 12,
        insets   = { left = 3, right = 3, top = 3, bottom = 3 },
    })
    titleBar:SetBackdropColor(0.15, 0.10, 0.05, 0.85)
    titleBar:SetBackdropBorderColor(0.55, 0.45, 0.30, 0.8)

    local titleText = titleBar:CreateFontString(nil, "OVERLAY")
    titleText:SetFont("Fonts\\MORPHEUS.TTF", 16, "")
    titleText:SetPoint("CENTER", 0, 1)
    titleText:SetText("|cffFFD100" .. GDL:T("Das Buch der Gefallenen") .. "|r |cff888888" .. GDL:T("— Was ist neu?") .. "|r")
    titleText:SetShadowOffset(1, -1)
    titleText:SetShadowColor(0, 0, 0, 0.8)

    -- ── CLOSE BUTTON ─────────────────────────────────────────
    local closeBtn = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", 2, 2)

    -- ── SCROLL FRAME ─────────────────────────────────────────
    scrollFrame = CreateFrame("ScrollFrame", "GDLWhatsNewScroll", frame, "UIPanelScrollFrameTemplate")
    scrollFrame:SetPoint("TOPLEFT", 14, -50)
    scrollFrame:SetPoint("BOTTOMRIGHT", -34, 52)

    content = CreateFrame("Frame", "GDLWhatsNewContent", scrollFrame)
    content:SetWidth(FRAME_W - 60)
    scrollFrame:SetScrollChild(content)

    -- Scroll-Thumb einfaerben
    local scrollBar = _G["GDLWhatsNewScrollScrollBar"]
    if scrollBar then
        local thumb = scrollBar:GetThumbTexture()
        if thumb then
            thumb:SetColorTexture(0.45, 0.35, 0.20, 0.6)
            thumb:SetWidth(8)
        end
    end

    -- ── STATUS BAR (Discord + Version) ───────────────────────
    local statusBar = CreateFrame("Frame", nil, frame, "BackdropTemplate")
    statusBar:SetHeight(28)
    statusBar:SetPoint("BOTTOMLEFT", 12, 12)
    statusBar:SetPoint("BOTTOMRIGHT", -12, 12)
    statusBar:SetBackdrop({
        bgFile   = "Interface\\ACHIEVEMENTFRAME\\UI-Achievement-Parchment-Horizontal",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        edgeSize = 12,
        insets   = { left = 3, right = 3, top = 3, bottom = 3 },
    })
    statusBar:SetBackdropColor(0.15, 0.10, 0.05, 0.85)
    statusBar:SetBackdropBorderColor(0.55, 0.45, 0.30, 0.8)

    -- Version links
    local versionText = statusBar:CreateFontString(nil, "OVERLAY")
    versionText:SetFont("Fonts\\FRIZQT__.TTF", 10, "")
    versionText:SetPoint("LEFT", 10, 0)
    versionText:SetText("|cffAAAAAAVersion " .. (addon.Config and addon.Config.VERSION or "9.5.0") .. "|r")
    versionText:SetShadowOffset(1, -1)

    -- Discord rechts (klickbar)
    local discordBtn = CreateFrame("Button", nil, statusBar)
    discordBtn:SetPoint("RIGHT", -8, 0)
    discordBtn:SetSize(220, 22)

    local discordText = discordBtn:CreateFontString(nil, "OVERLAY")
    discordText:SetFont("Fonts\\FRIZQT__.TTF", 10, "")
    discordText:SetAllPoints()
    discordText:SetJustifyH("RIGHT")
    discordText:SetText("|cff7289DA\xF0\x9F\x8E\xAE|r |cffAAAAAADiscord:|r |cff7289DA" .. DISCORD_URL .. "|r |cffFFD100(klick)|r")
    discordText:SetShadowOffset(1, -1)

    -- Highlight bei Hover
    local discordHL = discordBtn:CreateTexture(nil, "HIGHLIGHT")
    discordHL:SetColorTexture(0.45, 0.52, 0.85, 0.15)
    discordHL:SetAllPoints()

    discordBtn:SetScript("OnClick", function()
        -- Erstelle ein EditBox-Popup zum Kopieren
        WhatsNew:ShowCopyDialog("https://" .. DISCORD_URL)
    end)
    discordBtn:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_TOP")
        GameTooltip:SetText("|cff7289DADiscord Einladung|r")
        GameTooltip:AddLine("Klicke um den Link zu kopieren", 0.8, 0.8, 0.8)
        GameTooltip:AddLine("https://" .. DISCORD_URL, 0.45, 0.52, 0.85)
        GameTooltip:Show()
    end)
    discordBtn:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

    -- Schliessen-Button unten
    local closeBottom = CreateFrame("Button", nil, statusBar, "UIPanelButtonTemplate")
    closeBottom:SetSize(76, 22)
    closeBottom:SetPoint("CENTER", 0, 0)
    closeBottom:SetText("Schliessen")
    closeBottom:SetScript("OnClick", function() frame:Hide() end)
    -- Nur anzeigen wenn genug Platz — verstecken, Discord-Leiste reicht
    closeBottom:Hide()

    frame._content = content
    frame._scrollFrame = scrollFrame
    return frame
end

-- ══════════════════════════════════════════════════════════════
-- TIMELINE RENDERING
-- ══════════════════════════════════════════════════════════════

local function CreateTimelineNode(parent, yOffset, entry, index, total)
    local isCurrent = (entry.tag == "current")
    local nodeColor = entry.color or C_NODE_MINOR
    local tagInfo   = TAG_LABELS[entry.tag] or TAG_LABELS["feature"]

    -- ── NODE DOT ─────────────────────────────────────────────
    local dot = parent:CreateTexture(nil, "ARTWORK", nil, 3)
    local dotSize = isCurrent and 14 or 10
    dot:SetSize(dotSize, dotSize)
    dot:SetPoint("TOPLEFT", TIMELINE_X - dotSize/2, yOffset)
    dot:SetTexture("Interface\\COMMON\\Indicator-Green")
    dot:SetVertexColor(nodeColor[1], nodeColor[2], nodeColor[3], 1)

    -- Glow fuer aktuellen Node
    if isCurrent then
        local glow = parent:CreateTexture(nil, "ARTWORK", nil, 2)
        glow:SetSize(26, 26)
        glow:SetPoint("CENTER", dot, "CENTER", 0, 0)
        glow:SetTexture("Interface\\COMMON\\Indicator-Green")
        glow:SetVertexColor(nodeColor[1], nodeColor[2], nodeColor[3], 0.35)

        -- Pulsing animation
        local ag = glow:CreateAnimationGroup()
        ag:SetLooping("BOUNCE")
        local alpha = ag:CreateAnimation("Alpha")
        alpha:SetFromAlpha(0.2)
        alpha:SetToAlpha(0.6)
        alpha:SetDuration(1.2)
        alpha:SetSmoothing("IN_OUT")
        ag:Play()
    end

    local textLeft = TIMELINE_X + 16 -- Text startet rechts vom Node
    local textWidth = (FRAME_W - 60) - textLeft - 8

    -- ── VERSION + TAG ────────────────────────────────────────
    local versionStr = parent:CreateFontString(nil, "OVERLAY")
    versionStr:SetFont("Fonts\\MORPHEUS.TTF", isCurrent and 15 or 13, "")
    versionStr:SetPoint("TOPLEFT", textLeft, yOffset + 2)
    versionStr:SetWidth(textWidth)
    versionStr:SetJustifyH("LEFT")

    local tagStr = tagInfo[1]
    local vColor = isCurrent and "|cff00FF88" or "|cffFFD100"
    versionStr:SetText(vColor .. "v" .. entry.version .. "|r  " .. tagStr)
    versionStr:SetShadowOffset(1, -1)
    versionStr:SetShadowColor(0, 0, 0, 0.6)

    -- ── TITLE ────────────────────────────────────────────────
    local titleStr = parent:CreateFontString(nil, "OVERLAY")
    titleStr:SetFont("Fonts\\FRIZQT__.TTF", isCurrent and 12 or 11, "")
    titleStr:SetPoint("TOPLEFT", textLeft, yOffset - 16)
    titleStr:SetWidth(textWidth)
    titleStr:SetJustifyH("LEFT")
    titleStr:SetText("|cff" .. (isCurrent and "FFFFFF" or "E8D8C0") .. entry.title .. "|r")
    titleStr:SetShadowOffset(1, -1)
    titleStr:SetShadowColor(0, 0, 0, 0.4)

    -- ── TAG BACKGROUND ───────────────────────────────────────
    local tagBG = tagInfo[2]
    local bgTex = parent:CreateTexture(nil, "ARTWORK", nil, 0)
    bgTex:SetColorTexture(tagBG[1], tagBG[2], tagBG[3], tagBG[4])
    bgTex:SetPoint("TOPLEFT", textLeft - 6, yOffset + 5)
    bgTex:SetHeight(20)
    bgTex:SetPoint("RIGHT", parent, "RIGHT", -8, 0)

    -- ── ITEMS ────────────────────────────────────────────────
    local itemY = yOffset - 32
    for i, item in ipairs(entry.items) do
        local bullet = parent:CreateFontString(nil, "OVERLAY")
        bullet:SetFont("Fonts\\FRIZQT__.TTF", 10, "")
        bullet:SetPoint("TOPLEFT", textLeft + 4, itemY)
        bullet:SetWidth(textWidth - 8)
        bullet:SetJustifyH("LEFT")
        bullet:SetWordWrap(true)

        -- Letzer Eintrag bei "current" gruen hervorheben (Discord)
        local isDiscordLine = isCurrent and (i == #entry.items)
        local itemColor = isDiscordLine and "7289DA" or "B0A898"
        bullet:SetText("|cff" .. itemColor .. "- " .. item .. "|r")
        bullet:SetShadowOffset(1, -1)
        bullet:SetShadowColor(0, 0, 0, 0.3)

        itemY = itemY - (bullet:GetStringHeight() + 3)
    end

    -- ── CONNECTOR LINE (bis zum naechsten Node) ──────────────
    -- Wird nicht fuer den letzten Eintrag erstellt
    local blockHeight = math.abs(itemY - yOffset) + 14
    if index < total then
        local connector = parent:CreateTexture(nil, "ARTWORK", nil, 1)
        connector:SetColorTexture(C_LINE[1], C_LINE[2], C_LINE[3], C_LINE[4])
        connector:SetWidth(2)
        connector:SetPoint("TOP", dot, "BOTTOM", 0, 0)
        connector:SetHeight(blockHeight - dotSize + 8)
    end

    return blockHeight + 8
end

function WhatsNew:RenderTimeline()
    local f = CreateTimelineFrame()
    local c = f._content

    -- Clear previous content
    local regions = {c:GetRegions()}
    for _, r in ipairs(regions) do
        r:Hide()
        r:SetParent(nil)
    end

    -- ── HEADER ───────────────────────────────────────────────
    local header = c:CreateFontString(nil, "OVERLAY")
    header:SetFont("Fonts\\FRIZQT__.TTF", 10, "")
    header:SetPoint("TOPLEFT", TIMELINE_X + 16, -4)
    header:SetWidth(FRAME_W - 100)
    header:SetJustifyH("LEFT")
    header:SetText("|cff888888" .. GDL:T("Die Reise von Das Buch der Gefallenen — von Anfang bis heute.") .. "|r")
    header:SetShadowOffset(1, -1)

    -- ── HAUPTLINIE (wird spaeter gezeichnet) ─────────────────
    local yPos = -(CONTENT_PAD_TOP + 14)
    local totalEntries = #TIMELINE

    -- Timeline von OBEN (aelteste) nach UNTEN (neueste) — chronologisch
    for i, entry in ipairs(TIMELINE) do
        local blockH = CreateTimelineNode(c, yPos, entry, i, totalEntries)
        yPos = yPos - blockH
    end

    -- ── VERTIKALE HAUPTLINIE ─────────────────────────────────
    local mainLine = c:CreateTexture(nil, "ARTWORK", nil, 0)
    mainLine:SetColorTexture(C_LINE[1], C_LINE[2], C_LINE[3], 0.4)
    mainLine:SetWidth(2)
    mainLine:SetPoint("TOP", c, "TOPLEFT", TIMELINE_X, -(CONTENT_PAD_TOP + 14))
    mainLine:SetPoint("BOTTOM", c, "TOPLEFT", TIMELINE_X, yPos + 10)

    -- Content-Hoehe setzen
    c:SetHeight(math.abs(yPos) + CONTENT_PAD_BOT + 10)
end

-- ══════════════════════════════════════════════════════════════
-- COPY DIALOG (fuer Discord-Link)
-- ══════════════════════════════════════════════════════════════

local copyDialog

function WhatsNew:ShowCopyDialog(url)
    if not copyDialog then
        copyDialog = CreateFrame("Frame", "GDLWhatsNewCopy", UIParent, "BackdropTemplate")
        copyDialog:SetSize(340, 90)
        copyDialog:SetPoint("CENTER", 0, 100)
        copyDialog:SetFrameStrata("TOOLTIP")
        copyDialog:SetBackdrop({
            bgFile   = "Interface\\ACHIEVEMENTFRAME\\UI-Achievement-Parchment-Horizontal",
            edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
            edgeSize = 24,
            insets   = { left = 5, right = 5, top = 5, bottom = 5 },
        })
        copyDialog:SetBackdropColor(0.9, 0.85, 0.75, 1)
        copyDialog:SetBackdropBorderColor(0.7, 0.6, 0.4, 1)

        local label = copyDialog:CreateFontString(nil, "OVERLAY")
        label:SetFont("Fonts\\FRIZQT__.TTF", 11, "")
        label:SetPoint("TOP", 0, -14)
        label:SetText("|cffFFD100Strg+C zum Kopieren:|r")

        local editBox = CreateFrame("EditBox", nil, copyDialog, "InputBoxTemplate")
        editBox:SetSize(290, 22)
        editBox:SetPoint("TOP", 0, -36)
        editBox:SetAutoFocus(true)
        editBox:SetScript("OnEscapePressed", function() copyDialog:Hide() end)
        editBox:SetScript("OnEnterPressed", function() copyDialog:Hide() end)
        copyDialog._editBox = editBox

        local closeBtn = CreateFrame("Button", nil, copyDialog, "UIPanelCloseButton")
        closeBtn:SetPoint("TOPRIGHT", 2, 2)
        closeBtn:SetScale(0.8)
    end

    copyDialog._editBox:SetText(url)
    copyDialog:Show()
    copyDialog._editBox:HighlightText()
    copyDialog._editBox:SetFocus()
end

-- ══════════════════════════════════════════════════════════════
-- PUBLIC API
-- ══════════════════════════════════════════════════════════════

function WhatsNew:Show()
    self:RenderTimeline()
    local f = CreateTimelineFrame()
    f:Show()

    -- Fade-In Animation
    f:SetAlpha(0)
    local ag = f:CreateAnimationGroup()
    local fadeIn = ag:CreateAnimation("Alpha")
    fadeIn:SetFromAlpha(0)
    fadeIn:SetToAlpha(1)
    fadeIn:SetDuration(0.35)
    fadeIn:SetSmoothing("OUT")
    ag:SetScript("OnFinished", function() f:SetAlpha(1) end)
    ag:Play()

    -- Scroll ganz nach unten (neueste = "current")
    C_Timer.After(0.1, function()
        local scrollBar = _G["GDLWhatsNewScrollScrollBar"]
        if scrollBar then
            local _, maxVal = scrollBar:GetMinMaxValues()
            scrollBar:SetValue(maxVal)
        end
    end)

    -- Sound
    PlaySound(SOUNDKIT.IG_QUEST_LOG_OPEN or 844)
end

function WhatsNew:Hide()
    if frame then
        frame:Hide()
        PlaySound(SOUNDKIT.IG_QUEST_LOG_CLOSE or 845)
    end
end

function WhatsNew:Toggle()
    if frame and frame:IsShown() then
        self:Hide()
    else
        self:Show()
    end
end

-- ── AUTO-POPUP BEI NEUEM VERSION ─────────────────────────────
function WhatsNew:CheckAutoShow()
    if not GuildDeathLogDB then return end
    local currentVersion = addon.Config and addon.Config.VERSION or "9.5.0"
    local lastSeen = GuildDeathLogDB.whatsNewSeen or "0"

    if lastSeen ~= currentVersion then
        GuildDeathLogDB.whatsNewSeen = currentVersion
        -- Kurz warten bis UI geladen ist
        C_Timer.After(5, function()
            WhatsNew:Show()
            GDL:Print("|cffFFD100Was ist neu?|r Aendere Log: v" .. currentVersion .. " — |cff7289DADiscord: " .. DISCORD_URL .. "|r")
        end)
    end
end

-- ══════════════════════════════════════════════════════════════
-- MODULE REGISTRATION
-- ══════════════════════════════════════════════════════════════

GDL:RegisterModule("WhatsNew", WhatsNew)

-- Auto-Show nach Login pruefen
local l