-- ==============================================================
-- MODUL: Titles - Custom Titel für Hardcore-Meilensteine
-- v5.3.3 - Chat minimal (★) + An/Aus + Geschlecht + DE/EN
-- ==============================================================

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

local TITLE_PREFIX = "GDLTitle"
local BROADCAST_INTERVAL = 300  -- Alle 5 Minuten (war 120s)
local SYNC_DELAY = 5

local guildTitles = {}

C_ChatInfo.RegisterAddonMessagePrefix(TITLE_PREFIX)

-- ==============================================================
-- LOKALISIERUNG
-- ==============================================================

local locale = GetLocale()

local L_TITLE_DE = {
    NEW_TITLE = "*** NEUER TITEL FREIGESCHALTET! ***",
    USE_TITLES = "Verwende /gdl titles zum Auswaehlen",
    YOUR_TITLES = "Deine Titel",
    ACTIVE = "AKTIV",
    WEARS_TITLE = "Traegt nun den Titel: ",
}
local L_TITLE_EN = {
    NEW_TITLE = "*** NEW TITLE UNLOCKED! ***",
    USE_TITLES = "Use /gdl titles to select",
    YOUR_TITLES = "Your Titles",
    ACTIVE = "ACTIVE",
    WEARS_TITLE = "Now bears the title: ",
}
local L_TITLE = (locale == "deDE") and L_TITLE_DE or L_TITLE_EN

-- ==============================================================
-- TITEL-DEFINITIONEN - KOMPLETT!
-- ==============================================================

local function _mkTitleDefs(loc)
    local _prev = locale
    locale = loc
    local _defs = {
    -- ===========================================================
    -- LEGENDÄRE TITEL (Höchste Priorität)
    -- ===========================================================
    {id = "true_immortal", name = locale == "deDE" and "der Wahre Unsterbliche" or "the True Immortal", nameFemale = locale == "deDE" and "die Wahre Unsterbliche" or "the True Immortal", desc = locale == "deDE" and "Level 60 + Alle Raids + 30 Tage /played" or "Level 60 + All Raids + 30 days /played", icon = "Interface\\Icons\\Spell_Holy_Resurrection", color = {1, 0.5, 1}, requirement = "meta_true_immortal", priority = 500},
    {id = "perfectionist", name = locale == "deDE" and "der Perfektionist" or "the Perfectionist", nameFemale = locale == "deDE" and "die Perfektionistin" or "the Perfectionist", desc = locale == "deDE" and "Level 60 + Alle Berufe 300 + Alle Dungeons" or "Level 60 + All Profs 300 + All Dungeons", icon = "Interface\\Icons\\Spell_Holy_SearingLight", color = {0.9, 0.8, 0.5}, requirement = "meta_perfectionist", priority = 480},
    {id = "godslayer", name = locale == "deDE" and "Goetterschlaechter" or "Godslayer", nameFemale = locale == "deDE" and "Goetterschlaechterin" or "Godslayer", desc = locale == "deDE" and "C'Thun UND Kel'Thuzad besiegt" or "Defeated C'Thun AND Kel'Thuzad", icon = "Interface\\Icons\\INV_Misc_Eye_01", color = {0.8, 0.2, 0.8}, requirement = "meta_godslayer", priority = 450},
    {id = "legend_azeroth", name = locale == "deDE" and "Legende von Azeroth" or "Legend of Azeroth", nameFemale = locale == "deDE" and "Legende von Azeroth" or "Legend of Azeroth", desc = locale == "deDE" and "Level 60 + Alle Dungeons + 5.000 Kills" or "Level 60 + All Dungeons + 5,000 Kills", icon = "Interface\\Icons\\INV_Misc_Map02", color = {1, 0.84, 0}, requirement = "meta_legend_azeroth", priority = 400},
    {id = "immortal_veteran", name = locale == "deDE" and "Unsterblicher Veteran" or "Immortal Veteran", nameFemale = locale == "deDE" and "Unsterbliche Veteranin" or "Immortal Veteran", desc = locale == "deDE" and "Level 60 + 7 Tage /played" or "Level 60 + 7 days /played", icon = "Interface\\Icons\\Spell_Holy_AshesToAshes", color = {0.9, 0.7, 0.9}, requirement = "meta_immortal_veteran", priority = 380},
    {id = "dungeon_legend", name = locale == "deDE" and "Kerker-Legende" or "Dungeon Legend", nameFemale = locale == "deDE" and "Kerker-Legende" or "Dungeon Legend", desc = locale == "deDE" and "Alle Dungeons UND Raids gemeistert" or "All Dungeons AND Raids mastered", icon = "Interface\\Icons\\Spell_Holy_ChampionsBond", color = {0.7, 0.5, 1}, requirement = "meta_dungeon_legend", priority = 370},

    -- ===========================================================
    -- RAID-BOSSE
    -- ===========================================================
    {id = "kt_slayer", name = locale == "deDE" and "Bezwinger von Kel'Thuzad" or "Kel'Thuzad Slayer", nameFemale = locale == "deDE" and "Bezwingerin von Kel'Thuzad" or "Kel'Thuzad Slayer", desc = locale == "deDE" and "Kel'Thuzad besiegt" or "Defeated Kel'Thuzad", icon = "Interface\\Icons\\INV_Trinket_Naxxramas06", color = {0.6, 0.8, 1}, requirement = "boss_naxx_kt", priority = 360},
    {id = "cthun_slayer", name = locale == "deDE" and "Bezwinger von C'Thun" or "C'Thun Slayer", nameFemale = locale == "deDE" and "Bezwingerin von C'Thun" or "C'Thun Slayer", desc = locale == "deDE" and "C'Thun besiegt" or "Defeated C'Thun", icon = "Interface\\Icons\\INV_Misc_Eye_01", color = {0.5, 0.8, 0.5}, requirement = "boss_aq40_cthun", priority = 350},
    {id = "nef_slayer", name = locale == "deDE" and "Nefarian-Toeter" or "Nefarian Slayer", nameFemale = locale == "deDE" and "Nefarian-Toeterin" or "Nefarian Slayer", desc = locale == "deDE" and "Nefarian besiegt" or "Defeated Nefarian", icon = "Interface\\Icons\\INV_Misc_Head_Dragon_Black", color = {0.3, 0.3, 0.3}, requirement = "boss_bwl_nef", priority = 340},
    {id = "rag_slayer", name = locale == "deDE" and "Ragnaros-Toeter" or "Ragnaros Slayer", nameFemale = locale == "deDE" and "Ragnaros-Toeterin" or "Ragnaros Slayer", desc = locale == "deDE" and "Ragnaros besiegt" or "Defeated Ragnaros", icon = "Interface\\Icons\\Spell_Fire_Lavaspawn", color = {1, 0.5, 0.2}, requirement = "boss_mc_rag", priority = 330},
    {id = "ony_slayer", name = locale == "deDE" and "Drachenbezwinger" or "Dragon Slayer", nameFemale = locale == "deDE" and "Drachenbezwingerin" or "Dragon Slayer", desc = locale == "deDE" and "Onyxia besiegt" or "Defeated Onyxia", icon = "Interface\\Icons\\INV_Misc_Head_Dragon_01", color = {0.5, 0.3, 0.5}, requirement = "boss_ony", priority = 320},
    {id = "hakkar_slayer", name = locale == "deDE" and "Haekkar-Toeter" or "Hakkar Slayer", nameFemale = locale == "deDE" and "Haekkar-Toeterin" or "Hakkar Slayer", desc = locale == "deDE" and "Hakkar besiegt" or "Defeated Hakkar", icon = "Interface\\Icons\\Ability_Creature_Poison_05", color = {0.2, 0.8, 0.4}, requirement = "boss_zg_hakkar", priority = 310},
    {id = "ossirian_slayer", name = locale == "deDE" and "Ossirian-Toeter" or "Ossirian Slayer", nameFemale = locale == "deDE" and "Ossirian-Toeterin" or "Ossirian Slayer", desc = locale == "deDE" and "Ossirian besiegt" or "Defeated Ossirian", icon = "Interface\\Icons\\INV_Jewelry_Ring_AhnQiraj_01", color = {0.8, 0.7, 0.4}, requirement = "boss_aq20_ossirian", priority = 300},

    -- ===========================================================
    -- META-ACHIEVEMENTS
    -- ===========================================================
    {id = "raid_master", name = locale == "deDE" and "Raidmeister" or "Raid Master", nameFemale = locale == "deDE" and "Raidmeisterin" or "Raid Master", desc = locale == "deDE" and "Alle Raid-Endbosse besiegt" or "All raid end bosses defeated", icon = "Interface\\Icons\\INV_Helmet_06", color = {0.8, 0.6, 0.2}, requirement = "meta_all_raids", priority = 295},
    {id = "dungeon_master", name = locale == "deDE" and "Kerkermeister" or "Dungeon Master", nameFemale = locale == "deDE" and "Kerkermeisterin" or "Dungeon Master", desc = locale == "deDE" and "Alle Dungeon-Endbosse besiegt" or "All dungeon end bosses defeated", icon = "Interface\\Icons\\INV_Jewelry_Talisman_08", color = {0.5, 0.5, 0.8}, requirement = "meta_all_dungeons", priority = 290},
    {id = "high_dungeon_master", name = locale == "deDE" and "Meister der Hoeheren Kerker" or "High Dungeon Master", nameFemale = locale == "deDE" and "Meisterin der Hoeheren Kerker" or "High Dungeon Master", desc = locale == "deDE" and "Alle High-Level Dungeons" or "All high-level dungeons", icon = "Interface\\Icons\\INV_Misc_Key_14", color = {0.6, 0.4, 0.8}, requirement = "meta_high_dungeons", priority = 280},
    {id = "mid_dungeon_master", name = locale == "deDE" and "Meister der Mittleren Kerker" or "Mid Dungeon Master", nameFemale = locale == "deDE" and "Meisterin der Mittleren Kerker" or "Mid Dungeon Master", desc = locale == "deDE" and "Alle Mid-Level Dungeons" or "All mid-level dungeons", icon = "Interface\\Icons\\INV_Misc_Key_10", color = {0.5, 0.5, 0.7}, requirement = "meta_mid_dungeons", priority = 200},
    {id = "low_dungeon_master", name = locale == "deDE" and "Meister der Niederen Kerker" or "Low Dungeon Master", nameFemale = locale == "deDE" and "Meisterin der Niederen Kerker" or "Low Dungeon Master", desc = locale == "deDE" and "Alle Low-Level Dungeons" or "All low-level dungeons", icon = "Interface\\Icons\\INV_Misc_Key_04", color = {0.4, 0.6, 0.5}, requirement = "meta_low_dungeons", priority = 120},
    {id = "complete_crafter", name = locale == "deDE" and "Meisterhandwerker" or "Master Crafter", nameFemale = locale == "deDE" and "Meisterhandwerkerin" or "Master Crafter", desc = locale == "deDE" and "Hauptberuf 300 + Alle Nebenberufe 300" or "Main prof 300 + All secondary 300", icon = "Interface\\Icons\\Trade_Engineering", color = {0.7, 0.5, 0.3}, requirement = "meta_complete_crafter", priority = 275},
    {id = "secondary_master", name = locale == "deDE" and "Nebenberuf-Meister" or "Secondary Master", nameFemale = locale == "deDE" and "Nebenberuf-Meisterin" or "Secondary Master", desc = locale == "deDE" and "Angeln, Kochen, Erste Hilfe auf 300" or "Fishing, Cooking, First Aid at 300", icon = "Interface\\Icons\\Spell_Nature_EnchantArmor", color = {0.5, 0.6, 0.5}, requirement = "meta_all_secondary", priority = 180},

    -- ===========================================================
    -- HIGH-LEVEL DUNGEON BOSSE
    -- ===========================================================
    {id = "baron_slayer", name = locale == "deDE" and "Barontoeter" or "Baron Slayer", nameFemale = locale == "deDE" and "Barontoeterin" or "Baron Slayer", desc = locale == "deDE" and "Baron Rivendare besiegt" or "Defeated Baron Rivendare", icon = "Interface\\Icons\\INV_Sword_49", color = {0.4, 0.4, 0.5}, requirement = "boss_strat_ud", priority = 270},
    {id = "strat_live", name = locale == "deDE" and "Scharlachroter Kreuzfahrer" or "Scarlet Crusader", nameFemale = locale == "deDE" and "Scharlachrote Kreuzfahrerin" or "Scarlet Crusader", desc = locale == "deDE" and "Balnazzar besiegt" or "Defeated Balnazzar", icon = "Interface\\Icons\\Spell_Holy_HolyBolt", color = {0.8, 0.2, 0.2}, requirement = "boss_strat_live", priority = 265},
    {id = "scholo_slayer", name = locale == "deDE" and "Scholomance-Bezwinger" or "Scholomance Conqueror", nameFemale = locale == "deDE" and "Scholomance-Bezwingerin" or "Scholomance Conqueror", desc = locale == "deDE" and "Darkmaster Gandling besiegt" or "Defeated Darkmaster Gandling", icon = "Interface\\Icons\\Spell_Shadow_RaiseDead", color = {0.3, 0.5, 0.3}, requirement = "boss_scholo", priority = 260},
    {id = "ubrs_slayer", name = locale == "deDE" and "UBRS-Bezwinger" or "UBRS Conqueror", nameFemale = locale == "deDE" and "UBRS-Bezwingerin" or "UBRS Conqueror", desc = locale == "deDE" and "General Drakkisath besiegt" or "Defeated General Drakkisath", icon = "Interface\\Icons\\INV_Misc_Head_Dragon_01", color = {0.6, 0.3, 0.2}, requirement = "boss_ubrs", priority = 255},
    {id = "lbrs_slayer", name = locale == "deDE" and "LBRS-Bezwinger" or "LBRS Conqueror", nameFemale = locale == "deDE" and "LBRS-Bezwingerin" or "LBRS Conqueror", desc = locale == "deDE" and "Ueberlord Wyrmthalak besiegt" or "Defeated Overlord Wyrmthalak", icon = "Interface\\Icons\\INV_Misc_MonsterScales_15", color = {0.5, 0.4, 0.3}, requirement = "boss_lbrs", priority = 250},
    {id = "dm_north", name = locale == "deDE" and "Koenigs-Bezwinger" or "King Slayer", nameFemale = locale == "deDE" and "Koenigs-Bezwingerin" or "King Slayer", desc = locale == "deDE" and "Koenig Gordok besiegt" or "Defeated King Gordok", icon = "Interface\\Icons\\INV_Crown_01", color = {0.6, 0.5, 0.3}, requirement = "boss_dm_north", priority = 245},
    {id = "dm_west", name = locale == "deDE" and "Prinzentoeter" or "Prince Slayer", nameFemale = locale == "deDE" and "Prinzentoeterin" or "Prince Slayer", desc = locale == "deDE" and "Prinz Tortheldrin besiegt" or "Defeated Prince Tortheldrin", icon = "Interface\\Icons\\INV_Sword_26", color = {0.4, 0.5, 0.6}, requirement = "boss_dm_west", priority = 240},
    {id = "dm_east", name = locale == "deDE" and "Satyr-Toeter" or "Satyr Slayer", nameFemale = locale == "deDE" and "Satyr-Toeterin" or "Satyr Slayer", desc = locale == "deDE" and "Alzzin besiegt" or "Defeated Alzzin", icon = "Interface\\Icons\\Spell_Nature_AbolishMagic", color = {0.3, 0.6, 0.3}, requirement = "boss_dm_east", priority = 235},
    {id = "brd_emperor", name = locale == "deDE" and "Imperatortoeter" or "Emperor Slayer", nameFemale = locale == "deDE" and "Imperatortoeterin" or "Emperor Slayer", desc = locale == "deDE" and "Imperator Thaurissan besiegt" or "Defeated Emperor Thaurissan", icon = "Interface\\Icons\\INV_Crown_01", color = {0.8, 0.6, 0.2}, requirement = "boss_brd_emp", priority = 230},
    {id = "sunken_temple", name = locale == "deDE" and "Tempelreiniger" or "Temple Cleanser", nameFemale = locale == "deDE" and "Tempelreinigerin" or "Temple Cleanser", desc = locale == "deDE" and "Eranikus' Schatten besiegt" or "Defeated Shade of Eranikus", icon = "Interface\\Icons\\INV_Misc_Head_Dragon_Green", color = {0.3, 0.5, 0.4}, requirement = "boss_st", priority = 225},

    -- ===========================================================
    -- MID-LEVEL DUNGEON BOSSE
    -- ===========================================================
    {id = "mara_slayer", name = locale == "deDE" and "Prinzessinnentoeter" or "Princess Slayer", nameFemale = locale == "deDE" and "Prinzessinnentoeterin" or "Princess Slayer", desc = locale == "deDE" and "Prinzessin Theradras besiegt" or "Defeated Princess Theradras", icon = "Interface\\Icons\\Spell_Nature_EarthElemental_Totem", color = {0.5, 0.4, 0.3}, requirement = "boss_mara", priority = 195},
    {id = "zf_slayer", name = locale == "deDE" and "Sandscalp-Toeter" or "Sandscalp Slayer", nameFemale = locale == "deDE" and "Sandscalp-Toeterin" or "Sandscalp Slayer", desc = locale == "deDE" and "Haeuptling Sandscalp besiegt" or "Defeated Chief Sandscalp", icon = "Interface\\Icons\\Ability_Warrior_Cleave", color = {0.8, 0.7, 0.4}, requirement = "boss_zf", priority = 190},
    {id = "ulda_slayer", name = locale == "deDE" and "Archaedas-Toeter" or "Archaedas Slayer", nameFemale = locale == "deDE" and "Archaedas-Toeterin" or "Archaedas Slayer", desc = locale == "deDE" and "Archaedas besiegt" or "Defeated Archaedas", icon = "Interface\\Icons\\Spell_Nature_EarthElemental_Totem", color = {0.6, 0.5, 0.4}, requirement = "boss_ulda", priority = 185},
    {id = "rfd_slayer", name = locale == "deDE" and "Kaeltebringer-Toeter" or "Coldbringer Slayer", nameFemale = locale == "deDE" and "Kaeltebringer-Toeterin" or "Coldbringer Slayer", desc = locale == "deDE" and "Amnennar besiegt" or "Defeated Amnennar", icon = "Interface\\Icons\\Spell_Frost_FrostBolt02", color = {0.4, 0.5, 0.7}, requirement = "boss_rfd", priority = 170},
    {id = "rfk_slayer", name = locale == "deDE" and "Razorflank-Toeter" or "Razorflank Slayer", nameFemale = locale == "deDE" and "Razorflank-Toeterin" or "Razorflank Slayer", desc = locale == "deDE" and "Charlga Razorflank besiegt" or "Defeated Charlga Razorflank", icon = "Interface\\Icons\\Ability_Hunter_Pet_Boar", color = {0.5, 0.4, 0.3}, requirement = "boss_rfk", priority = 165},
    {id = "gnomer_slayer", name = locale == "deDE" and "Thermaplugg-Toeter" or "Thermaplugg Slayer", nameFemale = locale == "deDE" and "Thermaplugg-Toeterin" or "Thermaplugg Slayer", desc = locale == "deDE" and "Thermaplugg besiegt" or "Defeated Thermaplugg", icon = "Interface\\Icons\\INV_Gizmo_08", color = {0.4, 0.6, 0.4}, requirement = "boss_gnomer", priority = 160},
    {id = "sm_cath", name = locale == "deDE" and "Mograine-Toeter" or "Mograine Slayer", nameFemale = locale == "deDE" and "Mograine-Toeterin" or "Mograine Slayer", desc = locale == "deDE" and "Mograine besiegt" or "Defeated Mograine", icon = "Interface\\Icons\\INV_Sword_20", color = {0.8, 0.2, 0.2}, requirement = "boss_sm_cath", priority = 175},
    {id = "sm_arm", name = locale == "deDE" and "Herod-Toeter" or "Herod Slayer", nameFemale = locale == "deDE" and "Herod-Toeterin" or "Herod Slayer", desc = locale == "deDE" and "Herod besiegt" or "Defeated Herod", icon = "Interface\\Icons\\INV_Axe_40", color = {0.7, 0.3, 0.3}, requirement = "boss_sm_arm", priority = 155},
    {id = "sm_lib", name = locale == "deDE" and "Doan-Toeter" or "Doan Slayer", nameFemale = locale == "deDE" and "Doan-Toeterin" or "Doan Slayer", desc = locale == "deDE" and "Doan besiegt" or "Defeated Doan", icon = "Interface\\Icons\\INV_Staff_13", color = {0.5, 0.4, 0.6}, requirement = "boss_sm_lib", priority = 150},
    {id = "sm_gy", name = locale == "deDE" and "Blutmagier-Toeter" or "Bloodmage Slayer", nameFemale = locale == "deDE" and "Blutmagier-Toeterin" or "Bloodmage Slayer", desc = locale == "deDE" and "Thalnos besiegt" or "Defeated Thalnos", icon = "Interface\\Icons\\Spell_Shadow_LifeDrain02", color = {0.6, 0.2, 0.2}, requirement = "boss_sm_gy", priority = 145},

    -- ===========================================================
    -- LOW-LEVEL DUNGEON BOSSE
    -- ===========================================================
    {id = "sfk_slayer", name = locale == "deDE" and "Arugal-Toeter" or "Arugal Slayer", nameFemale = locale == "deDE" and "Arugal-Toeterin" or "Arugal Slayer", desc = locale == "deDE" and "Arugal besiegt" or "Defeated Arugal", icon = "Interface\\Icons\\Spell_Shadow_SummonFelHunter", color = {0.4, 0.4, 0.6}, requirement = "boss_sfk", priority = 115},
    {id = "bfd_slayer", name = locale == "deDE" and "Aku'mai-Toeter" or "Aku'mai Slayer", nameFemale = locale == "deDE" and "Aku'mai-Toeterin" or "Aku'mai Slayer", desc = locale == "deDE" and "Aku'mai besiegt" or "Defeated Aku'mai", icon = "Interface\\Icons\\Spell_Frost_SummonWaterElemental", color = {0.3, 0.4, 0.6}, requirement = "boss_bfd", priority = 110},
    {id = "stocks_slayer", name = locale == "deDE" and "Gefaengniswaerter" or "Prison Warden", nameFemale = locale == "deDE" and "Gefaengniswaerterin" or "Prison Warden", desc = locale == "deDE" and "Bazil Thredd besiegt" or "Defeated Bazil Thredd", icon = "Interface\\Icons\\INV_Misc_Key_01", color = {0.5, 0.5, 0.5}, requirement = "boss_stocks", priority = 105},
    {id = "dm_slayer", name = locale == "deDE" and "VanCleef-Toeter" or "VanCleef Slayer", nameFemale = locale == "deDE" and "VanCleef-Toeterin" or "VanCleef Slayer", desc = locale == "deDE" and "VanCleef besiegt" or "Defeated VanCleef", icon = "Interface\\Icons\\INV_Helmet_25", color = {0.6, 0.4, 0.2}, requirement = "boss_dm", priority = 100},
    {id = "wc_slayer", name = locale == "deDE" and "Mutanus-Toeter" or "Mutanus Slayer", nameFemale = locale == "deDE" and "Mutanus-Toeterin" or "Mutanus Slayer", desc = locale == "deDE" and "Mutanus besiegt" or "Defeated Mutanus", icon = "Interface\\Icons\\Spell_Nature_MirrorImage", color = {0.3, 0.5, 0.3}, requirement = "boss_wc", priority = 95},
    {id = "rfc_slayer", name = locale == "deDE" and "Taragaman-Toeter" or "Taragaman Slayer", nameFemale = locale == "deDE" and "Taragaman-Toeterin" or "Taragaman Slayer", desc = locale == "deDE" and "Taragaman besiegt" or "Defeated Taragaman", icon = "Interface\\Icons\\Spell_Fire_Fire", color = {0.7, 0.3, 0.2}, requirement = "boss_rfc", priority = 90},

    -- ===========================================================
    -- SPIELZEIT-TITEL
    -- ===========================================================
    {id = "eternal", name = locale == "deDE" and "der Ewige" or "the Eternal", nameFemale = locale == "deDE" and "die Ewige" or "the Eternal", desc = locale == "deDE" and "30 Tage /played" or "30 days /played", icon = "Interface\\Icons\\Spell_Holy_Resurrection", color = {0.9, 0.8, 0.5}, requirement = "played_720h", priority = 285},
    {id = "two_weeks", name = locale == "deDE" and "Zwei Wochen Stark" or "Two Weeks Strong", nameFemale = locale == "deDE" and "Zwei Wochen Stark" or "Two Weeks Strong", desc = locale == "deDE" and "14 Tage /played" or "14 days /played", icon = "Interface\\Icons\\Spell_Holy_SealOfWrath", color = {0.6, 0.6, 0.8}, requirement = "played_336h", priority = 220},
    {id = "one_week", name = locale == "deDE" and "Eine Woche Stark" or "One Week Strong", nameFemale = locale == "deDE" and "Eine Woche Stark" or "One Week Strong", desc = locale == "deDE" and "7 Tage /played" or "7 days /played", icon = "Interface\\Icons\\Spell_Holy_SealOfValor", color = {0.5, 0.5, 0.7}, requirement = "played_168h", priority = 140},
    {id = "three_days", name = locale == "deDE" and "Drei Tage Ueberlebt" or "Three Days Survived", nameFemale = locale == "deDE" and "Drei Tage Ueberlebt" or "Three Days Survived", desc = locale == "deDE" and "72h /played" or "72h /played", icon = "Interface\\Icons\\Spell_Holy_SealOfSalvation", color = {0.5, 0.5, 0.6}, requirement = "played_72h", priority = 55},
    {id = "first_day", name = locale == "deDE" and "Erster Tag" or "First Day", nameFemale = locale == "deDE" and "Erster Tag" or "First Day", desc = locale == "deDE" and "24h /played" or "24h /played", icon = "Interface\\Icons\\Spell_Nature_TimeStop", color = {0.4, 0.6, 0.7}, requirement = "played_24h", priority = 30},

    -- ===========================================================
    -- LEVEL-TITEL
    -- ===========================================================
    {id = "immortal", name = locale == "deDE" and "der Unsterbliche" or "the Immortal", nameFemale = locale == "deDE" and "die Unsterbliche" or "the Immortal", desc = locale == "deDE" and "Level 60" or "Level 60", icon = "Interface\\Icons\\INV_Crown_01", color = {1, 0.84, 0}, requirement = "level_60", priority = 210},
    {id = "veteran", name = locale == "deDE" and "der Veteran" or "the Veteran", nameFemale = locale == "deDE" and "die Veteranin" or "the Veteran", desc = locale == "deDE" and "Level 50" or "Level 50", icon = "Interface\\Icons\\INV_Shield_07", color = {0.6, 0.5, 0.7}, requirement = "level_50", priority = 130},
    {id = "survivor", name = locale == "deDE" and "der Ueberlebende" or "the Survivor", nameFemale = locale == "deDE" and "die Ueberlebende" or "the Survivor", desc = locale == "deDE" and "Level 40" or "Level 40", icon = "Interface\\Icons\\Ability_Mount_RidingHorse", color = {0.5, 0.6, 0.5}, requirement = "level_40", priority = 80},
    {id = "traveler", name = locale == "deDE" and "der Reisende" or "the Traveler", nameFemale = locale == "deDE" and "die Reisende" or "the Traveler", desc = locale == "deDE" and "Level 30" or "Level 30", icon = "Interface\\Icons\\INV_Shield_06", color = {0.4, 0.5, 0.6}, requirement = "level_30", priority = 45},
    {id = "adventurer", name = locale == "deDE" and "der Abenteurer" or "the Adventurer", nameFemale = locale == "deDE" and "die Abenteurerin" or "the Adventurer", desc = locale == "deDE" and "Level 20" or "Level 20", icon = "Interface\\Icons\\Spell_Holy_GreaterHeal", color = {0.4, 0.6, 0.4}, requirement = "level_20", priority = 40},
    {id = "newcomer", name = locale == "deDE" and "der Neuling" or "the Newcomer", nameFemale = locale == "deDE" and "die Neulingin" or "the Newcomer", desc = locale == "deDE" and "Level 10" or "Level 10", icon = "Interface\\Icons\\Spell_Holy_WordFortitude", color = {0.5, 0.7, 0.5}, requirement = "level_10", priority = 10},

    -- ===========================================================
    -- TOTAL KILL-TITEL
    -- ===========================================================
    {id = "massacre", name = locale == "deDE" and "Das Massaker" or "the Massacre", nameFemale = locale == "deDE" and "Das Massaker" or "the Massacre", desc = locale == "deDE" and "50.000 Kills" or "50,000 Kills", icon = "Interface\\Icons\\Spell_Shadow_DeathScream", color = {0.8, 0.1, 0.1}, requirement = "kills_total_50000", priority = 215},
    {id = "annihilator", name = locale == "deDE" and "Vernichter" or "Annihilator", nameFemale = locale == "deDE" and "Vernichterin" or "Annihilator", desc = locale == "deDE" and "25.000 Kills" or "25,000 Kills", icon = "Interface\\Icons\\Ability_Warrior_WarCry", color = {0.7, 0.2, 0.2}, requirement = "kills_total_25000", priority = 180},
    {id = "destroyer", name = locale == "deDE" and "Zerstoerer" or "Destroyer", nameFemale = locale == "deDE" and "Zerstoererin" or "Destroyer", desc = locale == "deDE" and "10.000 Kills" or "10,000 Kills", icon = "Interface\\Icons\\Ability_Warrior_BattleShout", color = {0.6, 0.3, 0.3}, requirement = "kills_total_10000", priority = 135},
    {id = "executioner", name = locale == "deDE" and "Henker" or "Executioner", nameFemale = locale == "deDE" and "Henkerin" or "Executioner", desc = locale == "deDE" and "5.000 Kills" or "5,000 Kills", icon = "Interface\\Icons\\Ability_Warrior_Rampage", color = {0.5, 0.3, 0.3}, requirement = "kills_total_5000", priority = 85},
    {id = "slayer", name = locale == "deDE" and "Schlaechter" or "Slayer", nameFemale = locale == "deDE" and "Schlaechterin" or "Slayer", desc = locale == "deDE" and "1.000 Kills" or "1,000 Kills", icon = "Interface\\Icons\\Ability_DualWield", color = {0.4, 0.3, 0.3}, requirement = "kills_total_1000", priority = 50},

    -- ===========================================================
    -- HUMANOID-KILL TITEL
    -- ===========================================================
    {id = "warlord", name = locale == "deDE" and "Kriegsherr" or "Warlord", nameFemale = locale == "deDE" and "Kriegsherrin" or "Warlord", desc = locale == "deDE" and "2.000 Humanoide" or "2,000 Humanoids", icon = "Interface\\Icons\\Ability_Warrior_BattleShout", color = {0.8, 0.3, 0.2}, requirement = "kill_humanoid_2000", priority = 92},
    {id = "bounty_hunter", name = locale == "deDE" and "Kopfgeldjaeger" or "Bounty Hunter", nameFemale = locale == "deDE" and "Kopfgeldjaegerin" or "Bounty Hunter", desc = locale == "deDE" and "500 Humanoide" or "500 Humanoids", icon = "Interface\\Icons\\INV_Misc_Coin_02", color = {0.7, 0.5, 0.2}, requirement = "kill_humanoid_500", priority = 70},
    {id = "bandit_slayer", name = locale == "deDE" and "Banditenjaeger" or "Bandit Slayer", nameFemale = locale == "deDE" and "Banditenjaegerin" or "Bandit Slayer", desc = locale == "deDE" and "100 Humanoide" or "100 Humanoids", icon = "Interface\\Icons\\Ability_Rogue_Disguise", color = {0.6, 0.4, 0.3}, requirement = "kill_humanoid_100", priority = 35},
    {id = "highwayman", name = locale == "deDE" and "Wegelagerer" or "Highwayman", nameFemale = locale == "deDE" and "Wegelagerin" or "Highwayman", desc = locale == "deDE" and "25 Humanoide" or "25 Humanoids", icon = "Interface\\Icons\\Ability_Rogue_Ambush", color = {0.5, 0.4, 0.3}, requirement = "kill_humanoid_25", priority = 22},

    -- ===========================================================
    -- BEAST-KILL TITEL
    -- ===========================================================
    {id = "beastmaster", name = locale == "deDE" and "Bestienmeister" or "Beast Master", nameFemale = locale == "deDE" and "Bestienmeisterin" or "Beast Master", desc = locale == "deDE" and "2.000 Wildtiere" or "2,000 Beasts", icon = "Interface\\Icons\\Ability_Hunter_BeastMastery", color = {0.6, 0.4, 0.2}, requirement = "kill_beast_2000", priority = 93},
    {id = "big_game_hunter", name = locale == "deDE" and "Grosswildjaeger" or "Big Game Hunter", nameFemale = locale == "deDE" and "Grosswildjaegerin" or "Big Game Hunter", desc = locale == "deDE" and "500 Wildtiere" or "500 Beasts", icon = "Interface\\Icons\\Ability_Hunter_BeastTaming", color = {0.5, 0.4, 0.3}, requirement = "kill_beast_500", priority = 68},
    {id = "tracker", name = locale == "deDE" and "Faehrtenleser" or "Tracker", nameFemale = locale == "deDE" and "Faehrtenleserin" or "Tracker", desc = locale == "deDE" and "100 Wildtiere" or "100 Beasts", icon = "Interface\\Icons\\Ability_Hunter_BeastCall", color = {0.4, 0.5, 0.3}, requirement = "kill_beast_100", priority = 33},
    {id = "hunter", name = locale == "deDE" and "Jaeger" or "Hunter", nameFemale = locale == "deDE" and "Jaegerin" or "Hunter", desc = locale == "deDE" and "25 Wildtiere" or "25 Beasts", icon = "Interface\\Icons\\Ability_Hunter_SniperShot", color = {0.5, 0.6, 0.3}, requirement = "kill_beast_25", priority = 20},

    -- ===========================================================
    -- UNDEAD-KILL TITEL
    -- ===========================================================
    {id = "plague_cleanser", name = locale == "deDE" and "Seuchenreiniger" or "Plague Cleanser", nameFemale = locale == "deDE" and "Seuchenreinigerin" or "Plague Cleanser", desc = locale == "deDE" and "5.000 Untote" or "5,000 Undead", icon = "Interface\\Icons\\Spell_Holy_PrayerOfHealing", color = {0.8, 0.7, 0.3}, requirement = "kill_undead_5000", priority = 145},
    {id = "undead_scourge", name = locale == "deDE" and "Geissel der Untoten" or "Scourge of the Undead", nameFemale = locale == "deDE" and "Geissel der Untoten" or "Scourge of the Undead", desc = locale == "deDE" and "1.000 Untote" or "1,000 Undead", icon = "Interface\\Icons\\Spell_Holy_SenseUndead", color = {0.6, 0.6, 0.3}, requirement = "kill_undead_1000", priority = 91},
    {id = "undead_slayer", name = locale == "deDE" and "Untotentoeter" or "Undead Slayer", nameFemale = locale == "deDE" and "Untotentoeterin" or "Undead Slayer", desc = locale == "deDE" and "500 Untote" or "500 Undead", icon = "Interface\\Icons\\Spell_Shadow_RaiseDead", color = {0.5, 0.5, 0.3}, requirement = "kill_undead_500", priority = 67},
    {id = "bone_breaker", name = locale == "deDE" and "Knochenbrecher" or "Bone Breaker", nameFemale = locale == "deDE" and "Knochenbrecherin" or "Bone Breaker", desc = locale == "deDE" and "100 Untote" or "100 Undead", icon = "Interface\\Icons\\Spell_Shadow_AnimateDead", color = {0.4, 0.5, 0.4}, requirement = "kill_undead_100", priority = 32},
    {id = "grave_defiler", name = locale == "deDE" and "Grabschaender" or "Grave Defiler", nameFemale = locale == "deDE" and "Grabschaenderin" or "Grave Defiler", desc = locale == "deDE" and "25 Untote" or "25 Undead", icon = "Interface\\Icons\\Spell_Shadow_DeathCoil", color = {0.4, 0.5, 0.4}, requirement = "kill_undead_25", priority = 25},

    -- ===========================================================
    -- DEMON-KILL TITEL
    -- ===========================================================
    {id = "eredarbane", name = locale == "deDE" and "Eredarbane" or "Eredar Bane", nameFemale = locale == "deDE" and "Eredarbane" or "Eredar Bane", desc = locale == "deDE" and "1.000 Daemonen" or "1,000 Demons", icon = "Interface\\Icons\\Spell_Shadow_SummonFelGuard", color = {0.6, 0.2, 0.6}, requirement = "kill_demon_1000", priority = 125},
    {id = "demon_slayer", name = locale == "deDE" and "Daemonentoeter" or "Demon Slayer", nameFemale = locale == "deDE" and "Daemonentoeterin" or "Demon Slayer", desc = locale == "deDE" and "500 Daemonen" or "500 Demons", icon = "Interface\\Icons\\Spell_Shadow_Metamorphosis", color = {0.5, 0.2, 0.5}, requirement = "kill_demon_500", priority = 66},
    {id = "demon_hunter_adv", name = locale == "deDE" and "Daemonenjagd-Veteran" or "Demon Hunting Veteran", nameFemale = locale == "deDE" and "Daemonenjagd-Veteranin" or "Demon Hunting Veteran", desc = locale == "deDE" and "100 Daemonen" or "100 Demons", icon = "Interface\\Icons\\Spell_Shadow_SummonFelGuard", color = {0.4, 0.2, 0.4}, requirement = "kill_demon_100", priority = 31},
    {id = "demon_hunter", name = locale == "deDE" and "Daemonenjaeger" or "Demon Hunter", nameFemale = locale == "deDE" and "Daemonenjaegerin" or "Demon Hunter", desc = locale == "deDE" and "25 Daemonen" or "25 Demons", icon = "Interface\\Icons\\Spell_Shadow_SummonImp", color = {0.5, 0.3, 0.5}, requirement = "kill_demon_25", priority = 23},

    -- ===========================================================
    -- DRAGONKIN-KILL TITEL
    -- ===========================================================
    {id = "dragonbane", name = locale == "deDE" and "Drachenbane" or "Dragonbane", nameFemale = locale == "deDE" and "Drachenbane" or "Dragonbane", desc = locale == "deDE" and "1.000 Drachkin" or "1,000 Dragonkin", icon = "Interface\\Icons\\INV_Misc_Head_Dragon_Black", color = {0.8, 0.5, 0.2}, requirement = "kill_dragonkin_1000", priority = 130},
    {id = "dragon_slayer", name = locale == "deDE" and "Drachentoeter" or "Dragon Slayer", nameFemale = locale == "deDE" and "Drachentoeterin" or "Dragon Slayer", desc = locale == "deDE" and "250 Drachkin" or "250 Dragonkin", icon = "Interface\\Icons\\INV_Misc_Head_Dragon_01", color = {0.7, 0.4, 0.2}, requirement = "kill_dragonkin_250", priority = 65},
    {id = "dragon_hunter", name = locale == "deDE" and "Drachenjaeger" or "Dragon Hunter", nameFemale = locale == "deDE" and "Drachenjaegerin" or "Dragon Hunter", desc = locale == "deDE" and "50 Drachkin" or "50 Dragonkin", icon = "Interface\\Icons\\INV_Misc_MonsterScales_05", color = {0.6, 0.4, 0.2}, requirement = "kill_dragonkin_50", priority = 30},
    {id = "wyrm_tracker", name = locale == "deDE" and "Wyrmjaeger" or "Wyrm Tracker", nameFemale = locale == "deDE" and "Wyrmjaegerin" or "Wyrm Tracker", desc = locale == "deDE" and "10 Drachkin" or "10 Dragonkin", icon = "Interface\\Icons\\INV_Misc_MonsterScales_02", color = {0.5, 0.4, 0.3}, requirement = "kill_dragonkin_10", priority = 15},

    -- ===========================================================
    -- ELEMENTAL-KILL TITEL
    -- ===========================================================
    {id = "elemental_lord", name = locale == "deDE" and "Elementarherr" or "Elemental Lord", nameFemale = locale == "deDE" and "Elementarherrin" or "Elemental Lord", desc = locale == "deDE" and "500 Elementare" or "500 Elementals", icon = "Interface\\Icons\\Spell_Fire_Elemental_Totem", color = {0.7, 0.4, 0.2}, requirement = "kill_elemental_500", priority = 64},
    {id = "elemental_slayer", name = locale == "deDE" and "Elementartoeter" or "Elemental Slayer", nameFemale = locale == "deDE" and "Elementartoeterin" or "Elemental Slayer", desc = locale == "deDE" and "100 Elementare" or "100 Elementals", icon = "Interface\\Icons\\Spell_Fire_FireBolt", color = {0.6, 0.4, 0.2}, requirement = "kill_elemental_100", priority = 29},
    {id = "elementalist", name = locale == "deDE" and "Elementarjaeger" or "Elementalist", nameFemale = locale == "deDE" and "Elementarjaegerin" or "Elementalist", desc = locale == "deDE" and "25 Elementare" or "25 Elementals", icon = "Interface\\Icons\\Spell_Fire_Fire", color = {0.5, 0.4, 0.2}, requirement = "kill_elemental_25", priority = 24},

    -- ===========================================================
    -- GIANT-KILL TITEL
    -- ===========================================================
    {id = "giant_slayer", name = locale == "deDE" and "Riesentoeter" or "Giant Slayer", nameFemale = locale == "deDE" and "Riesentoeterin" or "Giant Slayer", desc = locale == "deDE" and "250 Riesen" or "250 Giants", icon = "Interface\\Icons\\INV_Stone_15", color = {0.6, 0.5, 0.4}, requirement = "kill_giant_250", priority = 63},
    {id = "giant_hunter", name = locale == "deDE" and "Riesenjaeger" or "Giant Hunter", nameFemale = locale == "deDE" and "Riesenjaegerin" or "Giant Hunter", desc = locale == "deDE" and "50 Riesen" or "50 Giants", icon = "Interface\\Icons\\INV_Misc_Foot_Centaur", color = {0.5, 0.5, 0.4}, requirement = "kill_giant_50", priority = 28},
    {id = "giant_tracker", name = locale == "deDE" and "Riesenfaehrte" or "Giant Tracker", nameFemale = locale == "deDE" and "Riesenfaehrte" or "Giant Tracker", desc = locale == "deDE" and "10 Riesen" or "10 Giants", icon = "Interface\\Icons\\INV_Misc_Bone_HumanSkull_01", color = {0.4, 0.5, 0.4}, requirement = "kill_giant_10", priority = 14},

    -- ===========================================================
    -- GOLD-TITEL
    -- ===========================================================
    {id = "goldcap", name = locale == "deDE" and "Goldkappe" or "Gold Cap", nameFemale = locale == "deDE" and "Goldkappe" or "Gold Cap", desc = locale == "deDE" and "5.000 Gold" or "5,000 Gold", icon = "Interface\\Icons\\INV_Misc_Coin_17", color = {1, 0.84, 0}, requirement = "gold_5000", priority = 175},
    {id = "wealthy", name = locale == "deDE" and "Steinreich" or "Wealthy", nameFemale = locale == "deDE" and "Steinreich" or "Wealthy", desc = locale == "deDE" and "1.000 Gold" or "1,000 Gold", icon = "Interface\\Icons\\INV_Misc_Coin_06", color = {0.9, 0.7, 0.2}, requirement = "gold_1000", priority = 125},
    {id = "rich", name = locale == "deDE" and "Wohlhabend" or "Rich", nameFemale = locale == "deDE" and "Wohlhabend" or "Rich", desc = locale == "deDE" and "500 Gold" or "500 Gold", icon = "Interface\\Icons\\INV_Misc_Coin_05", color = {0.8, 0.6, 0.2}, requirement = "gold_500", priority = 75},
    {id = "comfortable", name = locale == "deDE" and "Gut situiert" or "Comfortable", nameFemale = locale == "deDE" and "Gut situiert" or "Comfortable", desc = locale == "deDE" and "100 Gold" or "100 Gold", icon = "Interface\\Icons\\INV_Misc_Coin_02", color = {0.7, 0.5, 0.2}, requirement = "gold_100", priority = 37},

    -- ===========================================================
    -- BERUFE-TITEL
    -- ===========================================================
    {id = "grandmaster", name = locale == "deDE" and "Grossmeister" or "Grandmaster", nameFemale = locale == "deDE" and "Grossmeisterin" or "Grandmaster", desc = locale == "deDE" and "Hauptberuf 300" or "Main profession 300", icon = "Interface\\Icons\\Trade_Engineering", color = {0.7, 0.5, 0.3}, requirement = "prof_300", priority = 170},
    {id = "artisan", name = locale == "deDE" and "Fachmann" or "Artisan", nameFemale = locale == "deDE" and "Fachfrau" or "Artisan", desc = locale == "deDE" and "Hauptberuf 225" or "Main profession 225", icon = "Interface\\Icons\\Trade_LeatherWorking", color = {0.6, 0.5, 0.3}, requirement = "prof_225", priority = 72},
    {id = "journeyman", name = locale == "deDE" and "Geselle" or "Journeyman", nameFemale = locale == "deDE" and "Gesellin" or "Journeyman", desc = locale == "deDE" and "Hauptberuf 150" or "Main profession 150", icon = "Interface\\Icons\\Trade_BlackSmithing", color = {0.5, 0.5, 0.3}, requirement = "prof_150", priority = 38},
    {id = "master_angler", name = locale == "deDE" and "Meisterangler" or "Master Angler", nameFemale = locale == "deDE" and "Meisteranglerin" or "Master Angler", desc = locale == "deDE" and "Angeln 300" or "Fishing 300", icon = "Interface\\Icons\\INV_Fishingpole_02", color = {0.3, 0.5, 0.7}, requirement = "fish_300", priority = 165},
    {id = "fisherman", name = locale == "deDE" and "Fischer" or "Fisherman", nameFemale = locale == "deDE" and "Fischerin" or "Fisherman", desc = locale == "deDE" and "Angeln 150" or "Fishing 150", icon = "Interface\\Icons\\Trade_Fishing", color = {0.3, 0.4, 0.6}, requirement = "fish_150", priority = 36},
    {id = "master_chef", name = locale == "deDE" and "Meisterkoch" or "Master Chef", nameFemale = locale == "deDE" and "Meisterkochin" or "Master Chef", desc = locale == "deDE" and "Kochen 300" or "Cooking 300", icon = "Interface\\Icons\\INV_Misc_Food_67", color = {0.7, 0.5, 0.3}, requirement = "cook_300", priority = 160},
    {id = "cook", name = locale == "deDE" and "Koch" or "Cook", nameFemale = locale == "deDE" and "Koechin" or "Cook", desc = locale == "deDE" and "Kochen 150" or "Cooking 150", icon = "Interface\\Icons\\INV_Misc_Food_15", color = {0.6, 0.4, 0.3}, requirement = "cook_150", priority = 34},
    {id = "field_medic", name = locale == "deDE" and "Feldarzt" or "Field Medic", nameFemale = locale == "deDE" and "Feldaerztin" or "Field Medic", desc = locale == "deDE" and "Erste Hilfe 300" or "First Aid 300", icon = "Interface\\Icons\\INV_Misc_Bandage_12", color = {0.8, 0.8, 0.8}, requirement = "firstaid_300", priority = 155},
    {id = "medic", name = locale == "deDE" and "Sanitaeter" or (locale == "frFR" and "Infirmier" or "Medic"), nameFemale = locale == "deDE" and "Sanitaeterin" or (locale == "frFR" and "Infirmiere" or "Medic"), desc = locale == "deDE" and "Erste Hilfe 150" or (locale == "frFR" and "Secourisme 150" or "First Aid 150"), icon = "Interface\\Icons\\Spell_Holy_SealOfSacrifice", color = {0.7, 0.7, 0.7}, requirement = "firstaid_150", priority = 35},

    -- ===========================================================
    -- PVP-TITEL (NEU - Episch!)
    -- ===========================================================
    {id = "pvp_legend", name = locale == "deDE" and "Legende der Schlachtfelder" or (locale == "frFR" and "Legende des Champs de Bataille" or "Legend of the Battlefields"), nameFemale = locale == "deDE" and "Legende der Schlachtfelder" or (locale == "frFR" and "Legende des Champs de Bataille" or "Legend of the Battlefields"), desc = locale == "deDE" and "500 HKs + Level 60" or "500 HKs + Level 60", icon = "Interface\\Icons\\Achievement_PVP_A_15", color = {1, 0.2, 0.2}, requirement = "meta_pvp_master", priority = 410},
    {id = "pvp_warlord", name = locale == "deDE" and "Blutiger Kriegsherr" or (locale == "frFR" and "Seigneur de Guerre Sanglant" or "Bloodied Warlord"), nameFemale = locale == "deDE" and "Blutige Kriegsherrin" or (locale == "frFR" and "Dame de Guerre Sanglante" or "Bloodied Warlord"), desc = locale == "deDE" and "1.000 Ehrenhafte Siege" or "1,000 Honorable Kills", icon = "Interface\\Icons\\Ability_Warrior_BattleShout", color = {0.9, 0.15, 0.15}, requirement = "pvp_1000", priority = 300},
    {id = "pvp_conqueror", name = locale == "deDE" and "Eroberer von Azeroth" or (locale == "frFR" and "Conquerant d'Azeroth" or "Conqueror of Azeroth"), nameFemale = locale == "deDE" and "Erobererin von Azeroth" or (locale == "frFR" and "Conquerante d'Azeroth" or "Conqueror of Azeroth"), desc = locale == "deDE" and "500 Ehrenhafte Siege" or "500 Honorable Kills", icon = "Interface\\Icons\\Achievement_PVP_A_14", color = {0.8, 0.2, 0.2}, requirement = "pvp_500", priority = 200},
    {id = "pvp_gladiator", name = locale == "deDE" and "Gladiator der Arena" or (locale == "frFR" and "Gladiateur de l'Arene" or "Arena Gladiator"), nameFemale = locale == "deDE" and "Gladiatorin der Arena" or (locale == "frFR" and "Gladiatrice de l'Arene" or "Arena Gladiator"), desc = locale == "deDE" and "100 Ehrenhafte Siege" or "100 Honorable Kills", icon = "Interface\\Icons\\Achievement_PVP_A_10", color = {0.7, 0.25, 0.25}, requirement = "pvp_100", priority = 110},
    {id = "pvp_fighter", name = locale == "deDE" and "Schlachtfeld-Kaempfer" or (locale == "frFR" and "Combattant du Champ de Bataille" or "Battlefield Combatant"), nameFemale = locale == "deDE" and "Schlachtfeld-Kaempferin" or (locale == "frFR" and "Combattante du Champ de Bataille" or "Battlefield Combatant"), desc = locale == "deDE" and "50 Ehrenhafte Siege" or "50 Honorable Kills", icon = "Interface\\Icons\\Achievement_PVP_A_05", color = {0.6, 0.3, 0.3}, requirement = "pvp_50", priority = 60},
    {id = "pvp_initiate", name = locale == "deDE" and "Ehrenhafter Streiter" or (locale == "frFR" and "Combattant Honorable" or "Honored Combatant"), nameFemale = locale == "deDE" and "Ehrenhafte Streiterin" or (locale == "frFR" and "Combattante Honorable" or "Honored Combatant"), desc = locale == "deDE" and "10 Ehrenhafte Siege" or "10 Honorable Kills", icon = "Interface\\Icons\\Achievement_PVP_A_01", color = {0.5, 0.35, 0.35}, requirement = "pvp_10", priority = 25},

    -- ===========================================================
    -- TODESCHRONIST-TITEL (Gildentode miterlebt - Episch!)
    -- ===========================================================
    {id = "soul_keeper", name = locale == "deDE" and "Hueter der verlorenen Seelen" or (locale == "frFR" and "Gardien des Ames Perdues" or "Keeper of Lost Souls"), nameFemale = locale == "deDE" and "Hueterin der verlorenen Seelen" or (locale == "frFR" and "Gardienne des Ames Perdues" or "Keeper of Lost Souls"), desc = locale == "deDE" and "100 Gildentode miterlebt" or "Witnessed 100 guild deaths", icon = "Interface\\Icons\\Spell_Shadow_Possession", color = {0.6, 0.2, 0.8}, requirement = "witness_100", priority = 310},
    {id = "reaper_companion", name = locale == "deDE" and "Gefaehrte des Sensenmanns" or (locale == "frFR" and "Compagnon de la Faucheuse" or "Reaper's Companion"), nameFemale = locale == "deDE" and "Gefaehrtin des Sensenmanns" or (locale == "frFR" and "Compagne de la Faucheuse" or "Reaper's Companion"), desc = locale == "deDE" and "50 Gildentode miterlebt" or "Witnessed 50 guild deaths", icon = "Interface\\Icons\\Spell_Shadow_RaiseDead", color = {0.5, 0.2, 0.6}, requirement = "witness_50", priority = 205},
    {id = "gravedigger", name = locale == "deDE" and "Totengraeber von Azeroth" or (locale == "frFR" and "Fossoyeur d'Azeroth" or "Gravedigger of Azeroth"), nameFemale = locale == "deDE" and "Totengraeberin von Azeroth" or (locale == "frFR" and "Fossoyeuse d'Azeroth" or "Gravedigger of Azeroth"), desc = locale == "deDE" and "25 Gildentode miterlebt" or "Witnessed 25 guild deaths", icon = "Interface\\Icons\\Spell_Shadow_AnimateDead", color = {0.4, 0.25, 0.5}, requirement = "witness_25", priority = 115},
    {id = "death_chronicler", name = locale == "deDE" and "Chronist des Jenseits" or (locale == "frFR" and "Chroniqueur de l'Au-Dela" or "Chronicler of the Beyond"), nameFemale = locale == "deDE" and "Chronistin des Jenseits" or (locale == "frFR" and "Chroniqueuse de l'Au-Dela" or "Chronicler of the Beyond"), desc = locale == "deDE" and "10 Gildentode miterlebt" or "Witnessed 10 guild deaths", icon = "Interface\\Icons\\INV_Misc_Book_09", color = {0.4, 0.3, 0.5}, requirement = "witness_10", priority = 55},
    {id = "first_witness", name = locale == "deDE" and "Zeuge des Untergangs" or (locale == "frFR" and "Temoin de la Chute" or "Witness of the Fall"), nameFemale = locale == "deDE" and "Zeugin des Untergangs" or (locale == "frFR" and "Temoin de la Chute" or "Witness of the Fall"), desc = locale == "deDE" and "1 Gildentod miterlebt" or "Witnessed 1 guild death", icon = "Interface\\Icons\\Spell_Shadow_DarkSummoning", color = {0.4, 0.3, 0.4}, requirement = "witness_1", priority = 12},

    -- ===========================================================
    -- UEBERLEBENS-TITEL (Echtzeit-Tage - Episch!)
    -- ===========================================================
    {id = "eternal_flame", name = locale == "deDE" and "Ewige Flamme von Azeroth" or (locale == "frFR" and "Flamme Eternelle d'Azeroth" or "Eternal Flame of Azeroth"), nameFemale = locale == "deDE" and "Ewige Flamme von Azeroth" or (locale == "frFR" and "Flamme Eternelle d'Azeroth" or "Eternal Flame of Azeroth"), desc = locale == "deDE" and "365 Tage Echtzeit ueberlebt" or "365 real-time days survived", icon = "Interface\\Icons\\Spell_Holy_Resurrection", color = {1, 0.65, 0}, requirement = "alive_365", priority = 420},
    {id = "unyielding", name = locale == "deDE" and "der Unbeugsame" or (locale == "frFR" and "l'Inflexible" or "the Unyielding"), nameFemale = locale == "deDE" and "die Unbeugsame" or (locale == "frFR" and "l'Inflexible" or "the Unyielding"), desc = locale == "deDE" and "90 Tage Echtzeit ueberlebt" or "90 real-time days survived", icon = "Interface\\Icons\\Spell_Nature_Reincarnation", color = {0.9, 0.6, 0.1}, requirement = "alive_90", priority = 320},
    {id = "ironwill", name = locale == "deDE" and "Eiserner Wille" or (locale == "frFR" and "Volonte de Fer" or "Iron Will"), nameFemale = locale == "deDE" and "Eiserner Wille" or (locale == "frFR" and "Volonte de Fer" or "Iron Will"), desc = locale == "deDE" and "30 Tage Echtzeit ueberlebt" or "30 real-time days survived", icon = "Interface\\Icons\\Spell_Holy_InnerFire", color = {0.7, 0.5, 0.15}, requirement = "alive_30", priority = 190},
    {id = "tenacious", name = locale == "deDE" and "der Zaehe" or (locale == "frFR" and "le Tenace" or "the Tenacious"), nameFemale = locale == "deDE" and "die Zaehe" or (locale == "frFR" and "la Tenace" or "the Tenacious"), desc = locale == "deDE" and "7 Tage Echtzeit ueberlebt" or "7 real-time days survived", icon = "Interface\\Icons\\Spell_Holy_GuardianSpirit", color = {0.5, 0.5, 0.3}, requirement = "alive_7", priority = 42},

    -- ===========================================================
    -- QUEST-TITEL (Episch!)
    -- ===========================================================
    {id = "lorekeeper", name = locale == "deDE" and "Wissenshueter von Azeroth" or (locale == "frFR" and "Gardien du Savoir d'Azeroth" or "Lorekeeper of Azeroth"), nameFemale = locale == "deDE" and "Wissenshueterin von Azeroth" or (locale == "frFR" and "Gardienne du Savoir d'Azeroth" or "Lorekeeper of Azeroth"), desc = locale == "deDE" and "1.000 Quests" or "1,000 Quests", icon = "Interface\\Icons\\INV_Misc_Book_12", color = {0.9, 0.7, 0.2}, requirement = "quest_1000", priority = 290},
    {id = "questmaster", name = locale == "deDE" and "Meister der Auftraege" or (locale == "frFR" and "Maitre des Quetes" or "Master of Quests"), nameFemale = locale == "deDE" and "Meisterin der Auftraege" or (locale == "frFR" and "Maitresse des Quetes" or "Master of Quests"), desc = locale == "deDE" and "500 Quests" or "500 Quests", icon = "Interface\\Icons\\INV_Misc_Note_05", color = {0.7, 0.55, 0.2}, requirement = "quest_500", priority = 185},
    {id = "adventure_seeker", name = locale == "deDE" and "Abenteuer-Sammler" or (locale == "frFR" and "Chercheur d'Aventures" or "Adventure Seeker"), nameFemale = locale == "deDE" and "Abenteuer-Sammlerin" or (locale == "frFR" and "Chercheuse d'Aventures" or "Adventure Seeker"), desc = locale == "deDE" and "250 Quests" or "250 Quests", icon = "Interface\\Icons\\INV_Misc_Note_02", color = {0.6, 0.45, 0.2}, requirement = "quest_250", priority = 95},
    {id = "quest_seeker", name = locale == "deDE" and "Auftragssucher" or (locale == "frFR" and "Chercheur de Quetes" or "Quest Seeker"), nameFemale = locale == "deDE" and "Auftragssucherin" or (locale == "frFR" and "Chercheuse de Quetes" or "Quest Seeker"), desc = locale == "deDE" and "100 Quests" or "100 Quests", icon = "Interface\\Icons\\INV_Misc_Note_01", color = {0.5, 0.4, 0.2}, requirement = "quest_100", priority = 48},

    -- ===========================================================
    -- GILDEN-TITEL (Episch!)
    -- ===========================================================
    {id = "guild_power", name = locale == "deDE" and "Bollwerk der Gilde" or (locale == "frFR" and "Rempart de la Guilde" or "Bulwark of the Guild"), nameFemale = locale == "deDE" and "Bollwerk der Gilde" or (locale == "frFR" and "Rempart de la Guilde" or "Bulwark of the Guild"), desc = locale == "deDE" and "Gilde hat 50+ Mitglieder" or "Guild has 50+ members", icon = "Interface\\Icons\\Spell_Holy_ChampionsBond", color = {0.8, 0.6, 0.2}, requirement = "guild_50", priority = 195},
    {id = "guild_family", name = locale == "deDE" and "Herz der Gilde" or (locale == "frFR" and "Coeur de la Guilde" or "Heart of the Guild"), nameFemale = locale == "deDE" and "Herz der Gilde" or (locale == "frFR" and "Coeur de la Guilde" or "Heart of the Guild"), desc = locale == "deDE" and "Gilde hat 25+ Mitglieder" or "Guild has 25+ members", icon = "Interface\\Icons\\Ability_Warrior_ShieldWall", color = {0.6, 0.5, 0.2}, requirement = "guild_25", priority = 100},
    {id = "guild_companion", name = locale == "deDE" and "Treuer Gildengefaehrte" or (locale == "frFR" and "Compagnon Fidele de la Guilde" or "Loyal Guild Companion"), nameFemale = locale == "deDE" and "Treue Gildengefaehrtin" or (locale == "frFR" and "Compagne Fidele de la Guilde" or "Loyal Guild Companion"), desc = locale == "deDE" and "Gilde hat 10+ Mitglieder" or "Guild has 10+ members", icon = "Interface\\Icons\\Ability_Warrior_RallyingCry", color = {0.5, 0.45, 0.2}, requirement = "guild_10", priority = 43},

    -- ===========================================================
    -- ULTIMATIVER META-TITEL (NEU!)
    -- ===========================================================
    {id = "avatar_azeroth", name = locale == "deDE" and "Avatar von Azeroth" or (locale == "frFR" and "Avatar d'Azeroth" or "Avatar of Azeroth"), nameFemale = locale == "deDE" and "Avatar von Azeroth" or (locale == "frFR" and "Avatar d'Azeroth" or "Avatar of Azeroth"), desc = locale == "deDE" and "Level 60 + Alle Raids + 50k Kills + 30 Tage /played" or "Level 60 + All Raids + 50k Kills + 30d /played", icon = "Interface\\Icons\\INV_Misc_Gem_Pearl_03", color = {1, 0.84, 1}, requirement = "meta_ultimate", priority = 520},
    {id = "eternal_chronicler", name = locale == "deDE" and "Ewiger Chronist der Gefallenen" or (locale == "frFR" and "Chroniqueur Eternel des Tombes" or "Eternal Chronicler of the Fallen"), nameFemale = locale == "deDE" and "Ewige Chronistin der Gefallenen" or (locale == "frFR" and "Chroniqueuse Eternelle des Tombes" or "Eternal Chronicler of the Fallen"), desc = locale == "deDE" and "50 Gildentode + Alle Dungeons" or "50 guild deaths + All Dungeons", icon = "Interface\\Icons\\INV_Misc_Book_11", color = {0.7, 0.4, 0.9}, requirement = "meta_witness_master", priority = 430},
    }
    locale = _prev
    return _defs
end

-- Beide Sprach-Arrays vorbauen (Quellen bleiben unveraendert)
local TITLE_DEFS_DE = _mkTitleDefs("deDE")
local TITLE_DEFS_EN = _mkTitleDefs("enUS")

-- Arbeitskopie mit FRISCHEN Objekten: ApplyLocale re-pointet Felder hier,
-- die Quell-Arrays bleiben sauber. Initial in Client-Sprache (inkl. frFR -> bleibt erhalten).
local TITLE_DEFS = {}
do
    local _srcInit = (locale == "deDE") and TITLE_DEFS_DE
        or ((locale == "frFR") and _mkTitleDefs("frFR") or TITLE_DEFS_EN)
    for i, t in ipairs(_srcInit) do
        local c = {}
        for k, v in pairs(t) do c[k] = v end
        TITLE_DEFS[i] = c
    end
end

-- ==============================================================
-- LOOKUP-TABELLEN
-- ==============================================================

local TITLE_BY_ID = {}
local TITLE_BY_REQUIREMENT = {}

for _, t in ipairs(TITLE_DEFS) do
    TITLE_BY_ID[t.id] = t
    if t.requirement then
        TITLE_BY_REQUIREMENT[t.requirement] = t
    end
end

-- ==============================================================
-- LOCALE NACHZIEHEN: forcedLocale (/gdl lang) ist beim File-Load noch nicht da.
-- Greift NUR bei explizit gesetztem Override (en/de) ein -> im Auto-Modus bleibt
-- die Client-Sprache erhalten (auch frFR). Idempotent: re-pointet Namen/Beschr.
-- ==============================================================
function Titles:ApplyLocale()
    local fl = GuildDeathLogDB and GuildDeathLogDB.forcedLocale
    if fl ~= "deDE" and fl ~= "enUS" then return end
    local useEN = (fl == "enUS")
    locale = useEN and "enUS" or "deDE"
    local src = useEN and TITLE_DEFS_EN or TITLE_DEFS_DE
    for i, t in ipairs(TITLE_DEFS) do
        local s = src[i]
        if s then t.name = s.name; t.nameFemale = s.nameFemale; t.desc = s.desc end
    end
    L_TITLE = useEN and L_TITLE_EN or L_TITLE_DE
end

-- ==============================================================
-- INITIALISIERUNG
-- ==============================================================

function Titles:Initialize()
    if self.initialized then return end
    self.initialized = true
    self:ApplyLocale()  -- forcedLocale ist jetzt verfuegbar -> ggf. Override anwenden
    GuildDeathLogDB.titles = GuildDeathLogDB.titles or {}
    
    -- Migration: alte globale "selected" in charKey verschieben
    if GuildDeathLogDB.titles.selected and type(GuildDeathLogDB.titles.selected) == "string" then
        local charKey = self:GetCharacterKey()
        GuildDeathLogDB.titles[charKey] = GuildDeathLogDB.titles[charKey] or {}
        if not GuildDeathLogDB.titles[charKey].selected then
            GuildDeathLogDB.titles[charKey].selected = GuildDeathLogDB.titles.selected
        end
        GuildDeathLogDB.titles.selected = nil
        GDL:Debug("Titles: Globale Titel-Auswahl nach " .. charKey .. " migriert")
    end

    -- Nameplate-Anzeige + Empfang fremder Titel: IMMER aktiv (kostenloses Feature).
    -- Jeder mit dem Addon sieht Titel anderer Spieler auf Nameplates.
    self:RegisterEvents()
    self:SetupNameplateHook()
    self:SetupCharacterSheet()   -- eigener Titel im Charakterfenster (frei)
    self:SetupTargetFrame()      -- Titel des anvisierten Spielers (frei)
    C_Timer.After(8, function() self:RequestAllTitles() end)

    -- Supporter-Features: eigenen Titel senden, Tooltip-Hook, Chat-Hook
    if GDL:IsSupporterActive() then
        self:SetupTooltipHook()
        self:SetupChatHook()
        C_Timer.After(SYNC_DELAY, function() self:BroadcastTitle() end)
        C_Timer.NewTicker(BROADCAST_INTERVAL, function()
            if GDL:IsSupporterActive() then self:BroadcastTitle() end
        end)
    end

    GDL:Debug("Titles: Modul initialisiert – Nameplate-Anzeige aktiv" ..
        (GDL:IsSupporterActive() and " (+ Supporter-Features)" or ""))
end

function Titles:RegisterEvents()
    if self.eventFrame then return end
    self.eventFrame = CreateFrame("Frame")
    self.eventFrame:RegisterEvent("CHAT_MSG_ADDON")
    self.eventFrame:RegisterEvent("GUILD_ROSTER_UPDATE")
    self.eventFrame:SetScript("OnEvent", function(frame, event, prefix, msg, channel, sender)
        if event == "CHAT_MSG_ADDON" and prefix == TITLE_PREFIX then
            self:HandleAddonMessage(msg, sender)
        elseif event == "GUILD_ROSTER_UPDATE" then
            C_Timer.After(5, function() self:CleanupNonMembers() end)
        end
    end)
end

-- Entfernt Titel-Daten von Ex-Gildenmitgliedern
function Titles:CleanupNonMembers()
    local Guild = GDL:GetModule("Guild")
    if not Guild then return end
    local removed = 0
    for name, _ in pairs(guildTitles) do
        -- Nur entfernen wenn weder Gildenmitglied noch in der aktuellen Gruppe
        local inGroup = UnitInParty(name) or UnitInRaid(name)
        if not Guild:IsMember(name) and not inGroup then
            guildTitles[name] = nil
            removed = removed + 1
        end
    end
    if removed > 0 then
        GDL:Debug("Titles: " .. removed .. " Ex-Mitglieder bereinigt")
    end
end

function Titles:BroadcastTitle()
    if not GDL:IsSupporterActive() then return end
    local selectedTitle = self:GetSelectedTitle()
    if not selectedTitle then return end
    local sex = UnitSex("player") or 2
    local sexCode = (sex == 3) and "F" or "M"
    local msg = "TITLE|" .. selectedTitle.id .. "|" .. sexCode
    if IsInGuild() then
        C_ChatInfo.SendAddonMessage(TITLE_PREFIX, msg, "GUILD")
    end
    -- Auch Party/Raid (damit Nicht-Gildenmitglieder mit Addon den Titel sehen)
    if IsInGroup() then
        C_ChatInfo.SendAddonMessage(TITLE_PREFIX, msg, IsInRaid() and "RAID" or "PARTY")
    end
end

function Titles:RequestAllTitles()
    if IsInGuild() then
        C_ChatInfo.SendAddonMessage(TITLE_PREFIX, "REQUEST", "GUILD")
    end
    if IsInGroup() then
        C_ChatInfo.SendAddonMessage(TITLE_PREFIX, "REQUEST", IsInRaid() and "RAID" or "PARTY")
    end
    GDL:Debug("Titles: Request gesendet")
end

function Titles:HandleAddonMessage(msg, sender)
    if not msg or msg == "" then return end
    local name = strsplit("-", sender)
    local myName = UnitName("player")
    
    -- Eigene Nachrichten für Request ignorieren
    if name == myName and msg == "REQUEST" then return end
    
    if msg == "REQUEST" then
        -- Jemand fragt nach Titeln - unseren senden
        C_Timer.After(math.random() * 2, function()
            self:BroadcastTitle()
        end)
        return
    end
    
    -- Titel-Update verarbeiten (Format: TITLE|id|M oder TITLE|id|F)
    local parts = {strsplit("|", msg)}
    local cmd = parts[1]
    local titleId = parts[2]
    local sexCode = parts[3] or "M"  -- Default: männlich
    
    if cmd == "TITLE" and titleId and TITLE_BY_ID[titleId] then
        -- Speichere Titel UND Geschlecht
        guildTitles[name] = {
            titleId = titleId,
            isFemale = (sexCode == "F")
        }
        GDL:Debug("Titles: " .. name .. " hat Titel " .. titleId .. " (" .. sexCode .. ")")
    elseif TITLE_BY_ID[msg] then
        -- Altes Format (nur ID) - Backward-Kompatibilität
        guildTitles[name] = {
            titleId = msg,
            isFemale = false
        }
    end

    -- Falls dieser Spieler gerade anvisiert ist: Ziel-Label sofort aktualisieren
    if self.UpdateTargetTitle and UnitExists("target") and UnitName("target") == name then
        self:UpdateTargetTitle()
    end
end

function Titles:GetUnlockedTitles()
    local Milestones = GDL:GetModule("Milestones")
    if not Milestones then return {} end
    local unlocked = {}
    for _, title in ipairs(TITLE_DEFS) do
        if title.requirement and Milestones:IsMilestoneUnlocked(title.requirement) then
            table.insert(unlocked, title)
        end
    end
    table.sort(unlocked, function(a, b) return (a.priority or 0) > (b.priority or 0) end)
    return unlocked
end

-- CharacterKey fuer charakter-spezifische Titel-Auswahl
function Titles:GetCharacterKey()
    -- GUID verwenden (gleich wie Milestones) damit Titel-Abfragen mit Meilensteinen übereinstimmen
    local guid = UnitGUID("player")
    if guid then return guid end
    local name = UnitName("player") or "Unknown"
    local realm = GetRealmName() or "Unknown"
    return name .. "-" .. realm
end

function Titles:GetSelectedTitle()
    local charKey = self:GetCharacterKey()
    local charData = GuildDeathLogDB.titles and GuildDeathLogDB.titles[charKey]
    local selectedId = charData and charData.selected
    
    if selectedId and TITLE_BY_ID[selectedId] then
        local Milestones = GDL:GetModule("Milestones")
        if Milestones and Milestones:IsMilestoneUnlocked(TITLE_BY_ID[selectedId].requirement) then
            return TITLE_BY_ID[selectedId]
        end
    end
    -- Fallback: hoechsten freigeschalteten Titel nutzen
    local unlocked = self:GetUnlockedTitles()
    return #unlocked > 0 and unlocked[1] or nil
end

function Titles:SelectTitle(titleId)
    if not TITLE_BY_ID[titleId] then return false end
    local Milestones = GDL:GetModule("Milestones")
    if not Milestones or not Milestones:IsMilestoneUnlocked(TITLE_BY_ID[titleId].requirement) then return false end
    
    local charKey = self:GetCharacterKey()
    GuildDeathLogDB.titles[charKey] = GuildDeathLogDB.titles[charKey] or {}
    local prev = GuildDeathLogDB.titles[charKey].selected
    GuildDeathLogDB.titles[charKey].selected = titleId
    self:BroadcastTitle()
    -- Sofort im Charakterfenster + Ziel-Frame aktualisieren
    if self.RefreshCharacterTitle then self:RefreshCharacterTitle() end
    if self.UpdateTargetTitle    then self:UpdateTargetTitle()    end
    -- Einzeiler in den Gildenchat — nur bei echtem Wechsel, nicht beim Re-Select
    if prev ~= titleId and GuildDeathLogDB.settings.guildPushEnabled ~= false and IsInGuild() then
        local t = TITLE_BY_ID[titleId]
        local isFemale = (UnitSex and UnitSex("player") == 3)
        local tName = (isFemale and t.nameFemale) or t.name
        pcall(SendChatMessage, (L_TITLE.WEARS_TITLE or "Now bears the title: ") .. tName, "GUILD")
    end
    return true
end

function Titles:SetSelectedTitle(titleId) return self:SelectTitle(titleId) end

-- Formatiert einen Titel mit der richtigen Geschlechtsform
function Titles:FormatTitle(title, isFemale)
    if not title then return "" end
    local c = title.color or {1, 1, 1}
    -- Wähle männliche oder weibliche Form
    local titleName = (isFemale and title.nameFemale) or title.name
    return string.format("|cff%02x%02x%02x<%s>|r", c[1]*255, c[2]*255, c[3]*255, titleName)
end

-- Formatiert einen Titel ohne Farbe (für Nameplates etc.)
function Titles:GetTitleText(title, isFemale)
    if not title then return "" end
    return (isFemale and title.nameFemale) or title.name
end

-- Holt Titel-Daten für einen Spieler (mit Geschlecht)
function Titles:GetTitleDataForPlayer(playerName)
    local data = guildTitles[playerName]
    if not data then return nil, false end
    
    -- Neue Struktur: {titleId = "...", isFemale = true/false}
    if type(data) == "table" then
        return TITLE_BY_ID[data.titleId], data.isFemale
    else
        -- Alte Struktur (nur titleId als string) - Backward-Kompatibilität
        return TITLE_BY_ID[data], false
    end
end

-- Legacy-Funktion für Kompatibilität
function Titles:GetTitleForPlayer(playerName)
    local title, _ = self:GetTitleDataForPlayer(playerName)
    return title
end

function Titles:GetFormattedName(playerName)
    local title, isFemale
    local myName = UnitName("player")
    if playerName == myName then
        title = self:GetSelectedTitle()
        isFemale = self:IsPlayerFemale()
    else
        title, isFemale = self:GetTitleDataForPlayer(playerName)
    end
    return title and (playerName .. " " .. self:FormatTitle(title, isFemale)) or playerName
end

-- ==============================================================
-- TOOLTIP INTEGRATION - Zeigt Titel bei Gildenmitgliedern!
-- ==============================================================

function Titles:SetupTooltipHook()
    -- Hook GameTooltip um Titel anzuzeigen
    GameTooltip:HookScript("OnTooltipSetUnit", function(tooltip)
        local _, unit = tooltip:GetUnit()
        if not unit then return end
        
        -- Nur für Spieler
        if not UnitIsPlayer(unit) then return end
        
        -- Nur für Gildenmitglieder
        local unitGuild = GetGuildInfo(unit)
        local myGuild = GetGuildInfo("player")
        if not unitGuild or not myGuild or unitGuild ~= myGuild then return end
        
        -- Spielername ohne Realm
        local name = UnitName(unit)
        if not name then return end
        
        -- Titel ermitteln: eigener Char oder anderer Spieler?
        local title, isFemale
        local myName = UnitName("player")
        if name == myName then
            -- EIGENER Charakter - direkt vom Selected Title holen
            title = self:GetSelectedTitle()
            isFemale = self:IsPlayerFemale()
        else
            -- ANDERER Spieler - aus Sync-Daten
            title, isFemale = self:GetTitleDataForPlayer(name)
        end
        if not title then return end
        
        -- Richtige Geschlechtsform wählen
        local titleText = self:GetTitleText(title, isFemale)
        
        -- Titel zum Tooltip hinzufügen
        local c = title.color or {1, 1, 1}
        tooltip:AddLine(" ")
        tooltip:AddLine("<" .. titleText .. ">", c[1], c[2], c[3])
        tooltip:AddLine(title.desc, 0.7, 0.7, 0.7)
        tooltip:Show()
    end)
    
    GDL:Debug("Titles: Tooltip-Hook aktiviert")
end

-- Chat-Integration entfernt (v5.3.3)
function Titles:SetupChatHook()
    -- Deaktiviert - verursacht Probleme mit WoW Classic
end

-- Toggle Nameplate-Titel
function Titles:ToggleNameplateTitles()
    GuildDeathLogDB.settings = GuildDeathLogDB.settings or {}
    if GuildDeathLogDB.settings.nameplateTitles == nil then
        GuildDeathLogDB.settings.nameplateTitles = true
    end
    GuildDeathLogDB.settings.nameplateTitles = not GuildDeathLogDB.settings.nameplateTitles

    local status = GuildDeathLogDB.settings.nameplateTitles
        and (locale == "deDE" and "|cff00FF00AN|r" or "|cff00FF00ON|r")
        or  (locale == "deDE" and "|cffFF0000AUS|r" or "|cffFF0000OFF|r")
    GDL:Print((locale == "deDE" and "Nameplate-Titel: " or "Nameplate Titles: ") .. status)

    -- Alle sichtbaren Labels sofort aktualisieren (verstecken wenn AUS)
    self:RefreshAllNameplateTitles()
end

-- ==============================================================
-- NAMEPLATE INTEGRATION
-- Ansatz: hooksecurefunc("CompactUnitFrame_UpdateName") –
-- genau wie PlayerTitleNames und ähnliche Addons.
-- Das Label sitzt direkt unter UnitFrame.name, ist an den
-- Blizzard-UnitFrame gebunden und braucht keinen Timer-Polling.
-- Keine schwebenden Orphan-Frames mehr.
-- ==============================================================

function Titles:SetupNameplateHook()
    -- Schritt 1: Beim Erstellen einer Nameplate ein GDL-Label anlegen,
    --            das direkt unter dem UnitFrame.name hängt.
    --            Nameplates werden in WoW gepooled – das Label bleibt
    --            am Pool-Slot und wird nur aktualisiert/versteckt.
    local function AttachLabel(namePlate)
        if namePlate._gdlTitleLabel then return end  -- bereits vorhanden
        local unitFrame = namePlate.UnitFrame
        if not unitFrame or not unitFrame.name then return end

        local label = unitFrame:CreateFontString(nil, "OVERLAY")
        label:SetFont("Fonts\\FRIZQT__.TTF", 9, "OUTLINE")
        -- Direkt unter dem Namenstext – genau wie PlayerTitleNames
        label:SetPoint("TOP", unitFrame.name, "BOTTOM", 0, -1)
        label:Hide()
        namePlate._gdlTitleLabel = label
    end

    -- Alle bereits existierenden Nameplates sofort bestücken
    for _, namePlate in pairs(C_NamePlate.GetNamePlates()) do
        AttachLabel(namePlate)
    end

    -- Zukünftige Nameplates abdecken
    local npFrame = CreateFrame("Frame")
    npFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
    npFrame:SetScript("OnEvent", function(_, _, unitToken)
        local np = C_NamePlate.GetNamePlateForUnit(unitToken)
        if np then
            AttachLabel(np)
            -- Sofortiges Update für alle (kein Supporter-Gate beim Anzeigen)
            self:_UpdateLabel(np, unitToken)
        end
    end)

    -- Schritt 2: hooksecurefunc("CompactUnitFrame_UpdateName")
    --            Feuert bei JEDER Namensänderung (Ziel, Zone, Auswahl).
    --            Damit ist kein Poll-Timer nötig.
    hooksecurefunc("CompactUnitFrame_UpdateName", function(frame)
        -- HÄRTUNG (9.7.4): Dieser Hook feuert SEHR oft (jedes Nameplate-Namens-
        -- update). Ein einziger ungefangener Fehler hier erzeugt Fehler-Spam pro
        -- Frame bis zum /reload. Body komplett in pcall — im Zweifel passiert
        -- lieber nichts, statt das UI zuzumüllen.
        if not frame or type(frame) ~= "table" then return end
        if GuildDeathLogDB.settings and GuildDeathLogDB.settings.nameplateTitles == false then return end
        if not frame.unit or not frame.unit:find("nameplate") then return end
        -- IsForbidden: Schutz gegen Lua-Fehler bei geschützten Frames im Kampf
        if frame.IsForbidden and frame:IsForbidden() then return end

        pcall(function()
            local np = C_NamePlate.GetNamePlateForUnit(frame.unit)
            if not np then return end
            AttachLabel(np)  -- Sicherheitsnetz falls Label fehlt
            self:_UpdateLabel(np, frame.unit)
        end)
    end)

    GDL:Debug("Titles: Nameplate-Hook (CompactUnitFrame_UpdateName) aktiviert")
end

-- Internes Update eines einzelnen Labels anhand des UnitTokens.
-- Wird von sowohl dem Event als auch dem hooksecurefunc aufgerufen.
function Titles:_UpdateLabel(namePlate, unitToken)
    local label = namePlate._gdlTitleLabel
    if not label then return end

    -- Früh raus wenn Feature deaktiviert
    if GuildDeathLogDB.settings and GuildDeathLogDB.settings.nameplateTitles == false then
        label:Hide()
        return
    end

    -- Nur Spieler
    if not UnitIsPlayer(unitToken) then
        label:Hide()
        return
    end

    local name = UnitName(unitToken)
    if not name then
        label:Hide()
        return
    end

    -- Titel ermitteln: eigener Char oder Sync-Daten (kein Guild-Gate – jeder mit Addon-Daten wird gezeigt)
    local title, isFemale
    if name == UnitName("player") then
        title = self:GetSelectedTitle()
        isFemale = self:IsPlayerFemale()
    else
        title, isFemale = self:GetTitleDataForPlayer(name)
    end

    if not title then
        label:Hide()
        return
    end

    local titleText = self:GetTitleText(title, isFemale)
    local c = title.color or {1, 1, 1}
    label:SetText(string.format("|cff%02x%02x%02x<%s>|r", c[1]*255, c[2]*255, c[3]*255, titleText))
    label:Show()
end

-- Alle aktuell sichtbaren Nameplates neu zeichnen / verstecken.
-- Wird von ToggleNameplateTitles und Code-Einlösung genutzt.
function Titles:RefreshAllNameplateTitles()
    for _, namePlate in pairs(C_NamePlate.GetNamePlates()) do
        if namePlate._gdlTitleLabel then
            if GuildDeathLogDB.settings and GuildDeathLogDB.settings.nameplateTitles == false then
                namePlate._gdlTitleLabel:Hide()
            else
                -- Unit-Token korrekt suchen (BUG FIX: war "GetNamePlateForUnit and nil" = immer nil)
                local unit = nil
                for i = 1, 40 do
                    local tok = "nameplate" .. i
                    if UnitExists(tok) and C_NamePlate.GetNamePlateForUnit(tok) == namePlate then
                        unit = tok
                        break
                    end
                end
                if unit then
                    self:_UpdateLabel(namePlate, unit)
                end
            end
        end
    end
end

-- Prüft ob der eigene Charakter weiblich ist
function Titles:IsPlayerFemale()
    local sex = UnitSex("player")
    return sex == 3  -- 3 = female
end

-- ==============================================================
-- CHARAKTERFENSTER + ZIEL-FRAME: gewaehlten Titel anzeigen
-- Eigener Titel lokal, fremde aus Sync. Geschlechtskorrekt.
-- Frei (wie Nameplates) – kein Supporter-Gate.
-- ==============================================================

-- Charakterfenster: eigenen gewaehlten Titel ueber dem Modell anzeigen
function Titles:RefreshCharacterTitle()
    local fs = self._charTitleFS
    if not fs then return end
    local title = self:GetSelectedTitle()
    if not title then fs:Hide(); return end
    -- Wie die Header-Zeilen drueber: nativer Standard-Font + -Farbe, mit < >
    local nm = self:GetTitleText(title, self:IsPlayerFemale())
    fs:SetText("<" .. nm .. ">")

    -- Horizontal exakt auf die Charakterfenster-Mitte ausrichten (wie die
    -- Standard-Header-Zeilen), nicht auf die Modell-Mitte (die sitzt links).
    -- dx = Versatz Fenster-Mitte <-> Modell-Mitte, in lokalen Pixeln.
    local model = _G.CharacterModelScene or _G.CharacterModelFrame or _G.PaperDollFrame
    local cf    = _G.CharacterFrame
    local dx = 0
    if cf and model and cf.GetCenter and model.GetCenter then
        local fcx = cf:GetCenter()
        local mcx = model:GetCenter()
        local sc  = (model.GetEffectiveScale and model:GetEffectiveScale()) or 1
        if fcx and mcx and sc and sc > 0 then dx = (fcx - mcx) / sc end
    end
    fs:ClearAllPoints()
    fs:SetPoint("BOTTOM", model, "TOP", dx, 9)
    fs:Show()
end

function Titles:SetupCharacterSheet()
    if self._charTitleFS then return end
    local model = _G.CharacterModelScene or _G.CharacterModelFrame
    local host  = _G.PaperDollFrame or _G.CharacterFrame
    if not host then return end

    -- Eigene Zeile im Header (knapp ueber dem Modell), exakt im Stil der
    -- Standard-Zeilen darueber: GameFontNormalSmall (gelb), kein Hintergrund.
    local fs = host:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    fs:SetPoint("BOTTOM", model or host, "TOP", 0, 9)
    fs:SetJustifyH("CENTER")
    self._charTitleFS = fs

    if host.HookScript then
        host:HookScript("OnShow", function()
            self:RefreshCharacterTitle()
            -- Nach dem Layout nochmal: erst dann liefern GetCenter() saubere Werte
            if C_Timer then C_Timer.After(0, function() self:RefreshCharacterTitle() end) end
        end)
    end
    self:RefreshCharacterTitle()
end

-- Ziel-Frame: Titel des anvisierten Spielers unter dem Namen
function Titles:UpdateTargetTitle()
    local fs = self._targetTitleFS
    if not fs then return end
    if not UnitExists("target") or not UnitIsPlayer("target") then fs:Hide(); return end
    local name = UnitName("target")
    if not name then fs:Hide(); return end

    local title, isFemale
    if name == UnitName("player") then
        title = self:GetSelectedTitle(); isFemale = self:IsPlayerFemale()
    else
        title, isFemale = self:GetTitleDataForPlayer(name)
    end
    if not title then fs:Hide(); return end

    -- Sichtbares Ziel: echtes Geschlecht bevorzugen (sonst Sync-Wert)
    if UnitSex then
        local sx = UnitSex("target")
        if sx == 2 or sx == 3 then isFemale = (sx == 3) end
    end
    fs:SetText(self:FormatTitle(title, isFemale))
    fs:Show()
end

function Titles:SetupTargetFrame()
    if self._targetTitleFS then return end
    local tf = _G.TargetFrame
    if not tf then return end
    local fs = tf:CreateFontString(nil, "OVERLAY")
    fs:SetFont("Fonts\\FRIZQT__.TTF", 10, "OUTLINE")
    local nameAnchor = _G.TargetFrameTextureFrameName or tf
    fs:SetPoint("TOP", nameAnchor, "BOTTOM", 0, -1)
    fs:SetJustifyH("CENTER")
    self._targetTitleFS = fs
    if not self._targetEventFrame then
        self._targetEventFrame = CreateFrame("Frame")
        self._targetEventFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
        self._targetEventFrame:SetScript("OnEvent", function() self:UpdateTargetTitle() end)
    end
    self:UpdateTargetTitle()
end

function Titles:OnMilestoneUnlocked(milestoneId)
    -- Nur wenn Supporter aktiv
    if not GDL:IsSupporterActive() then return end
    
    local title = TITLE_BY_REQUIREMENT[milestoneId]
    if not title then return end
    
    -- Eigenes Geschlecht für korrekte Anzeige
    local isFemale = self:IsPlayerFemale()
    
    GDL:Print("=======================================")
    GDL:Print("|cffFFD100" .. L_TITLE.NEW_TITLE .. "|r")
    GDL:Print(self:FormatTitle(title, isFemale))
    GDL:Print("|cffAAAAAA" .. title.desc .. "|r")
    GDL:Print("|cff888888" .. L_TITLE.USE_TITLES .. "|r")
    GDL:Print("=======================================")
    PlaySound(8959)
end

function Titles:GetStats()
    local unlocked = self:GetUnlockedTitles()
    return #unlocked, #TITLE_DEFS
end

function Titles:PrintTitles()
    local unlocked = self:GetUnlockedTitles()
    local unlockedCount, total = self:GetStats()
    local selected = self:GetSelectedTitle()
    
    -- Eigenes Geschlecht für korrekte Anzeige
    local isFemale = self:IsPlayerFemale()
    
    GDL:Print("=== " .. L_TITLE.YOUR_TITLES .. " (" .. unlockedCount .. "/" .. total .. ") ===")
    for _, title in ipairs(unlocked) do
        local marker = (selected and selected.id == title.id) and " |cff00FF00< " .. L_TITLE.ACTIVE .. "|r" or ""
        GDL:Print("  " .. self:FormatTitle(title, isFemale) .. marker)
    end
    GDL:Print("|cff888888" .. L_TITLE.USE_TITLES .. "|r")
end

function Titles:GetAllTitles() return TITLE_DEFS end
function Titles:GetTitleById(titleId) return TITLE_BY_ID[titleId] end

local initFrame = CreateFrame("Frame")
initFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
initFrame:SetScript("OnEvent", function(self, event)
    if event == "PLAYER_ENTERING_WORLD" then
        C_Timer.After(4, function() Titles:Initialize() end)
        self:UnregisterEvent("PLAYER_ENTERING_WORLD")
    end
end)

GDL:RegisterModule("Titles", Titles)
