-- This file is generated by ChatGPT for MSUF (Fonts split)
-- Options\MSUF_Options_Fonts.lua

local addonName, ns = ...
ns = ns or {}

-- Fonts tab builder extracted from Options\MSUF_Options_Core.lua (cumulative, no regression).
function ns.MSUF_Options_Fonts_Build(panel, fontGroup)
    if not panel or not fontGroup then return end

    -- Safe cleanup (no behavior change):
    -- This builder was extracted from Options_Core, where many variables were locals.
    -- After splitting, plain assignments would create accidental globals.
    -- Predeclare the intended locals once so later assignments stay scoped.
    local fontTitle, globalFontHeader, globalFontLine, fontColorHeader, fontColorLine
    local fontDrop, fontChoices, names, used, info
    local boldCheck, noOutlineCheck, nameClassColorCheck, npcNameRedCheck, powerTextColorByTypeCheck, shortenNamesCheck, textBackdropCheck
    local shortenNameMaxCharsSlider, shortenNameFrontMaskSlider
    local textSizeHeader, textSizeLine
    local nameFontSizeSlider, hpFontSizeSlider, powerFontSizeSlider, castbarSpellNameFontSizeSlider

    -- EnsureDB: in Options_Core this is often a local helper.
    -- After splitting, we must not rely on it being global.
    local function EnsureDB()
        local fn = _G and _G.EnsureDB
        if type(fn) == "function" then
            return fn()
        end

        local fn2 = (ns and ns.MSUF_UnitframeCore and ns.MSUF_UnitframeCore.UFCore_EnsureDBOnce)
            or (_G and _G.UFCore_EnsureDBOnce)

        if type(fn2) == "function" then
            return pcall(fn2)
        end
    end

    -- Late-bind helpers from Core (available once CreateOptionsPanel() runs).
    local CreateLabeledSlider = (ns and (ns.MSUF_CreateLabeledSlider or ns.CreateLabeledSlider)) or _G.CreateLabeledSlider
    local MSUF_ExpandDropdownClickArea = (ns and ns.MSUF_ExpandDropdownClickArea) or _G.MSUF_ExpandDropdownClickArea

    if type(CreateLabeledSlider) ~= "function" then
        local warn = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontDisableSmall")
        warn:SetPoint("TOPLEFT", fontGroup, "TOPLEFT", 16, -140)
        warn:SetText("MSUF: Fonts builder missing CreateLabeledSlider (Core export).")
        return
    end
    if type(MSUF_ExpandDropdownClickArea) ~= "function" then
        -- Safe fallback: no click-area expansion (still functional).
        MSUF_ExpandDropdownClickArea = function() end
    end

    -- LibSharedMedia access:
    -- In Options_Core this is usually provided via a local MSUF_GetLSM helper.
    -- After splitting, we must not rely on a global. Keep a robust fallback.
    local function MSUF_GetLSM_Compat()
        local fn = (ns and ns.MSUF_GetLSM) or (_G and _G.MSUF_GetLSM)
        if type(fn) == "function" then
            local ok, lib = pcall(fn)
            if ok then return lib end
        end

        if _G and _G.LibStub then
            local ok, lib = pcall(_G.LibStub, "LibSharedMedia-3.0", true)
            if ok then return lib end
        end
        return nil
    end

    -- Castbars LoD ensure helper:
    -- In Options_Core this may exist as a global/core helper. After splitting, don't assume it.
    local function MSUF_EnsureCastbars_Compat()
        local fn = (ns and ns.MSUF_EnsureCastbars) or (_G and _G.MSUF_EnsureCastbars)
        if type(fn) == "function" then
            pcall(fn)
            return
        end

        local ensureAddon = _G and _G.MSUF_EnsureAddonLoaded
        if type(ensureAddon) == "function" then
            pcall(ensureAddon, "MidnightSimpleUnitFrames_Castbars")
            return
        end

        if _G and _G.LoadAddOn then
            pcall(_G.LoadAddOn, "MidnightSimpleUnitFrames_Castbars")
        end
    end

    -- Use the *real* scrollable dropdown helper exported by Options_Core.
    -- (Our previous self-contained scroll shim broke UIDropDownMenu behavior on some clients.)
    local MSUF_MakeDropdownScrollable = (ns and ns.MSUF_MakeDropdownScrollable) or (_G and _G.MSUF_MakeDropdownScrollable)
    if type(MSUF_MakeDropdownScrollable) ~= "function" then
        MSUF_MakeDropdownScrollable = function() end
    end

    -- Layout request helper (exported by Options_Core). Keep a safe fallback.
    local function MSUF_Options_RequestLayoutAll_Compat(reason)
        local fn = (ns and ns.MSUF_Options_RequestLayoutAll) or (_G and _G.MSUF_Options_RequestLayoutAll)
        if type(fn) == "function" then
            return fn(reason)
        end

        -- Fallback (older cores): request per-unit layouts if possible.
        local req = _G and _G.MSUF_UFCore_RequestLayoutForUnit
        if type(req) == "function" then
            for _, k in ipairs({ "player", "target", "focus", "targettarget", "pet", "boss" }) do
                pcall(req, k, reason or "OPTIONS_ALL", (k == "target" or k == "focus" or k == "targettarget"))
            end
            return
        end

        if type(_G.ApplyAllSettings) == "function" then
            pcall(_G.ApplyAllSettings)
        end
    end

    -- Call into main/module font refresh (main chunk may keep this local; main exports MSUF_UpdateAllFonts)
    local function MSUF_CallUpdateAllFonts()
        local fn
        if _G then
            fn = _G.MSUF_UpdateAllFonts or _G.UpdateAllFonts
        end
        if (not fn) and ns and ns.MSUF_UpdateAllFonts then
            fn = ns.MSUF_UpdateAllFonts
        end
        if type(fn) == "function" then
            return fn()
        end
    end

        fontTitle = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
        fontTitle:SetPoint("TOPLEFT", fontGroup, "TOPLEFT", 16, -140)

    globalFontHeader = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontNormal")
    globalFontHeader:SetPoint("TOPLEFT", fontGroup, "TOPLEFT", 16, -140)
    globalFontHeader:SetText("Global font")

    globalFontLine = fontGroup:CreateTexture(nil, "ARTWORK")
    globalFontLine:SetColorTexture(1, 1, 1, 0.2)
    globalFontLine:SetSize(220, 1)
    globalFontLine:SetPoint("TOPLEFT", globalFontHeader, "BOTTOMLEFT", 0, -4)

    fontColorHeader = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontNormal")
    fontColorHeader:SetPoint("TOPLEFT", fontGroup, "TOPLEFT", 276, -140)
    fontColorHeader:SetText("Font color & style")

    fontColorLine = fontGroup:CreateTexture(nil, "ARTWORK")
    fontColorLine:SetColorTexture(1, 1, 1, 0.2)
    fontColorLine:SetSize(260, 1)
    fontColorLine:SetPoint("TOPLEFT", fontColorHeader, "BOTTOMLEFT", 0, -4)

    fontDrop = CreateFrame("Frame", "MSUF_FontDropdown", fontGroup, "UIDropDownMenuTemplate")
    MSUF_ExpandDropdownClickArea(fontDrop)
    fontDrop:SetPoint("TOPLEFT", globalFontLine, "BOTTOMLEFT", -16, -8)

        fontChoices = {}

        local function MSUF_RebuildFontChoices()
            fontChoices = {}

            local internal = (_G.MSUF_FONT_LIST or FONT_LIST or {})
            for _, info in ipairs(internal) do
                table.insert(fontChoices, {
                    key   = info.key,   -- e.g. "FRIZQT" / "EXPRESSWAY"
                    label = info.name,  -- dropdown label
                    path  = info.path,  -- file path for internal fonts (may be nil)
                })
            end

	            local LSM = MSUF_GetLSM_Compat()
            if LSM then
                -- Make sure internal / Blizzard fonts are also resolvable via LibSharedMedia.
                -- IMPORTANT: LSM:Fetch("font", key) will *always* return the library default if the key isn't registered,
                -- which makes Blizzard's built-in keys (FRIZQT/ARIALN/MORPHEUS/SKURRI) look "dead".
                -- Use noDefault=true when checking existence, then register the built-ins if missing.
                if LSM.Register then
                    for _, data in ipairs(fontChoices) do
                        local k  = data.key
                        local fp = data.path
                        if k and k ~= "" and fp and fp ~= "" then
                            local existing
                            if LSM.Fetch then
                                local okFetch, val = pcall(LSM.Fetch, LSM, "font", k, true) -- noDefault=true
                                if okFetch then existing = val end
                            end

                            if not existing then
                                pcall(LSM.Register, LSM, "font", k, fp)
                            end
                        end
                    end
                end

                names = LSM:List("font")
                table.sort(names)

                used = {}
                for _, e in ipairs(fontChoices) do
                    used[e.key] = true   -- dedupe by KEY
                end

                for _, name in ipairs(names) do
                    if not used[name] then
                        table.insert(fontChoices, {
                            key   = name,  -- key that LSM:Fetch expects
                            label = name,
                        })
                        used[name] = true
                    end
                end
            end
        end

    local function FontDropdown_Initialize(self, level)
        EnsureDB()

        if not fontChoices or #fontChoices == 0 then
            MSUF_RebuildFontChoices()
        end

        info = UIDropDownMenu_CreateInfo()
        local fontKey = MSUF_DB.general.fontKey

        for _, data in ipairs(fontChoices) do
            local thisKey   = data.key
            local thisLabel = data.label

            info.text       = thisLabel
            info.value      = thisKey

            local _fp = _G.MSUF_GetFontPreviewObject or MSUF_GetFontPreviewObject or (ns and ns.MSUF_GetFontPreviewObject)
            if _fp then
                info.fontObject = _fp(thisKey)
            else
                info.fontObject = GameFontHighlightSmall
            end

            info.func = function()
                EnsureDB()
                MSUF_DB.general.fontKey = thisKey

                UIDropDownMenu_SetSelectedValue(fontDrop, thisKey)
                UIDropDownMenu_SetText(fontDrop, thisLabel)

                MSUF_CallUpdateAllFonts()

                if C_Timer and C_Timer.After then
                    C_Timer.After(0, function()
                        MSUF_CallUpdateAllFonts()
                    end)
                end
            end

            info.checked = (fontKey == thisKey)
            UIDropDownMenu_AddButton(info, level)
        end
    end
        UIDropDownMenu_Initialize(fontDrop, FontDropdown_Initialize)
        UIDropDownMenu_SetWidth(fontDrop, 180)

    			-- IMPORTANT: Do NOT disable this dropdown when LibSharedMedia is missing.
    			-- Users must still be able to pick Blizzard/bundled fonts from MSUF_FONT_LIST.

        fontDrop._msufButtonWidth = 180
        MSUF_MakeDropdownScrollable(fontDrop, 12)
        do
            local fontKey2 = MSUF_DB.general.fontKey
            local currentLabel = fontKey2
            for _, data in ipairs(fontChoices) do
                if data.key == fontKey2 then
                    currentLabel = data.label
                    break
                end
            end
            UIDropDownMenu_SetSelectedValue(fontDrop, fontKey2)
            UIDropDownMenu_SetText(fontDrop, currentLabel)
        end
    local colorList = {
        { key = "white",     r=1,   g=1,   b=1,   label="White" },
        { key = "black",     r=0,   g=0,   b=0,   label="Black" },
        { key = "red",       r=1,   g=0,   b=0,   label="Red" },
        { key = "green",     r=0,   g=1,   b=0,   label="Green" },
        { key = "blue",      r=0,   g=0,   b=1,   label="Blue" },
        { key = "yellow",    r=1,   g=1,   b=0,   label="Yellow" },
        { key = "cyan",      r=0,   g=1,   b=1,   label="Cyan" },
        { key = "magenta",   r=1,   g=0,   b=1,   label="Magenta" },
        { key = "orange",    r=1,   g=0.5, b=0,   label="Orange" },
        { key = "purple",    r=0.6, g=0,   b=0.8, label="Purple" },
        { key = "pink",      r=1,   g=0.6, b=0.8, label="Pink" },
        { key = "turquoise", r=0,   g=0.9, b=0.8, label="Turquoise" },
        { key = "grey",      r=0.5, g=0.5, b=0.5, label="Grey" },
        { key = "brown",     r=0.6, g=0.3, b=0.1, label="Brown" },
        { key = "gold",      r=1,   g=0.85,b=0.1, label="Gold" },
    }

    -- Keep a copy on the panel for split-modules and future refactors.
    -- Also keep the legacy global table (Core LoadFromDB still falls back to it).
    panel.__MSUF_COLOR_LIST = colorList
    _G.MSUF_COLOR_LIST = colorList

            boldCheck = CreateFrame("CheckButton", "MSUF_BoldTextCheck", fontGroup, "UICheckButtonTemplate")
        boldCheck:SetPoint("TOPLEFT", fontColorLine, "BOTTOMLEFT", 0, -12)
        boldCheck.text = _G["MSUF_BoldTextCheckText"]
        boldCheck.text:SetText("Use bold text (THICKOUTLINE)")

        noOutlineCheck = CreateFrame("CheckButton", "MSUF_NoOutlineCheck", fontGroup, "UICheckButtonTemplate")
        noOutlineCheck:SetPoint("TOPLEFT", boldCheck, "BOTTOMLEFT", 0, -4)
        noOutlineCheck.text = _G["MSUF_NoOutlineCheckText"]
        noOutlineCheck.text:SetText("Disable black outline around text")

        nameClassColorCheck = CreateFrame("CheckButton", "MSUF_NameClassColorCheck", fontGroup, "UICheckButtonTemplate")
        nameClassColorCheck:SetPoint("TOPLEFT", noOutlineCheck, "BOTTOMLEFT", 0, -4)
        nameClassColorCheck.text = _G["MSUF_NameClassColorCheckText"]
        nameClassColorCheck.text:SetText("Color player names by class")

        npcNameRedCheck = CreateFrame("CheckButton", "MSUF_NPCNameRedCheck", fontGroup, "UICheckButtonTemplate")
        npcNameRedCheck:SetPoint("TOPLEFT", nameClassColorCheck, "BOTTOMLEFT", 0, -4)
        npcNameRedCheck.text = _G["MSUF_NPCNameRedCheckText"]
        npcNameRedCheck.text:SetText("Color NPC/boss names using NPC colors")

        powerTextColorByTypeCheck = CreateFrame("CheckButton", "MSUF_PowerTextColorByTypeCheck", fontGroup, "UICheckButtonTemplate")
        powerTextColorByTypeCheck:SetPoint("TOPLEFT", npcNameRedCheck, "BOTTOMLEFT", 0, -4)
        powerTextColorByTypeCheck.text = _G["MSUF_PowerTextColorByTypeCheckText"]
        powerTextColorByTypeCheck.text:SetText("Color power text by power type")

        shortenNamesCheck = CreateFrame("CheckButton", "MSUF_ShortenNamesCheck", fontGroup, "UICheckButtonTemplate")
        shortenNamesCheck:SetPoint("TOPLEFT", powerTextColorByTypeCheck, "BOTTOMLEFT", 0, -4)
        shortenNamesCheck.text = _G["MSUF_ShortenNamesCheckText"]
        shortenNamesCheck.text:SetText("Shorten unit names (except Player)")

        -- Name shortening direction (secret-safe viewport clip)
        local shortenNameClipSideLabel = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontNormal")
        shortenNameClipSideLabel:SetPoint("TOPLEFT", shortenNamesCheck, "BOTTOMLEFT", 16, -12)
        shortenNameClipSideLabel:SetText("Truncation style")

        local shortenNameClipSideDrop = CreateFrame("Frame", "MSUF_ShortenNameClipSideDrop", fontGroup, "UIDropDownMenuTemplate")
        if MSUF_ExpandDropdownClickArea then MSUF_ExpandDropdownClickArea(shortenNameClipSideDrop) end
        shortenNameClipSideDrop:SetPoint("TOPLEFT", shortenNameClipSideLabel, "BOTTOMLEFT", -16, -4)
        UIDropDownMenu_SetWidth(shortenNameClipSideDrop, 180)

        local function MSUF_GetShortenClipSideLabel(value)
            if value == "RIGHT" then
                return "Keep start (show first letters)"
            end
            return "Keep end (show last letters)"
        end

        local function MSUF_UpdateShortenMaskLabel()
            local side = (MSUF_DB and MSUF_DB.general and MSUF_DB.general.shortenNameClipSide) or "LEFT"
            local shortenEnabled = (MSUF_DB and MSUF_DB.shortenNames) and true or false
            local t = _G["MSUF_ShortenNameFrontMaskSliderText"]
            if t and t.SetText then
                if not shortenEnabled then
                    t:SetText("Reserved space")
                elseif side == "RIGHT" then
                    t:SetText("Reserved space (unused)")
                else
                    t:SetText("Reserved space (left)")
                end
            end

            -- Legacy mode uses pure FontString width clipping (no viewport inset), so mask is irrelevant.
            if shortenNameFrontMaskSlider and shortenNameFrontMaskSlider.Enable and shortenNameFrontMaskSlider.Disable then
                if not shortenEnabled then
                    shortenNameFrontMaskSlider:Disable()
                elseif side == "RIGHT" then
                    shortenNameFrontMaskSlider:Disable()
                else
                    shortenNameFrontMaskSlider:Enable()
                end
            end
        end

        local function MSUF_ShortenClipSide_OnSelect(value)
            EnsureDB()
            MSUF_DB.general.shortenNameClipSide = value
            UIDropDownMenu_SetSelectedValue(shortenNameClipSideDrop, value)
            UIDropDownMenu_SetText(shortenNameClipSideDrop, MSUF_GetShortenClipSideLabel(value))
            MSUF_UpdateShortenMaskLabel()

            if MSUF_DB.shortenNames then
                if MSUF_CallUpdateAllFonts then MSUF_CallUpdateAllFonts() end
                if ns and ns.MSUF_RefreshAllFrames then ns.MSUF_RefreshAllFrames() end
            end
        end

        UIDropDownMenu_Initialize(shortenNameClipSideDrop, function(self, level)
            if not level then return end
            EnsureDB()
            local g = MSUF_DB.general or {}
            local current = g.shortenNameClipSide or "LEFT"

            local function AddOption(text, value)
                local info = UIDropDownMenu_CreateInfo()
                info.text = text
                info.value = value
                info.func = function()
                    MSUF_ShortenClipSide_OnSelect(value)
                end
                info.checked = (current == value)
                UIDropDownMenu_AddButton(info, level)
            end

            AddOption("Keep end (show last letters)", "LEFT")
            AddOption("Keep start (show first letters)", "RIGHT")
        end)

        shortenNameClipSideDrop:SetScript("OnShow", function(self)
            EnsureDB()
            local g = MSUF_DB.general or {}
            local current = g.shortenNameClipSide or "LEFT"
            UIDropDownMenu_SetSelectedValue(self, current)
            UIDropDownMenu_SetText(self, MSUF_GetShortenClipSideLabel(current))
            MSUF_UpdateShortenMaskLabel()
        end)

    -- R41z0r-style name shortening control (secret-safe: width clipping only)
    shortenNameMaxCharsSlider = CreateFrame("Slider", "MSUF_ShortenNameMaxCharsSlider", fontGroup, "OptionsSliderTemplate")
    shortenNameMaxCharsSlider:SetWidth(180)
    shortenNameMaxCharsSlider:SetMinMaxValues(6, 30)
    shortenNameMaxCharsSlider:SetValueStep(1)
    shortenNameMaxCharsSlider:SetObeyStepOnDrag(true)
    shortenNameMaxCharsSlider:SetPoint("TOPLEFT", shortenNameClipSideDrop, "BOTTOMLEFT", 16, -18)

    _G["MSUF_ShortenNameMaxCharsSliderLow"]:SetText("6")
    _G["MSUF_ShortenNameMaxCharsSliderHigh"]:SetText("30")
    _G["MSUF_ShortenNameMaxCharsSliderText"]:SetText("Max name length")

    if MSUF_StyleSlider then
        MSUF_StyleSlider(shortenNameMaxCharsSlider)
    end

    -- Front mask (px): secret-safe viewport inset using a clipping frame (no overlay color)
    shortenNameFrontMaskSlider = CreateFrame("Slider", "MSUF_ShortenNameFrontMaskSlider", fontGroup, "OptionsSliderTemplate")
    shortenNameFrontMaskSlider:SetWidth(180)
    shortenNameFrontMaskSlider:SetMinMaxValues(0, 40)
    shortenNameFrontMaskSlider:SetValueStep(1)
    shortenNameFrontMaskSlider:SetObeyStepOnDrag(true)
    	shortenNameFrontMaskSlider:SetPoint("TOPLEFT", shortenNameMaxCharsSlider, "BOTTOMLEFT", 0, -28)

    _G["MSUF_ShortenNameFrontMaskSliderLow"]:SetText("0")
    _G["MSUF_ShortenNameFrontMaskSliderHigh"]:SetText("40")
    _G["MSUF_ShortenNameFrontMaskSliderText"]:SetText("Reserved space")

    if MSUF_StyleSlider then
        MSUF_StyleSlider(shortenNameFrontMaskSlider)
    end

    -- Info icon (click the "i" to show details)
    local msufShortenInfoBtn = CreateFrame("Button", "MSUF_ShortenNameInfoButton", fontGroup)
    msufShortenInfoBtn:SetSize(16, 16)
    msufShortenInfoBtn:SetPoint("TOPLEFT", shortenNameFrontMaskSlider, "BOTTOMLEFT", 0, -10)
    msufShortenInfoBtn:SetNormalTexture("Interface\\FriendsFrame\\InformationIcon")
    msufShortenInfoBtn:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD")
    msufShortenInfoBtn:SetHitRectInsets(-4, -4, -4, -4)

    msufShortenInfoBtn:SetScript("OnClick", function(self)
        if GameTooltip:IsOwned(self) and GameTooltip:IsShown() then
            GameTooltip:Hide()
            return
        end
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        -- GameTooltip:SetText signature differs across client versions.
        -- Keep it ultra-safe (no optional color/alpha params), use AddLine for colored/wrapped text.
        GameTooltip:SetText("Name Shortening")
        EnsureDB()
        local side = (MSUF_DB and MSUF_DB.general and MSUF_DB.general.shortenNameClipSide) or "LEFT"
        if side == "RIGHT" then
            GameTooltip:AddLine("Keep start: shows the first letters (clips the end).", 1, 1, 1, true)
            GameTooltip:AddLine("Legacy clean mode uses plain FontString width clipping.", 0.95, 0.95, 0.95, true)
        else
            GameTooltip:AddLine("Keep end: shows the last letters (clips the beginning).", 1, 1, 1, true)
            GameTooltip:AddLine("Reserved space protects the clipped edge (avoids overlaps).", 0.95, 0.95, 0.95, true)
        end
        GameTooltip:Show()
    end)


        textBackdropCheck = CreateFrame("CheckButton", "MSUF_TextBackdropCheck", fontGroup, "UICheckButtonTemplate")
        textBackdropCheck:SetPoint("TOPLEFT", shortenNameFrontMaskSlider, "BOTTOMLEFT", 0, -4)
        textBackdropCheck.text = _G["MSUF_TextBackdropCheckText"]
        textBackdropCheck.text:SetText("Add text shadow (backdrop)")

        EnsureDB()
        boldCheck:SetChecked(MSUF_DB.general.boldText and true or false)
        noOutlineCheck:SetChecked(MSUF_DB.general.noOutline and true or false)  -- NEW
        nameClassColorCheck:SetChecked(MSUF_DB.general.nameClassColor and true or false)
        npcNameRedCheck:SetChecked(MSUF_DB.general.npcNameRed and true or false)
        if powerTextColorByTypeCheck then
            powerTextColorByTypeCheck:SetChecked(MSUF_DB.general.colorPowerTextByType and true or false)
        end

    local g = MSUF_DB.general
    if g.shortenNameMaxChars == nil then g.shortenNameMaxChars = 6 end
    g.shortenNameMaxChars = tonumber(g.shortenNameMaxChars) or 6
    if g.shortenNameMaxChars < 4 then g.shortenNameMaxChars = 4 end
    if g.shortenNameMaxChars > 40 then g.shortenNameMaxChars = 40 end

    if g.shortenNameFrontMaskPx == nil then g.shortenNameFrontMaskPx = 8 end
    g.shortenNameFrontMaskPx = tonumber(g.shortenNameFrontMaskPx) or 8
    if g.shortenNameFrontMaskPx < 0 then g.shortenNameFrontMaskPx = 0 end
    if g.shortenNameFrontMaskPx > 40 then g.shortenNameFrontMaskPx = 40 end

    if g.shortenNameClipSide == nil then g.shortenNameClipSide = "LEFT" end
    if g.shortenNameShowDots == nil then g.shortenNameShowDots = true end

    if shortenNameMaxCharsSlider then shortenNameMaxCharsSlider:SetValue(g.shortenNameMaxChars) end
    if shortenNameFrontMaskSlider then shortenNameFrontMaskSlider:SetValue(g.shortenNameFrontMaskPx) end
    shortenNamesCheck:SetChecked(MSUF_DB.shortenNames and true or false)

    if shortenNameClipSideDrop then
        UIDropDownMenu_SetSelectedValue(shortenNameClipSideDrop, g.shortenNameClipSide)
        UIDropDownMenu_SetText(shortenNameClipSideDrop, MSUF_GetShortenClipSideLabel(g.shortenNameClipSide))
        MSUF_UpdateShortenMaskLabel()
    end

    local enabled = (MSUF_DB.shortenNames and true or false)
    if shortenNameMaxCharsSlider then
        if enabled then shortenNameMaxCharsSlider:Enable() else shortenNameMaxCharsSlider:Disable() end
    end
    if shortenNameFrontMaskSlider then
        if enabled then shortenNameFrontMaskSlider:Enable() else shortenNameFrontMaskSlider:Disable() end
    end
    if shortenNameClipSideDrop and MSUF_SetDropDownEnabled then
        MSUF_SetDropDownEnabled(shortenNameClipSideDrop, shortenNameClipSideLabel, enabled)
    end
        textBackdropCheck:SetChecked(MSUF_DB.general.textBackdrop and true or false)

        boldCheck:SetScript("OnClick", function(self)
            EnsureDB()
            MSUF_DB.general.boldText = self:GetChecked() and true or false
            MSUF_CallUpdateAllFonts()
        end)
        noOutlineCheck:SetScript("OnClick", function(self)
            EnsureDB()
            MSUF_DB.general.noOutline = self:GetChecked() and true or false
            MSUF_CallUpdateAllFonts()
        end)

        nameClassColorCheck:SetScript("OnClick", function(self)
            EnsureDB()
            MSUF_DB.general.nameClassColor = self:GetChecked() and true or false

            if type(_G.MSUF_RefreshAllIdentityColors) == "function" then
                _G.MSUF_RefreshAllIdentityColors()
            end
        end)

        npcNameRedCheck:SetScript("OnClick", function(self)
            EnsureDB()
            MSUF_DB.general.npcNameRed = self:GetChecked() and true or false

            if type(_G.MSUF_RefreshAllIdentityColors) == "function" then
                _G.MSUF_RefreshAllIdentityColors()
            end
        end)

        if powerTextColorByTypeCheck then
            powerTextColorByTypeCheck:SetScript("OnClick", function(self)
                EnsureDB()
                MSUF_DB.general.colorPowerTextByType = self:GetChecked() and true or false

                if type(_G.MSUF_RefreshAllPowerTextColors) == "function" then
                    _G.MSUF_RefreshAllPowerTextColors()
                end
                if MSUF_CallUpdateAllFonts then
                    MSUF_CallUpdateAllFonts() -- font/shadow only; colors are handled by refresh/fast-path
                end
            end)
        end

    shortenNamesCheck:SetScript("OnClick", function(self)
        EnsureDB()
        MSUF_DB.shortenNames = self:GetChecked() and true or false

        if shortenNameMaxCharsSlider then
            if MSUF_DB.shortenNames then
                shortenNameMaxCharsSlider:Enable()
            else
                shortenNameMaxCharsSlider:Disable()
            end
        end
        if shortenNameFrontMaskSlider then
            if MSUF_DB.shortenNames then
                shortenNameFrontMaskSlider:Enable()
            else
                shortenNameFrontMaskSlider:Disable()
            end
        end

        if shortenNameClipSideDrop and MSUF_SetDropDownEnabled then
            MSUF_SetDropDownEnabled(shortenNameClipSideDrop, shortenNameClipSideLabel, MSUF_DB.shortenNames)
            MSUF_UpdateShortenMaskLabel()
        end

        MSUF_Options_RequestLayoutAll_Compat("SHORTEN_NAMES")
        if MSUF_CallUpdateAllFonts then
            MSUF_CallUpdateAllFonts()
        end
        if ns and ns.MSUF_RefreshAllFrames then
            ns.MSUF_RefreshAllFrames()
        end
    end)

    if shortenNameMaxCharsSlider then
        shortenNameMaxCharsSlider:SetScript("OnValueChanged", function(self, value)
            EnsureDB()
            value = math.floor((tonumber(value) or 16) + 0.5)
            MSUF_DB.general.shortenNameMaxChars = value

            if MSUF_DB.shortenNames then
                if MSUF_CallUpdateAllFonts then
                    MSUF_CallUpdateAllFonts()
                end
                if ns and ns.MSUF_RefreshAllFrames then
                    ns.MSUF_RefreshAllFrames()
                end
            end
        end)
    end

    if shortenNameFrontMaskSlider then
        shortenNameFrontMaskSlider:SetScript("OnValueChanged", function(self, value)
            EnsureDB()
            value = math.floor((tonumber(value) or 0) + 0.5)
            if value < 0 then value = 0 end
            if value > 40 then value = 40 end
            MSUF_DB.general.shortenNameFrontMaskPx = value

            if MSUF_DB.shortenNames then
                if MSUF_CallUpdateAllFonts then
                    MSUF_CallUpdateAllFonts()
                end
                if ns and ns.MSUF_RefreshAllFrames then
                    ns.MSUF_RefreshAllFrames()
                end
            end
        end)
    end

        textBackdropCheck:SetScript("OnClick", function(self)
            EnsureDB()
            MSUF_DB.general.textBackdrop = self:GetChecked() and true or false
            MSUF_CallUpdateAllFonts()
        end)

        textSizeHeader = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontNormal")
        textSizeHeader:ClearAllPoints()
        -- Text size defaults belong under the Global font dropdown (left column)
        -- so the right column (style checkboxes) stays clean and non-overlapping.
        textSizeHeader:SetPoint("TOPLEFT", fontDrop, "BOTTOMLEFT", 16, -26)
        textSizeHeader:SetText("Text sizes")

        textSizeLine = fontGroup:CreateTexture(nil, "ARTWORK")
        textSizeLine:SetColorTexture(1, 1, 1, 0.2)
        textSizeLine:SetSize(260, 1)
        textSizeLine:ClearAllPoints()
        textSizeLine:SetPoint("TOPLEFT", textSizeHeader, "BOTTOMLEFT", 0, -4)

        -- These sliders are GLOBAL defaults. Unitframes inherit them unless they override locally.
        local textSizeHelp = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontDisableSmall")
        textSizeHelp:SetPoint("TOPLEFT", textSizeLine, "BOTTOMLEFT", 0, -6)
        textSizeHelp:SetWidth(260)
        textSizeHelp:SetJustifyH("LEFT")
        textSizeHelp:SetText("Global defaults. Frames inherit unless overridden in Unitframes > Text.")

        local function MSUF_ListFontOverrides(confField)
            EnsureDB()
            local out = {}
            local keys = { "player", "target", "targettarget", "focus", "pet", "boss" }
            local pretty = { player="Player", target="Target", targettarget="ToT", focus="Focus", pet="Pet", boss="Boss" }
            for _, k in ipairs(keys) do
                local c = MSUF_DB[k]
                if c and c[confField] ~= nil then
                    out[#out + 1] = pretty[k] or k
                end
            end
            return out
        end

        -- Compact one-row layout for text size defaults (Global).
        -- Unitframes inherit these values unless they override locally.
        local function MSUF_CompactTextSizeSlider(slider, shortLabel)
            if not slider then return end

            -- Keep the whole control compact so we can fit multiple columns on one row.
            slider:SetWidth(110)

            local n = slider.GetName and slider:GetName()
            if n then
                local low  = _G[n .. "Low"]
                local high = _G[n .. "High"]
                local text = _G[n .. "Text"]

                -- Low/High labels cost too much horizontal space in a 4-column row.
                if low  then low:Hide()  end
                if high then high:Hide() end

                if text then
                    if shortLabel then text:SetText(shortLabel) end
                    text:ClearAllPoints()
                    text:SetPoint("BOTTOM", slider, "TOP", 0, 6)
                    text:SetJustifyH("CENTER")
                end
            end

            if slider.editBox then
                slider.editBox:SetSize(44, 18)
                slider.editBox:ClearAllPoints()
                slider.editBox:SetPoint("TOP", slider, "BOTTOM", 0, -8)
            end

            if slider.minusButton then
                slider.minusButton:SetSize(18, 18)
                if slider.minusButton.text then
                    slider.minusButton.text:SetFont("Fonts\\FRIZQT__.TTF", 10, "OUTLINE")
                end
            end

            if slider.plusButton then
                slider.plusButton:SetSize(18, 18)
                if slider.plusButton.text then
                    slider.plusButton.text:SetFont("Fonts\\FRIZQT__.TTF", 10, "OUTLINE")
                end
            end
        end

        local function MSUF_FormatOverrideSummary(list)
            if not list or #list == 0 then
                return "Overrides: -", nil
            end
            if #list == 1 then
                return "Overrides: " .. list[1], list[1]
            end
            return "Overrides: " .. list[1] .. " +" .. tostring(#list - 1), table.concat(list, ", ")
        end

        local function MSUF_ApplyOverrideTooltip(fs)
            if not fs then return end
            fs:EnableMouse(true)
            fs:SetScript("OnEnter", function(self)
                if self.MSUF_FullOverrideList and self.MSUF_FullOverrideList ~= "" then
                    GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                    GameTooltip:SetText("Overrides", 1, 0.9, 0.4)
                    GameTooltip:AddLine(self.MSUF_FullOverrideList, 1, 1, 1, true)
                    GameTooltip:Show()
                end
            end)
            fs:SetScript("OnLeave", function()
                if GameTooltip then GameTooltip:Hide() end
            end)
        end

        -- Two rows: (Name | HP) then (Power | Castbar)
        local colGap = 30

        -- Name
        nameFontSizeSlider = CreateLabeledSlider(
            "MSUF_NameFontSizeSlider", "Name", fontGroup,
            8, 32, 1,
            16, -250 -- will be repositioned below
        )
        nameFontSizeSlider:ClearAllPoints()
        nameFontSizeSlider:SetPoint("TOPLEFT", textSizeHelp, "BOTTOMLEFT", 0, -16)
        MSUF_CompactTextSizeSlider(nameFontSizeSlider, "Name")

        nameFontSizeSlider.onValueChanged = function(self, value)
            EnsureDB()
            MSUF_DB.general.nameFontSize = math.floor(value + 0.5)
            MSUF_CallUpdateAllFonts()
        end

        local nameFontOverrideInfo = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontDisableSmall")
        nameFontOverrideInfo:SetPoint("TOP", nameFontSizeSlider.editBox, "BOTTOM", 0, -2)
        nameFontOverrideInfo:SetWidth(120)
        nameFontOverrideInfo:SetJustifyH("CENTER")
        nameFontOverrideInfo:SetText("")
        MSUF_ApplyOverrideTooltip(nameFontOverrideInfo)

        -- HP
        hpFontSizeSlider = CreateLabeledSlider(
            "MSUF_HealthFontSizeSlider", "Health", fontGroup,
            8, 32, 1,
            16, -320 -- will be repositioned below
        )
        hpFontSizeSlider:ClearAllPoints()
        hpFontSizeSlider:SetPoint("TOPLEFT", nameFontSizeSlider, "TOPRIGHT", colGap, 0)
        MSUF_CompactTextSizeSlider(hpFontSizeSlider, "HP")

        hpFontSizeSlider.onValueChanged = function(self, value)
            EnsureDB()
            MSUF_DB.general.hpFontSize = math.floor(value + 0.5)
            MSUF_CallUpdateAllFonts()
        end

        local hpFontOverrideInfo = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontDisableSmall")
        hpFontOverrideInfo:SetPoint("TOP", hpFontSizeSlider.editBox, "BOTTOM", 0, -2)
        hpFontOverrideInfo:SetWidth(120)
        hpFontOverrideInfo:SetJustifyH("CENTER")
        hpFontOverrideInfo:SetText("")
        MSUF_ApplyOverrideTooltip(hpFontOverrideInfo)

        -- Power
        powerFontSizeSlider = CreateLabeledSlider(
            "MSUF_PowerFontSizeSlider", "Power", fontGroup,
            8, 32, 1,
            16, -390 -- will be repositioned below
        )
        powerFontSizeSlider:ClearAllPoints()
        powerFontSizeSlider:SetPoint("TOPLEFT", nameFontSizeSlider, "BOTTOMLEFT", 0, -84)
        MSUF_CompactTextSizeSlider(powerFontSizeSlider, "Power")

        powerFontSizeSlider.onValueChanged = function(self, value)
            EnsureDB()
            MSUF_DB.general.powerFontSize = math.floor(value + 0.5)
            MSUF_CallUpdateAllFonts()
        end

        local powerFontOverrideInfo = fontGroup:CreateFontString(nil, "ARTWORK", "GameFontDisableSmall")
        powerFontOverrideInfo:SetPoint("TOP", powerFontSizeSlider.editBox, "BOTTOM", 0, -2)
        powerFontOverrideInfo:SetWidth(120)
        powerFontOverrideInfo:SetJustifyH("CENTER")
        powerFontOverrideInfo:SetText("")
        MSUF_ApplyOverrideTooltip(powerFontOverrideInfo)

        -- Castbar spell name (global, no per-unit override)
        castbarSpellNameFontSizeSlider = CreateLabeledSlider(
            "MSUF_CastbarSpellNameFontSizeSlider",
            "Castbar",
            fontGroup,
            0, 30, 1,
            16, -460 -- will be repositioned below
        )
        castbarSpellNameFontSizeSlider:ClearAllPoints()
        castbarSpellNameFontSizeSlider:SetPoint("TOPLEFT", powerFontSizeSlider, "TOPRIGHT", colGap, 0)
        MSUF_CompactTextSizeSlider(castbarSpellNameFontSizeSlider, "Castbar")

        castbarSpellNameFontSizeSlider.onValueChanged = function(self, value)
            EnsureDB()
            MSUF_DB.general.castbarSpellNameFontSize = value
            MSUF_EnsureCastbars_Compat(); if type(MSUF_UpdateCastbarVisuals) == "function" then MSUF_UpdateCastbarVisuals() end
        end

        -- Reset button (placed at the bottom of the block so it doesn't clutter the sliders)
        local resetFontOverridesBtn = CreateFrame("Button", "MSUF_ResetFontOverridesBtn", fontGroup, "UIPanelButtonTemplate")
        resetFontOverridesBtn:SetSize(240, 20)
        resetFontOverridesBtn:SetPoint("TOPLEFT", powerFontOverrideInfo, "BOTTOMLEFT", -10, -14)
        resetFontOverridesBtn:SetText("Reset overrides")
        resetFontOverridesBtn.tooltipText = "Clears per-unit Name/Health/Power and per-castbar Cast Name/Time font size overrides so everything inherits the global defaults again."

        if not StaticPopupDialogs["MSUF_RESET_FONT_OVERRIDES"] then
            StaticPopupDialogs["MSUF_RESET_FONT_OVERRIDES"] = {
                text = "Reset all font size overrides?\n\nThis clears per-unit overrides for Name/Health/Power AND per-castbar overrides for Cast Name/Time so everything inherits the global defaults.",
                button1 = YES,
                button2 = NO,
                whileDead = true,
                hideOnEscape = true,
                preferredIndex = 3,
                OnAccept = function()
                    EnsureDB()
                    local keys = { "player", "target", "targettarget", "focus", "pet", "boss" }
                    for _, k in ipairs(keys) do
                        local c = MSUF_DB[k]
                        if c then
                            c.nameFontSize = nil
                            c.hpFontSize = nil
                            c.powerFontSize = nil
                        end
                    end
                    -- Also clear per-castbar font size overrides (Cast Name / Cast Time)
                    MSUF_DB.general = MSUF_DB.general or {}
                    local gg = MSUF_DB.general
                    local castUnits = { "player", "target", "focus" }
                    for _, u in ipairs(castUnits) do
                        local pfx = (type(MSUF_GetCastbarPrefix) == "function") and MSUF_GetCastbarPrefix(u) or nil
                        if pfx then
                            gg[pfx .. "SpellNameFontSize"] = nil
                            gg[pfx .. "TimeFontSize"] = nil
                        end
                    end
                    gg.bossCastSpellNameFontSize = nil
                    gg.bossCastTimeFontSize = nil
                    MSUF_CallUpdateAllFonts()
                    if ns and ns.MSUF_RefreshAllFrames then
                        ns.MSUF_RefreshAllFrames()
                    end
                    if type(MSUF_UpdateCastbarVisuals) == "function" then
                        MSUF_EnsureCastbars_Compat(); if type(MSUF_UpdateCastbarVisuals) == "function" then MSUF_UpdateCastbarVisuals() end
                    end
                end,
            }
        end

        resetFontOverridesBtn:SetScript("OnClick", function()
            StaticPopup_Show("MSUF_RESET_FONT_OVERRIDES")
        end)

        local function MSUF_UpdateGlobalTextSizeOverrideInfo()
            local list, summary, full

            -- Name
            list = MSUF_ListFontOverrides("nameFontSize")
            if nameFontOverrideInfo then
                summary, full = MSUF_FormatOverrideSummary(list)
                nameFontOverrideInfo:SetText(summary)
                nameFontOverrideInfo.MSUF_FullOverrideList = full or ""
            end

            -- HP
            list = MSUF_ListFontOverrides("hpFontSize")
            if hpFontOverrideInfo then
                summary, full = MSUF_FormatOverrideSummary(list)
                hpFontOverrideInfo:SetText(summary)
                hpFontOverrideInfo.MSUF_FullOverrideList = full or ""
            end

            -- Power
            list = MSUF_ListFontOverrides("powerFontSize")
            if powerFontOverrideInfo then
                summary, full = MSUF_FormatOverrideSummary(list)
                powerFontOverrideInfo:SetText(summary)
                powerFontOverrideInfo.MSUF_FullOverrideList = full or ""
            end
        end

        fontGroup:HookScript("OnShow", MSUF_UpdateGlobalTextSizeOverrideInfo)
        resetFontOverridesBtn:HookScript("OnClick", function()
            C_Timer.After(0, MSUF_UpdateGlobalTextSizeOverrideInfo)
        end)

        MSUF_UpdateGlobalTextSizeOverrideInfo()

        -- MSUF_FONT_MENU_BOXED_LAYOUT: Modern boxed layout for Fonts tab (no preview yet)
        do
            if not _G["MSUF_FontsMenuPanelLeft"] then
                local whiteTex = MSUF_TEX_WHITE8 or "Interface\\Buttons\\WHITE8X8"

                -- Explicitly hide legacy Misc labels/lines so nothing bleeds through the boxed layout
                if miscLeftHeader then miscLeftHeader:Hide() end
                if miscLeftLine then miscLeftLine:Hide() end
                if miscRightHeader then miscRightHeader:Hide() end
                if miscRightLine then miscRightLine:Hide() end
                if indicatorsLabel then indicatorsLabel:Hide() end
                if indicatorsLine then indicatorsLine:Hide() end
                if resIndicatorPosLabel then resIndicatorPosLabel:Hide() end

                local function SetupPanel(panel, titleText)
                    if (not panel.SetBackdrop) and BackdropTemplateMixin and Mixin then
                        Mixin(panel, BackdropTemplateMixin)
                    end
                    if panel.SetBackdrop then
                        panel:SetBackdrop({
                            bgFile = whiteTex,
                            edgeFile = whiteTex,
                            tile = true,
                            tileSize = 16,
                            edgeSize = 2,
                            insets = { left = 2, right = 2, top = 2, bottom = 2 },
                        })
                        panel:SetBackdropColor(0, 0, 0, 0.35)
                        panel:SetBackdropBorderColor(1, 1, 1, 0.25)
                    end
                    panel:SetFrameLevel(fontGroup:GetFrameLevel() + 1)

                    panel.MSUF_Title = panel:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
                    panel.MSUF_Title:SetText(titleText)
                    panel.MSUF_Title:SetPoint("TOPLEFT", panel, "TOPLEFT", 14, -12)

                    panel.MSUF_Line = panel:CreateTexture(nil, "ARTWORK")
                    panel.MSUF_Line:SetColorTexture(1, 1, 1, 0.18)
                    panel.MSUF_Line:SetHeight(1)
                    panel.MSUF_Line:SetPoint("TOPLEFT", panel, "TOPLEFT", 12, -34)
                    panel.MSUF_Line:SetPoint("TOPRIGHT", panel, "TOPRIGHT", -12, -34)
                end

                local function CreateSectionHeader(panel, globalKey, text)
                    local fs = panel:CreateFontString(nil, "ARTWORK", "GameFontNormal")
                    fs:SetText(text)
                    fs:SetTextColor(1, 0.82, 0, 1)
                    _G[globalKey] = fs
                    return fs
                end

                local left = CreateFrame("Frame", "MSUF_FontsMenuPanelLeft", fontGroup, "BackdropTemplate")
                -- Slightly taller so the added Name Shortening controls fit cleanly without the panel backdrop ending early.
                left:SetSize(320, 560)
                left:SetPoint("TOPLEFT", fontGroup, "TOPLEFT", 0, -110)
                SetupPanel(left, "Font Settings")

                local right = CreateFrame("Frame", "MSUF_FontsMenuPanelRight", fontGroup, "BackdropTemplate")
                -- Taller to accommodate the new Name Shortening mode dropdown + sliders (prevents the right panel border from clipping).
                right:SetSize(320, 560)
                right:SetPoint("TOPLEFT", left, "TOPRIGHT", 14, 0)
                SetupPanel(right, "Font color & style")

                CreateSectionHeader(left, "MSUF_FontsMenuSection_Global", "Global font")
                CreateSectionHeader(left, "MSUF_FontsMenuSection_Sizes", "Text sizes")

                CreateSectionHeader(right, "MSUF_FontsMenuSection_Style", "Text style")
                CreateSectionHeader(right, "MSUF_FontsMenuSection_Colors", "Name colors")
                CreateSectionHeader(right, "MSUF_FontsMenuSection_Names", "Name display")
            end

            local left = _G["MSUF_FontsMenuPanelLeft"]
            local right = _G["MSUF_FontsMenuPanelRight"]

            local secGlobal = _G["MSUF_FontsMenuSection_Global"]
            local secSizes = _G["MSUF_FontsMenuSection_Sizes"]

            local secStyle = _G["MSUF_FontsMenuSection_Style"]
            local secColors = _G["MSUF_FontsMenuSection_Colors"]
            local secNames = _G["MSUF_FontsMenuSection_Names"]

            -- Ensure positions (in case menu is rebuilt)
            left:ClearAllPoints()
            left:SetPoint("TOPLEFT", fontGroup, "TOPLEFT", 0, -110)

            right:ClearAllPoints()
            right:SetPoint("TOPLEFT", left, "TOPRIGHT", 14, 0)

            -- Hide legacy headers/lines (replaced by boxed layout)
            if fontTitle then fontTitle:Hide() end
            if globalFontHeader then globalFontHeader:Hide() end
            if globalFontLine then globalFontLine:Hide() end
            if textSizeHeader then textSizeHeader:Hide() end
            if textSizeLine then textSizeLine:Hide() end
            if fontColorHeader then fontColorHeader:Hide() end
            if fontColorLine then fontColorLine:Hide() end

            -- Left panel: Global font
            secGlobal:ClearAllPoints()
            secGlobal:SetPoint("TOPLEFT", left, "TOPLEFT", 14, -44)

            fontDrop:ClearAllPoints()
            fontDrop:SetPoint("TOPLEFT", secGlobal, "BOTTOMLEFT", -14, -8)
            UIDropDownMenu_SetWidth(fontDrop, 260)
            fontDrop._msufButtonWidth = 260
            fontDrop:SetWidth(260)

            -- Left panel: Text sizes
            secSizes:ClearAllPoints()
            secSizes:SetPoint("TOPLEFT", fontDrop, "BOTTOMLEFT", 14, -18)

            textSizeHelp:ClearAllPoints()
            textSizeHelp:SetPoint("TOPLEFT", secSizes, "BOTTOMLEFT", 0, -4)
            textSizeHelp:SetWidth(290)

            local colGap = 30

            nameFontSizeSlider:ClearAllPoints()
            nameFontSizeSlider:SetPoint("TOPLEFT", textSizeHelp, "BOTTOMLEFT", 0, -18)

            hpFontSizeSlider:ClearAllPoints()
            hpFontSizeSlider:SetPoint("TOPLEFT", nameFontSizeSlider, "TOPRIGHT", colGap, 0)

            powerFontSizeSlider:ClearAllPoints()
            powerFontSizeSlider:SetPoint("TOPLEFT", nameFontSizeSlider, "BOTTOMLEFT", 0, -84)

            castbarSpellNameFontSizeSlider:ClearAllPoints()
            castbarSpellNameFontSizeSlider:SetPoint("TOPLEFT", powerFontSizeSlider, "TOPRIGHT", colGap, 0)
            resetFontOverridesBtn:ClearAllPoints()
            resetFontOverridesBtn:SetPoint("BOTTOMLEFT", left, "BOTTOMLEFT", 14, 14)
            resetFontOverridesBtn:SetWidth(280)

            -- Right panel: Text style
            secStyle:ClearAllPoints()
            secStyle:SetPoint("TOPLEFT", right, "TOPLEFT", 14, -44)

            boldCheck:ClearAllPoints()
            boldCheck:SetPoint("TOPLEFT", secStyle, "BOTTOMLEFT", -2, -8)

            noOutlineCheck:ClearAllPoints()
            noOutlineCheck:SetPoint("TOPLEFT", boldCheck, "BOTTOMLEFT", 0, -10)

            textBackdropCheck:ClearAllPoints()
            textBackdropCheck:SetPoint("TOPLEFT", noOutlineCheck, "BOTTOMLEFT", 0, -10)

            -- Right panel: Name colors
            secColors:ClearAllPoints()
            secColors:SetPoint("TOPLEFT", textBackdropCheck, "BOTTOMLEFT", 2, -18)

            -- Divider line under "Name colors"
            local colorsLine = right.MSUF_SectionLine_Colors
            if not colorsLine then
                colorsLine = right:CreateTexture(nil, "ARTWORK")
                right.MSUF_SectionLine_Colors = colorsLine
                colorsLine:SetColorTexture(1, 1, 1, 0.20)
                colorsLine:SetHeight(1)
            end
            colorsLine:ClearAllPoints()
            colorsLine:SetPoint("TOPLEFT", secColors, "BOTTOMLEFT", -16, -4)
            colorsLine:SetWidth(286)

            nameClassColorCheck:ClearAllPoints()
            nameClassColorCheck:SetPoint("TOPLEFT", colorsLine, "BOTTOMLEFT", 14, -8)

            npcNameRedCheck:ClearAllPoints()
            npcNameRedCheck:SetPoint("TOPLEFT", nameClassColorCheck, "BOTTOMLEFT", 0, -10)

            if powerTextColorByTypeCheck then
                powerTextColorByTypeCheck:ClearAllPoints()
                powerTextColorByTypeCheck:SetPoint("TOPLEFT", npcNameRedCheck, "BOTTOMLEFT", 0, -10)
            end

            -- Right panel: Name formatting
            secNames:ClearAllPoints()
            secNames:SetPoint("TOPLEFT", (powerTextColorByTypeCheck or npcNameRedCheck), "BOTTOMLEFT", 2, -18)

            -- Divider line under "Name formatting"
            local namesLine = right.MSUF_SectionLine_Names
            if not namesLine then
                namesLine = right:CreateTexture(nil, "ARTWORK")
                right.MSUF_SectionLine_Names = namesLine
                namesLine:SetColorTexture(1, 1, 1, 0.20)
                namesLine:SetHeight(1)
            end
            namesLine:ClearAllPoints()
            namesLine:SetPoint("TOPLEFT", secNames, "BOTTOMLEFT", -16, -4)
            namesLine:SetWidth(286)

            shortenNamesCheck:ClearAllPoints()
            shortenNamesCheck:SetPoint("TOPLEFT", namesLine, "BOTTOMLEFT", 14, -8)


            -- Keep the new Name Shortening controls inside the boxed right panel (avoid bottom clipping)
            if shortenNameClipSideLabel and shortenNameClipSideLabel.ClearAllPoints then
                shortenNameClipSideLabel:ClearAllPoints()
                shortenNameClipSideLabel:SetPoint("TOPLEFT", shortenNamesCheck, "BOTTOMLEFT", 16, -10)
            end
            if shortenNameClipSideDrop and shortenNameClipSideDrop.ClearAllPoints then
                shortenNameClipSideDrop:ClearAllPoints()
                shortenNameClipSideDrop:SetPoint("TOPLEFT", shortenNameClipSideLabel, "BOTTOMLEFT", -16, -2)
                UIDropDownMenu_SetWidth(shortenNameClipSideDrop, 180)
                shortenNameClipSideDrop._msufButtonWidth = 180
            end
            if shortenNameMaxCharsSlider and shortenNameMaxCharsSlider.ClearAllPoints then
                shortenNameMaxCharsSlider:ClearAllPoints()
                shortenNameMaxCharsSlider:SetPoint("TOPLEFT", shortenNameClipSideDrop, "BOTTOMLEFT", 16, -12)
            end
            if shortenNameFrontMaskSlider and shortenNameFrontMaskSlider.ClearAllPoints then
                shortenNameFrontMaskSlider:ClearAllPoints()
                shortenNameFrontMaskSlider:SetPoint("TOPLEFT", shortenNameMaxCharsSlider, "BOTTOMLEFT", 0, -20)
            end
            local infoBtn = _G and _G["MSUF_ShortenNameInfoButton"]
            if infoBtn and infoBtn.ClearAllPoints and shortenNameFrontMaskSlider then
                infoBtn:ClearAllPoints()
                infoBtn:SetPoint("TOPLEFT", shortenNameFrontMaskSlider, "BOTTOMLEFT", 0, -6)
            end
        end

    -- Expose choices + rebuild to Core LoadFromDB (no extra globals).
    panel.__MSUF_FontChoices = fontChoices
    panel.__MSUF_RebuildFontChoices = MSUF_RebuildFontChoices

    -- Expose key widgets for Core panel wiring.
    panel.fontDrop                   = fontDrop
    panel.fontColorDrop              = fontColorDrop
    panel.nameFontSizeSlider         = nameFontSizeSlider
    panel.hpFontSizeSlider           = hpFontSizeSlider
    panel.powerFontSizeSlider        = powerFontSizeSlider
    panel.fontSizeSlider             = fontSizeSlider
    panel.boldCheck                  = boldCheck
    panel.nameClassColorCheck        = nameClassColorCheck
    panel.npcNameRedCheck            = npcNameRedCheck
    panel.shortenNamesCheck          = shortenNamesCheck
    panel.shortenNameClipSideDrop    = shortenNameClipSideDrop
    panel.textBackdropCheck          = textBackdropCheck
    panel.highlightEnableCheck       = highlightEnableCheck
    panel.highlightColorDrop         = highlightColorDrop
    panel.castbarSpellNameFontSizeSlider = castbarSpellNameFontSizeSlider
end
