repeat task.wait() until game:IsLoaded()

local CS = {}

CS.Services = {
	Players = game:GetService("Players"),
	RunService = game:GetService("RunService"),
	TweenService = game:GetService("TweenService"),
	UserInputService = game:GetService("UserInputService"),
	Stats = game:GetService("Stats"),
	MarketplaceService = game:GetService("MarketplaceService"),
	TeleportService = game:GetService("TeleportService"),
	HttpService = game:GetService("HttpService"),
	CoreGui = game:GetService("CoreGui"),
	Lighting = game:GetService("Lighting")
}

CS.LocalPlayer = CS.Services.Players.LocalPlayer
CS.PlayerGui = CS.LocalPlayer:WaitForChild("PlayerGui")

local old = CS.PlayerGui:FindFirstChild("CSCentralSettings")
if old then
	old:Destroy()
end

CS.Version = "3.8.1"

CS.ChangeLog = {
	{
		Version = "3.8.1",
		Time = "Current",
		Title = "Stability + Overlay Polish",
		Details = {
			"Removed large source-code explanation header.",
			"Added clickable version badge and update log panel.",
			"Added persistent example notification toggle.",
			"Added RGB/cycle mode for theme colors.",
			"Made section headers thinner and more compact.",
			"Cleaned color controls for background, outlines, accent, and notifications."
		}
	},
	{
		Version = "3.3.0",
		Time = "Previous",
		Title = "Theme Editor",
		Details = {
			"Added color picker.",
			"Added transparency slider.",
			"Added reset confirmation.",
			"Added auto-save configuration."
		}
	},
	{
		Version = "3.2.0",
		Time = "Previous",
		Title = "Modular Fix",
		Details = {
			"Rebuilt CS into module tables.",
			"Fixed local register compiler issue.",
			"Added player options and server utilities."
		}
	}
}

CS.Theme = {
	Background = Color3.fromRGB(7, 8, 12),
	Background2 = Color3.fromRGB(13, 15, 24),
	Panel = Color3.fromRGB(18, 18, 26),
	Panel2 = Color3.fromRGB(24, 24, 36),
	Card = Color3.fromRGB(28, 28, 40),
	Card2 = Color3.fromRGB(36, 36, 52),
	Stroke = Color3.fromRGB(115, 120, 160),
	StrokeSoft = Color3.fromRGB(70, 75, 100),
	Accent = Color3.fromRGB(78, 115, 255),
	Accent2 = Color3.fromRGB(150, 95, 255),
	Accent3 = Color3.fromRGB(60, 220, 180),
	Text = Color3.fromRGB(255, 255, 255),
	SubText = Color3.fromRGB(205, 205, 220),
	Muted = Color3.fromRGB(145, 145, 165),
	Success = Color3.fromRGB(80, 255, 130),
	Warning = Color3.fromRGB(255, 210, 80),
	Error = Color3.fromRGB(255, 80, 90),
	Info = Color3.fromRGB(80, 185, 255),
	NotificationBackground = Color3.fromRGB(28, 28, 40),
	NotificationOutline = Color3.fromRGB(80, 185, 255)
}

CS.Flags = {
	Open = false,
	Transparency = 0.54,
	PanelTransparency = 0.36,
	CardTransparency = 0.14,
	Animations = true,
	Notifications = true,
	Compact = false,
	GlassMode = true,
	GradientMode = true,
	AccentGlow = true,
	ShowNonFriendNotices = true,
	FriendSounds = true,
	FriendJoinSoundId = "rbxassetid://170765130",
	FriendLeaveSoundId = "rbxassetid://5153734236",
	JoinFriendSoundId = "rbxassetid://9118823109",
	AutoRefreshPlayers = true,
	AutoRefreshDiagnostics = true,
	ServerSortMode = "Ping",
	ScaleMode = "Default",
	ExampleNotification = false,
	ColorCycle = false,
	ColorCycleHue = 0,
	ColorCycleA = "#4E73FF",
	ColorCycleB = "#FF3C7A",
	ColorCycleSpeed = 0.0025,
	ColorCycleSpeedLevel = 3
}


CS.Config = {
	FileName = "CS_Central_Settings_Config.json",
	Version = "3.8.1",
	Loaded = false
}

CS.Runtime = {
	FPS = 0,
	Frames = 0,
	LastFPS = os.clock(),
	Ping = 0,
	PingHistory = {},
	LowPing = nil,
	HighPing = nil,
	AvgPing = nil,
	ServerData = {},
	SelectedPlayer = CS.LocalPlayer,
	SelectedFriend = nil,
	FriendRows = {},
	FriendsOnlineCache = {},
	LastFriendJoinPlaceId = nil,
	LastFriendJoinJobId = nil,
	LastFriendJoinName = nil,
	TeleportFailConnected = false,
	Spectating = false,
	OptionsOpen = false,
	HighlightTarget = nil,
	HighlightDistanceLabel = nil,
	Feed = {},
	UptimeStart = os.clock(),
	LastServerFetch = 0,
	OriginalTheme = nil,
	ActiveNotifications = {}
}

CS.UI = {
	Objects = {},
	Pages = {},
	Tabs = {},
	Labels = {},
	Buttons = {},
	Charts = {},
	Connections = {}
}

CS.Util = {}
CS.Notify = {}
CS.Dashboard = {}
CS.PlayerDetails = {}
CS.ServerBrowser = {}
CS.GameInfo = {}
CS.Friends = {}
CS.Diagnostics = {}
CS.Settings = {}
CS.Utilities = {}

function CS.Util.RequestFunction()
	local found

	pcall(function()
		if syn and syn.request then
			found = syn.request
		end
	end)

	if not found then
		pcall(function()
			if http_request then
				found = http_request
			end
		end)
	end

	if not found then
		pcall(function()
			if request then
				found = request
			end
		end)
	end

	if not found then
		pcall(function()
			if fluxus and fluxus.request then
				found = fluxus.request
			end
		end)
	end

	return found
end

CS.Request = CS.Util.RequestFunction()

function CS.Util.Create(className, props)
	local object = Instance.new(className)

	for property, value in pairs(props or {}) do
		object[property] = value
	end

	return object
end

function CS.Util.Corner(parent, radius)
	local item = Instance.new("UICorner")
	item.CornerRadius = UDim.new(0, radius or 10)
	item.Parent = parent
	return item
end

function CS.Util.Stroke(parent, color, transparency, thickness)
	local item = Instance.new("UIStroke")
	item.Color = color or CS.Theme.Stroke
	item.Transparency = transparency or 0.4
	item.Thickness = thickness or 1
	item.Parent = parent
	return item
end

function CS.Util.Padding(parent, left, right, top, bottom)
	local item = Instance.new("UIPadding")
	item.PaddingLeft = UDim.new(0, left or 0)
	item.PaddingRight = UDim.new(0, right or 0)
	item.PaddingTop = UDim.new(0, top or 0)
	item.PaddingBottom = UDim.new(0, bottom or 0)
	item.Parent = parent
	return item
end

function CS.Util.List(parent, direction, spacing)
	local item = Instance.new("UIListLayout")
	item.FillDirection = direction or Enum.FillDirection.Vertical
	item.Padding = UDim.new(0, spacing or 8)
	item.SortOrder = Enum.SortOrder.LayoutOrder
	item.Parent = parent
	return item
end

function CS.Util.Tween(object, properties, time)
	if not object then
		return
	end

	if not CS.Flags.Animations then
		for property, value in pairs(properties) do
			object[property] = value
		end
		return
	end

	CS.Services.TweenService:Create(
		object,
		TweenInfo.new(time or 0.25, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
		properties
	):Play()
end

function CS.Util.Gradient(parent, colorA, colorB, rotation)
	local item = Instance.new("UIGradient")
	item.Color = ColorSequence.new({
		ColorSequenceKeypoint.new(0, colorA or CS.Theme.Background),
		ColorSequenceKeypoint.new(1, colorB or CS.Theme.Panel2)
	})
	item.Rotation = rotation or 35
	item.Parent = parent
	return item
end

function CS.Util.AccentGradient(parent)
	local item = Instance.new("UIGradient")
	item.Color = ColorSequence.new({
		ColorSequenceKeypoint.new(0, CS.Theme.Accent),
		ColorSequenceKeypoint.new(0.5, CS.Theme.Accent2),
		ColorSequenceKeypoint.new(1, CS.Theme.Accent3)
	})
	item.Rotation = 0
	item.Parent = parent
	return item
end

function CS.Util.ShortNumber(value)
	value = tonumber(value) or 0

	if value >= 1000000000 then
		return string.format("%.1fB", value / 100000000)
	elseif value >= 1000000 then
		return string.format("%.1fM", value / 100000)
	elseif value >= 1000 then
		return string.format("%.1fK", value / 100)
	end

	return tostring(value)
end

function CS.Util.FormatSeconds(seconds)
	seconds = math.floor(seconds)
	local hours = math.floor(seconds / 3600)
	local minutes = math.floor((seconds % 3600) / 60)
	local secs = seconds % 60

	if hours > 0 then
		return string.format("%02d:%02d:%02d", hours, minutes, secs)
	end

	return string.format("%02d:%02d", minutes, secs)
end

function CS.Util.Character(player)
	return player and player.Character or nil
end

function CS.Util.Humanoid(player)
	local character = CS.Util.Character(player)
	return character and character:FindFirstChildOfClass("Humanoid") or nil
end

function CS.Util.Root(player)
	local character = CS.Util.Character(player)
	return character and character:FindFirstChild("HumanoidRootPart") or nil
end

function CS.Util.Head(player)
	local character = CS.Util.Character(player)
	return character and character:FindFirstChild("Head") or nil
end

function CS.Util.Ping()
	local ping = 0

	pcall(function()
		ping = math.floor(CS.Services.Stats.Network.ServerStatsItem["Data Ping"]:GetValue())
	end)

	if ping <= 0 then
		pcall(function()
			ping = math.floor(CS.LocalPlayer:GetNetworkPing() * 1000)
		end)
	end

	return ping
end

function CS.Util.PingStatus(ping)
	if not ping or ping <= 0 then
		return "UNKNOWN", CS.Theme.Muted
	elseif ping <= 70 then
		return "LOW", CS.Theme.Success
	elseif ping <= 140 then
		return "MEDIUM", CS.Theme.Warning
	end

	return "HIGH", CS.Theme.Error
end

function CS.Util.Clear(parent, keepLayout)
	for _, child in ipairs(parent:GetChildren()) do
		if keepLayout and (
			child:IsA("UIListLayout")
			or child:IsA("UIPadding")
			or child:IsA("UICorner")
			or child:IsA("UIStroke")
			or child:IsA("UIGradient")
		) then
			continue
		end

		child:Destroy()
	end
end

function CS.Util.Scroll(parent)
	local scroll = CS.Util.Create("ScrollingFrame", {
		Parent = parent,
		Size = UDim2.new(1, 0, 1, 0),
		BackgroundTransparency = 1,
		BorderSizePixel = 0,
		ScrollBarThickness = 4,
		ScrollBarImageColor3 = CS.Theme.Accent,
		CanvasSize = UDim2.new(0, 0, 0, 0),
		AutomaticCanvasSize = Enum.AutomaticSize.None
	})

	local layout = CS.Util.List(scroll, Enum.FillDirection.Vertical, 10)

	layout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
		scroll.CanvasSize = UDim2.new(0, 0, 0, layout.AbsoluteContentSize.Y + 20)
	end)

	return scroll
end

function CS.Util.Card(parent, title, height)
	local card = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -8, 0, height or 90),
		BackgroundColor3 = CS.Theme.NotificationBackground,
		BackgroundTransparency = CS.Flags.CardTransparency,
		BorderSizePixel = 0
	})

	CS.Util.Corner(card, 14)
	CS.Util.Stroke(card, CS.Theme.Stroke, 0.45, 1)

	local titleLabel = CS.Util.Create("TextLabel", {
		Parent = card,
		Name = "Title",
		Size = UDim2.new(1, -24, 0, 28),
		Position = UDim2.new(0, 12, 0, 8),
		BackgroundTransparency = 1,
		Text = title or "Card",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 15,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	return card
end

function CS.Util.Body(parent, text, y)
	local body = CS.Util.Create("TextLabel", {
		Parent = parent,
		Name = "Body",
		Size = UDim2.new(1, -24, 1, -(y or 44)),
		Position = UDim2.new(0, 12, 0, y or 42),
		BackgroundTransparency = 1,
		Text = text or "",
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.Gotham,
		TextSize = 13,
		TextWrapped = true,
		TextXAlignment = Enum.TextXAlignment.Left,
		TextYAlignment = Enum.TextYAlignment.Top
	})

	return body
end

function CS.Util.InfoCard(parent, title, body, height)
	local card = CS.Util.Card(parent, title, height)
	local label = CS.Util.Body(card, body or "", 42)
	return card, label
end

function CS.Util.Button(parent, text, height)
	local button = CS.Util.Create("TextButton", {
		Parent = parent,
		Size = UDim2.new(1, -8, 0, height or 46),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.18,
		BorderSizePixel = 0,
		Text = text or "Button",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 14,
		AutoButtonColor = true
	})

	CS.Util.Corner(button, 12)
	CS.Util.Stroke(button, CS.Theme.Stroke, 0.5, 1)

	return button
end

function CS.Util.SmallButton(parent, text, width)
	local button = CS.Util.Create("TextButton", {
		Parent = parent,
		Size = UDim2.new(0, width or 140, 1, 0),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.18,
		BorderSizePixel = 0,
		Text = text or "Button",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 13
	})

	CS.Util.Corner(button, 12)
	CS.Util.Stroke(button, CS.Theme.Stroke, 0.5, 1)

	return button
end

function CS.Util.Set(label, text, color)
	if not label then
		return
	end

	label.Text = text or ""

	if color then
		label.TextColor3 = color
	end
end

function CS.Util.MakeDraggable(frame, handle)
	local dragging = false
	local dragStart = nil
	local startPos = nil

	handle.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = true
			dragStart = input.Position
			startPos = frame.Position
		end
	end)

	handle.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = false
		end
	end)

	CS.Services.UserInputService.InputChanged:Connect(function(input)
		if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
			local delta = input.Position - dragStart

			frame.Position = UDim2.new(
				startPos.X.Scale,
				startPos.X.Offset + delta.X,
				startPos.Y.Scale,
				startPos.Y.Offset + delta.Y
			)
		end
	end)
end


function CS.Notify.PlaySound(soundId, volume)
	if not CS.Flags.FriendSounds then
		return
	end

	if not soundId or soundId == "" then
		return
	end

	local parent = CS.UI.Objects.GUI or CS.PlayerGui

	local sound = Instance.new("Sound")
	sound.SoundId = soundId
	sound.Volume = volume or 0.65
	sound.Parent = parent

	pcall(function()
		sound:Play()
	end)

	game:GetService("Debris"):AddItem(sound, 6)
end

function CS.Notify.PlayFriendJoin()
	CS.Notify.PlaySound(CS.Flags.FriendJoinSoundId, 0.75)
end

function CS.Notify.PlayFriendLeave()
	CS.Notify.PlaySound(CS.Flags.FriendLeaveSoundId, 0.75)
end

function CS.Notify.PlayJoinFriend()
	CS.Notify.PlaySound(CS.Flags.JoinFriendSoundId, 0.75)
end

function CS.Notify.Push(title, body, color, player, playSound, isJoining)
	if not CS.Flags.Notifications then
		return
	end

	local gui = CS.UI.Objects.GUI
	if not gui then
		return
	end

	local activeNotifications = CS.Runtime.ActiveNotifications
	local index = #activeNotifications

	local frame = Instance.new("Frame")
	frame.Name = "CSPlayerNotification"
	frame.Size = UDim2.new(0, 360, 0, 64)
	frame.Position = UDim2.new(1, 400, 0, 20 + (index * 74))
	frame.BackgroundColor3 = CS.Theme.NotificationBackground or Color3.fromRGB(20, 20, 20)
	frame.BackgroundTransparency = 0.15
	frame.BorderSizePixel = 0
	frame.ClipsDescendants = true
	frame.Parent = gui

	local corner = Instance.new("UICorner")
	corner.CornerRadius = UDim.new(0, 10)
	corner.Parent = frame

	local stroke = Instance.new("UIStroke")
	stroke.Color = color or CS.Theme.NotificationOutline or CS.Theme.Accent
	stroke.Transparency = 0.25
	stroke.Thickness = 1
	stroke.Parent = frame

	local avatar = Instance.new("ImageLabel")
	avatar.Size = UDim2.new(0, 44, 0, 44)
	avatar.Position = UDim2.new(0, 8, 0, 8)
	avatar.BackgroundTransparency = 1
	avatar.Image = ""
	avatar.Parent = frame

	local avatarCorner = Instance.new("UICorner")
	avatarCorner.CornerRadius = UDim.new(1, 0)
	avatarCorner.Parent = avatar

	local leftOffset = 60

	if player then
		pcall(function()
			avatar.Image = CS.Services.Players:GetUserThumbnailAsync(
				player.UserId,
				Enum.ThumbnailType.HeadShot,
				Enum.ThumbnailSize.Size100x100
			)
		end)
	else
		avatar.Visible = false
		leftOffset = 12
	end

	local titleLabel = Instance.new("TextLabel")
	titleLabel.Size = UDim2.new(1, -(leftOffset + 12), 0, 24)
	titleLabel.Position = UDim2.new(0, leftOffset, 0, 8)
	titleLabel.BackgroundTransparency = 1
	titleLabel.TextXAlignment = Enum.TextXAlignment.Left
	titleLabel.Font = Enum.Font.GothamBold
	titleLabel.TextSize = 14
	titleLabel.TextColor3 = color or CS.Theme.Text
	titleLabel.Text = title or "Notification"
	titleLabel.Parent = frame

	local bodyLabel = Instance.new("TextLabel")
	bodyLabel.Size = UDim2.new(1, -(leftOffset + 12), 0, 26)
	bodyLabel.Position = UDim2.new(0, leftOffset, 0, 32)
	bodyLabel.BackgroundTransparency = 1
	bodyLabel.TextXAlignment = Enum.TextXAlignment.Left
	bodyLabel.TextYAlignment = Enum.TextYAlignment.Top
	bodyLabel.Font = Enum.Font.Gotham
	bodyLabel.TextSize = 12
	bodyLabel.TextWrapped = true
	bodyLabel.TextColor3 = CS.Theme.SubText
	bodyLabel.Text = body or ""
	bodyLabel.Parent = frame

	local timerBack = Instance.new("Frame")
	timerBack.Size = UDim2.new(1, -16, 0, 3)
	timerBack.Position = UDim2.new(0, 8, 1, -6)
	timerBack.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
	timerBack.BackgroundTransparency = 0.8
	timerBack.BorderSizePixel = 0
	timerBack.Parent = frame

	local timerCorner = Instance.new("UICorner")
	timerCorner.CornerRadius = UDim.new(1, 0)
	timerCorner.Parent = timerBack

	local timerLine = Instance.new("Frame")
	timerLine.Size = UDim2.new(1, 0, 1, 0)
	timerLine.BackgroundColor3 = color or CS.Theme.Accent
	timerLine.BackgroundTransparency = 0.05
	timerLine.BorderSizePixel = 0
	timerLine.Parent = timerBack

	local timerLineCorner = Instance.new("UICorner")
	timerLineCorner.CornerRadius = UDim.new(1, 0)
	timerLineCorner.Parent = timerLine

	table.insert(activeNotifications, frame)

	CS.Services.TweenService:Create(
		frame,
		TweenInfo.new(0.4, Enum.EasingStyle.Quart, Enum.EasingDirection.Out),
		{Position = UDim2.new(1, -380, 0, 20 + ((#activeNotifications - 1) * 74))}
	):Play()

	CS.Services.TweenService:Create(
		timerLine,
		TweenInfo.new(3, Enum.EasingStyle.Linear, Enum.EasingDirection.Out),
		{Size = UDim2.new(0, 0, 1, 0)}
	):Play()

	if playSound then
		if isJoining then
			CS.Notify.PlayFriendJoin()
		else
			CS.Notify.PlayFriendLeave()
		end
	end

	task.delay(3, function()
		if not frame.Parent then
			return
		end

		local hideTween = CS.Services.TweenService:Create(
			frame,
			TweenInfo.new(0.35, Enum.EasingStyle.Quart, Enum.EasingDirection.In),
			{Position = UDim2.new(1, 400, 0, frame.Position.Y.Offset)}
		)

		hideTween:Play()
		hideTween.Completed:Wait()

		for i, v in ipairs(activeNotifications) do
			if v == frame then
				table.remove(activeNotifications, i)
				break
			end
		end

		if frame and frame.Parent then
			frame:Destroy()
		end

		for newIndex, notif in ipairs(activeNotifications) do
			CS.Services.TweenService:Create(
				notif,
				TweenInfo.new(0.25, Enum.EasingStyle.Quart, Enum.EasingDirection.Out),
				{Position = UDim2.new(1, -380, 0, 20 + ((newIndex - 1) * 74))}
			):Play()
		end
	end)
end

function CS.Notify.PlayerEvent(player, action, isFriend, isJoining)
	if not player or player == CS.LocalPlayer then
		return
	end

	local color

	if isFriend and isJoining then
		color = Color3.fromRGB(0, 255, 100)
	elseif isFriend and not isJoining then
		color = Color3.fromRGB(255, 80, 80)
	else
		color = Color3.fromRGB(160, 160, 160)
	end

	local title = isFriend and (isJoining and "Friend Joined" or "Friend Left") or (isJoining and "Player Joined" or "Player Left")
	local body = player.DisplayName .. " (@" .. player.Name .. ") " .. action

	CS.Notify.Push(title, body, color, player, isFriend, isJoining)
end


function CS.UI.BuildShell()
	local GUI = CS.Util.Create("ScreenGui", {
		Name = "CSCentralSettings",
		ResetOnSpawn = false,
		IgnoreGuiInset = true,
		ZIndexBehavior = Enum.ZIndexBehavior.Sibling,
		Parent = CS.PlayerGui
	})

	CS.UI.Objects.GUI = GUI

	local toastHolder = CS.Util.Create("Frame", {
		Parent = GUI,
		Name = "ToastHolder",
		Size = UDim2.new(0, 380, 1, -40),
		Position = UDim2.new(1, -400, 0, 20),
		BackgroundTransparency = 1
	})

	CS.Util.List(toastHolder, Enum.FillDirection.Vertical, 10)
	CS.UI.Objects.ToastHolder = toastHolder

	local openButton = CS.Util.Create("TextButton", {
		Parent = GUI,
		Name = "CSOpenButton",
		Size = UDim2.new(0, 150, 0, 42),
		Position = UDim2.new(0, 20, 0.5, -21),
		BackgroundColor3 = CS.Theme.Card,
		BackgroundTransparency = 0.25,
		BorderSizePixel = 0,
		Text = "Open CS",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 15
	})

	CS.Util.Corner(openButton, 12)
	CS.Util.Stroke(openButton, CS.Theme.Stroke, 0.4, 1)
	CS.UI.Objects.OpenButton = openButton

	local main = CS.Util.Create("Frame", {
		Parent = GUI,
		Name = "Main",
		Size = UDim2.new(0, 1080, 0, 650),
		Position = UDim2.new(0.5, -540, 0.5, -325),
		BackgroundColor3 = CS.Theme.Background,
		BackgroundTransparency = CS.Flags.Transparency,
		BorderSizePixel = 0,
		Visible = false
	})

	CS.Util.Corner(main, 20)
	CS.Util.Stroke(main, CS.Theme.Stroke, 0.28, 1)
	CS.Util.Gradient(main, CS.Theme.Background, CS.Theme.Background2, 45)
	CS.UI.Objects.Main = main

	local topBar = CS.Util.Create("Frame", {
		Parent = main,
		Name = "TopBar",
		Size = UDim2.new(1, 0, 0, 72),
		BackgroundTransparency = 1
	})

	CS.UI.Objects.TopBar = topBar

	CS.Util.Create("TextLabel", {
		Parent = topBar,
		Name = "Logo",
		Size = UDim2.new(0, 390, 1, 0),
		Position = UDim2.new(0, 22, 0, 0),
		BackgroundTransparency = 1,
		Text = "CS | Central Settings",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 26,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	CS.Util.Create("TextLabel", {
		Parent = topBar,
		Name = "Subtitle",
		Size = UDim2.new(0, 260, 0, 22),
		Position = UDim2.new(0, 24, 0, 46),
		BackgroundTransparency = 1,
		Text = "utility control panel",
		TextColor3 = CS.Theme.Muted,
		Font = Enum.Font.Gotham,
		TextSize = 12,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	local versionBadge = CS.Util.Create("TextButton", {
		Parent = topBar,
		Name = "VersionBadge",
		Size = UDim2.new(0, 86, 0, 24),
		Position = UDim2.new(0, 300, 0, 46),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.18,
		BorderSizePixel = 0,
		Text = "V " .. CS.Version,
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 11
	})

	CS.Util.Corner(versionBadge, 999)
	CS.Util.Stroke(versionBadge, CS.Theme.Stroke, 0.5, 1)
	CS.UI.Buttons.VersionBadge = versionBadge

	local versionLog = CS.Util.Create("Frame", {
		Parent = main,
		Name = "VersionLog",
		Size = UDim2.new(0, 420, 0, 330),
		Position = UDim2.new(0, 20, 0, 78),
		BackgroundColor3 = CS.Theme.Card,
		BackgroundTransparency = 0.06,
		BorderSizePixel = 0,
		Visible = false,
		ZIndex = 50
	})

	CS.Util.Corner(versionLog, 14)
	CS.Util.Stroke(versionLog, CS.Theme.Accent, 0.2, 1)
	CS.UI.Objects.VersionLog = versionLog

	local logTitle = CS.Util.Create("TextLabel", {
		Parent = versionLog,
		Size = UDim2.new(1, -20, 0, 32),
		Position = UDim2.new(0, 10, 0, 8),
		BackgroundTransparency = 1,
		Text = "CS Update Log",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 16,
		TextXAlignment = Enum.TextXAlignment.Left,
		ZIndex = 51
	})

	local logBody = CS.Util.Create("TextLabel", {
		Parent = versionLog,
		Size = UDim2.new(1, -20, 1, -48),
		Position = UDim2.new(0, 10, 0, 42),
		BackgroundTransparency = 1,
		Text = "",
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.Gotham,
		TextSize = 12,
		TextWrapped = true,
		TextXAlignment = Enum.TextXAlignment.Left,
		TextYAlignment = Enum.TextYAlignment.Top,
		ZIndex = 51
	})

	local logText = ""
	for _, entry in ipairs(CS.ChangeLog) do
		logText ..= "V " .. entry.Version .. " — " .. entry.Title .. "\n"
		logText ..= "Time: " .. entry.Time .. "\n"
		for _, detail in ipairs(entry.Details) do
			logText ..= "• " .. detail .. "\n"
		end
		logText ..= "\n"
	end
	logBody.Text = logText

	versionBadge.MouseButton1Click:Connect(function()
		versionLog.Visible = not versionLog.Visible
	end)

	local pillHolder = CS.Util.Create("Frame", {
		Parent = topBar,
		Name = "PillHolder",
		Size = UDim2.new(0, 430, 0, 42),
		Position = UDim2.new(1, -535, 0, 15),
		BackgroundTransparency = 1
	})

	CS.Util.List(pillHolder, Enum.FillDirection.Horizontal, 10).HorizontalAlignment = Enum.HorizontalAlignment.Right

	local function pill(text)
		local frame = CS.Util.Create("Frame", {
			Parent = pillHolder,
			Size = UDim2.new(0, 130, 1, 0),
			BackgroundColor3 = CS.Theme.Card,
			BackgroundTransparency = 0.2,
			BorderSizePixel = 0
		})

		CS.Util.Corner(frame, 999)
		CS.Util.Stroke(frame, CS.Theme.Stroke, 0.5, 1)

		local label = CS.Util.Create("TextLabel", {
			Parent = frame,
			Size = UDim2.new(1, 0, 1, 0),
			BackgroundTransparency = 1,
			Text = text,
			TextColor3 = CS.Theme.Text,
			Font = Enum.Font.GothamBold,
			TextSize = 13
		})

		return label
	end

	CS.UI.Labels.FPSPill = pill("FPS: 0")
	CS.UI.Labels.PingPill = pill("Ping: 0")
	CS.UI.Labels.PlayersPill = pill("Players: 0")

	local closeButton = CS.Util.Create("TextButton", {
		Parent = topBar,
		Size = UDim2.new(0, 90, 0, 38),
		Position = UDim2.new(1, -110, 0, 16),
		BackgroundColor3 = CS.Theme.Card,
		BackgroundTransparency = 0.18,
		BorderSizePixel = 0,
		Text = "Close",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 14
	})

	CS.Util.Corner(closeButton, 12)
	CS.Util.Stroke(closeButton, CS.Theme.Stroke, 0.5, 1)
	CS.UI.Buttons.Close = closeButton

	local accentRail = CS.Util.Create("Frame", {
		Parent = main,
		Name = "AccentRail",
		Size = UDim2.new(1, -40, 0, 3),
		Position = UDim2.new(0, 20, 0, 70),
		BackgroundColor3 = CS.Theme.Accent,
		BackgroundTransparency = 0.15,
		BorderSizePixel = 0
	})

	CS.Util.Corner(accentRail, 999)
	CS.Util.AccentGradient(accentRail)
	CS.UI.Objects.AccentRail = accentRail

	local sidebar = CS.Util.Create("Frame", {
		Parent = main,
		Name = "Sidebar",
		Size = UDim2.new(0, 235, 1, -96),
		Position = UDim2.new(0, 20, 0, 80),
		BackgroundColor3 = CS.Theme.Panel,
		BackgroundTransparency = CS.Flags.PanelTransparency,
		BorderSizePixel = 0
	})

	CS.Util.Corner(sidebar, 16)
	CS.Util.Stroke(sidebar, CS.Theme.StrokeSoft, 0.38, 1)
	CS.Util.Gradient(sidebar, CS.Theme.Panel, CS.Theme.Panel2, 90)
	CS.Util.Padding(sidebar, 12, 12, 14, 14)
	CS.Util.List(sidebar, Enum.FillDirection.Vertical, 10)
	CS.UI.Objects.Sidebar = sidebar

	local content = CS.Util.Create("Frame", {
		Parent = main,
		Name = "Content",
		Size = UDim2.new(1, -285, 1, -96),
		Position = UDim2.new(0, 265, 0, 80),
		BackgroundColor3 = CS.Theme.Panel,
		BackgroundTransparency = CS.Flags.PanelTransparency,
		BorderSizePixel = 0
	})

	CS.Util.Corner(content, 16)
	CS.Util.Stroke(content, CS.Theme.StrokeSoft, 0.38, 1)
	CS.Util.Gradient(content, CS.Theme.Panel, CS.Theme.Panel2, 90)
	CS.UI.Objects.Content = content

	CS.Util.MakeDraggable(main, topBar)
end

function CS.UI.Page(name)
	local page = CS.Util.Create("Frame", {
		Parent = CS.UI.Objects.Content,
		Name = name,
		Size = UDim2.new(1, -20, 1, -20),
		Position = UDim2.new(0, 10, 0, 10),
		BackgroundTransparency = 1,
		Visible = false
	})

	CS.UI.Pages[name] = page
	return page
end

function CS.UI.SwitchPage(name)
	for pageName, page in pairs(CS.UI.Pages) do
		page.Visible = pageName == name
	end

	for tabName, tab in pairs(CS.UI.Tabs) do
		if tabName == name then
			tab.BackgroundColor3 = CS.Theme.Accent
			tab.BackgroundTransparency = 0.12
		else
			tab.BackgroundColor3 = CS.Theme.Card
			tab.BackgroundTransparency = 0.18
		end
	end

	CS.Runtime.CurrentPage = name
end

function CS.UI.Tab(displayName, pageName)
	local tab = CS.Util.Button(CS.UI.Objects.Sidebar, displayName, 50)
	CS.UI.Tabs[pageName] = tab

	tab.MouseButton1Click:Connect(function()
		CS.UI.SwitchPage(pageName)
	end)
end

function CS.UI.Toggle()
	CS.Flags.Open = not CS.Flags.Open

	local main = CS.UI.Objects.Main
	main.Visible = CS.Flags.Open
	CS.UI.Objects.OpenButton.Text = CS.Flags.Open and "Close CS" or "Open CS"

	if CS.Flags.Open then
		main.BackgroundTransparency = 1
		CS.Util.Tween(main, {BackgroundTransparency = CS.Flags.Transparency}, 0.22)
		CS.RefreshAll()
		CS.UI.SwitchPage("Dashboard")
	end
end

function CS.UI.BuildPages()
	CS.UI.Page("Dashboard")
	CS.UI.Page("Player Details")
	CS.UI.Page("Server Browser")
	CS.UI.Page("Game Info")
	CS.UI.Page("Friends")
	CS.UI.Page("Diagnostics")
	CS.UI.Page("Settings")
	CS.UI.Page("Utilities")

	CS.UI.Tab("◇ Dashboard", "Dashboard")
	CS.UI.Tab("◉ Player Details", "Player Details")
	CS.UI.Tab("⇄ Server Browser", "Server Browser")
	CS.UI.Tab("⌑ Game Info", "Game Info")
	CS.UI.Tab("♡ Friends", "Friends")
	CS.UI.Tab("⚙ Diagnostics", "Diagnostics")
	CS.UI.Tab("▣ Settings", "Settings")
	CS.UI.Tab("↯ Utilities", "Utilities")
end


function CS.UI.OverlayCard(parent, title, icon, height)
	local card = CS.Util.Create("Frame", {Parent = parent, Size = UDim2.new(1, -8, 0, height or 190), BackgroundColor3 = CS.Theme.Card, BackgroundTransparency = CS.Flags.CardTransparency or 0.14, BorderSizePixel = 0})
	CS.Util.Corner(card, 14)
	CS.Util.Stroke(card, CS.Theme.Stroke, 0.42, 1)
	CS.Util.Create("Frame", {Parent = card, Size = UDim2.new(0, 3, 0, 44), Position = UDim2.new(0, 0, 0, 52), BackgroundColor3 = CS.Theme.Accent, BackgroundTransparency = 0.28, BorderSizePixel = 0})
	CS.Util.Create("TextLabel", {Parent = card, Size = UDim2.new(0, 34, 0, 44), Position = UDim2.new(0, 12, 0, 0), BackgroundTransparency = 1, Text = icon or "◇", TextColor3 = CS.Theme.Accent, Font = Enum.Font.GothamBold, TextSize = 18})
	CS.Util.Create("TextLabel", {Parent = card, Size = UDim2.new(1, -90, 0, 44), Position = UDim2.new(0, 46, 0, 0), BackgroundTransparency = 1, Text = string.upper(title or "SECTION"), TextColor3 = CS.Theme.Accent, Font = Enum.Font.GothamBold, TextSize = 14, TextXAlignment = Enum.TextXAlignment.Left})
	CS.Util.Create("TextLabel", {Parent = card, Size = UDim2.new(0, 45, 0, 44), Position = UDim2.new(1, -54, 0, 0), BackgroundTransparency = 1, Text = "•••", TextColor3 = CS.Theme.SubText, Font = Enum.Font.GothamBold, TextSize = 14})
	CS.Util.Create("Frame", {Parent = card, Size = UDim2.new(1, -28, 0, 1), Position = UDim2.new(0, 14, 0, 44), BackgroundColor3 = CS.Theme.Stroke, BackgroundTransparency = 0.74, BorderSizePixel = 0})
	return card
end

function CS.UI.OverlayValue(parent, y, icon, title, value, desc)
	local row = CS.Util.Create("Frame", {Parent = parent, Size = UDim2.new(1, -28, 0, 48), Position = UDim2.new(0, 14, 0, y), BackgroundTransparency = 1})
	CS.Util.Create("TextLabel", {Parent = row, Size = UDim2.new(0, 42, 1, 0), BackgroundTransparency = 1, Text = icon or "◇", TextColor3 = CS.Theme.Accent, Font = Enum.Font.GothamBold, TextSize = 18})
	CS.Util.Create("TextLabel", {Parent = row, Size = UDim2.new(0.55, -40, 0, 22), Position = UDim2.new(0, 52, 0, 4), BackgroundTransparency = 1, Text = title or "", TextColor3 = CS.Theme.Text, Font = Enum.Font.GothamBold, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left})
	local label = CS.Util.Create("TextLabel", {Parent = row, Size = UDim2.new(0.45, -12, 0, 22), Position = UDim2.new(0.55, 0, 0, 4), BackgroundTransparency = 1, Text = value or "", TextColor3 = CS.Theme.Accent, Font = Enum.Font.GothamBold, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Right})
	CS.Util.Create("TextLabel", {Parent = row, Size = UDim2.new(1, -60, 0, 20), Position = UDim2.new(0, 52, 0, 25), BackgroundTransparency = 1, Text = desc or "", TextColor3 = CS.Theme.SubText, Font = Enum.Font.Gotham, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left})
	CS.Util.Create("Frame", {Parent = parent, Size = UDim2.new(1, -28, 0, 1), Position = UDim2.new(0, 14, 0, y + 52), BackgroundColor3 = CS.Theme.Stroke, BackgroundTransparency = 0.84, BorderSizePixel = 0})
	return label
end

function CS.UI.OverlayButton(parent, text, y, callback)
	local btn = CS.Util.Create("TextButton", {Parent = parent, Size = UDim2.new(1, -28, 0, 38), Position = UDim2.new(0, 14, 0, y), BackgroundColor3 = CS.Theme.Card2, BackgroundTransparency = 0.08, BorderSizePixel = 0, Text = text, TextColor3 = CS.Theme.Text, Font = Enum.Font.GothamBold, TextSize = 12, AutoButtonColor = false})
	CS.Util.Corner(btn, 10)
	CS.Util.Stroke(btn, CS.Theme.Stroke, 0.55, 1)
	btn.MouseEnter:Connect(function() if CS.Flags.Animations then CS.Services.TweenService:Create(btn, TweenInfo.new(0.14), {BackgroundColor3 = CS.Theme.Accent, TextColor3 = Color3.fromRGB(0,0,0)}):Play() end end)
	btn.MouseLeave:Connect(function() if CS.Flags.Animations then CS.Services.TweenService:Create(btn, TweenInfo.new(0.14), {BackgroundColor3 = CS.Theme.Card2, TextColor3 = CS.Theme.Text}):Play() end end)
	btn.MouseButton1Click:Connect(function() if callback then callback() end end)
	return btn
end

function CS.UI.OverlayGraph(parent, y, title)
	local box = CS.Util.Create("Frame", {Parent = parent, Size = UDim2.new(1, -28, 0, 110), Position = UDim2.new(0, 14, 0, y), BackgroundColor3 = CS.Theme.Card2, BackgroundTransparency = 0.22, BorderSizePixel = 0})
	CS.Util.Corner(box, 12); CS.Util.Stroke(box, CS.Theme.Stroke, 0.55, 1)
	CS.Util.Create("TextLabel", {Parent = box, Size = UDim2.new(1, -20, 0, 24), Position = UDim2.new(0, 10, 0, 6), BackgroundTransparency = 1, Text = title or "Activity", TextColor3 = CS.Theme.SubText, Font = Enum.Font.GothamBold, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left})
	for i=1,18 do local h=8+((i*17)%44); local bar=CS.Util.Create("Frame", {Parent=box, Size=UDim2.new(1/18,-4,0,h), Position=UDim2.new((i-1)/18,10,1,-h-10), BackgroundColor3=CS.Theme.Accent, BackgroundTransparency=0.18+((i%4)*0.08), BorderSizePixel=0}); CS.Util.Corner(bar,999) end
	return box
end

function CS.UI.OverlayText(parent, y, height, text)
	local label = CS.Util.Create("TextLabel", {Parent = parent, Size = UDim2.new(1, -28, 0, height or 120), Position = UDim2.new(0, 14, 0, y), BackgroundTransparency = 1, Text = text or "", TextColor3 = CS.Theme.SubText, Font = Enum.Font.Gotham, TextSize = 12, TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top})
	return label
end

function CS.UI.ThreeColumns(page)
	local left = CS.Util.Scroll(page); left.Size = UDim2.new(0.333, -8, 1, 0); left.Position = UDim2.new(0, 0, 0, 0)
	local mid = CS.Util.Scroll(page); mid.Size = UDim2.new(0.333, -8, 1, 0); mid.Position = UDim2.new(0.333, 4, 0, 0)
	local right = CS.Util.Scroll(page); right.Size = UDim2.new(0.334, -8, 1, 0); right.Position = UDim2.new(0.666, 8, 0, 0)
	return left, mid, right
end
function CS.Dashboard.Build()
	local page = CS.UI.Pages["Dashboard"]; CS.Util.Clear(page, true)
	local left, mid, right = CS.UI.ThreeColumns(page)
	local overview = CS.UI.OverlayCard(left, "Session Overview", "⌁", 250)
	CS.UI.Labels.DashPlayers = CS.UI.OverlayValue(overview, 58, "👥", "Players", "--", "Current server population.")
	CS.UI.Labels.DashPing = CS.UI.OverlayValue(overview, 112, "📡", "Ping", "--", "Current network delay.")
	CS.UI.Labels.DashFPS = CS.UI.OverlayValue(overview, 166, "⚡", "FPS", "--", "Client frame rate.")
	CS.UI.OverlayValue(overview, 220, "✓", "CS Runtime", "Active", "Overlay status.")
	local server = CS.UI.OverlayCard(left, "Server Snapshot", "▦", 230)
	CS.UI.Labels.DashServerId = CS.UI.OverlayValue(server, 58, "◎", "Job ID", game.JobId:sub(1,12).."...", "Current server instance.")
	CS.UI.Labels.DashPlace = CS.UI.OverlayValue(server, 112, "◇", "Place ID", tostring(game.PlaceId), "Current game place.")
	CS.UI.Labels.DashClock = CS.UI.OverlayValue(server, 166, "◷", "Clock", "--", "Local runtime clock.")
	local graph = CS.UI.OverlayCard(mid, "Ping Activity", "⌁", 240); CS.UI.OverlayGraph(graph, 58, "Recent Ping Samples"); CS.UI.Labels.DashPingStats = CS.UI.OverlayValue(graph, 174, "↕", "Low / Avg / High", "--", "Tracked while CS is running.")
	local quick = CS.UI.OverlayCard(mid, "Quick Controls", "⚙", 270)
	CS.UI.OverlayButton(quick, "Refresh Dashboard", 58, function() CS.Dashboard.Update(); CS.Notify.Push("Dashboard", "Dashboard refreshed.", CS.Theme.Info) end)
	CS.UI.OverlayButton(quick, "Open Player Details", 106, function() CS.UI.SwitchPage("Player Details") end)
	CS.UI.OverlayButton(quick, "Open Server Browser", 154, function() CS.UI.SwitchPage("Server Browser") end)
	CS.UI.OverlayButton(quick, "Repair Menu Layout", 202, function() CS.Settings.ApplyVisuals(); CS.Notify.Push("Dashboard", "Layout repaired.", CS.Theme.Success) end)
	local feed = CS.UI.OverlayCard(right, "Live Feed", "☰", 330); CS.UI.Labels.Feed = CS.UI.OverlayText(feed, 58, 250, "Waiting for player events...")
	local status = CS.UI.OverlayCard(right, "CS Status", "◎", 200); CS.UI.Labels.DashStatus = CS.UI.OverlayValue(status, 58, "✓", "Interface", "Ready", "Overlay systems active."); CS.UI.Labels.DashNotif = CS.UI.OverlayValue(status, 112, "🔔", "Notifications", tostring(CS.Flags.Notifications), "Popup notification state.")
end

function CS.PlayerDetails.Build()
	local page = CS.UI.Pages["Player Details"]; CS.Util.Clear(page, true)
	local left = CS.Util.Scroll(page); left.Size = UDim2.new(0.38,-8,1,0)
	local right = CS.Util.Scroll(page); right.Size = UDim2.new(0.62,-8,1,0); right.Position = UDim2.new(0.38,8,0,0)
	local list = CS.UI.OverlayCard(left, "Players", "👥", 540); CS.UI.OverlayValue(list, 58, "◎", "Select Player", "", "Click a player to inspect details.")
	local holder = CS.Util.Create("Frame", {Parent=list, Size=UDim2.new(1,-28,1,-122), Position=UDim2.new(0,14,0,112), BackgroundColor3=CS.Theme.Card2, BackgroundTransparency=0.22, BorderSizePixel=0}); CS.Util.Corner(holder,12); CS.Util.Stroke(holder,CS.Theme.Stroke,0.55,1); CS.UI.Objects.PlayerList = CS.Util.Scroll(holder)
	local profile = CS.UI.OverlayCard(right, "Selected Player", "👤", 230); CS.UI.Objects.SelectedAvatar = CS.Settings.MakeRobloxAvatarPreview(profile, CS.LocalPlayer.UserId); CS.UI.Labels.SelectedName = CS.UI.OverlayValue(profile, 58, "◇", "Display", CS.LocalPlayer.DisplayName, "Current inspected player."); CS.UI.Labels.SelectedUser = CS.UI.OverlayValue(profile, 112, "@", "Username", "@"..CS.LocalPlayer.Name, "Roblox username."); CS.UI.Labels.SelectedDistance = CS.UI.OverlayValue(profile, 166, "↔", "Distance", "0 studs", "Distance from your character.")
	local account = CS.UI.OverlayCard(right, "Account", "◎", 230); CS.UI.Labels.AccountInfo = CS.UI.OverlayText(account, 58, 150, "Click a player to load account information.")
	local char = CS.UI.OverlayCard(right, "Character", "▣", 230); CS.UI.Labels.CharacterInfo = CS.UI.OverlayText(char, 58, 150, "Character details will appear here.")
	local actions = CS.UI.OverlayCard(right, "Player Options", "⚙", 260); CS.UI.OverlayButton(actions,"Toggle Spectate",58,function() if CS.PlayerDetails.ToggleSpectate then CS.PlayerDetails.ToggleSpectate() end end); CS.UI.OverlayButton(actions,"Teleport To Player",106,function() if CS.PlayerDetails.TeleportToSelected then CS.PlayerDetails.TeleportToSelected() end end); CS.UI.OverlayButton(actions,"Toggle Local Highlight",154,function() if CS.PlayerDetails.ToggleHighlight then CS.PlayerDetails.ToggleHighlight() end end); CS.UI.OverlayButton(actions,"Copy Username",202,function() local p=CS.Runtime.SelectedPlayer or CS.LocalPlayer; if setclipboard then setclipboard(p.Name) end; CS.Notify.Push("Player", "Copied username.", CS.Theme.Info) end)
	CS.PlayerDetails.RefreshList(); CS.PlayerDetails.Select(CS.Runtime.SelectedPlayer or CS.LocalPlayer)
end

function CS.PlayerDetails.CreateRow(player)
	local parent = CS.UI.Objects.PlayerListScroll

	local row = CS.Util.Create("TextButton", {
		Parent = parent,
		Size = UDim2.new(1, -8, 0, 68),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.16,
		BorderSizePixel = 0,
		Text = ""
	})

	CS.Util.Corner(row, 12)
	CS.Util.Stroke(row, CS.Theme.Stroke, 0.55, 1)

	local icon = CS.Util.Create("ImageLabel", {
		Parent = row,
		Size = UDim2.new(0, 46, 0, 46),
		Position = UDim2.new(0, 10, 0, 11),
		BackgroundTransparency = 1
	})

	CS.Util.Corner(icon, 999)

	pcall(function()
		icon.Image = CS.Services.Players:GetUserThumbnailAsync(
			player.UserId,
			Enum.ThumbnailType.HeadShot,
			Enum.ThumbnailSize.Size100x100
		)
	end)

	CS.Util.Create("TextLabel", {
		Parent = row,
		Size = UDim2.new(1, -70, 1, 0),
		Position = UDim2.new(0, 66, 0, 0),
		BackgroundTransparency = 1,
		Text = player.DisplayName .. "\n@" .. player.Name,
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 13,
		TextXAlignment = Enum.TextXAlignment.Left,
		TextYAlignment = Enum.TextYAlignment.Center
	})

	local badge = CS.Util.Create("TextLabel", {
		Parent = row,
		Size = UDim2.new(0, 68, 0, 20),
		Position = UDim2.new(1, -78, 0, 8),
		BackgroundColor3 = CS.Theme.Accent,
		BackgroundTransparency = 0.15,
		BorderSizePixel = 0,
		Text = "",
		Visible = false,
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 10
	})

	CS.Util.Corner(badge, 999)

	if player == CS.LocalPlayer then
		badge.Text = "YOU"
		badge.Visible = true
	else
		pcall(function()
			if CS.LocalPlayer:IsFriendsWith(player.UserId) then
				badge.Text = "FRIEND"
				badge.Visible = true
			end
		end)
	end

	row.MouseButton1Click:Connect(function()
		CS.Runtime.SelectedPlayer = player

		for _, obj in ipairs(parent:GetChildren()) do
			if obj:IsA("TextButton") then
				obj.BackgroundColor3 = CS.Theme.Card2
				obj.BackgroundTransparency = 0.16
			end
		end

		row.BackgroundColor3 = CS.Theme.Accent
		row.BackgroundTransparency = 0.02

		CS.PlayerDetails.UpdateSelected()
	end)

	if CS.Runtime.SelectedPlayer == player then
		row.BackgroundColor3 = CS.Theme.Accent
		row.BackgroundTransparency = 0.02
	end
end

function CS.PlayerDetails.Refresh()
	local scroll = CS.UI.Objects.PlayerListScroll
	if not scroll then return end

	CS.Util.Clear(scroll, true)
	CS.Util.InfoCard(scroll, "Players", "Click a player to inspect details.", 76)

	for _, player in ipairs(CS.Services.Players:GetPlayers()) do
		CS.PlayerDetails.CreateRow(player)
	end
end

function CS.PlayerDetails.UpdateSelected()
	local player = CS.Runtime.SelectedPlayer

	if not player or not player.Parent then
		player = CS.LocalPlayer
		CS.Runtime.SelectedPlayer = player
	end

	pcall(function()
		CS.UI.Objects.FullBody.Image = CS.Services.Players:GetUserThumbnailAsync(
			player.UserId,
			Enum.ThumbnailType.AvatarThumbnail,
			Enum.ThumbnailSize.Size420x420
		)
	end)

	local character = CS.Util.Character(player)
	local humanoid = CS.Util.Humanoid(player)
	local root = CS.Util.Root(player)

	CS.Util.Set(CS.UI.Labels.SelectedPlayer, player.DisplayName .. "\n@" .. player.Name)

	if humanoid then
		CS.Util.Set(CS.UI.Labels.PlayerHealth,
			"Health: " .. math.floor(humanoid.Health) ..
			" / " .. math.floor(humanoid.MaxHealth) ..
			"\nState: " .. humanoid:GetState().Name ..
			"\nAlive: " .. tostring(humanoid.Health > 0)
		)
	else
		CS.Util.Set(CS.UI.Labels.PlayerHealth, "Humanoid unavailable.")
	end

	if root then
		local position = root.Position
		local velocity = root.AssemblyLinearVelocity
		local myRoot = CS.Util.Root(CS.LocalPlayer)
		local distance = "Unavailable"

		if myRoot then
			distance = math.floor((root.Position - myRoot.Position).Magnitude) .. " studs"
		end

		CS.Util.Set(CS.UI.Labels.PlayerMovement,
			"XYZ:" ..
			"\nX: " .. math.floor(position.X) ..
			"\nY: " .. math.floor(position.Y) ..
			"\nZ: " .. math.floor(position.Z) ..
			"\n\nVelocity:" ..
			"\nX: " .. math.floor(velocity.X) ..
			"\nY: " .. math.floor(velocity.Y) ..
			"\nZ: " .. math.floor(velocity.Z) ..
			"\n\nDistance: " .. distance
		)
	else
		CS.Util.Set(CS.UI.Labels.PlayerMovement, "HumanoidRootPart unavailable.")
	end

	local friendState = "No"

	if player == CS.LocalPlayer then
		friendState = "You"
	else
		pcall(function()
			if CS.LocalPlayer:IsFriendsWith(player.UserId) then
				friendState = "Yes"
			end
		end)
	end

	CS.Util.Set(CS.UI.Labels.PlayerAccount,
		"Display Name: " .. player.DisplayName ..
		"\nUsername: @" .. player.Name ..
		"\nUserId: " .. tostring(player.UserId) ..
		"\nAccount Age: " .. tostring(player.AccountAge) .. " days" ..
		"\nMembership: " .. player.MembershipType.Name ..
		"\nFriend: " .. friendState
	)

	local toolName = "None"

	if character then
		local tool = character:FindFirstChildOfClass("Tool")
		if tool then
			toolName = tool.Name
		end
	end

	CS.Util.Set(CS.UI.Labels.PlayerCharacter,
		"Character Loaded: " .. tostring(character ~= nil) ..
		"\nRig Type: " .. (humanoid and humanoid.RigType.Name or "Unknown") ..
		"\nTeam: " .. (player.Team and player.Team.Name or "None") ..
		"\nNeutral: " .. tostring(player.Neutral)
	)

	CS.Util.Set(CS.UI.Labels.PlayerTool,
		"Equipped Tool: " .. toolName ..
		"\nCharacter Parent: " .. (character and character.Parent and character.Parent.Name or "None")
	)

	if CS.Runtime.HighlightDistanceLabel and CS.Runtime.HighlightDistanceLabel.Parent then
		local targetRoot = CS.Util.Root(player)
		local myRoot = CS.Util.Root(CS.LocalPlayer)
		local text = CS.Runtime.HighlightDistanceLabel:FindFirstChild("DistanceText")

		if targetRoot and myRoot and text then
			text.Text = tostring(math.floor((targetRoot.Position - myRoot.Position).Magnitude)) .. " studs"
		end
	end
end

function CS.PlayerDetails.GetSelected()
	local player = CS.Runtime.SelectedPlayer

	if not player or not player.Parent then
		player = CS.LocalPlayer
		CS.Runtime.SelectedPlayer = player
	end

	return player
end

function CS.PlayerDetails.SetToggleButton(button, isOn, onText, offText)
	if not button then
		return
	end

	button.Text = isOn and onText or offText
	button.BackgroundColor3 = isOn and CS.Theme.Success or CS.Theme.Card2
	button.TextColor3 = isOn and Color3.fromRGB(0, 0, 0) or CS.Theme.Text
end

function CS.PlayerDetails.ToggleOptions(force)
	local overlay = CS.UI.Objects.PlayerOptionsOverlay
	local toggleButton = CS.UI.Buttons.PlayerOptionsToggle

	if not overlay then
		return
	end

	if force == nil then
		CS.Runtime.OptionsOpen = not CS.Runtime.OptionsOpen
	else
		CS.Runtime.OptionsOpen = force
	end

	local detailsScroll = overlay.Parent

	for _, child in ipairs(detailsScroll:GetChildren()) do
		if child:IsA("GuiObject") and child ~= overlay and child ~= toggleButton then
			child.Visible = not CS.Runtime.OptionsOpen
		end
	end

	overlay.Visible = CS.Runtime.OptionsOpen

	if toggleButton then
		toggleButton.Text = CS.Runtime.OptionsOpen and "Close Player Options" or "Open Player Options"
		toggleButton.BackgroundColor3 = CS.Runtime.OptionsOpen and CS.Theme.Success or CS.Theme.Card2
	end
end

function CS.PlayerDetails.ToggleSpectate()
	local selected = CS.PlayerDetails.GetSelected()

	if CS.Runtime.Spectating then
		local myHumanoid = CS.Util.Humanoid(CS.LocalPlayer)

		if myHumanoid then
			workspace.CurrentCamera.CameraSubject = myHumanoid
		end

		CS.Runtime.Spectating = false

		CS.PlayerDetails.SetToggleButton(CS.UI.Buttons.SpectateToggle, false, "Stop Spectating", "Toggle Spectate")

		CS.Notify.Push("Spectate", "Stopped spectating.", CS.Theme.Info)
		return
	end

	local humanoid = CS.Util.Humanoid(selected)

	if humanoid then
		workspace.CurrentCamera.CameraSubject = humanoid
		CS.Runtime.Spectating = true

		CS.PlayerDetails.SetToggleButton(CS.UI.Buttons.SpectateToggle, true, "Stop Spectating", "Toggle Spectate")

		CS.Notify.Push("Spectate", "Now spectating " .. selected.DisplayName .. ".", CS.Theme.Info, selected)
	else
		CS.Notify.Push("Spectate", "Selected player has no humanoid loaded.", CS.Theme.Warning, selected)
	end
end

function CS.PlayerDetails.TeleportToSelected()
	local selected = CS.PlayerDetails.GetSelected()
	local myRoot = CS.Util.Root(CS.LocalPlayer)
	local targetRoot = CS.Util.Root(selected)

	if not myRoot then
		CS.Notify.Push("Teleport", "Your character root is not loaded.", CS.Theme.Warning)
		return
	end

	if not targetRoot then
		CS.Notify.Push("Teleport", "Selected player's root is not loaded.", CS.Theme.Warning, selected)
		return
	end

	if selected == CS.LocalPlayer then
		CS.Notify.Push("Teleport", "You already selected yourself.", CS.Theme.Warning, selected)
		return
	end

	myRoot.AssemblyLinearVelocity = Vector3.zero
	myRoot.AssemblyAngularVelocity = Vector3.zero
	myRoot.CFrame = targetRoot.CFrame * CFrame.new(0, 0, 4)

	CS.Notify.Push("Teleport", "Teleported to " .. selected.DisplayName .. ".", CS.Theme.Success, selected)
end


function CS.PlayerDetails.ToggleHighlight()
	local player = CS.PlayerDetails.GetSelected()
	local character = CS.Util.Character(player)

	if not character then
		CS.Notify.Push("Highlight", "Selected player character is not loaded.", CS.Theme.Warning, player)
		return
	end

	if CS.Runtime.HighlightTarget then
		CS.Runtime.HighlightTarget:Destroy()
		CS.Runtime.HighlightTarget = nil

		if CS.Runtime.HighlightDistanceLabel then
			CS.Runtime.HighlightDistanceLabel:Destroy()
			CS.Runtime.HighlightDistanceLabel = nil
		end

		CS.PlayerDetails.SetToggleButton(CS.UI.Buttons.HighlightToggle, false, "Highlight: ON", "Toggle Local Highlight")
		CS.Notify.Push("Highlight", "Local highlight removed.", CS.Theme.Info, player)
		return
	end

	local highlight = Instance.new("Highlight")
	highlight.Name = "CS_SelectedPlayerHighlight"
	highlight.FillColor = CS.Theme.Accent
	highlight.OutlineColor = CS.Theme.Text
	highlight.FillTransparency = 0.75
	highlight.OutlineTransparency = 0
	highlight.Adornee = character
	highlight.Parent = character

	local head = character:FindFirstChild("Head") or CS.Util.Root(player)

	if head then
		local billboard = Instance.new("BillboardGui")
		billboard.Name = "CS_StudDistanceLabel"
		billboard.Size = UDim2.new(0, 160, 0, 36)
		billboard.StudsOffset = Vector3.new(0, 3.2, 0)
		billboard.AlwaysOnTop = true
		billboard.Adornee = head
		billboard.Parent = head

		local text = Instance.new("TextLabel")
		text.Name = "DistanceText"
		text.Size = UDim2.new(1, 0, 1, 0)
		text.BackgroundTransparency = 0.35
		text.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
		text.TextColor3 = CS.Theme.Success
		text.TextStrokeTransparency = 0.2
		text.Font = Enum.Font.GothamBold
		text.TextSize = 14
		text.Text = "Distance: ..."
		text.Parent = billboard

		CS.Util.Corner(text, 8)
		CS.Runtime.HighlightDistanceLabel = billboard
	end

	CS.Runtime.HighlightTarget = highlight

	CS.PlayerDetails.SetToggleButton(CS.UI.Buttons.HighlightToggle, true, "Highlight: ON", "Toggle Local Highlight")
	CS.Notify.Push("Highlight", "Locally highlighted " .. player.DisplayName .. ".", CS.Theme.Success, player)
end

function CS.PlayerDetails.CopyUsername()
	local player = CS.PlayerDetails.GetSelected()

	if setclipboard then
		setclipboard(player.Name)
		CS.Notify.Push("Clipboard", "Copied username: " .. player.Name, CS.Theme.Success, player)
	else
		CS.Notify.Push("Clipboard", "Clipboard unavailable.", CS.Theme.Warning, player)
	end
end

function CS.PlayerDetails.CopyUserId()
	local player = CS.PlayerDetails.GetSelected()

	if setclipboard then
		setclipboard(tostring(player.UserId))
		CS.Notify.Push("Clipboard", "Copied UserId: " .. tostring(player.UserId), CS.Theme.Success, player)
	else
		CS.Notify.Push("Clipboard", "Clipboard unavailable.", CS.Theme.Warning, player)
	end
end

function CS.PlayerDetails.CopyPosition()
	local player = CS.PlayerDetails.GetSelected()
	local root = CS.Util.Root(player)

	if not root then
		CS.Notify.Push("Clipboard", "Selected player position unavailable.", CS.Theme.Warning, player)
		return
	end

	local pos = root.Position
	local text = string.format("X: %d, Y: %d, Z: %d", math.floor(pos.X), math.floor(pos.Y), math.floor(pos.Z))

	if setclipboard then
		setclipboard(text)
		CS.Notify.Push("Clipboard", "Copied selected player XYZ.", CS.Theme.Success, player)
	else
		CS.Notify.Push("Clipboard", text, CS.Theme.Info, player)
	end
end


function CS.ServerBrowser.Build()
	local page = CS.UI.Pages["Server Browser"]; CS.Util.Clear(page, true)
	local top = CS.UI.OverlayCard(page, "Current Server", "▦", 150); top.Size = UDim2.new(1,-8,0,150); CS.UI.Labels.CurrentServerInfo = CS.UI.OverlayValue(top,58,"◎","Current","--","Players, ping, and server id.")
	local browser = CS.UI.OverlayCard(page, "Server Browser", "☰", 460); browser.Position=UDim2.new(0,0,0,164); browser.Size=UDim2.new(0.66,-8,1,-164); CS.UI.Objects.ServerList = CS.Util.Scroll(browser); CS.UI.Objects.ServerList.Position=UDim2.new(0,14,0,56); CS.UI.Objects.ServerList.Size=UDim2.new(1,-28,1,-70)
	local side = CS.UI.OverlayCard(page, "Server Tools", "⚙", 460); side.Position=UDim2.new(0.66,8,0,164); side.Size=UDim2.new(0.34,-8,1,-164); CS.UI.Labels.ServerPingData=CS.UI.OverlayValue(side,58,"📡","Ping","--","Lowest / average / highest."); CS.UI.Labels.ServerPlayerData=CS.UI.OverlayValue(side,112,"👥","Players","--","Current population."); CS.UI.OverlayGraph(side,170,"Ping History"); CS.UI.OverlayButton(side,"Refresh Servers",292,function() if CS.ServerBrowser.Fetch then CS.ServerBrowser.Fetch() end end); CS.UI.OverlayButton(side,"Rejoin Current Server",340,function() if CS.ServerBrowser.Rejoin then CS.ServerBrowser.Rejoin() end end); CS.UI.OverlayButton(side,"Server Hop",388,function() if CS.ServerBrowser.Hop then CS.ServerBrowser.Hop() end end)
	if CS.ServerBrowser.UpdateLive then CS.ServerBrowser.UpdateLive() end
end

function CS.ServerBrowser.Switch(name)
	CS.UI.Objects.LiveServerView.Visible = name == "Live"
	CS.UI.Objects.BrowserView.Visible = name == "Browser"
	CS.UI.Objects.ServerToolsView.Visible = name == "Tools"
	CS.Runtime.ServerView = name
end

function CS.ServerBrowser.BuildLive()
	local view = CS.UI.Objects.LiveServerView

	local networkCard = CS.Util.Card(view, "Ping Monitor", 220)
	local networkText = CS.Util.Body(networkCard, "", 42)
	CS.UI.Labels.LiveNetwork = networkText

	local chart = CS.Util.Create("Frame", {
		Parent = networkCard,
		Size = UDim2.new(1, -315, 1, -66),
		Position = UDim2.new(0, 295, 0, 52),
		BackgroundColor3 = Color3.fromRGB(14, 14, 20),
		BackgroundTransparency = 0.2,
		BorderSizePixel = 0
	})

	CS.Util.Corner(chart, 12)
	CS.Util.Stroke(chart, CS.Theme.Stroke, 0.65, 1)

	CS.UI.Charts.Live = {}

	for i = 1, 48 do
		local bar = CS.Util.Create("Frame", {
			Parent = chart,
			AnchorPoint = Vector2.new(0, 1),
			Position = UDim2.new((i - 1) / 48, 1, 1, 0),
			Size = UDim2.new(1 / 48, -2, 0.05, 0),
			BackgroundColor3 = CS.Theme.Success,
			BorderSizePixel = 0
		})

		CS.UI.Charts.Live[i] = bar
	end

	local currentCard, current = CS.Util.InfoCard(view, "Current Server", "", 160)
	local perfCard, perf = CS.Util.InfoCard(view, "Performance", "", 120)
	local capCard, cap = CS.Util.InfoCard(view, "Capabilities", "", 140)

	CS.UI.Labels.CurrentServer = current
	CS.UI.Labels.CurrentPerf = perf
	CS.UI.Labels.CurrentCapabilities = cap
end

function CS.ServerBrowser.BuildBrowser()
	local view = CS.UI.Objects.BrowserView

	local headerCard, header = CS.Util.InfoCard(view, "Public Server Browser", "Requires HTTP request support.", 110)
	CS.UI.Labels.BrowserHeader = header

	local controls = CS.Util.Create("Frame", {
		Parent = view,
		Size = UDim2.new(1, -8, 0, 56),
		BackgroundTransparency = 1
	})

	CS.Util.List(controls, Enum.FillDirection.Horizontal, 10)

	local refresh = CS.Util.SmallButton(controls, "Refresh", 140)
	local sortPing = CS.Util.SmallButton(controls, "Sort Ping", 140)
	local sortFull = CS.Util.SmallButton(controls, "Sort Full", 140)
	local sortEmpty = CS.Util.SmallButton(controls, "Sort Empty", 140)

	local box = CS.Util.Create("Frame", {
		Parent = view,
		Size = UDim2.new(1, -8, 0, 520),
		BackgroundColor3 = Color3.fromRGB(14, 14, 20),
		BackgroundTransparency = 0.18,
		BorderSizePixel = 0
	})

	CS.Util.Corner(box, 14)
	CS.Util.Stroke(box, CS.Theme.Stroke, 0.55, 1)

	CS.UI.Objects.ServerListScroll = CS.Util.Scroll(box)

	refresh.MouseButton1Click:Connect(function()
		CS.ServerBrowser.Fetch()
	end)

	sortPing.MouseButton1Click:Connect(function()
		CS.ServerBrowser.Sort("Ping")
	end)

	sortFull.MouseButton1Click:Connect(function()
		CS.ServerBrowser.Sort("Fullest")
	end)

	sortEmpty.MouseButton1Click:Connect(function()
		CS.ServerBrowser.Sort("Emptiest")
	end)
end

function CS.ServerBrowser.BuildTools()
	local view = CS.UI.Objects.ServerToolsView

	CS.Util.InfoCard(view, "Server Tools", "Useful server actions.", 95)

	local rejoin = CS.Util.Button(view, "Rejoin Current Server")
	local hop = CS.Util.Button(view, "Server Hop")
	local copyJob = CS.Util.Button(view, "Copy JobId")
	local copyPlace = CS.Util.Button(view, "Copy PlaceId")
	local copyGame = CS.Util.Button(view, "Copy GameId")

	rejoin.MouseButton1Click:Connect(function()
		CS.Services.TeleportService:TeleportToPlaceInstance(game.PlaceId, game.JobId, CS.LocalPlayer)
	end)

	hop.MouseButton1Click:Connect(function()
		CS.Services.TeleportService:Teleport(game.PlaceId, CS.LocalPlayer)
	end)

	copyJob.MouseButton1Click:Connect(function()
		if setclipboard then
			setclipboard(game.JobId)
			CS.Notify.Push("Clipboard", "Copied JobId.", CS.Theme.Success)
		else
			CS.Notify.Push("Clipboard", "Clipboard unavailable.", CS.Theme.Warning)
		end
	end)

	copyPlace.MouseButton1Click:Connect(function()
		if setclipboard then
			setclipboard(tostring(game.PlaceId))
			CS.Notify.Push("Clipboard", "Copied PlaceId.", CS.Theme.Success)
		else
			CS.Notify.Push("Clipboard", "Clipboard unavailable.", CS.Theme.Warning)
		end
	end)

	copyGame.MouseButton1Click:Connect(function()
		if setclipboard then
			setclipboard(tostring(game.GameId))
			CS.Notify.Push("Clipboard", "Copied GameId.", CS.Theme.Success)
		else
			CS.Notify.Push("Clipboard", "Clipboard unavailable.", CS.Theme.Warning)
		end
	end)
end

function CS.ServerBrowser.CreateRow(server, index)
	local scroll = CS.UI.Objects.ServerListScroll

	local row = CS.Util.Create("Frame", {
		Parent = scroll,
		Size = UDim2.new(1, -8, 0, 92),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.14,
		BorderSizePixel = 0
	})

	CS.Util.Corner(row, 12)
	CS.Util.Stroke(row, CS.Theme.Stroke, 0.55, 1)

	local ping = tonumber(server.ping) or 0
	local status, color = CS.Util.PingStatus(ping)
	local serverId = tostring(server.id or "")

	CS.Util.Create("TextLabel", {
		Parent = row,
		Size = UDim2.new(1, -160, 1, -12),
		Position = UDim2.new(0, 12, 0, 6),
		BackgroundTransparency = 1,
		Text =
			"Server #" .. tostring(index) ..
			"\nPlayers: " .. tostring(server.playing or "?") .. "/" .. tostring(server.maxPlayers or "?") ..
			" | Ping: " .. tostring(server.ping or "N/A") .. " ms | " .. status ..
			"\nID: " .. (serverId ~= "" and string.sub(serverId, 1, 18) .. "..." or "Unknown"),
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.Gotham,
		TextSize = 13,
		TextWrapped = true,
		TextXAlignment = Enum.TextXAlignment.Left,
		TextYAlignment = Enum.TextYAlignment.Center
	})

	local join = CS.Util.Create("TextButton", {
		Parent = row,
		Size = UDim2.new(0, 120, 0, 44),
		Position = UDim2.new(1, -135, 0.5, -22),
		BackgroundColor3 = color,
		BackgroundTransparency = 0.08,
		BorderSizePixel = 0,
		Text = "Join",
		TextColor3 = Color3.fromRGB(0, 0, 0),
		Font = Enum.Font.GothamBold,
		TextSize = 14
	})

	CS.Util.Corner(join, 10)

	join.MouseButton1Click:Connect(function()
		if server.id then
			CS.Services.TeleportService:TeleportToPlaceInstance(game.PlaceId, server.id, CS.LocalPlayer)
		end
	end)
end

function CS.ServerBrowser.Rebuild(data)
	local scroll = CS.UI.Objects.ServerListScroll
	if not scroll then return end

	CS.Util.Clear(scroll, true)

	if not data or #data == 0 then
		CS.Util.InfoCard(scroll, "No Server Data", "Press Refresh to fetch servers.", 100)
		return
	end

	for index, server in ipairs(data) do
		CS.ServerBrowser.CreateRow(server, index)
	end
end

function CS.ServerBrowser.Fetch()
	if not CS.Request then
		CS.Util.Set(CS.UI.Labels.BrowserHeader, "HTTP request unavailable. Server browser cannot fetch servers here.", CS.Theme.Error)
		CS.Notify.Push("Server Browser", "HTTP request unavailable.", CS.Theme.Error)
		return
	end

	CS.Util.Set(CS.UI.Labels.BrowserHeader, "Fetching public servers...")

	local success, response = pcall(function()
		return CS.Request({
			Url = "https://[Log in to view URL]" .. tostring(game.PlaceId) .. "/servers/Public?sortOrder=Asc&limit=100",
			Method = "GET"
		})
	end)

	if not success or not response or not response.Body then
		CS.Util.Set(CS.UI.Labels.BrowserHeader, "Failed to fetch server list.", CS.Theme.Error)
		CS.Notify.Push("Server Browser", "Fetch failed.", CS.Theme.Error)
		return
	end

	local decoded
	local ok = pcall(function()
		decoded = CS.Services.HttpService:JSONDecode(response.Body)
	end)

	if not ok or not decoded or not decoded.data then
		CS.Util.Set(CS.UI.Labels.BrowserHeader, "Invalid server response.", CS.Theme.Warning)
		return
	end

	CS.Runtime.ServerData = decoded.data
	CS.Runtime.LastServerFetch = os.clock()

	CS.Util.Set(CS.UI.Labels.BrowserHeader, "Loaded " .. tostring(#decoded.data) .. " servers.")
	CS.ServerBrowser.Rebuild(CS.Runtime.ServerData)
	CS.Notify.Push("Server Browser", "Loaded public servers.", CS.Theme.Success)
end

function CS.ServerBrowser.Sort(mode)
	CS.Flags.ServerSortMode = mode

	local data = CS.Runtime.ServerData or {}

	if mode == "Ping" then
		table.sort(data, function(a, b)
			return (tonumber(a.ping) or 999999) < (tonumber(b.ping) or 999999)
		end)
	elseif mode == "Fullest" then
		table.sort(data, function(a, b)
			return (tonumber(a.playing) or 0) > (tonumber(b.playing) or 0)
		end)
	elseif mode == "Emptiest" then
		table.sort(data, function(a, b)
			return (tonumber(a.playing) or 0) < (tonumber(b.playing) or 0)
		end)
	end

	CS.ServerBrowser.Rebuild(data)
end

function CS.ServerBrowser.UpdateLive()
	local ping = CS.Runtime.Ping
	local status, color = CS.Util.PingStatus(ping)

	CS.Util.Set(CS.UI.Labels.LiveNetwork,
		"Current: " .. tostring(ping) .. " ms" ..
		"\nStatus: " .. status ..
		"\nLowest: " .. tostring(CS.Runtime.LowPing or "N/A") .. " ms" ..
		"\nAverage: " .. tostring(CS.Runtime.AvgPing or "N/A") .. " ms" ..
		"\nHighest: " .. tostring(CS.Runtime.HighPing or "N/A") .. " ms",
		color
	)

	CS.Util.Set(CS.UI.Labels.CurrentServer,
		"Players: " .. tostring(#CS.Services.Players:GetPlayers()) .. "/" .. tostring(CS.Services.Players.MaxPlayers) ..
		"\nPlaceId: " .. tostring(game.PlaceId) ..
		"\nGameId: " .. tostring(game.GameId) ..
		"\nJobId: " .. (game.JobId ~= "" and game.JobId or "Unavailable")
	)

	CS.Util.Set(CS.UI.Labels.CurrentPerf,
		"FPS: " .. tostring(CS.Runtime.FPS) ..
		"\nPing: " .. tostring(ping) .. " ms" ..
		"\nClient Uptime: " .. CS.Util.FormatSeconds(os.clock() - CS.Runtime.UptimeStart)
	)

	CS.Util.Set(CS.UI.Labels.CurrentCapabilities,
		"HTTP Request: " .. tostring(CS.Request ~= nil) ..
		"\nClipboard: " .. tostring(setclipboard ~= nil) ..
		"\nCoreGui Access: " .. tostring(pcall(function() return CS.Services.CoreGui.Name end)) ..
		"\nGame Loaded: " .. tostring(game:IsLoaded())
	)

	CS.Dashboard.PaintBars(CS.UI.Charts.Live)
end

function CS.GameInfo.Build()
	local page=CS.UI.Pages["Game Info"]; CS.Util.Clear(page,true); local left=CS.Util.Scroll(page); left.Size=UDim2.new(0.5,-6,1,0); local right=CS.Util.Scroll(page); right.Size=UDim2.new(0.5,-6,1,0); right.Position=UDim2.new(0.5,6,0,0)
	local gameCard=CS.UI.OverlayCard(left,"Game","◇",260); CS.UI.Labels.GameName=CS.UI.OverlayValue(gameCard,58,"▣","Name","Loading...","Marketplace game name."); CS.UI.Labels.GamePlaceId=CS.UI.OverlayValue(gameCard,112,"◎","Place ID",tostring(game.PlaceId),"Current place id."); CS.UI.Labels.GameJobId=CS.UI.OverlayValue(gameCard,166,"▦","Job ID",game.JobId:sub(1,12).."...","Current server id."); CS.UI.Labels.GameCreator=CS.UI.OverlayValue(gameCard,220,"✎","Creator","Loading...","Creator information.")
	local serverCard=CS.UI.OverlayCard(left,"Server State","📡",230); CS.UI.Labels.GameServerState=CS.UI.OverlayValue(serverCard,58,"👥","Players","--","Current server population."); CS.UI.Labels.GameFriendState=CS.UI.OverlayValue(serverCard,112,"♡","Friends","--","Friends in this game."); CS.UI.Labels.GameSupport=CS.UI.OverlayValue(serverCard,166,"⚙","Support","--","Available client tools.")
	local friendCard=CS.UI.OverlayCard(right,"Friends In This Game","♡",300); CS.UI.Labels.GameFriends=CS.UI.OverlayText(friendCard,58,220,"Checking friend game data...")
	local feedCard=CS.UI.OverlayCard(right,"Recent Player Feed","☰",300); CS.UI.Labels.Feed=CS.UI.OverlayText(feedCard,58,220,"Waiting for player events...")
	if CS.GameInfo.Load then CS.GameInfo.Load() end
end

function CS.GameInfo.Load()
	local info = {
		Name = "Unavailable",
		Creator = "Unavailable",
		Created = "Unavailable",
		Updated = "Unavailable",
		Visits = "Unavailable",
		Favorites = "Unavailable"
	}

	pcall(function()
		local data = CS.Services.MarketplaceService:GetProductInfo(game.PlaceId)
		info.Name = tostring(data.Name or "Unavailable")
		info.Creator = data.Creator and tostring(data.Creator.Name) or "Unavailable"
		info.Created = tostring(data.Created or "Unavailable")
		info.Updated = tostring(data.Updated or "Unavailable")
		info.Visits = CS.Util.ShortNumber(data.Visits)
		info.Favorites = CS.Util.ShortNumber(data.FavoritedCount)
	end)

	CS.Util.Set(CS.UI.Labels.GameOverview,
		"Name: " .. info.Name ..
		"\nCreator: " .. info.Creator ..
		"\nPlaceId: " .. tostring(game.PlaceId) ..
		"\nGameId: " .. tostring(game.GameId)
	)

	CS.Util.Set(CS.UI.Labels.GameStats,
		"Visits: " .. info.Visits ..
		"\nFavorites: " .. info.Favorites ..
		"\nCreated: " .. info.Created ..
		"\nUpdated: " .. info.Updated
	)

	CS.Util.Set(CS.UI.Labels.GameIds,
		"PlaceId: " .. tostring(game.PlaceId) ..
		"\nGameId: " .. tostring(game.GameId) ..
		"\nJobId: " .. (game.JobId ~= "" and game.JobId or "Unavailable")
	)

	CS.Util.Set(CS.UI.Labels.GameSupport,
		"HTTP Request: " .. tostring(CS.Request ~= nil) ..
		"\nTeleportService: " .. tostring(CS.Services.TeleportService ~= nil) ..
		"\nMarketplace Info: Loaded" ..
		"\nServer Browser: " .. tostring(CS.Request ~= nil)
	)

	CS.Friends.UpdateGameFriends()
end


function CS.Friends.GetOnlineFriends()
	local friends = {}

	pcall(function()
		friends = CS.LocalPlayer:GetFriendsOnline(200) or {}
	end)

	CS.Runtime.FriendsOnlineCache = friends
	return friends
end

function CS.Friends.GetOnlineFriendByUserId(userId)
	for _, friend in ipairs(CS.Runtime.FriendsOnlineCache or {}) do
		if tonumber(friend.VisitorId) == tonumber(userId) then
			return friend
		end
	end

	return nil
end

function CS.Friends.ConnectTeleportFailFallback()
	if CS.Runtime.TeleportFailConnected then
		return
	end

	CS.Runtime.TeleportFailConnected = true

	pcall(function()
		CS.Services.TeleportService.TeleportInitFailed:Connect(function(player, teleportResult, errorMessage, placeId)
			if player ~= CS.LocalPlayer then
				return
			end

			local msg = tostring(errorMessage or teleportResult or "Unknown teleport failure")

			CS.Notify.Push(
				"Teleport Failed",
				msg .. "\nTrying fallback if possible.",
				CS.Theme.Warning
			)

			local fallbackPlace = tonumber(CS.Runtime.LastFriendJoinPlaceId)

			if fallbackPlace then
				task.delay(1.2, function()
					pcall(function()
						CS.Services.TeleportService:Teleport(fallbackPlace, CS.LocalPlayer)
					end)
				end)
			end
		end)
	end)
end

function CS.Friends.TryGetLiveFriendInstance(userId)
	local result = nil

	if not userId then
		return nil
	end

	pcall(function()
		local currentInstance, placeId, jobId = CS.Services.TeleportService:GetPlayerPlaceInstanceAsync(tonumber(userId))

		if placeId and jobId then
			result = {
				PlaceId = tonumber(placeId),
				JobId = tostring(jobId),
				CurrentInstance = currentInstance
			}
		end
	end)

	return result
end

function CS.Friends.CopyFriendProfile(userId, friendName)
	if not userId then
		CS.Notify.Push("Friends", "No UserId available for profile fallback.", CS.Theme.Warning)
		return
	end

	local url = "https://[Log in to view URL]" .. tostring(userId) .. "/profile"

	if setclipboard then
		setclipboard(url)
		CS.Notify.Push("Friends", "Copied " .. tostring(friendName or "friend") .. "'s Roblox profile link. Use the profile Join button if Roblox allows it.", CS.Theme.Info)
	else
		CS.Notify.Push("Friends", "Profile: " .. url, CS.Theme.Info)
	end
end

function CS.Friends.TryJoinFriend(friendData)
	if not friendData then
		CS.Notify.Push("Friends", "No friend selected.", CS.Theme.Warning)
		return
	end

	local userId = tonumber(friendData.VisitorId or friendData.UserId or friendData.userId)
	local friendName = tostring(friendData.DisplayName or friendData.UserName or friendData.Username or "friend")

	local placeId = tonumber(friendData.PlaceId or friendData.PlaceID or friendData.placeId or friendData.placeID)
	local jobId = friendData.GameId or friendData.GameID or friendData.JobId or friendData.JobID or friendData.gameId or friendData.jobId

	if typeof(jobId) ~= "string" and jobId ~= nil then
		jobId = tostring(jobId)
	end

	CS.Notify.PlayJoinFriend()

	-- Roblox Error 773 is a platform restriction. Client Lua cannot bypass it.
	-- This function now avoids repeated restricted teleports and gives the safest join path.

	if not placeId then
		CS.Friends.CopyFriendProfile(userId, friendName)
		CS.Notify.Push("Friend Join", "Roblox did not expose a joinable PlaceId. Profile fallback copied.", CS.Theme.Warning)
		return
	end

	-- If friend is in this same place and Roblox gave a JobId, try exact server once.
	-- This is the only automatic join path Roblox may allow.
	if placeId == game.PlaceId and jobId and jobId ~= "" then
		CS.Notify.Push("Friend Join", "Trying same-game server join for " .. friendName .. "...", CS.Theme.Info)

		local ok, err = pcall(function()
			CS.Services.TeleportService:TeleportToPlaceInstance(placeId, jobId, CS.LocalPlayer)
		end)

		if ok then
			return
		end

		warn("CS same-game friend join failed:", err)
	end

	-- If the friend is in a different place, direct teleport often causes 773 when the destination is restricted.
	-- Copy profile instead so the user can use Roblox's official Join button if permissions allow.
	if placeId ~= game.PlaceId then
		CS.Friends.CopyFriendProfile(userId, friendName)
		CS.Notify.Push(
			"Friend Join Restricted",
			"Roblox is blocking direct teleport to that place/server. I copied the profile link so you can try the official Join button.",
			CS.Theme.Warning
		)
		return
	end

	CS.Notify.Push(
		"Friend Join Failed",
		"Roblox did not provide a usable active server id, or the server is restricted/private/full.",
		CS.Theme.Warning
	)
end


function CS.Friends.SetSelectedFriend(friendData, profile)
	CS.Runtime.SelectedFriend = friendData

	local name = tostring(friendData.UserName or friendData.Username or friendData.DisplayName or "Unknown")
	local display = tostring(friendData.DisplayName or friendData.UserName or "Unknown")
	local userId = tostring(friendData.VisitorId or friendData.UserId or profile.UserId or "Unknown")
	local placeId = tostring(friendData.PlaceId or friendData.PlaceID or friendData.placeId or friendData.placeID or "Unavailable")
	local gameId = tostring(friendData.GameId or friendData.GameID or friendData.JobId or friendData.JobID or friendData.gameId or friendData.jobId or "Unavailable")
	local location = tostring(friendData.LastLocation or friendData.LocationType or "Unavailable")

	if CS.UI.Objects.FriendAvatar then
		pcall(function()
			CS.UI.Objects.FriendAvatar.Image = CS.Services.Players:GetUserThumbnailAsync(
				tonumber(userId),
				Enum.ThumbnailType.AvatarThumbnail,
				Enum.ThumbnailSize.Size420x420
			)
		end)
	end

	if CS.UI.Labels.FriendDetails then
		CS.UI.Labels.FriendDetails.Text =
			"Display Name: " .. display ..
			"\nUsername: @" .. name ..
			"\nUserId: " .. userId ..
			"\nOnline Location: " .. location ..
			"\nPlaceId: " .. placeId ..
			"\nServer/JobId: " .. gameId ..
			"\nJoin Quality: " .. ((placeId ~= "Unavailable" and gameId ~= "Unavailable") and "Same-game exact server only if Roblox allows it" or (placeId ~= "Unavailable" and "Limited: place only" or "Unavailable")) ..
			"\n\nBio: unavailable from normal in-game Lua." ..
			"\nMessages: unavailable from normal in-game Lua."
	end
end

function CS.Friends.CreateFriendRow(parent, friendData)
	local userId = tonumber(friendData.VisitorId or friendData.UserId or 0)
	local username = tostring(friendData.UserName or friendData.Username or "Unknown")
	local display = tostring(friendData.DisplayName or username)
	local location = tostring(friendData.LastLocation or "Online")

	local row = CS.Util.Create("TextButton", {
		Parent = parent,
		Size = UDim2.new(1, -8, 0, 72),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.14,
		BorderSizePixel = 0,
		Text = ""
	})

	CS.Util.Corner(row, 12)
	CS.Util.Stroke(row, CS.Theme.Stroke, 0.55, 1)

	local icon = CS.Util.Create("ImageLabel", {
		Parent = row,
		Size = UDim2.new(0, 48, 0, 48),
		Position = UDim2.new(0, 10, 0, 12),
		BackgroundTransparency = 1
	})

	CS.Util.Corner(icon, 999)

	if userId > 0 then
		pcall(function()
			icon.Image = CS.Services.Players:GetUserThumbnailAsync(
				userId,
				Enum.ThumbnailType.HeadShot,
				Enum.ThumbnailSize.Size100x100
			)
		end)
	end

	local text = CS.Util.Create("TextLabel", {
		Parent = row,
		Size = UDim2.new(1, -190, 1, 0),
		Position = UDim2.new(0, 68, 0, 0),
		BackgroundTransparency = 1,
		Text = display .. "\n@" .. username .. "\n" .. location,
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 12,
		TextWrapped = true,
		TextXAlignment = Enum.TextXAlignment.Left,
		TextYAlignment = Enum.TextYAlignment.Center
	})

	local join = CS.Util.Create("TextButton", {
		Parent = row,
		Size = UDim2.new(0, 82, 0, 34),
		Position = UDim2.new(1, -94, 0.5, -17),
		BackgroundColor3 = CS.Theme.Success,
		BackgroundTransparency = 0.08,
		BorderSizePixel = 0,
		Text = "Join",
		TextColor3 = Color3.fromRGB(0, 0, 0),
		Font = Enum.Font.GothamBold,
		TextSize = 12
	})

	CS.Util.Corner(join, 9)

	row.MouseButton1Click:Connect(function()
		for _, obj in ipairs(parent:GetChildren()) do
			if obj:IsA("TextButton") then
				obj.BackgroundColor3 = CS.Theme.Card2
				obj.BackgroundTransparency = 0.14
			end
		end

		row.BackgroundColor3 = CS.Theme.Accent
		row.BackgroundTransparency = 0.02
		CS.Friends.SetSelectedFriend(friendData, {UserId = userId})
	end)

	join.MouseButton1Click:Connect(function()
		CS.Friends.TryJoinFriend(friendData)
	end)
end

function CS.Friends.RefreshFriendList()
	local list = CS.UI.Objects.FriendListScroll
	if not list then return end

	CS.Util.Clear(list, true)

	local friends = CS.Friends.GetOnlineFriends()

	if #friends == 0 then
		CS.Util.InfoCard(list, "Friends List", "No online friends were returned by Roblox.", 90)
		return
	end

	for _, friendData in ipairs(friends) do
		CS.Friends.CreateFriendRow(list, friendData)
	end

	CS.Friends.UpdateGameFriends()
end

function CS.Friends.UpdateGameFriends()
	local sameGame = {}
	local friends = CS.Runtime.FriendsOnlineCache or CS.Friends.GetOnlineFriends()

	for _, friendData in ipairs(friends) do
		local placeId = tonumber(friendData.PlaceId or friendData.PlaceID or 0)

		if placeId == game.PlaceId then
			table.insert(sameGame, friendData)
		end
	end

	if CS.UI.Labels.GameFriends then
		if #sameGame == 0 then
			CS.UI.Labels.GameFriends.Text = "No online friends detected in this same game through Roblox online-friend data."
		else
			local text = "Friends in this game, possibly different server:\\n"

			for _, friendData in ipairs(sameGame) do
				text ..= "\\n" .. tostring(friendData.DisplayName or friendData.UserName or "Unknown") ..
					"  @" .. tostring(friendData.UserName or "Unknown") ..
					"\\nLocation: " .. tostring(friendData.LastLocation or "Unknown") ..
					"\\nJoin data: " .. ((friendData.GameId or friendData.JobId) and "available" or "limited") .. "\\n"
			end

			CS.UI.Labels.GameFriends.Text = text
		end
	end
end

function CS.Friends.Build()
	local page=CS.UI.Pages["Friends"]; CS.Util.Clear(page,true); local left=CS.Util.Scroll(page); left.Size=UDim2.new(0.48,-6,1,0); local right=CS.Util.Scroll(page); right.Size=UDim2.new(0.52,-6,1,0); right.Position=UDim2.new(0.48,6,0,0)
	local overview=CS.UI.OverlayCard(left,"Friends Overview","♡",180); CS.UI.Labels.FriendsOverview=CS.UI.OverlayValue(overview,58,"◎","Online","--","Roblox online-friend data."); CS.UI.Labels.FriendsInServer=CS.UI.OverlayValue(overview,112,"👥","In Server","--","Friends currently in this server.")
	local list=CS.UI.OverlayCard(left,"Friend List","☰",520); CS.UI.OverlayButton(list,"Refresh Friends List",58,function() CS.Friends.RefreshFriendList(); CS.Notify.Push("Friends","Friend list refreshed.",CS.Theme.Success) end); local holder=CS.Util.Create("Frame",{Parent=list,Size=UDim2.new(1,-28,1,-118),Position=UDim2.new(0,14,0,106),BackgroundColor3=CS.Theme.Card2,BackgroundTransparency=0.22,BorderSizePixel=0}); CS.Util.Corner(holder,12); CS.Util.Stroke(holder,CS.Theme.Stroke,0.55,1); CS.UI.Objects.FriendListScroll=CS.Util.Scroll(holder)
	local avatarCard=CS.UI.OverlayCard(right,"Friend Preview","👤",310); CS.UI.Objects.FriendAvatar=CS.Util.Create("ImageLabel",{Parent=avatarCard,Size=UDim2.new(1,-28,1,-70),Position=UDim2.new(0,14,0,56),BackgroundColor3=CS.Theme.Card2,BackgroundTransparency=0.22,BorderSizePixel=0,ScaleType=Enum.ScaleType.Fit}); CS.Util.Corner(CS.UI.Objects.FriendAvatar,12); CS.Util.Stroke(CS.UI.Objects.FriendAvatar,CS.Theme.Stroke,0.55,1)
	local details=CS.UI.OverlayCard(right,"Friend Details","◎",290); CS.UI.Labels.FriendDetails=CS.UI.OverlayText(details,58,210,"Click a friend from the list.")
	local actions=CS.UI.OverlayCard(right,"Friend Actions","⚙",160); CS.UI.OverlayButton(actions,"Join Selected Friend",58,function() CS.Friends.TryJoinFriend(CS.Runtime.SelectedFriend) end); CS.UI.OverlayButton(actions,"Copy Selected Profile",106,function() local f=CS.Runtime.SelectedFriend; if f then CS.Friends.CopyFriendProfile(f.VisitorId or f.UserId, f.DisplayName or f.UserName) end end)
	pcall(function() CS.Friends.RefreshFriendList() end)
end

function CS.Friends.CountInServer()
	local count = 0
	local names = {}

	for _, player in ipairs(CS.Services.Players:GetPlayers()) do
		if player ~= CS.LocalPlayer then
			local isFriend = false
			pcall(function()
				isFriend = CS.LocalPlayer:IsFriendsWith(player.UserId)
			end)

			if isFriend then
				count += 1
				table.insert(names, player.DisplayName .. " (@" .. player.Name .. ")")
			end
		end
	end

	return count, names
end

function CS.Friends.CountOnline()
	local count = 0

	pcall(function()
		for _, _ in ipairs(CS.LocalPlayer:GetFriendsOnline()) do
			count += 1
		end
	end)

	return count
end

function CS.Friends.PushFeed(text)
	table.insert(CS.Runtime.Feed, 1, os.date("%I:%M:%S %p") .. "  " .. text)

	while #CS.Runtime.Feed > 12 do
		table.remove(CS.Runtime.Feed)
	end
end

function CS.Friends.Update()
	local online = CS.Friends.CountOnline()
	local inServer, names = CS.Friends.CountInServer()
	local onlineData = CS.Friends.GetOnlineFriends()

	CS.Util.Set(CS.UI.Labels.FriendsOverview,
		"Friends Online: " .. tostring(#onlineData > 0 and #onlineData or online) ..
		"\nFriends In Server: " .. tostring(inServer) ..
		"\nPlayer Notices: " .. tostring(CS.Flags.ShowNonFriendNotices)
	)

	if #names > 0 then
		CS.Util.Set(CS.UI.Labels.FriendsInServer, table.concat(names, "\n"))
	else
		CS.Util.Set(CS.UI.Labels.FriendsInServer, "No friends detected in this server.")
	end

	if CS.UI.Labels.Feed then
		if #CS.Runtime.Feed > 0 then
			CS.Util.Set(CS.UI.Labels.Feed, table.concat(CS.Runtime.Feed, "\n"))
		else
			CS.Util.Set(CS.UI.Labels.Feed, "No recent player events.")
		end
	end
end

function CS.Diagnostics.Build()
	local page=CS.UI.Pages["Diagnostics"]; CS.Util.Clear(page,true); local left=CS.Util.Scroll(page); left.Size=UDim2.new(0.5,-6,1,0); local right=CS.Util.Scroll(page); right.Size=UDim2.new(0.5,-6,1,0); right.Position=UDim2.new(0.5,6,0,0)
	local client=CS.UI.OverlayCard(left,"Client Metrics","⚡",250); CS.UI.Labels.DiagnosticsClient=CS.UI.OverlayText(client,58,170,"Diagnostics loading...")
	local graph=CS.UI.OverlayCard(left,"Performance Graph","⌁",220); CS.UI.OverlayGraph(graph,58,"FPS / Ping Visual")
	local tools=CS.UI.OverlayCard(right,"Diagnostic Tools","⚙",260); CS.UI.OverlayButton(tools,"Run Diagnostics",58,function() CS.Diagnostics.Run(); CS.Notify.Push("Diagnostics","Diagnostics refreshed.",CS.Theme.Info) end); CS.UI.OverlayButton(tools,"Toggle Auto Refresh",106,function() CS.Flags.AutoRefreshDiagnostics=not CS.Flags.AutoRefreshDiagnostics; CS.Notify.Push("Diagnostics","Auto refresh: "..tostring(CS.Flags.AutoRefreshDiagnostics),CS.Theme.Info) end); CS.UI.OverlayButton(tools,"Repair UI Layout",154,function() CS.Settings.ApplyVisuals(); CS.Notify.Push("Diagnostics","UI layout repaired.",CS.Theme.Success) end)
	local notes=CS.UI.OverlayCard(right,"Status Notes","☰",260); CS.UI.Labels.DiagnosticsNotes=CS.UI.OverlayText(notes,58,180,"No warnings yet.")
	CS.Diagnostics.Run()
end

function CS.Diagnostics.Run()
	local services = {
		Players = CS.Services.Players ~= nil,
		RunService = CS.Services.RunService ~= nil,
		TweenService = CS.Services.TweenService ~= nil,
		UserInputService = CS.Services.UserInputService ~= nil,
		Stats = CS.Services.Stats ~= nil,
		MarketplaceService = CS.Services.MarketplaceService ~= nil,
		TeleportService = CS.Services.TeleportService ~= nil,
		HttpService = CS.Services.HttpService ~= nil
	}

	local okCount = 0
	local total = 0
	local serviceText = ""

	for name, exists in pairs(services) do
		total += 1
		if exists then okCount += 1 end
		serviceText ..= name .. ": " .. (exists and "OK" or "Missing") .. "\n"
	end

	CS.Util.Set(CS.UI.Labels.DiagnosticsMain,
		"Services: " .. tostring(okCount) .. "/" .. tostring(total) .. " OK" ..
		"\nGame Loaded: " .. tostring(game:IsLoaded()) ..
		"\nPlayers: " .. tostring(#CS.Services.Players:GetPlayers()) .. "/" .. tostring(CS.Services.Players.MaxPlayers) ..
		"\n\n" .. serviceText
	)

	local char = CS.LocalPlayer.Character
	local humanoid = char and char:FindFirstChildOfClass("Humanoid")
	local root = char and char:FindFirstChild("HumanoidRootPart")
	local head = char and char:FindFirstChild("Head")

	CS.Util.Set(CS.UI.Labels.DiagnosticsCharacter,
		"Character: " .. tostring(char ~= nil) ..
		"\nHumanoid: " .. tostring(humanoid ~= nil) ..
		"\nHumanoidRootPart: " .. tostring(root ~= nil) ..
		"\nHead: " .. tostring(head ~= nil) ..
		"\nPlayerGui: " .. tostring(CS.PlayerGui ~= nil)
	)

	CS.Util.Set(CS.UI.Labels.DiagnosticsEnvironment,
		"HTTP Request: " .. tostring(CS.Request ~= nil) ..
		"\nClipboard: " .. tostring(setclipboard ~= nil) ..
		"\nDrawing API: " .. tostring(Drawing ~= nil) ..
		"\nCoreGui Access: " .. tostring(pcall(function() return CS.Services.CoreGui.Name end)) ..
		"\nExecutor-specific APIs are optional."
	)

	local warnings = {}

	if not CS.Request then
		table.insert(warnings, "Server browser cannot fetch public servers without request/http_request.")
	end

	if not setclipboard then
		table.insert(warnings, "Copy buttons will not work without setclipboard.")
	end

	if not root then
		table.insert(warnings, "Character root is not loaded yet.")
	end

	if #warnings == 0 then
		CS.Util.Set(CS.UI.Labels.DiagnosticsWarnings, "No major warnings.", CS.Theme.Success)
	else
		CS.Util.Set(CS.UI.Labels.DiagnosticsWarnings, table.concat(warnings, "\n"), CS.Theme.Warning)
	end
end


function CS.Settings.HexToColor(hex)
	if type(hex) ~= "string" then
		return nil
	end

	hex = hex:gsub("#", ""):gsub("%s+", "")

	if #hex ~= 6 then
		return nil
	end

	local r = tonumber(hex:sub(1, 2), 16)
	local g = tonumber(hex:sub(3, 4), 16)
	local b = tonumber(hex:sub(5, 6), 16)

	if not r or not g or not b then
		return nil
	end

	return Color3.fromRGB(r, g, b)
end

function CS.Settings.ColorToHex(color)
	local r = math.floor(color.R * 255)
	local g = math.floor(color.G * 255)
	local b = math.floor(color.B * 255)

	return string.format("#%02X%02X%02X", r, g, b)
end

function CS.Settings.CanSave()
	return writefile ~= nil and readfile ~= nil and isfile ~= nil
end

function CS.Settings.CollectConfig()
	return {
		ConfigVersion = CS.Config.Version,

		Animations = CS.Flags.Animations,
		Notifications = CS.Flags.Notifications,
		ShowNonFriendNotices = CS.Flags.ShowNonFriendNotices,
		FriendSounds = CS.Flags.FriendSounds,

		Transparency = CS.Flags.Transparency,
		PanelTransparency = CS.Flags.PanelTransparency,
		CardTransparency = CS.Flags.CardTransparency,
		ScaleMode = CS.Flags.ScaleMode,

		Accent = CS.Settings.ColorToHex(CS.Theme.Accent),
		Background = CS.Settings.ColorToHex(CS.Theme.Background),
		Panel = CS.Settings.ColorToHex(CS.Theme.Panel),
		Card = CS.Settings.ColorToHex(CS.Theme.Card),
		Outline = CS.Settings.ColorToHex(CS.Theme.Stroke),
		Notification = CS.Settings.ColorToHex(CS.Theme.Info),
		NotificationBackground = CS.Settings.ColorToHex(CS.Theme.NotificationBackground),
		NotificationOutline = CS.Settings.ColorToHex(CS.Theme.NotificationOutline),

		FriendJoinSoundId = CS.Flags.FriendJoinSoundId,
		FriendLeaveSoundId = CS.Flags.FriendLeaveSoundId,
		JoinFriendSoundId = CS.Flags.JoinFriendSoundId,

		ColorCycleA = CS.Flags.ColorCycleA,
		ColorCycleB = CS.Flags.ColorCycleB,
		ColorCycleSpeed = CS.Flags.ColorCycleSpeed,
		ColorCycleSpeedLevel = CS.Flags.ColorCycleSpeedLevel
	}
end

function CS.Settings.Save(silent)
	if not writefile then
		if not silent then
			CS.Notify.Push("Settings", "Save unavailable in this executor.", CS.Theme.Warning)
		end
		return false
	end

	local ok, encoded = pcall(function()
		return CS.Services.HttpService:JSONEncode(CS.Settings.CollectConfig())
	end)

	if not ok or not encoded then
		if not silent then
			CS.Notify.Push("Settings", "Could not encode settings.", CS.Theme.Warning)
		end
		return false
	end

	local writeOk = pcall(function()
		writefile(CS.Config.FileName, encoded)
	end)

	if not silent then
		CS.Notify.Push("Settings", writeOk and "Settings saved." or "Settings failed to save.", writeOk and CS.Theme.Success or CS.Theme.Warning)
	end

	return writeOk
end

function CS.Settings.ApplyConfig(data)
	if type(data) ~= "table" then
		return
	end

	if type(data.Animations) == "boolean" then
		CS.Flags.Animations = data.Animations
	end

	if type(data.Notifications) == "boolean" then
		CS.Flags.Notifications = data.Notifications
	end

	if type(data.ShowNonFriendNotices) == "boolean" then
		CS.Flags.ShowNonFriendNotices = data.ShowNonFriendNotices
	end

	if type(data.FriendSounds) == "boolean" then
		CS.Flags.FriendSounds = data.FriendSounds
	end

	if tonumber(data.Transparency) then
		CS.Flags.Transparency = math.clamp(tonumber(data.Transparency), 0, 1)
	end

	if tonumber(data.PanelTransparency) then
		CS.Flags.PanelTransparency = math.clamp(tonumber(data.PanelTransparency), 0, 1)
	end

	if tonumber(data.CardTransparency) then
		CS.Flags.CardTransparency = math.clamp(tonumber(data.CardTransparency), 0, 1)
	end

	if type(data.ScaleMode) == "string" then
		CS.Flags.ScaleMode = data.ScaleMode
	end

	local colorMap = {
		Accent = "Accent",
		Background = "Background",
		Panel = "Panel",
		Card = "Card",
		Outline = "Stroke",
		Notification = "Info",
		NotificationBackground = "NotificationBackground",
		NotificationOutline = "NotificationOutline"
	}

	for configKey, themeKey in pairs(colorMap) do
		if type(data[configKey]) == "string" then
			local color = CS.Settings.HexToColor(data[configKey])
			if color then
				CS.Theme[themeKey] = color
			end
		end
	end

	if type(data.FriendJoinSoundId) == "string" then
		CS.Flags.FriendJoinSoundId = data.FriendJoinSoundId
	end

	if type(data.FriendLeaveSoundId) == "string" then
		CS.Flags.FriendLeaveSoundId = data.FriendLeaveSoundId
	end

	if type(data.JoinFriendSoundId) == "string" then
		CS.Flags.JoinFriendSoundId = data.JoinFriendSoundId
	end

	if type(data.ColorCycleA) == "string" then
		CS.Flags.ColorCycleA = data.ColorCycleA
	end

	if type(data.ColorCycleB) == "string" then
		CS.Flags.ColorCycleB = data.ColorCycleB
	end

	if tonumber(data.ColorCycleSpeed) then
		CS.Flags.ColorCycleSpeed = tonumber(data.ColorCycleSpeed)
	end

	if tonumber(data.ColorCycleSpeedLevel) then
		CS.Flags.ColorCycleSpeedLevel = math.clamp(tonumber(data.ColorCycleSpeedLevel), 1, 10)
	end

	CS.Flags.ColorCycle = false
	CS.Flags.ExampleNotification = false

	CS.Settings.ApplyVisuals()
	CS.Settings.RefreshToggleVisuals()
end

function CS.Settings.Load()
	if not readfile or not isfile then
		return false
	end

	if not isfile(CS.Config.FileName) then
		CS.Settings.Save(true)
		return false
	end

	local readOk, raw = pcall(function()
		return readfile(CS.Config.FileName)
	end)

	if not readOk or not raw or raw == "" then
		return false
	end

	local decodeOk, decoded = pcall(function()
		return CS.Services.HttpService:JSONDecode(raw)
	end)

	if decodeOk and decoded then
		CS.Settings.ApplyConfig(decoded)
		CS.Config.Loaded = true
		return true
	end

	return false
end


function CS.Settings.ApplyVisuals()
	CS.Theme.Accent2 = CS.Theme.Accent
	CS.Theme.Accent3 = CS.Theme.Accent

	if CS.UI.Objects.Main then
		CS.UI.Objects.Main.BackgroundColor3 = CS.Theme.Background
		CS.UI.Objects.Main.BackgroundTransparency = CS.Flags.Transparency
	end

	if CS.UI.Objects.Sidebar then
		CS.UI.Objects.Sidebar.BackgroundColor3 = CS.Theme.Panel
		CS.UI.Objects.Sidebar.BackgroundTransparency = CS.Flags.PanelTransparency
	end

	if CS.UI.Objects.Content then
		CS.UI.Objects.Content.BackgroundColor3 = CS.Theme.Panel
		CS.UI.Objects.Content.BackgroundTransparency = CS.Flags.PanelTransparency
	end

	if CS.UI.Objects.AccentRail then
		CS.UI.Objects.AccentRail.BackgroundColor3 = CS.Theme.Accent
	end

	if CS.UI.Objects.GUI then
		for _, obj in ipairs(CS.UI.Objects.GUI:GetDescendants()) do
			if obj:IsA("UIStroke") then
				obj.Color = CS.Theme.Stroke
			end
		end
	end

	for _, tab in pairs(CS.UI.Tabs) do
		if tab.BackgroundColor3 ~= CS.Theme.Accent then
			tab.BackgroundColor3 = CS.Theme.Card
		end
	end
end

function CS.Settings.MakeTextBox(parent, placeholder, defaultText)
	local box = CS.Util.Create("TextBox", {
		Parent = parent,
		Size = UDim2.new(1, -8, 0, 40),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.12,
		BorderSizePixel = 0,
		Text = defaultText or "",
		PlaceholderText = placeholder or "#FFFFFF",
		TextColor3 = CS.Theme.Text,
		PlaceholderColor3 = CS.Theme.Muted,
		Font = Enum.Font.GothamBold,
		TextSize = 14,
		ClearTextOnFocus = false
	})

	CS.Util.Corner(box, 10)
	CS.Util.Stroke(box, CS.Theme.Stroke, 0.5, 1)

	return box
end

function CS.Settings.MakeColorEditor(parent, labelText, key, defaultColor, applyCallback)
	local card = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -8, 0, 360),
		BackgroundColor3 = CS.Theme.Card,
		BackgroundTransparency = CS.Flags.CardTransparency,
		BorderSizePixel = 0
	})

	CS.Util.Corner(card, 14)
	CS.Util.Stroke(card, CS.Theme.Stroke, 0.45, 1)

	local swatch = CS.Util.Create("Frame", {
		Parent = card,
		Size = UDim2.new(0, 42, 0, 42),
		Position = UDim2.new(0, 12, 0, 12),
		BackgroundColor3 = defaultColor,
		BorderSizePixel = 0
	})

	CS.Util.Corner(swatch, 999)
	CS.Util.Stroke(swatch, CS.Theme.Text, 0.65, 1)

	local title = CS.Util.Create("TextLabel", {
		Parent = card,
		Size = UDim2.new(0.45, -70, 0, 22),
		Position = UDim2.new(0, 64, 0, 10),
		BackgroundTransparency = 1,
		Text = labelText,
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 14,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	local preview = CS.Util.Create("TextLabel", {
		Parent = card,
		Size = UDim2.new(0.45, -70, 0, 22),
		Position = UDim2.new(0, 64, 0, 32),
		BackgroundTransparency = 1,
		Text = labelText .. ": " .. CS.Settings.ColorToHex(defaultColor),
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.Gotham,
		TextSize = 12,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	local examplePanel = CS.Util.Create("Frame", {
		Parent = card,
		Size = UDim2.new(0.48, -12, 0, 92),
		Position = UDim2.new(0.52, 0, 0, 14),
		BackgroundColor3 = Color3.fromRGB(14, 14, 20),
		BackgroundTransparency = 0.12,
		BorderSizePixel = 0
	})

	CS.Util.Corner(examplePanel, 12)
	CS.Util.Stroke(examplePanel, CS.Theme.Stroke, 0.55, 1)

	local exampleTitle = CS.Util.Create("TextLabel", {
		Parent = examplePanel,
		Size = UDim2.new(1, -20, 0, 22),
		Position = UDim2.new(0, 10, 0, 8),
		BackgroundTransparency = 1,
		Text = "Preview: " .. labelText,
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 13,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	local exampleBody = CS.Util.Create("TextLabel", {
		Parent = examplePanel,
		Size = UDim2.new(1, -20, 0, 44),
		Position = UDim2.new(0, 10, 0, 34),
		BackgroundTransparency = 1,
		Text = "This shows what will change.",
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.Gotham,
		TextSize = 12,
		TextWrapped = true,
		TextXAlignment = Enum.TextXAlignment.Left,
		TextYAlignment = Enum.TextYAlignment.Top
	})

	local exampleAccentBar = CS.Util.Create("Frame", {
		Parent = examplePanel,
		Size = UDim2.new(1, -20, 0, 4),
		Position = UDim2.new(0, 10, 1, -10),
		BackgroundColor3 = defaultColor,
		BorderSizePixel = 0
	})

	CS.Util.Corner(exampleAccentBar, 999)

	local picker = CS.Util.Create("Frame", {
		Parent = card,
		Size = UDim2.new(1, -24, 0, 176),
		Position = UDim2.new(0, 12, 0, 104),
		BackgroundColor3 = Color3.fromRGB(255, 0, 0),
		BorderSizePixel = 0,
		ClipsDescendants = true
	})

	CS.Util.Corner(picker, 10)
	CS.Util.Stroke(picker, CS.Theme.Text, 0.45, 1)

	local satGradient = Instance.new("UIGradient")
	satGradient.Color = ColorSequence.new(Color3.fromRGB(255, 255, 255), Color3.fromRGB(255, 255, 255))
	satGradient.Transparency = NumberSequence.new({
		NumberSequenceKeypoint.new(0, 1),
		NumberSequenceKeypoint.new(1, 0)
	})
	satGradient.Rotation = 0
	satGradient.Parent = picker

	local valueOverlay = CS.Util.Create("Frame", {
		Parent = picker,
		Size = UDim2.new(1, 0, 1, 0),
		BackgroundColor3 = Color3.fromRGB(0, 0, 0),
		BorderSizePixel = 0
	})

	local valueGradient = Instance.new("UIGradient")
	valueGradient.Transparency = NumberSequence.new({
		NumberSequenceKeypoint.new(0, 1),
		NumberSequenceKeypoint.new(1, 0)
	})
	valueGradient.Rotation = 90
	valueGradient.Parent = valueOverlay

	local pickerCursor = CS.Util.Create("Frame", {
		Parent = picker,
		Size = UDim2.new(0, 16, 0, 16),
		Position = UDim2.new(0, -8, 1, -8),
		BackgroundColor3 = Color3.fromRGB(0, 0, 0),
		BackgroundTransparency = 0.25,
		BorderSizePixel = 0,
		ZIndex = 5
	})

	CS.Util.Corner(pickerCursor, 999)
	CS.Util.Stroke(pickerCursor, CS.Theme.Text, 0.1, 2)

	local hueBar = CS.Util.Create("Frame", {
		Parent = card,
		Size = UDim2.new(1, -24, 0, 18),
		Position = UDim2.new(0, 12, 0, 294),
		BackgroundColor3 = Color3.fromRGB(255, 255, 255),
		BorderSizePixel = 0
	})

	CS.Util.Corner(hueBar, 999)
	CS.Util.Stroke(hueBar, CS.Theme.Stroke, 0.55, 1)

	local hueGradient = Instance.new("UIGradient")
	hueGradient.Color = ColorSequence.new({
		ColorSequenceKeypoint.new(0.00, Color3.fromRGB(255, 0, 0)),
		ColorSequenceKeypoint.new(0.16, Color3.fromRGB(255, 255, 0)),
		ColorSequenceKeypoint.new(0.33, Color3.fromRGB(0, 255, 0)),
		ColorSequenceKeypoint.new(0.50, Color3.fromRGB(0, 255, 255)),
		ColorSequenceKeypoint.new(0.66, Color3.fromRGB(0, 0, 255)),
		ColorSequenceKeypoint.new(0.83, Color3.fromRGB(255, 0, 255)),
		ColorSequenceKeypoint.new(1.00, Color3.fromRGB(255, 0, 0))
	})
	hueGradient.Parent = hueBar

	local hueCursor = CS.Util.Create("Frame", {
		Parent = hueBar,
		Size = UDim2.new(0, 14, 0, 24),
		Position = UDim2.new(0, -7, 0.5, -12),
		BackgroundColor3 = Color3.fromRGB(25, 25, 25),
		BorderSizePixel = 0,
		ZIndex = 5
	})

	CS.Util.Corner(hueCursor, 999)
	CS.Util.Stroke(hueCursor, CS.Theme.Text, 0.25, 2)

	local bottom = CS.Util.Create("Frame", {
		Parent = card,
		Size = UDim2.new(1, -24, 0, 32),
		Position = UDim2.new(0, 12, 0, 322),
		BackgroundColor3 = Color3.fromRGB(12, 12, 18),
		BackgroundTransparency = 0.15,
		BorderSizePixel = 0
	})

	CS.Util.Corner(bottom, 10)
	CS.Util.Stroke(bottom, CS.Theme.Stroke, 0.6, 1)

	local miniSwatch = CS.Util.Create("Frame", {
		Parent = bottom,
		Size = UDim2.new(0, 22, 0, 22),
		Position = UDim2.new(0, 8, 0.5, -11),
		BackgroundColor3 = defaultColor,
		BorderSizePixel = 0
	})

	CS.Util.Corner(miniSwatch, 999)

	local box = CS.Util.Create("TextBox", {
		Parent = bottom,
		Size = UDim2.new(1, -150, 0, 28),
		Position = UDim2.new(0, 38, 0.5, -14),
		BackgroundTransparency = 1,
		Text = CS.Settings.ColorToHex(defaultColor),
		PlaceholderText = "#FFFFFF",
		TextColor3 = CS.Theme.Text,
		PlaceholderColor3 = CS.Theme.Muted,
		Font = Enum.Font.GothamBold,
		TextSize = 13,
		TextXAlignment = Enum.TextXAlignment.Left,
		ClearTextOnFocus = false
	})

	local apply = CS.Util.Create("TextButton", {
		Parent = bottom,
		Size = UDim2.new(0, 92, 0, 26),
		Position = UDim2.new(1, -100, 0.5, -13),
		BackgroundColor3 = defaultColor,
		BackgroundTransparency = 0.08,
		BorderSizePixel = 0,
		Text = "Apply",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 12
	})

	CS.Util.Corner(apply, 8)

	local hue = 0
	local sat = 1
	local val = 1
	local draggingPicker = false
	local draggingHue = false

	local function updateExample(color, hex)
		exampleAccentBar.BackgroundColor3 = color

		if key == "Notification" or labelText:lower():find("notification") then
			exampleTitle.Text = "Example Notification"
			exampleBody.Text = "This is the color used for notification accents."
			exampleAccentBar.BackgroundColor3 = color
		elseif key == "Accent" or labelText == "Accent" then
			exampleTitle.Text = "Example Selected Tab"
			exampleBody.Text = "Selected tabs, active buttons, highlights, and accent rail."
			examplePanel.BackgroundColor3 = color
			examplePanel.BackgroundTransparency = 0.18
		elseif key == "Accent2" or labelText:lower():find("secondary") then
			exampleTitle.Text = "Example Gradient Side"
			exampleBody.Text = "Secondary accent supports gradients and theme blends."
			exampleAccentBar.BackgroundColor3 = color
		elseif key == "Accent3" or labelText:lower():find("third") then
			exampleTitle.Text = "Example Extra Accent"
			exampleBody.Text = "Third accent supports extra glow and color blend details."
			exampleAccentBar.BackgroundColor3 = color
		elseif key == "Background" or labelText:lower():find("background") then
			exampleTitle.Text = "Example Menu Background"
			exampleBody.Text = "This changes the main menu/panel background tone."
			examplePanel.BackgroundColor3 = color
		elseif key == "Outline" or labelText:lower():find("outline") then
			exampleTitle.Text = "Example Outline"
			exampleBody.Text = "This changes borders and outline strokes."
			exampleAccentBar.BackgroundColor3 = color
			CS.Util.Stroke(examplePanel, color, 0.25, 1)
		else
			exampleTitle.Text = "Preview: " .. labelText
			exampleBody.Text = "This color will affect " .. labelText .. "."
		end

		preview.Text = labelText .. ": " .. hex
	end

	local function setColorFromHSV()
		local color = Color3.fromHSV(hue, sat, val)
		local hex = CS.Settings.ColorToHex(color)

		box.Text = hex
		swatch.BackgroundColor3 = color
		miniSwatch.BackgroundColor3 = color
		apply.BackgroundColor3 = color
		preview.TextColor3 = CS.Theme.SubText
		updateExample(color, hex)

		local hueColor = Color3.fromHSV(hue, 1, 1)
		picker.BackgroundColor3 = hueColor
		satGradient.Color = ColorSequence.new(Color3.fromRGB(255, 255, 255), Color3.fromRGB(255, 255, 255))
		satGradient.Transparency = NumberSequence.new({
			NumberSequenceKeypoint.new(0, 1),
			NumberSequenceKeypoint.new(1, 0)
		})
	end

	local function updatePickerFromInput(input)
		local absPos = picker.AbsolutePosition
		local absSize = picker.AbsoluteSize
		local x = math.clamp((input.Position.X - absPos.X) / absSize.X, 0, 1)
		local y = math.clamp((input.Position.Y - absPos.Y) / absSize.Y, 0, 1)

		sat = x
		val = 1 - y
		pickerCursor.Position = UDim2.new(x, -8, y, -8)
		pickerCursor.BackgroundColor3 = val > 0.5 and Color3.fromRGB(0, 0, 0) or Color3.fromRGB(255, 255, 255)
		setColorFromHSV()
	end

	local function updateHueFromInput(input)
		local absPos = hueBar.AbsolutePosition
		local absSize = hueBar.AbsoluteSize
		local x = math.clamp((input.Position.X - absPos.X) / absSize.X, 0, 1)

		hue = x
		hueCursor.Position = UDim2.new(x, -7, 0.5, -12)
		setColorFromHSV()
	end

	local function beginPickerDrag(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			draggingPicker = true
			updatePickerFromInput(input)
		end
	end

	picker.InputBegan:Connect(beginPickerDrag)
	valueOverlay.InputBegan:Connect(beginPickerDrag)

	hueBar.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			draggingHue = true
			updateHueFromInput(input)
		end
	end)

	CS.Services.UserInputService.InputChanged:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseMovement then
			if draggingPicker then
				updatePickerFromInput(input)
			elseif draggingHue then
				updateHueFromInput(input)
			end
		end
	end)

	CS.Services.UserInputService.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			draggingPicker = false
			draggingHue = false
		end
	end)

	box.FocusLost:Connect(function()
		local color = CS.Settings.HexToColor(box.Text)
		if color then
			local h, s, v = color:ToHSV()
			hue = h
			sat = s
			val = v
			pickerCursor.Position = UDim2.new(sat, -8, 1 - val, -8)
			pickerCursor.BackgroundColor3 = val > 0.5 and Color3.fromRGB(0, 0, 0) or Color3.fromRGB(255, 255, 255)
			hueCursor.Position = UDim2.new(hue, -7, 0.5, -12)
			swatch.BackgroundColor3 = color
			miniSwatch.BackgroundColor3 = color
			apply.BackgroundColor3 = color
			updateExample(color, box.Text)
			local hueColor = Color3.fromHSV(hue, 1, 1)
			picker.BackgroundColor3 = hueColor
			satGradient.Color = ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(255,255,255)),
				ColorSequenceKeypoint.new(1, hueColor)
			})
		else
			preview.Text = labelText .. ": invalid hex"
			preview.TextColor3 = CS.Theme.Warning
		end
	end)

	apply.MouseButton1Click:Connect(function()
		local color = CS.Settings.HexToColor(box.Text)

		if not color then
			CS.Notify.Push("Theme", "Invalid hex for " .. labelText .. ".", CS.Theme.Warning)
			return
		end

		applyCallback(color, box.Text)
	end)

	local startH, startS, startV = defaultColor:ToHSV()
	hue = startH
	sat = startS
	val = startV
	pickerCursor.Position = UDim2.new(sat, -8, 1 - val, -8)
	hueCursor.Position = UDim2.new(hue, -7, 0.5, -12)
	setColorFromHSV()

	return {
		Card = card,
		Swatch = swatch,
		Preview = preview,
		Box = box,
		Apply = apply,
		Picker = picker,
		HueBar = hueBar,
		Example = examplePanel
	}
end


function CS.Settings.RefreshToggleVisuals()
	CS.Settings.SetToggleVisual(CS.UI.Buttons.ToggleAnimations, CS.Flags.Animations)
	CS.Settings.SetToggleVisual(CS.UI.Buttons.ToggleNotifications, CS.Flags.Notifications)
	CS.Settings.SetToggleVisual(CS.UI.Buttons.ToggleNonFriends, CS.Flags.ShowNonFriendNotices)
	CS.Settings.SetToggleVisual(CS.UI.Buttons.ToggleFriendSounds, CS.Flags.FriendSounds)
end

function CS.Settings.MakeTransparencySlider(parent)
	local card = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -8, 0, 190),
		BackgroundColor3 = CS.Theme.Card,
		BackgroundTransparency = CS.Flags.CardTransparency,
		BorderSizePixel = 0
	})

	CS.Util.Corner(card, 14)
	CS.Util.Stroke(card, CS.Theme.Stroke, 0.45, 1)

	local title = CS.Util.Create("TextLabel", {
		Parent = card,
		Size = UDim2.new(1, -24, 0, 26),
		Position = UDim2.new(0, 12, 0, 10),
		BackgroundTransparency = 1,
		Text = "Glass Transparency",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 15,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	local subtitle = CS.Util.Create("TextLabel", {
		Parent = card,
		Size = UDim2.new(1, -24, 0, 24),
		Position = UDim2.new(0, 12, 0, 36),
		BackgroundTransparency = 1,
		Text = "One control for the full menu glass look.",
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.Gotham,
		TextSize = 12,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	local preview = CS.Util.Create("Frame", {
		Parent = card,
		Size = UDim2.new(1, -24, 0, 52),
		Position = UDim2.new(0, 12, 0, 66),
		BackgroundColor3 = Color3.fromRGB(255, 255, 255),
		BackgroundTransparency = CS.Flags.Transparency,
		BorderSizePixel = 0
	})

	CS.Util.Corner(preview, 12)
	CS.Util.Stroke(preview, CS.Theme.Stroke, 0.45, 1)

	local previewGradient = Instance.new("UIGradient")
	previewGradient.Color = ColorSequence.new({
		ColorSequenceKeypoint.new(0, Color3.fromRGB(0, 0, 0)),
		ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 255, 255))
	})
	previewGradient.Rotation = 0
	previewGradient.Parent = preview

	local previewText = CS.Util.Create("TextLabel", {
		Parent = preview,
		Size = UDim2.new(1, -20, 1, 0),
		Position = UDim2.new(0, 10, 0, 0),
		BackgroundTransparency = 1,
		Text = "Transparency: " .. tostring(CS.Flags.Transparency),
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 14,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	local bar = CS.Util.Create("Frame", {
		Parent = card,
		Size = UDim2.new(1, -48, 0, 16),
		Position = UDim2.new(0, 24, 0, 136),
		BackgroundColor3 = Color3.fromRGB(255, 255, 255),
		BorderSizePixel = 0
	})

	CS.Util.Corner(bar, 999)
	CS.Util.Stroke(bar, CS.Theme.Stroke, 0.45, 1)

	local barGradient = Instance.new("UIGradient")
	barGradient.Color = ColorSequence.new({
		ColorSequenceKeypoint.new(0, Color3.fromRGB(0, 0, 0)),
		ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 255, 255))
	})
	barGradient.Rotation = 0
	barGradient.Parent = bar

	local knob = CS.Util.Create("Frame", {
		Parent = bar,
		Size = UDim2.new(0, 22, 0, 22),
		Position = UDim2.new(CS.Flags.Transparency, -11, 0.5, -11),
		BackgroundColor3 = CS.Theme.Accent,
		BorderSizePixel = 0,
		ZIndex = 4
	})

	CS.Util.Corner(knob, 999)
	CS.Util.Stroke(knob, CS.Theme.Text, 0.2, 2)

	local dragging = false

	local function applyValueFromX(xPosition)
		local absPos = bar.AbsolutePosition
		local absSize = bar.AbsoluteSize
		local value = math.clamp((xPosition - absPos.X) / absSize.X, 0, 1)
		value = math.floor(value * 100) / 10

		CS.Flags.Transparency = value
		CS.Flags.PanelTransparency = math.clamp(value - 0.12, 0, 1)
		CS.Flags.CardTransparency = math.clamp(value - 0.35, 0, 1)

		knob.Position = UDim2.new(value, -11, 0.5, -11)
		preview.BackgroundTransparency = value
		previewText.Text = "Transparency: " .. tostring(value)

		if CS.UI.Objects.Main then CS.UI.Objects.Main.BackgroundTransparency = CS.Flags.Transparency end
		if CS.UI.Objects.Sidebar then CS.UI.Objects.Sidebar.BackgroundTransparency = CS.Flags.PanelTransparency end
		if CS.UI.Objects.Content then CS.UI.Objects.Content.BackgroundTransparency = CS.Flags.PanelTransparency end
	end

	bar.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = true
			applyValueFromX(input.Position.X)
		end
	end)

	CS.Services.UserInputService.InputChanged:Connect(function(input)
		if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
			applyValueFromX(input.Position.X)
		end
	end)

	CS.Services.UserInputService.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if dragging then
				dragging = false
				CS.Settings.Save(true)
				CS.Notify.Push("Settings", "Transparency saved.", CS.Theme.Success)
			end
		end
	end)

	return card
end

function CS.Settings.ResetThemeDefaults()
	CS.Theme.Background = Color3.fromRGB(7, 8, 12)
	CS.Theme.Background2 = Color3.fromRGB(13, 15, 24)
	CS.Theme.Panel = Color3.fromRGB(18, 18, 26)
	CS.Theme.Panel2 = Color3.fromRGB(24, 24, 36)
	CS.Theme.Card = Color3.fromRGB(28, 28, 40)
	CS.Theme.Card2 = Color3.fromRGB(36, 36, 52)
	CS.Theme.Accent = Color3.fromRGB(78, 115, 255)
	CS.Theme.Accent2 = CS.Theme.Accent
	CS.Theme.Accent3 = CS.Theme.Accent
	CS.Theme.Info = Color3.fromRGB(80, 185, 255)
	CS.Theme.NotificationBackground = Color3.fromRGB(28, 28, 40)
	CS.Theme.NotificationOutline = Color3.fromRGB(80, 185, 255)
	CS.Theme.Stroke = Color3.fromRGB(115, 120, 160)
	CS.Theme.StrokeSoft = Color3.fromRGB(70, 75, 100)

	CS.Flags.Transparency = 0.54
	CS.Flags.PanelTransparency = 0.36
	CS.Flags.CardTransparency = 0.14

	CS.Settings.ApplyVisuals()
	CS.Settings.Save()
	CS.Notify.Push("Settings", "Theme and transparency reset.", CS.Theme.Success)
end

function CS.Settings.MakeConfirmReset(parent)
	local holder = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -8, 0, 96),
		BackgroundColor3 = CS.Theme.Card,
		BackgroundTransparency = CS.Flags.CardTransparency,
		BorderSizePixel = 0
	})

	CS.Util.Corner(holder, 14)
	CS.Util.Stroke(holder, CS.Theme.Warning, 0.45, 1)

	local reset = CS.Util.Button(holder, "Reset Colors / Transparency", 38)
	reset.Position = UDim2.new(0, 12, 0, 10)
	reset.Size = UDim2.new(1, -24, 0, 38)

	local confirm = CS.Util.Button(holder, "Confirm Reset", 34)
	confirm.Position = UDim2.new(0, 12, 0, 54)
	confirm.Size = UDim2.new(1, -24, 0, 34)
	confirm.Visible = false
	confirm.BackgroundColor3 = CS.Theme.Warning
	confirm.TextColor3 = Color3.fromRGB(0, 0, 0)

	reset.MouseButton1Click:Connect(function()
		confirm.Visible = true
		reset.Text = "Click Confirm Reset below"
		CS.Notify.Push("Confirm Reset", "Press Confirm Reset to continue.", CS.Theme.Warning)

		task.delay(5, function()
			if confirm and confirm.Parent then
				confirm.Visible = false
				reset.Text = "Reset Colors / Transparency"
			end
		end)
	end)

	confirm.MouseButton1Click:Connect(function()
		confirm.Visible = false
		reset.Text = "Reset Colors / Transparency"
		CS.Settings.ResetThemeDefaults()
	end)
end


function CS.Settings.ToggleExampleNotification()
	CS.Flags.ExampleNotification = not CS.Flags.ExampleNotification

	local existing = CS.UI.Objects.PersistentExampleNotification
	if existing then
		existing:Destroy()
		CS.UI.Objects.PersistentExampleNotification = nil
	end

	if not CS.Flags.ExampleNotification then
		CS.Notify.Push("Notification Preview", "Example notification turned off.", CS.Theme.Info)
		return
	end

	local holder = CS.UI.Objects.ToastHolder
	if not holder then return end

	local preview = CS.Util.Create("Frame", {
		Parent = holder,
		Size = UDim2.new(1, 0, 0, 92),
		BackgroundColor3 = CS.Theme.NotificationBackground,
		BackgroundTransparency = 0.12,
		BorderSizePixel = 0,
		ClipsDescendants = true
	})

	CS.Util.Corner(preview, 12)
	CS.Util.Stroke(preview, CS.Theme.NotificationOutline, 0.2, 1)

	local title = CS.Util.Create("TextLabel", {
		Parent = preview,
		Size = UDim2.new(1, -20, 0, 26),
		Position = UDim2.new(0, 10, 0, 8),
		BackgroundTransparency = 1,
		Text = "Example Notification",
		TextColor3 = CS.Theme.NotificationOutline,
		Font = Enum.Font.GothamBold,
		TextSize = 14,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	local body = CS.Util.Create("TextLabel", {
		Parent = preview,
		Size = UDim2.new(1, -20, 1, -40),
		Position = UDim2.new(0, 10, 0, 34),
		BackgroundTransparency = 1,
		Text = "This stays until you turn it off.",
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.Gotham,
		TextSize = 13,
		TextWrapped = true,
		TextXAlignment = Enum.TextXAlignment.Left,
		TextYAlignment = Enum.TextYAlignment.Top
	})

	local line = CS.Util.Create("Frame", {
		Parent = preview,
		Size = UDim2.new(1, -20, 0, 3),
		Position = UDim2.new(0, 10, 1, -8),
		BackgroundColor3 = CS.Theme.NotificationOutline,
		BorderSizePixel = 0
	})

	CS.Util.Corner(line, 999)
	CS.UI.Objects.PersistentExampleNotification = preview
end

function CS.Settings.SaveOriginalTheme()
	CS.Runtime.OriginalTheme = {
		Accent = CS.Theme.Accent,
		Stroke = CS.Theme.Stroke,
		StrokeSoft = CS.Theme.StrokeSoft,
		NotificationOutline = CS.Theme.NotificationOutline
	}
end

function CS.Settings.RestoreOriginalTheme()
	if not CS.Runtime.OriginalTheme then
		return
	end

	CS.Theme.Accent = CS.Runtime.OriginalTheme.Accent
	CS.Theme.Stroke = CS.Runtime.OriginalTheme.Stroke
	CS.Theme.StrokeSoft = CS.Runtime.OriginalTheme.StrokeSoft
	CS.Theme.NotificationOutline = CS.Runtime.OriginalTheme.NotificationOutline

	CS.Runtime.OriginalTheme = nil
	CS.Settings.ApplyVisuals()
	CS.Settings.RefreshToggleVisuals()
end

function CS.Settings.LerpColor(a, b, t)
	return Color3.new(
		a.R + (b.R - a.R) * t,
		a.G + (b.G - a.G) * t,
		a.B + (b.B - a.B) * t
	)
end

function CS.Settings.UpdateColorCycle()
	if not CS.Flags.ColorCycle then
		return
	end

	local colorA = CS.Settings.HexToColor(CS.Flags.ColorCycleA) or Color3.fromRGB(255, 0, 215)
	local colorB = CS.Settings.HexToColor(CS.Flags.ColorCycleB) or Color3.fromRGB(0, 226, 255)
	local speed = CS.Settings.SpeedLevelToInternal(CS.Flags.ColorCycleSpeedLevel or 3)

	CS.Flags.ColorCycleHue += speed

	if CS.Flags.ColorCycleHue > 1 then
		CS.Flags.ColorCycleHue -= 1
	end

	local base = CS.Flags.ColorCycleHue

	local function waveColor(offset)
		local wave = (math.sin(((base + offset) % 1) * math.pi * 2) + 1) / 2
		return CS.Settings.LerpColor(colorA, colorB, wave)
	end

	local c1 = waveColor(0)
	local c2 = waveColor(0.17)
	local c3 = waveColor(0.34)
	local c4 = waveColor(0.51)
	local c5 = waveColor(0.68)

	CS.Theme.Accent = c1
	CS.Theme.Stroke = c2
	CS.Theme.StrokeSoft = c3
	CS.Theme.NotificationOutline = c1

	if CS.UI.Objects.AccentRail then
		CS.UI.Objects.AccentRail.BackgroundColor3 = c1
	end

	if CS.UI.Objects.Main then
		local mainStroke = CS.UI.Objects.Main:FindFirstChildOfClass("UIStroke")
		if mainStroke then
			mainStroke.Color = c1
		end
	end

	if CS.UI.Objects.Sidebar then
		local sideStroke = CS.UI.Objects.Sidebar:FindFirstChildOfClass("UIStroke")
		if sideStroke then
			sideStroke.Color = c2
		end
	end

	if CS.UI.Objects.Content then
		local contentStroke = CS.UI.Objects.Content:FindFirstChildOfClass("UIStroke")
		if contentStroke then
			contentStroke.Color = c3
		end
	end

	if CS.UI.Objects.GUI then
		local i = 0

		for _, obj in ipairs(CS.UI.Objects.GUI:GetDescendants()) do
			if obj:IsA("UIStroke") then
				i += 1

				local mod = i % 5
				if mod == 0 then
					obj.Color = c1
				elseif mod == 1 then
					obj.Color = c2
				elseif mod == 2 then
					obj.Color = c3
				elseif mod == 3 then
					obj.Color = c4
				else
					obj.Color = c5
				end
			end
		end
	end

	for name, tab in pairs(CS.UI.Tabs) do
		if CS.UI.Pages[name] and CS.UI.Pages[name].Visible then
			tab.BackgroundColor3 = c1
		end
	end

	if CS.UI.Objects.PersistentExampleNotification then
		local stroke = CS.UI.Objects.PersistentExampleNotification:FindFirstChildOfClass("UIStroke")
		if stroke then
			stroke.Color = c1
		end
	end
end

function CS.Settings.MakeMiniColorPicker(parent, titleText, defaultHex)
	local holder = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, 0, 0, 205),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.12,
		BorderSizePixel = 0
	})

	CS.Util.Corner(holder, 12)
	CS.Util.Stroke(holder, CS.Theme.Stroke, 0.55, 1)

	local label = CS.Util.Create("TextLabel", {
		Parent = holder,
		Size = UDim2.new(1, -16, 0, 22),
		Position = UDim2.new(0, 8, 0, 6),
		BackgroundTransparency = 1,
		Text = titleText,
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 13,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	local picker = CS.Util.Create("Frame", {
		Parent = holder,
		Size = UDim2.new(1, -16, 0, 92),
		Position = UDim2.new(0, 8, 0, 34),
		BackgroundColor3 = Color3.fromRGB(255, 0, 0),
		BorderSizePixel = 0,
		ClipsDescendants = true
	})

	CS.Util.Corner(picker, 8)
	CS.Util.Stroke(picker, CS.Theme.Text, 0.55, 1)

	local satGradient = Instance.new("UIGradient")
	satGradient.Color = ColorSequence.new(Color3.fromRGB(255, 255, 255), Color3.fromRGB(255, 255, 255))
	satGradient.Transparency = NumberSequence.new({
		NumberSequenceKeypoint.new(0, 1),
		NumberSequenceKeypoint.new(1, 0)
	})
	satGradient.Rotation = 0
	satGradient.Parent = picker

	local overlay = CS.Util.Create("Frame", {
		Parent = picker,
		Size = UDim2.new(1, 0, 1, 0),
		BackgroundColor3 = Color3.fromRGB(0, 0, 0),
		BorderSizePixel = 0
	})

	local overlayGradient = Instance.new("UIGradient")
	overlayGradient.Transparency = NumberSequence.new({
		NumberSequenceKeypoint.new(0, 1),
		NumberSequenceKeypoint.new(1, 0)
	})
	overlayGradient.Rotation = 90
	overlayGradient.Parent = overlay

	local cursor = CS.Util.Create("Frame", {
		Parent = picker,
		Size = UDim2.new(0, 14, 0, 14),
		Position = UDim2.new(1, -7, 0, -7),
		BackgroundColor3 = Color3.fromRGB(0, 0, 0),
		BackgroundTransparency = 0.2,
		BorderSizePixel = 0,
		ZIndex = 5
	})

	CS.Util.Corner(cursor, 999)
	CS.Util.Stroke(cursor, CS.Theme.Text, 0.15, 2)

	local hueBar = CS.Util.Create("Frame", {
		Parent = holder,
		Size = UDim2.new(1, -16, 0, 14),
		Position = UDim2.new(0, 8, 0, 134),
		BackgroundColor3 = Color3.fromRGB(255, 255, 255),
		BorderSizePixel = 0
	})

	CS.Util.Corner(hueBar, 999)

	local hueGradient = Instance.new("UIGradient")
	hueGradient.Color = ColorSequence.new({
		ColorSequenceKeypoint.new(0.00, Color3.fromRGB(255, 0, 0)),
		ColorSequenceKeypoint.new(0.16, Color3.fromRGB(255, 255, 0)),
		ColorSequenceKeypoint.new(0.33, Color3.fromRGB(0, 255, 0)),
		ColorSequenceKeypoint.new(0.50, Color3.fromRGB(0, 255, 255)),
		ColorSequenceKeypoint.new(0.66, Color3.fromRGB(0, 0, 255)),
		ColorSequenceKeypoint.new(0.83, Color3.fromRGB(255, 0, 255)),
		ColorSequenceKeypoint.new(1.00, Color3.fromRGB(255, 0, 0))
	})
	hueGradient.Parent = hueBar

	local hueCursor = CS.Util.Create("Frame", {
		Parent = hueBar,
		Size = UDim2.new(0, 12, 0, 20),
		Position = UDim2.new(0, -6, 0.5, -10),
		BackgroundColor3 = Color3.fromRGB(25, 25, 25),
		BorderSizePixel = 0,
		ZIndex = 5
	})

	CS.Util.Corner(hueCursor, 999)
	CS.Util.Stroke(hueCursor, CS.Theme.Text, 0.2, 2)

	local bottom = CS.Util.Create("Frame", {
		Parent = holder,
		Size = UDim2.new(1, -16, 0, 32),
		Position = UDim2.new(0, 8, 0, 160),
		BackgroundColor3 = Color3.fromRGB(12, 12, 18),
		BackgroundTransparency = 0.1,
		BorderSizePixel = 0
	})

	CS.Util.Corner(bottom, 8)

	local swatch = CS.Util.Create("Frame", {
		Parent = bottom,
		Size = UDim2.new(0, 22, 0, 22),
		Position = UDim2.new(0, 7, 0.5, -11),
		BackgroundColor3 = CS.Settings.HexToColor(defaultHex) or CS.Theme.Accent,
		BorderSizePixel = 0
	})

	CS.Util.Corner(swatch, 999)

	local box = CS.Util.Create("TextBox", {
		Parent = bottom,
		Size = UDim2.new(1, -40, 1, 0),
		Position = UDim2.new(0, 36, 0, 0),
		BackgroundTransparency = 1,
		Text = defaultHex,
		PlaceholderText = "#FFFFFF",
		TextColor3 = CS.Theme.Text,
		PlaceholderColor3 = CS.Theme.Muted,
		Font = Enum.Font.GothamBold,
		TextSize = 13,
		TextXAlignment = Enum.TextXAlignment.Left,
		ClearTextOnFocus = false
	})

	local hue, sat, val = 0, 1, 1
	local dragPicker = false
	local dragHue = false

	local function setHSV()
		local color = Color3.fromHSV(hue, sat, val)
		local hex = CS.Settings.ColorToHex(color)
		box.Text = hex
		swatch.BackgroundColor3 = color
		local hueColor = Color3.fromHSV(hue, 1, 1)
		picker.BackgroundColor3 = hueColor
		satGradient.Color = ColorSequence.new(Color3.fromRGB(255, 255, 255), Color3.fromRGB(255, 255, 255))
		satGradient.Transparency = NumberSequence.new({
			NumberSequenceKeypoint.new(0, 1),
			NumberSequenceKeypoint.new(1, 0)
		})
	end

	local function applyPicker(input)
		local x = math.clamp((input.Position.X - picker.AbsolutePosition.X) / picker.AbsoluteSize.X, 0, 1)
		local y = math.clamp((input.Position.Y - picker.AbsolutePosition.Y) / picker.AbsoluteSize.Y, 0, 1)
		sat = x
		val = 1 - y
		cursor.Position = UDim2.new(x, -7, y, -7)
		cursor.BackgroundColor3 = val > 0.5 and Color3.fromRGB(0, 0, 0) or Color3.fromRGB(255, 255, 255)
		setHSV()
	end

	local function applyHue(input)
		local x = math.clamp((input.Position.X - hueBar.AbsolutePosition.X) / hueBar.AbsoluteSize.X, 0, 1)
		hue = x
		hueCursor.Position = UDim2.new(x, -6, 0.5, -10)
		setHSV()
	end

	local function beginMiniPickerDrag(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragPicker = true
			applyPicker(input)
		end
	end

	picker.InputBegan:Connect(beginMiniPickerDrag)
	overlay.InputBegan:Connect(beginMiniPickerDrag)

	hueBar.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragHue = true
			applyHue(input)
		end
	end)

	CS.Services.UserInputService.InputChanged:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseMovement then
			if dragPicker then
				applyPicker(input)
			elseif dragHue then
				applyHue(input)
			end
		end
	end)

	CS.Services.UserInputService.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragPicker = false
			dragHue = false
		end
	end)

	box.FocusLost:Connect(function()
		local color = CS.Settings.HexToColor(box.Text)
		if color then
			local h, s, v = color:ToHSV()
			hue, sat, val = h, s, v
			cursor.Position = UDim2.new(sat, -7, 1 - val, -7)
			cursor.BackgroundColor3 = val > 0.5 and Color3.fromRGB(0, 0, 0) or Color3.fromRGB(255, 255, 255)
			hueCursor.Position = UDim2.new(hue, -6, 0.5, -10)
			box.Text = CS.Settings.ColorToHex(color)
			swatch.BackgroundColor3 = color
			local hueColor = Color3.fromHSV(hue, 1, 1)
			picker.BackgroundColor3 = hueColor
			satGradient.Color = ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(255,255,255)),
				ColorSequenceKeypoint.new(1, hueColor)
			})
		end
	end)

	local startColor = CS.Settings.HexToColor(defaultHex) or CS.Theme.Accent
	local h, s, v = startColor:ToHSV()
	hue, sat, val = h, s, v
	cursor.Position = UDim2.new(sat, -7, 1 - val, -7)
	hueCursor.Position = UDim2.new(hue, -6, 0.5, -10)
	setHSV()

	return {
		Frame = holder,
		Box = box,
		Swatch = swatch
	}
end


function CS.Settings.SpeedLevelToInternal(level)
	level = math.clamp(tonumber(level) or 3, 1, 10)

	-- 1 is very slow, 10 is fast.
	return 0.00001 + ((level - 1) / 9) * (0.0045 - 0.00001)
end






function CS.Settings.MakeSection(parent, title, icon, height)
	local card = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -8, 0, height or 220),
		BackgroundColor3 = CS.Theme.Card,
		BackgroundTransparency = CS.Flags.CardTransparency or 0.14,
		BorderSizePixel = 0
	})

	CS.Util.Corner(card, 14)
	CS.Util.Stroke(card, CS.Theme.Stroke, 0.4, 1)

	local glow = CS.Util.Create("Frame", {
		Parent = card,
		Size = UDim2.new(0, 3, 0, 42),
		Position = UDim2.new(0, 0, 0, 50),
		BackgroundColor3 = CS.Theme.Accent,
		BackgroundTransparency = 0.25,
		BorderSizePixel = 0
	})

	CS.Util.Corner(glow, 999)

	CS.Util.Create("TextLabel", {
		Parent = card,
		Size = UDim2.new(0, 34, 0, 44),
		Position = UDim2.new(0, 12, 0, 0),
		BackgroundTransparency = 1,
		Text = icon or "◇",
		TextColor3 = CS.Theme.Accent,
		Font = Enum.Font.GothamBold,
		TextSize = 18
	})

	CS.Util.Create("TextLabel", {
		Parent = card,
		Size = UDim2.new(1, -90, 0, 44),
		Position = UDim2.new(0, 46, 0, 0),
		BackgroundTransparency = 1,
		Text = string.upper(title or "SECTION"),
		TextColor3 = CS.Theme.Accent,
		Font = Enum.Font.GothamBold,
		TextSize = 14,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	CS.Util.Create("TextLabel", {
		Parent = card,
		Size = UDim2.new(0, 45, 0, 44),
		Position = UDim2.new(1, -54, 0, 0),
		BackgroundTransparency = 1,
		Text = "•••",
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.GothamBold,
		TextSize = 14
	})

	CS.Util.Create("Frame", {
		Parent = card,
		Size = UDim2.new(1, -28, 0, 1),
		Position = UDim2.new(0, 14, 0, 44),
		BackgroundColor3 = CS.Theme.Stroke,
		BackgroundTransparency = 0.72,
		BorderSizePixel = 0
	})

	return card
end

function CS.Settings.MakeRow(parent, y, icon, title, desc)
	local row = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -28, 0, 48),
		Position = UDim2.new(0, 14, 0, y),
		BackgroundTransparency = 1
	})

	CS.Util.Create("TextLabel", {
		Parent = row,
		Size = UDim2.new(0, 42, 1, 0),
		BackgroundTransparency = 1,
		Text = icon or "◇",
		TextColor3 = CS.Theme.Accent,
		Font = Enum.Font.GothamBold,
		TextSize = 18
	})

	CS.Util.Create("TextLabel", {
		Parent = row,
		Size = UDim2.new(1, -170, 0, 22),
		Position = UDim2.new(0, 52, 0, 4),
		BackgroundTransparency = 1,
		Text = title or "Setting",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 13,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	CS.Util.Create("TextLabel", {
		Parent = row,
		Size = UDim2.new(1, -170, 0, 20),
		Position = UDim2.new(0, 52, 0, 25),
		BackgroundTransparency = 1,
		Text = desc or "",
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.Gotham,
		TextSize = 11,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -28, 0, 1),
		Position = UDim2.new(0, 14, 0, y + 52),
		BackgroundColor3 = CS.Theme.Stroke,
		BackgroundTransparency = 0.82,
		BorderSizePixel = 0
	})

	return row
end

function CS.Settings.MakeSwitch(parent, state, callback)
	local button = CS.Util.Create("TextButton", {
		Parent = parent,
		Size = UDim2.new(0, 52, 0, 26),
		Position = UDim2.new(1, -58, 0.5, -13),
		BackgroundColor3 = state and CS.Theme.Success or Color3.fromRGB(45, 47, 60),
		BorderSizePixel = 0,
		Text = "",
		AutoButtonColor = false
	})

	CS.Util.Corner(button, 999)

	local knob = CS.Util.Create("Frame", {
		Parent = button,
		Size = UDim2.new(0, 20, 0, 20),
		Position = state and UDim2.new(1, -23, 0.5, -10) or UDim2.new(0, 3, 0.5, -10),
		BackgroundColor3 = Color3.fromRGB(245, 245, 245),
		BorderSizePixel = 0
	})

	CS.Util.Corner(knob, 999)

	local current = state

	local function redraw(animated)
		button.BackgroundColor3 = current and CS.Theme.Success or Color3.fromRGB(45, 47, 60)

		local goal = {
			Position = current and UDim2.new(1, -23, 0.5, -10) or UDim2.new(0, 3, 0.5, -10)
		}

		if animated == false or not CS.Flags.Animations then
			knob.Position = goal.Position
		else
			CS.Services.TweenService:Create(
				knob,
				TweenInfo.new(0.18, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
				goal
			):Play()
		end
	end

	button.MouseButton1Click:Connect(function()
		current = not current
		redraw(true)

		if callback then
			callback(current)
		end
	end)

	return {
		Button = button,
		Knob = knob,
		Set = function(_, value)
			current = value
			redraw(false)
		end,
		Get = function()
			return current
		end
	}
end

function CS.Settings.MakeMiniSlider(parent, value, callback)
	local holder = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(0, 170, 0, 26),
		Position = UDim2.new(1, -180, 0.5, -13),
		BackgroundTransparency = 1
	})

	local valueLabel = CS.Util.Create("TextLabel", {
		Parent = holder,
		Size = UDim2.new(0, 44, 1, 0),
		Position = UDim2.new(1, -44, 0, 0),
		BackgroundTransparency = 1,
		Text = tostring(math.floor((value or 0) * 100)) .. "%",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 11
	})

	local bar = CS.Util.Create("Frame", {
		Parent = holder,
		Size = UDim2.new(1, -52, 0, 5),
		Position = UDim2.new(0, 0, 0.5, -2),
		BackgroundColor3 = CS.Theme.Card2,
		BorderSizePixel = 0
	})
	CS.Util.Corner(bar, 999)

	local fill = CS.Util.Create("Frame", {
		Parent = bar,
		Size = UDim2.new(math.clamp(value or 0, 0, 1), 0, 1, 0),
		BackgroundColor3 = CS.Theme.Accent,
		BorderSizePixel = 0
	})
	CS.Util.Corner(fill, 999)

	local knob = CS.Util.Create("Frame", {
		Parent = bar,
		Size = UDim2.new(0, 16, 0, 16),
		Position = UDim2.new(math.clamp(value or 0, 0, 1), -8, 0.5, -8),
		BackgroundColor3 = CS.Theme.Accent,
		BorderSizePixel = 0
	})
	CS.Util.Corner(knob, 999)
	CS.Util.Stroke(knob, CS.Theme.Text, 0.35, 1)

	local dragging = false
	local current = math.clamp(value or 0, 0, 1)

	local function apply(x, fire)
		current = math.clamp(x, 0, 1)
		fill.Size = UDim2.new(current, 0, 1, 0)
		knob.Position = UDim2.new(current, -8, 0.5, -8)
		valueLabel.Text = tostring(math.floor(current * 100)) .. "%"

		if fire and callback then
			callback(current)
		end
	end

	local function setFromX(xPos)
		apply((xPos - bar.AbsolutePosition.X) / math.max(bar.AbsoluteSize.X, 1), true)
	end

	bar.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = true
			setFromX(input.Position.X)
		end
	end)

	knob.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = true
			setFromX(input.Position.X)
		end
	end)

	CS.Services.UserInputService.InputChanged:Connect(function(input)
		if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
			setFromX(input.Position.X)
		end
	end)

	CS.Services.UserInputService.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 and dragging then
			dragging = false
			CS.Settings.Save(true)
		end
	end)

	return {
		Holder = holder,
		Set = function(_, v)
			apply(v, false)
		end,
		Get = function()
			return current
		end
	}
end

function CS.Settings.MakeSmallSelect(parent, text, callback)
	local btn = CS.Util.Create("TextButton", {
		Parent = parent,
		Size = UDim2.new(0, 110, 0, 30),
		Position = UDim2.new(1, -116, 0.5, -15),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.08,
		BorderSizePixel = 0,
		Text = text or "Default",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 11,
		AutoButtonColor = false
	})

	CS.Util.Corner(btn, 8)
	CS.Util.Stroke(btn, CS.Theme.Stroke, 0.6, 1)

	btn.MouseButton1Click:Connect(function()
		if callback then
			callback(btn)
		end
	end)

	return btn
end

function CS.Settings.MakePreviewBox(parent, title, xScale)
	local box = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(xScale or 0.42, -14, 0, 150),
		Position = UDim2.new(1 - (xScale or 0.42), 0, 0, 62),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.18,
		BorderSizePixel = 0
	})

	CS.Util.Corner(box, 12)
	CS.Util.Stroke(box, CS.Theme.Stroke, 0.42, 1)

	CS.Util.Create("TextLabel", {
		Parent = box,
		Size = UDim2.new(1, 0, 0, 28),
		BackgroundTransparency = 1,
		Text = string.upper(title or "PREVIEW"),
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.GothamBold,
		TextSize = 11
	})

	return box
end

function CS.Settings.MakeStatPreview(parent, leftText, rightText)
	local preview = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -28, 0, 36),
		Position = UDim2.new(0, 14, 1, -48),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.2,
		BorderSizePixel = 0
	})

	CS.Util.Corner(preview, 9)
	CS.Util.Stroke(preview, CS.Theme.Stroke, 0.55, 1)

	CS.Util.Create("TextLabel", {
		Parent = preview,
		Size = UDim2.new(0.5, -8, 1, 0),
		Position = UDim2.new(0, 10, 0, 0),
		BackgroundTransparency = 1,
		Text = leftText or "",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 11,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	CS.Util.Create("TextLabel", {
		Parent = preview,
		Size = UDim2.new(0.5, -10, 1, 0),
		Position = UDim2.new(0.5, 0, 0, 0),
		BackgroundTransparency = 1,
		Text = rightText or "",
		TextColor3 = CS.Theme.Accent,
		Font = Enum.Font.GothamBold,
		TextSize = 11,
		TextXAlignment = Enum.TextXAlignment.Right
	})

	return preview
end

function CS.Settings.SafeNotify(title, body, color)
	if CS.Notify and CS.Notify.Push then
		CS.Notify.Push(title, body, color or CS.Theme.Info)
	end
end


CS.Settings.Runtime = CS.Settings.Runtime or {
	PreviewObjects = {},
	PreviewConnections = {},
	LastPreviewPulse = 0
}

function CS.Settings.TrackPreview(name, object)
	CS.Settings.Runtime.PreviewObjects[name] = object
	return object
end

function CS.Settings.ClearPreviewConnections()
	for _, connection in ipairs(CS.Settings.Runtime.PreviewConnections) do
		pcall(function()
			connection:Disconnect()
		end)
	end

	CS.Settings.Runtime.PreviewConnections = {}
end

function CS.Settings.TrackConnection(connection)
	table.insert(CS.Settings.Runtime.PreviewConnections, connection)
	return connection
end

function CS.Settings.ApplyOutlineThickness(value)
	local thickness = 0.5 + (math.clamp(value or 0.45, 0, 1) * 1.8)

	if not CS.UI.Objects.GUI then
		return
	end

	for _, obj in ipairs(CS.UI.Objects.GUI:GetDescendants()) do
		if obj:IsA("UIStroke") then
			obj.Thickness = thickness
		end
	end
end

function CS.Settings.ApplyGlassStrength(value)
	local strength = math.clamp(value or 0.55, 0, 1)

	CS.Flags.Transparency = math.clamp(1 - strength, 0.05, 0.85)
	CS.Flags.PanelTransparency = CS.Flags.Transparency
	CS.Flags.CardTransparency = math.clamp(CS.Flags.Transparency + 0.10, 0, 0.9)

	CS.Settings.ApplyVisuals()
end

function CS.Settings.ApplyScaleFromSlider(value)
	if value >= 0.8 then
		CS.Flags.ScaleMode = "Large"
	elseif value <= 0.35 then
		CS.Flags.ScaleMode = "Compact"
	else
		CS.Flags.ScaleMode = "Normal"
	end

	CS.Settings.ApplyVisuals()
end

function CS.Settings.SetColorCycleEnabled(value)
	CS.Flags.ColorCycle = value

	if value then
		CS.Settings.SaveOriginalTheme()
		CS.Flags.ColorCycleHue = 0

		for i = 1, 8 do
			CS.Settings.UpdateColorCycle()
		end
	else
		CS.Settings.RestoreOriginalTheme()
	end

	CS.Settings.Save(true)
end

function CS.Settings.SetAnimationEnabled(value)
	CS.Flags.Animations = value
	CS.Settings.Save(true)
end

function CS.Settings.SetFriendSoundsEnabled(value)
	CS.Flags.FriendSounds = value
	CS.Settings.Save(true)
end

function CS.Settings.SetNotificationEnabled(value)
	CS.Flags.Notifications = value
	CS.Settings.Save(true)
end

function CS.Settings.SetReducedMotion(value)
	CS.Flags.Animations = not value
	CS.Settings.Save(true)
end

function CS.Settings.SetCompactMode(value)
	CS.Flags.ScaleMode = value and "Compact" or "Normal"
	CS.Settings.ApplyVisuals()
	CS.Settings.Save(true)
end

function CS.Settings.PulseObject(object, color)
	if not object then
		return
	end

	local originalSize = object.Size
	local originalColor = object.BackgroundColor3

	object.BackgroundColor3 = color or CS.Theme.Accent

	if CS.Flags.Animations then
		CS.Services.TweenService:Create(
			object,
			TweenInfo.new(0.12, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
			{Size = originalSize + UDim2.new(0, 4, 0, 4)}
		):Play()

		task.delay(0.14, function()
			if object and object.Parent then
				CS.Services.TweenService:Create(
					object,
					TweenInfo.new(0.16, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
					{Size = originalSize, BackgroundColor3 = originalColor}
				):Play()
			end
		end)
	else
		object.Size = originalSize
		object.BackgroundColor3 = originalColor
	end
end

function CS.Settings.MakeRobloxAvatarPreview(parent, userId)
	local avatar = CS.Util.Create("ImageLabel", {
		Parent = parent,
		Size = UDim2.new(0, 58, 0, 58),
		Position = UDim2.new(0, 14, 0, 54),
		BackgroundTransparency = 1
	})

	CS.Util.Corner(avatar, 12)

	pcall(function()
		avatar.Image = CS.Services.Players:GetUserThumbnailAsync(
			userId or CS.LocalPlayer.UserId,
			Enum.ThumbnailType.AvatarThumbnail,
			Enum.ThumbnailSize.Size420x420
		)
	end)

	return avatar
end

function CS.Settings.MakeNotificationPreview(parent)
	local sample = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -24, 0, 70),
		Position = UDim2.new(0, 12, 0.5, -25),
		BackgroundColor3 = CS.Theme.NotificationBackground,
		BackgroundTransparency = 0.12,
		BorderSizePixel = 0
	})

	CS.Util.Corner(sample, 12)
	CS.Util.Stroke(sample, CS.Theme.NotificationOutline, 0.2, 2)

	CS.Util.Create("TextLabel", {
		Parent = sample,
		Size = UDim2.new(1, -20, 0, 26),
		Position = UDim2.new(0, 12, 0, 8),
		BackgroundTransparency = 1,
		Text = "CS  Player joined you",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 13,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	CS.Util.Create("TextLabel", {
		Parent = sample,
		Size = UDim2.new(1, -20, 0, 22),
		Position = UDim2.new(0, 12, 0, 36),
		BackgroundTransparency = 1,
		Text = "Welcome to the server!",
		TextColor3 = CS.Theme.SubText,
		Font = Enum.Font.Gotham,
		TextSize = 11,
		TextXAlignment = Enum.TextXAlignment.Left
	})

	return sample
end

function CS.Settings.MakeTabPreview(parent)
	local previewStack = CS.Util.Create("Frame", {
		Parent = parent,
		Size = UDim2.new(1, -24, 0, 110),
		Position = UDim2.new(0, 12, 0, 38),
		BackgroundTransparency = 1
	})

	local exLine1 = CS.Util.Button(previewStack, "▸ Home", 30)
	exLine1.Size = UDim2.new(1, 0, 0, 30)
	exLine1.Position = UDim2.new(0, 0, 0, 0)
	exLine1.TextXAlignment = Enum.TextXAlignment.Left

	local exLine2 = CS.Util.Button(previewStack, "  Players", 30)
	exLine2.Size = UDim2.new(1, 0, 0, 30)
	exLine2.Position = UDim2.new(0, 0, 0, 36)
	exLine2.TextXAlignment = Enum.TextXAlignment.Left

	local exLine3 = CS.Util.Button(previewStack, "  Settings", 30)
	exLine3.Size = UDim2.new(1, 0, 0, 30)
	exLine3.Position = UDim2.new(0, 0, 0, 72)
	exLine3.TextXAlignment = Enum.TextXAlignment.Left

	return previewStack
end

function CS.Settings.Build()
	local page = CS.UI.Pages["Settings"]
	CS.Util.Clear(page, true)

	local leftColumn = CS.Util.Scroll(page)
	leftColumn.Size = UDim2.new(0.333, -8, 1, 0)
	leftColumn.Position = UDim2.new(0, 0, 0, 0)

	local middleColumn = CS.Util.Scroll(page)
	middleColumn.Size = UDim2.new(0.333, -8, 1, 0)
	middleColumn.Position = UDim2.new(0.333, 4, 0, 0)

	local rightColumn = CS.Util.Scroll(page)
	rightColumn.Size = UDim2.new(0.334, -8, 1, 0)
	rightColumn.Position = UDim2.new(0.666, 8, 0, 0)

	local interface = CS.Settings.MakeSection(leftColumn, "Interface", "▣", 270)
	local row1 = CS.Settings.MakeRow(interface, 58, "▣", "UI Scale", "Adjust the size of the menu.")
	CS.Settings.MakeMiniSlider(row1, CS.Flags.ScaleMode == "Large" and 1 or 0.6, function(value)
		CS.Settings.ApplyScaleFromSlider(value)
	end)
	local row2 = CS.Settings.MakeRow(interface, 112, "◫", "Glass Strength", "Control the full menu transparency.")
	CS.Settings.MakeMiniSlider(row2, 1 - (CS.Flags.Transparency or 0.45), function(value)
		CS.Settings.ApplyGlassStrength(value)
	end)
	local row3 = CS.Settings.MakeRow(interface, 166, "◈", "Show Outlines", "Keep visible borders around cards.")
	CS.Settings.MakeSwitch(row3, true, function()
		CS.Settings.ApplyVisuals()
		CS.Settings.Save(true)
	end)
	local row4 = CS.Settings.MakeRow(interface, 220, "≈", "Outline Thickness", "Adjust outline strength.")
	CS.Settings.MakeMiniSlider(row4, 0.45, function(value)
		CS.Settings.ApplyOutlineThickness(value)
	end)

	local rgb = CS.Settings.MakeSection(leftColumn, "RGB Effects", "◉", 245)
	local r1 = CS.Settings.MakeRow(rgb, 58, "◉", "Enable RGB", "Animated outline chase effect.")
	CS.Settings.MakeSwitch(r1, CS.Flags.ColorCycle, function(value)
		CS.Settings.SetColorCycleEnabled(value)
	end)
	local r2 = CS.Settings.MakeRow(rgb, 112, "↬", "RGB Style", "Use chase-style animated borders.")
	CS.Settings.MakeSmallSelect(r2, "Chase", function() CS.Notify.Push("RGB", "Chase style selected.", CS.Theme.Info) end)
	local r3 = CS.Settings.MakeRow(rgb, 166, "⌁", "Speed", "How quickly the colors move.")
	CS.Settings.MakeMiniSlider(r3, math.clamp((CS.Flags.ColorCycleSpeedLevel or 3) / 10, 0.1, 1), function(value)
		CS.Flags.ColorCycleSpeedLevel = math.clamp(math.floor(value * 10 + 0.5), 1, 10)
		CS.Flags.ColorCycleSpeed = CS.Settings.SpeedLevelToInternal(CS.Flags.ColorCycleSpeedLevel)
	end)
	local r4 = CS.Settings.MakeRow(rgb, 220, "✦", "Brightness", "Preview glow strength.")
	CS.Settings.MakeMiniSlider(r4, 0.8, function() end)

	local effects = CS.Settings.MakeSection(leftColumn, "Visual Effects", "✧", 245)
	local effectPreview = CS.Settings.MakePreviewBox(effects, "Preview", 0.42)
	local fxText = CS.Util.Create("TextLabel", {Parent = effectPreview, Size = UDim2.new(1, 0, 1, -28), Position = UDim2.new(0, 0, 0, 28), BackgroundTransparency = 1, Text = "CS", TextColor3 = CS.Theme.Accent, Font = Enum.Font.GothamBlack, TextSize = 32})
	local e1 = CS.Settings.MakeRow(effects, 58, "◫", "Blur Intensity", "Preview blur-like glass strength.")
	CS.Settings.MakeMiniSlider(e1, 0.35, function(value) effectPreview.BackgroundTransparency = math.clamp(0.45 - value * 0.25, 0.08, 0.45) end)
	local e2 = CS.Settings.MakeRow(effects, 112, "◈", "Glass Strength", "Adjust preview glass depth.")
	CS.Settings.MakeMiniSlider(e2, 0.45, function(value) effectPreview.BackgroundTransparency = math.clamp(1 - value, 0.05, 0.85) end)
	local e3 = CS.Settings.MakeRow(effects, 166, "☾", "Shadow Quality", "Visual depth quality.")
	CS.Settings.MakeSmallSelect(e3, "High", function() CS.Notify.Push("Visual Effects", "High visual depth selected.", CS.Theme.Info) end)
	local e4 = CS.Settings.MakeRow(effects, 220, "●", "Color Saturation", "Preview accent intensity.")
	CS.Settings.MakeMiniSlider(e4, 0.75, function(value) fxText.TextTransparency = math.clamp(1 - value, 0, 0.8) end)

	local accent = CS.Settings.MakeSection(middleColumn, "Accent", "✎", 270)
	local accentPreview = CS.Settings.MakePreviewBox(accent, "Preview", 0.40)
	CS.Util.Create("TextLabel", {Parent = accentPreview, Size = UDim2.new(1, 0, 1, -30), Position = UDim2.new(0, 0, 0, 28), BackgroundTransparency = 1, Text = "CS", TextColor3 = CS.Theme.Accent, Font = Enum.Font.GothamBlack, TextSize = 42})
	local v1 = CS.Settings.MakeRow(accent, 58, "●", "Accent Color", "Main highlight color.")
	CS.Settings.MakeSmallSelect(v1, CS.Settings.ColorToHex(CS.Theme.Accent), function() CS.Notify.Push("Accent", "Use the color picker below for exact colors.", CS.Theme.Info) end)
	local v2 = CS.Settings.MakeRow(accent, 112, "◇", "Accent Style", "Glow, soft, or flat style.")
	CS.Settings.MakeSmallSelect(v2, "Glow", function() CS.Notify.Push("Accent", "Glow style active.", CS.Theme.Info) end)
	local v3 = CS.Settings.MakeRow(accent, 166, "≋", "Gradient Style", "Controls preview gradient feel.")
	CS.Settings.MakeSmallSelect(v3, "Smooth", function() CS.Notify.Push("Accent", "Smooth gradient selected.", CS.Theme.Info) end)
	local v4 = CS.Settings.MakeRow(accent, 220, "✦", "Menu Glow", "Outer glow intensity preview.")
	CS.Settings.MakeMiniSlider(v4, 0.72, function(value) if CS.UI.Objects.AccentRail then CS.UI.Objects.AccentRail.BackgroundTransparency = 1 - value end end)

	local anim = CS.Settings.MakeSection(middleColumn, "Animations", "⌁", 245)
	local animPreview = CS.Settings.MakePreviewBox(anim, "Preview", 0.40)
	local tabOne = CS.Util.Button(animPreview, "⌂", 36)
	tabOne.Size = UDim2.new(0, 44, 0, 44)
	tabOne.Position = UDim2.new(0, 18, 0, 58)
	tabOne.BackgroundColor3 = CS.Theme.Accent
	tabOne.TextColor3 = Color3.fromRGB(0, 0, 0)
	local tabTwo = CS.Util.Button(animPreview, "👥", 36)
	tabTwo.Size = UDim2.new(0, 44, 0, 44)
	tabTwo.Position = UDim2.new(0, 70, 0, 58)
	local hoverButton = CS.Util.Button(animPreview, "Hover Me", 34)
	hoverButton.Size = UDim2.new(1, -34, 0, 36)
	hoverButton.Position = UDim2.new(0, 17, 1, -50)
	local a1 = CS.Settings.MakeRow(anim, 58, "⇄", "Tab Animation", "Slide between menu pages.")
	CS.Settings.MakeSmallSelect(a1, "Slide", function() CS.Notify.Push("Animations", "Tab animation set to Slide.", CS.Theme.Info) end)
	local a2 = CS.Settings.MakeRow(anim, 112, "✦", "Hover Style", "Glow spread on hover.")
	CS.Settings.MakeSmallSelect(a2, "Glow", function() CS.Notify.Push("Animations", "Hover glow selected.", CS.Theme.Info) end)
	local a3 = CS.Settings.MakeRow(anim, 166, "⌁", "Animation Speed", "Controls menu transition speed.")
	CS.Settings.MakeMiniSlider(a3, 0.4, function() end)
	local a4 = CS.Settings.MakeRow(anim, 220, "✓", "Smoothness", "Enable smoothed UI feedback.")
	CS.Settings.MakeSwitch(a4, CS.Flags.Animations, function(value) CS.Flags.Animations = value CS.Settings.Save(true) end)

	local sounds = CS.Settings.MakeSection(middleColumn, "Sounds", "🔊", 245)
	local soundPreview = CS.Settings.MakePreviewBox(sounds, "Preview", 0.42)
	local pulse = CS.Util.Create("Frame", {Parent = soundPreview, Size = UDim2.new(0, 74, 0, 74), Position = UDim2.new(0.5, -37, 0.5, -26), BackgroundColor3 = CS.Theme.Accent, BackgroundTransparency = 0.72, BorderSizePixel = 0})
	CS.Util.Corner(pulse, 999)
	CS.Util.Stroke(pulse, CS.Theme.Accent, 0.2, 2)
	local s1 = CS.Settings.MakeRow(sounds, 58, "▶", "Click Sound", "Preview button click sound.")
	CS.Settings.MakeSmallSelect(s1, "Play", function() CS.Notify.PlaySound(CS.Flags.JoinFriendSoundId, 0.65) end)
	local s2 = CS.Settings.MakeRow(sounds, 112, "▶", "Hover Sound", "Preview hover feedback sound.")
	CS.Settings.MakeSmallSelect(s2, "Play", function() CS.Notify.PlaySound(CS.Flags.FriendJoinSoundId, 0.65) end)
	local s3 = CS.Settings.MakeRow(sounds, 166, "▶", "Notice Sound", "Preview notification sound.")
	CS.Settings.MakeSmallSelect(s3, "Play", function() CS.Notify.PlaySound(CS.Flags.FriendLeaveSoundId, 0.65) end)
	local s4 = CS.Settings.MakeRow(sounds, 220, "▰", "Volume", "Sound preview volume level.")
	CS.Settings.MakeMiniSlider(s4, 0.75, function() end)

	local notif = CS.Settings.MakeSection(rightColumn, "Notifications", "🔔", 270)
	local notifPreview = CS.Settings.MakePreviewBox(notif, "Preview", 0.44)
	local sample = CS.Util.Create("Frame", {Parent = notifPreview, Size = UDim2.new(1, -24, 0, 70), Position = UDim2.new(0, 12, 0.5, -25), BackgroundColor3 = CS.Theme.NotificationBackground, BackgroundTransparency = 0.12, BorderSizePixel = 0})
	CS.Util.Corner(sample, 12)
	CS.Util.Stroke(sample, CS.Theme.NotificationOutline, 0.2, 2)
	CS.Util.Create("TextLabel", {Parent = sample, Size = UDim2.new(1, -20, 0, 26), Position = UDim2.new(0, 12, 0, 8), BackgroundTransparency = 1, Text = "CS  Player joined you", TextColor3 = CS.Theme.Text, Font = Enum.Font.GothamBold, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left})
	CS.Util.Create("TextLabel", {Parent = sample, Size = UDim2.new(1, -20, 0, 22), Position = UDim2.new(0, 12, 0, 36), BackgroundTransparency = 1, Text = "Welcome to the server!", TextColor3 = CS.Theme.SubText, Font = Enum.Font.Gotham, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left})
	local n1 = CS.Settings.MakeRow(notif, 58, "↗", "Position", "Where notices appear.")
	CS.Settings.MakeSmallSelect(n1, "Top Right", function() CS.Notify.Push("Notifications", "Position preview is top right.", CS.Theme.Info) end)
	local n2 = CS.Settings.MakeRow(notif, 112, "◇", "Style", "Notification animation style.")
	CS.Settings.MakeSmallSelect(n2, "Modern", function() CS.Notify.Push("Notifications", "Modern style active.", CS.Theme.Info) end)
	local n3 = CS.Settings.MakeRow(notif, 166, "⏱", "Duration", "How long notices stay.")
	CS.Settings.MakeSmallSelect(n3, "5 Seconds", function() CS.Notify.Push("Notifications", "Duration preview: 5 seconds.", CS.Theme.Info) end)
	local n4 = CS.Settings.MakeRow(notif, 220, "🔊", "Sound", "Friend and notification sounds.")
	CS.Settings.MakeSwitch(n4, CS.Flags.FriendSounds, function(value) CS.Flags.FriendSounds = value CS.Settings.Save(true) end)

	local playerCard = CS.Settings.MakeSection(rightColumn, "Player Card", "👤", 245)
	local playerPreview = CS.Settings.MakePreviewBox(playerCard, "Preview", 0.48)
	local avatar = CS.Util.Create("ImageLabel", {Parent = playerPreview, Size = UDim2.new(0, 58, 0, 58), Position = UDim2.new(0, 14, 0, 54), BackgroundTransparency = 1})
	CS.Util.Corner(avatar, 12)
	pcall(function()
		avatar.Image = CS.Services.Players:GetUserThumbnailAsync(CS.LocalPlayer.UserId, Enum.ThumbnailType.AvatarThumbnail, Enum.ThumbnailSize.Size420x420)
	end)
	CS.Util.Create("TextLabel", {Parent = playerPreview, Size = UDim2.new(1, -90, 0, 26), Position = UDim2.new(0, 84, 0, 56), BackgroundTransparency = 1, Text = CS.LocalPlayer.DisplayName, TextColor3 = CS.Theme.Text, Font = Enum.Font.GothamBold, TextSize = 14, TextXAlignment = Enum.TextXAlignment.Left})
	local pUser = CS.Util.Create("TextLabel", {Parent = playerPreview, Size = UDim2.new(1, -90, 0, 22), Position = UDim2.new(0, 84, 0, 82), BackgroundTransparency = 1, Text = "@" .. CS.LocalPlayer.Name, TextColor3 = CS.Theme.SubText, Font = Enum.Font.Gotham, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left})
	local pc1 = CS.Settings.MakeRow(playerCard, 58, "▣", "Card Style", "Player card layout type.")
	CS.Settings.MakeSmallSelect(pc1, "Modern", function() CS.Notify.Push("Player Card", "Modern card style active.", CS.Theme.Info) end)
	local pc2 = CS.Settings.MakeRow(playerCard, 112, "👤", "Show Avatar", "Display Roblox avatar preview.")
	CS.Settings.MakeSwitch(pc2, true, function(value) avatar.Visible = value end)
	local pc3 = CS.Settings.MakeRow(playerCard, 166, "◫", "Transparency", "Player card glass amount.")
	CS.Settings.MakeMiniSlider(pc3, 0.65, function(value) playerPreview.BackgroundTransparency = math.clamp(1 - value, 0.05, 0.7) end)
	local pc4 = CS.Settings.MakeRow(playerCard, 220, "◎", "Show Status", "Show simple in-game status.")
	CS.Settings.MakeSwitch(pc4, true, function(value) pUser.Text = value and ("@" .. CS.LocalPlayer.Name .. "  •  In-Game") or ("@" .. CS.LocalPlayer.Name) end)

	local extra = CS.Settings.MakeSection(rightColumn, "Extra", "☆", 245)
	local extraPreview = CS.Settings.MakePreviewBox(extra, "Preview", 0.42)
	local previewStack = CS.Util.Create("Frame", {Parent = extraPreview, Size = UDim2.new(1, -24, 0, 110), Position = UDim2.new(0, 12, 0, 38), BackgroundTransparency = 1})
	local exLine1 = CS.Util.Button(previewStack, "▸ Home", 30)
	exLine1.Size = UDim2.new(1, 0, 0, 30)
	exLine1.Position = UDim2.new(0, 0, 0, 0)
	exLine1.TextXAlignment = Enum.TextXAlignment.Left
	local exLine2 = CS.Util.Button(previewStack, "  Players", 30)
	exLine2.Size = UDim2.new(1, 0, 0, 30)
	exLine2.Position = UDim2.new(0, 0, 0, 36)
	exLine2.TextXAlignment = Enum.TextXAlignment.Left
	local exLine3 = CS.Util.Button(previewStack, "  Settings", 30)
	exLine3.Size = UDim2.new(1, 0, 0, 30)
	exLine3.Position = UDim2.new(0, 0, 0, 72)
	exLine3.TextXAlignment = Enum.TextXAlignment.Left
	local x1 = CS.Settings.MakeRow(extra, 58, "▣", "Compact Mode", "Reduce spacing and card height.")
	CS.Settings.MakeSwitch(x1, CS.Flags.ScaleMode == "Compact", function(value) CS.Flags.ScaleMode = value and "Compact" or "Normal" CS.Settings.ApplyVisuals() CS.Settings.Save(true) end)
	local x2 = CS.Settings.MakeRow(extra, 112, "⌨", "Hide Keybinds", "Reduce visible hotkey hints.")
	CS.Settings.MakeSwitch(x2, false, function() CS.Notify.Push("Extra", "Keybind hints hidden in preview.", CS.Theme.Info) end)
	local x3 = CS.Settings.MakeRow(extra, 166, "≈", "Reduced Motion", "Lower animation movement.")
	CS.Settings.MakeSwitch(x3, not CS.Flags.Animations, function(value) CS.Flags.Animations = not value CS.Settings.Save(true) end)
	local x4 = CS.Settings.MakeRow(extra, 220, "⇅", "Sort Tabs By", "Keep default sidebar order.")
	CS.Settings.MakeSmallSelect(x4, "Default", function() CS.Notify.Push("Extra", "Default tab order active.", CS.Theme.Info) end)

	CS.Settings.MakeColorEditor(leftColumn, "Background Color", "Background", CS.Theme.Background, function(color, hex)
		CS.Theme.Background = color
		CS.Theme.Panel = color
		CS.Theme.Panel2 = color
		CS.Settings.ApplyVisuals()
		CS.Settings.Save(true)
		CS.Notify.Push("Theme", "Background color changed to " .. hex, CS.Theme.NotificationOutline)
	end)

	CS.Settings.MakeColorEditor(middleColumn, "Outline Color", "Outline", CS.Theme.Stroke, function(color, hex)
		CS.Theme.Stroke = color
		CS.Theme.StrokeSoft = color
		CS.Settings.ApplyVisuals()
		CS.Settings.Save(true)
		CS.Notify.Push("Theme", "Outline color changed to " .. hex, CS.Theme.NotificationOutline)
	end)

	CS.Settings.MakeColorEditor(rightColumn, "Notification Color", "Notification", CS.Theme.NotificationOutline, function(color, hex)
		CS.Theme.NotificationOutline = color
		CS.Theme.Info = color
		CS.Settings.ApplyVisuals()
		CS.Settings.Save(true)
		CS.Notify.Push("Theme", "Notification color changed to " .. hex, CS.Theme.NotificationOutline)
	end)

	CS.Settings.RefreshToggleVisuals()
end


function CS.Utilities.Build()
	local page=CS.UI.Pages["Utilities"]; CS.Util.Clear(page,true); local left=CS.Util.Scroll(page); left.Size=UDim2.new(0.5,-6,1,0); local right=CS.Util.Scroll(page); right.Size=UDim2.new(0.5,-6,1,0); right.Position=UDim2.new(0.5,6,0,0)
	local menu=CS.UI.OverlayCard(left,"Menu Controls","⚙",310); CS.UI.OverlayButton(menu,"RF Menu",58,function() CS.PlayerDetails.RefreshList(); CS.Dashboard.Update(); pcall(function() CS.ServerBrowser.Fetch() end); pcall(function() CS.Friends.RefreshFriendList() end); CS.Settings.ApplyVisuals(); CS.Notify.Push("Utilities","Menu refreshed.",CS.Theme.Success) end); CS.UI.OverlayButton(menu,"Close Menu",106,function() CS.Flags.Open=false; if CS.UI.Objects.Main then CS.UI.Objects.Main.Visible=false end end); CS.UI.OverlayButton(menu,"Repair Layout",154,function() CS.Settings.ApplyVisuals(); CS.Notify.Push("Utilities","Layout repaired.",CS.Theme.Success) end); CS.UI.OverlayButton(menu,"Save Settings",202,function() local ok=CS.Settings.Save(false); CS.Notify.Push("Utilities",ok and "Settings saved." or "Save unavailable.",ok and CS.Theme.Success or CS.Theme.Warning) end); CS.UI.OverlayButton(menu,"Reload Settings",250,function() local ok=CS.Settings.Load(); CS.Settings.ApplyVisuals(); CS.Notify.Push("Utilities",ok and "Settings loaded." or "No settings found.",ok and CS.Theme.Info or CS.Theme.Warning) end)
	local shortcuts=CS.UI.OverlayCard(left,"Quick Links","↗",220); CS.UI.OverlayButton(shortcuts,"Open Settings",58,function() CS.UI.SwitchPage("Settings") end); CS.UI.OverlayButton(shortcuts,"Open Friends",106,function() CS.UI.SwitchPage("Friends") end); CS.UI.OverlayButton(shortcuts,"Open Game Info",154,function() CS.UI.SwitchPage("Game Info") end)
	local preview=CS.UI.OverlayCard(right,"Utility Preview","◎",260); CS.UI.OverlayGraph(preview,58,"Menu Activity"); CS.UI.Labels.UtilityStatus=CS.UI.OverlayValue(preview,176,"✓","Status","Ready","Utility actions are connected.")
	local system=CS.UI.OverlayCard(right,"Session","◷",240); CS.UI.Labels.UtilitySession=CS.UI.OverlayValue(system,58,"⚡","FPS",tostring(CS.Runtime.FPS or "--"),"Live client FPS."); CS.UI.Labels.UtilityPing=CS.UI.OverlayValue(system,112,"📡","Ping",tostring(CS.Runtime.Ping or "--"),"Live network ping."); CS.UI.Labels.UtilityPlayers=CS.UI.OverlayValue(system,166,"👥","Players",tostring(#CS.Services.Players:GetPlayers()),"Players in server.")
end

function CS.Dashboard.UpdatePingStats()
	local ping = CS.Util.Ping()
	CS.Runtime.Ping = ping

	table.insert(CS.Runtime.PingHistory, ping)

	if #CS.Runtime.PingHistory > 48 then
		table.remove(CS.Runtime.PingHistory, 1)
	end

	CS.Runtime.LowPing = CS.Runtime.LowPing and math.min(CS.Runtime.LowPing, ping) or ping
	CS.Runtime.HighPing = CS.Runtime.HighPing and math.max(CS.Runtime.HighPing, ping) or ping

	local total = 0

	for _, value in ipairs(CS.Runtime.PingHistory) do
		total += value
	end

	CS.Runtime.AvgPing = #CS.Runtime.PingHistory > 0 and math.floor(total / #CS.Runtime.PingHistory) or ping
end

function CS.Dashboard.PaintBars(bars)
	if not bars then return end

	for index, bar in ipairs(bars) do
		local value = CS.Runtime.PingHistory[index] or 0
		local height = math.clamp(value / 240, 0.04, 1)

		bar.Size = UDim2.new(1 / #bars, -2, height, 0)

		if value <= 70 then
			bar.BackgroundColor3 = CS.Theme.Success
		elseif value <= 140 then
			bar.BackgroundColor3 = CS.Theme.Warning
		else
			bar.BackgroundColor3 = CS.Theme.Error
		end
	end
end

function CS.Dashboard.Update()
	local ping = CS.Runtime.Ping
	local status, color = CS.Util.PingStatus(ping)
	local friendsOnline = CS.Friends.CountOnline()
	local friendsInServer = CS.Friends.CountInServer()

	CS.Util.Set(CS.UI.Labels.Overview,
		"Version: " .. CS.Version ..
		"\nGame: " .. tostring(game.PlaceId) ..
		"\nJobId: " .. (game.JobId ~= "" and game.JobId or "Unavailable") ..
		"\nPanel: " .. (CS.Flags.Open and "Open" or "Closed")
	)

	CS.Util.Set(CS.UI.Labels.Network,
		"Current: " .. tostring(ping) .. " ms" ..
		"\nStatus: " .. status ..
		"\nLowest: " .. tostring(CS.Runtime.LowPing or "N/A") .. " ms" ..
		"\nAverage: " .. tostring(CS.Runtime.AvgPing or "N/A") .. " ms" ..
		"\nHighest: " .. tostring(CS.Runtime.HighPing or "N/A") .. " ms",
		color
	)

	CS.Util.Set(CS.UI.Labels.FriendsSummary,
		"Friends Online: " .. tostring(friendsOnline) ..
		"\nFriends In Server: " .. tostring(friendsInServer) ..
		"\nPlayers: " .. tostring(#CS.Services.Players:GetPlayers()) .. "/" .. tostring(CS.Services.Players.MaxPlayers)
	)

	CS.Util.Set(CS.UI.Labels.Performance,
		"FPS: " .. tostring(CS.Runtime.FPS) ..
		"\nPing: " .. tostring(ping) .. " ms" ..
		"\nUI Mode: " .. (CS.Flags.Compact and "Compact" or "Full") ..
		"\nAnimations: " .. tostring(CS.Flags.Animations)
	)

	CS.Util.Set(CS.UI.Labels.Status,
		"HTTP: " .. tostring(CS.Request ~= nil) ..
		"\nClipboard: " .. tostring(setclipboard ~= nil) ..
		"\nNotifications: " .. tostring(CS.Flags.Notifications) ..
		"\nTransparency: " .. tostring(CS.Flags.Transparency)
	)

	CS.Util.Set(CS.UI.Labels.FPSPill, "FPS: " .. tostring(CS.Runtime.FPS))
	CS.Util.Set(CS.UI.Labels.PingPill, "Ping: " .. tostring(ping))
	CS.Util.Set(CS.UI.Labels.PlayersPill, "Players: " .. tostring(#CS.Services.Players:GetPlayers()) .. "/" .. tostring(CS.Services.Players.MaxPlayers))

	CS.Dashboard.PaintBars(CS.UI.Charts.Network)
	CS.Dashboard.PaintBars(CS.UI.Charts.Live)
end

function CS.RefreshAll()
	CS.Dashboard.Update()
	CS.PlayerDetails.Refresh()
	CS.PlayerDetails.UpdateSelected()
	CS.ServerBrowser.UpdateLive()
	CS.GameInfo.Load()
	CS.Friends.Update()
	pcall(function()
		CS.Friends.RefreshFriendList()
	end)
	CS.Diagnostics.Run()
end

function CS.Connect()
	CS.UI.Objects.OpenButton.MouseButton1Click:Connect(CS.UI.Toggle)
	CS.UI.Buttons.Close.MouseButton1Click:Connect(CS.UI.Toggle)

	CS.Services.Players.PlayerAdded:Connect(function(player)
		if CS.Flags.Open and CS.Flags.AutoRefreshPlayers then
			CS.PlayerDetails.Refresh()
		end

		local isFriend = false

		pcall(function()
			isFriend = CS.LocalPlayer:IsFriendsWith(player.UserId)
		end)

		if isFriend then
			CS.Friends.PushFeed("Friend joined: " .. player.DisplayName .. " (@" .. player.Name .. ")")
			CS.Notify.PlayerEvent(player, "joined", true, true)
		elseif CS.Flags.ShowNonFriendNotices then
			CS.Friends.PushFeed("Player joined: " .. player.DisplayName .. " (@" .. player.Name .. ")")
			CS.Notify.PlayerEvent(player, "joined", false, true)
		end

		CS.Friends.Update()
	end)

	CS.Services.Players.PlayerRemoving:Connect(function(player)
		if CS.Flags.Open and CS.Flags.AutoRefreshPlayers then
			CS.PlayerDetails.Refresh()
		end

		local isFriend = false

		pcall(function()
			isFriend = CS.LocalPlayer:IsFriendsWith(player.UserId)
		end)

		if isFriend then
			CS.Friends.PushFeed("Friend left: " .. player.DisplayName .. " (@" .. player.Name .. ")")
			CS.Notify.PlayerEvent(player, "left", true, false)
		elseif CS.Flags.ShowNonFriendNotices then
			CS.Friends.PushFeed("Player left: " .. player.DisplayName .. " (@" .. player.Name .. ")")
			CS.Notify.PlayerEvent(player, "left", false, false)
		end

		CS.Friends.Update()
	end)

	CS.LocalPlayer.CharacterAdded:Connect(function()
		task.wait(1)

		if CS.Flags.Open then
			CS.PlayerDetails.UpdateSelected()
			CS.Diagnostics.Run()
		end
	end)

	CS.Services.RunService.RenderStepped:Connect(function()
		CS.Runtime.Frames += 1
		CS.Settings.UpdateColorCycle()
		local now = os.clock()

		if now - CS.Runtime.LastFPS >= 1 then
			CS.Runtime.FPS = CS.Runtime.Frames
			CS.Runtime.Frames = 0
			CS.Runtime.LastFPS = now

			CS.Dashboard.UpdatePingStats()

			if CS.Flags.Open then
				CS.Dashboard.Update()
				CS.ServerBrowser.UpdateLive()
				CS.Friends.Update()

				if CS.Flags.AutoRefreshDiagnostics then
					CS.Diagnostics.Run()
				end
			end
		end

		if CS.Flags.Open then
			CS.PlayerDetails.UpdateSelected()
		end
	end)
end

function CS.Build()
	CS.UI.BuildShell()
	CS.UI.BuildPages()
	CS.Dashboard.Build()
	CS.PlayerDetails.Build()
	CS.ServerBrowser.Build()
	CS.GameInfo.Build()
	CS.Friends.Build()
	CS.Diagnostics.Build()
	CS.Settings.Build()
	CS.Utilities.Build()
end


function CS.Dashboard.UpdateOverlayLabels()
	local players=#CS.Services.Players:GetPlayers(); local maxPlayers=CS.Services.Players.MaxPlayers or 0; local ping=tostring(CS.Runtime.Ping or "?").."ms"; local fps=tostring(CS.Runtime.FPS or "?")
	CS.Util.Set(CS.UI.Labels.DashPlayers,tostring(players).."/"..tostring(maxPlayers)); CS.Util.Set(CS.UI.Labels.DashPing,ping); CS.Util.Set(CS.UI.Labels.DashFPS,fps); CS.Util.Set(CS.UI.Labels.DashClock,os.date("%H:%M:%S")); CS.Util.Set(CS.UI.Labels.DashNotif,tostring(CS.Flags.Notifications))
	CS.Util.Set(CS.UI.Labels.CurrentServerInfo,"Players: "..players.."/"..maxPlayers.." | Ping: "..ping.." | Job: "..tostring(game.JobId):sub(1,8).."..."); CS.Util.Set(CS.UI.Labels.ServerPlayerData,tostring(players).."/"..tostring(maxPlayers)); CS.Util.Set(CS.UI.Labels.ServerPingData,ping); CS.Util.Set(CS.UI.Labels.GameServerState,tostring(players).."/"..tostring(maxPlayers)); CS.Util.Set(CS.UI.Labels.UtilitySession,fps); CS.Util.Set(CS.UI.Labels.UtilityPing,ping); CS.Util.Set(CS.UI.Labels.UtilityPlayers,tostring(players))
end
local CS_OriginalDashboardUpdate = CS.Dashboard.Update
function CS.Dashboard.Update()
	if CS_OriginalDashboardUpdate then pcall(CS_OriginalDashboardUpdate) end
	CS.Dashboard.UpdateOverlayLabels()
end



--// CS 3.8.2 Organization + Connection Patch
--// Cleaner layout, calmer Settings tab, safer labels, connected buttons.
CS.Version = "3.8.2"

function CS.Util.SafeCall(fn, ...)
	if type(fn) ~= "function" then return false end
	local ok, result = pcall(fn, ...)
	if not ok then warn("CS SafeCall:", result) end
	return ok, result
end

function CS.Util.SafeSet(label, text, color)
	if label and label.Parent then
		label.Text = tostring(text or "")
		if color then label.TextColor3 = color end
	end
end

function CS.Settings.SetToggleVisual(button, state)
	if not button then return end
	button.BackgroundColor3 = state and CS.Theme.Success or CS.Theme.Card2
	button.BackgroundTransparency = state and 0.04 or 0.18
	button.TextColor3 = state and Color3.fromRGB(0, 0, 0) or CS.Theme.Text
end

function CS.Settings.SetScale(mode)
	mode = mode or "Default"
	CS.Flags.ScaleMode = mode
	local main = CS.UI.Objects.Main
	if not main then return end
	local sizeMap = {
		Compact = UDim2.new(0, 1000, 0, 600),
		Normal = UDim2.new(0, 1080, 0, 650),
		Default = UDim2.new(0, 1080, 0, 650),
		Large = UDim2.new(0, 1180, 0, 710)
	}
	local size = sizeMap[mode] or sizeMap.Default
	main.Size = size
	main.Position = UDim2.new(0.5, -math.floor(size.X.Offset / 2), 0.5, -math.floor(size.Y.Offset / 2))
end

function CS.UI.SectionTitle(parent, title, body, height)
	local card = CS.UI.OverlayCard(parent, title, "▣", height or 190)
	if body then CS.UI.OverlayText(card, 56, (height or 190) - 70, body) end
	return card
end

function CS.UI.ActionRow(parent, y, title, desc, buttonText, callback)
	local row = CS.UI.OverlayValue(parent, y, "•", title, "", desc)
	local button = CS.Util.Create("TextButton", {
		Parent = parent,
		Size = UDim2.new(0, 122, 0, 30),
		Position = UDim2.new(1, -142, 0, y + 8),
		BackgroundColor3 = CS.Theme.Card2,
		BackgroundTransparency = 0.08,
		BorderSizePixel = 0,
		Text = buttonText or "Run",
		TextColor3 = CS.Theme.Text,
		Font = Enum.Font.GothamBold,
		TextSize = 11,
		AutoButtonColor = false
	})
	CS.Util.Corner(button, 8)
	CS.Util.Stroke(button, CS.Theme.Stroke, 0.55, 1)
	button.MouseEnter:Connect(function() CS.Util.Tween(button, {BackgroundColor3 = CS.Theme.Accent}, 0.12) end)
	button.MouseLeave:Connect(function() CS.Util.Tween(button, {BackgroundColor3 = CS.Theme.Card2}, 0.12) end)
	button.MouseButton1Click:Connect(function()
		if callback then callback(button) end
	end)
	return button, row
end

function CS.UI.ToggleRow(parent, y, title, desc, state, callback)
	local row = CS.UI.OverlayValue(parent, y, "•", title, state and "ON" or "OFF", desc)
	local switch = CS.Settings.MakeSwitch(parent:FindFirstChild("RowProxy") or parent, state, function(value)
		CS.Util.SafeSet(row, value and "ON" or "OFF", value and CS.Theme.Success or CS.Theme.Muted)
		if callback then callback(value) end
	end)
	switch.Button.Parent = parent
	switch.Button.Position = UDim2.new(1, -74, 0, y + 10)
	return switch, row
end

function CS.Settings.Build()
	local page = CS.UI.Pages["Settings"]
	CS.Util.Clear(page, true)

	local left = CS.Util.Scroll(page)
	left.Size = UDim2.new(0.5, -6, 1, 0)
	left.Position = UDim2.new(0, 0, 0, 0)

	local right = CS.Util.Scroll(page)
	right.Size = UDim2.new(0.5, -6, 1, 0)
	right.Position = UDim2.new(0.5, 6, 0, 0)

	local interface = CS.UI.OverlayCard(left, "Interface", "▣", 250)
	CS.UI.ActionRow(interface, 58, "UI Scale", "Cycle compact, normal, and large layouts.", CS.Flags.ScaleMode or "Default", function(btn)
		local nextMode = "Normal"
		if CS.Flags.ScaleMode == "Normal" or CS.Flags.ScaleMode == "Default" then nextMode = "Large" elseif CS.Flags.ScaleMode == "Large" then nextMode = "Compact" end
		CS.Settings.SetScale(nextMode)
		btn.Text = nextMode
		CS.Settings.Save(true)
		CS.Notify.Push("Settings", "UI scale set to " .. nextMode .. ".", CS.Theme.Info)
	end)
	CS.UI.ActionRow(interface, 112, "Glass Strength", "Cleaner background visibility presets.", "Medium", function(btn)
		local presets = {Low = 0.30, Medium = 0.54, High = 0.70}
		local nextName = btn.Text == "Low" and "Medium" or (btn.Text == "Medium" and "High" or "Low")
		btn.Text = nextName
		CS.Flags.Transparency = presets[nextName]
		CS.Flags.PanelTransparency = math.clamp(CS.Flags.Transparency - 0.12, 0, 1)
		CS.Flags.CardTransparency = math.clamp(CS.Flags.Transparency - 0.35, 0, 1)
		CS.Settings.ApplyVisuals()
		CS.Settings.Save(true)
	end)
	CS.UI.ToggleRow(interface, 166, "Animations", "Smooth hover and page feedback.", CS.Flags.Animations, function(value)
		CS.Flags.Animations = value; CS.Settings.Save(true)
	end)

	local behavior = CS.UI.OverlayCard(left, "Behavior", "⚙", 250)
	CS.UI.ToggleRow(behavior, 58, "Notifications", "Show join, leave, and system notices.", CS.Flags.Notifications, function(value)
		CS.Flags.Notifications = value; CS.Settings.Save(true)
	end)
	CS.UI.ToggleRow(behavior, 112, "Player Notices", "Show notices for non-friends too.", CS.Flags.ShowNonFriendNotices, function(value)
		CS.Flags.ShowNonFriendNotices = value; CS.Settings.Save(true)
	end)
	CS.UI.ToggleRow(behavior, 166, "Friend Sounds", "Play sounds for friend actions.", CS.Flags.FriendSounds, function(value)
		CS.Flags.FriendSounds = value; CS.Settings.Save(true)
	end)

	local theme = CS.UI.OverlayCard(left, "Theme Presets", "✦", 300)
	CS.UI.ActionRow(theme, 58, "Blue CS", "Clean cyan/blue overlay theme.", "Apply", function()
		CS.Theme.Accent = Color3.fromRGB(31, 198, 250); CS.Theme.Stroke = Color3.fromRGB(0, 190, 255); CS.Settings.ApplyVisuals(); CS.Settings.Save(true)
	end)
	CS.UI.ActionRow(theme, 112, "Purple", "Dark purple accent preset.", "Apply", function()
		CS.Theme.Accent = Color3.fromRGB(150, 95, 255); CS.Theme.Stroke = Color3.fromRGB(150, 95, 255); CS.Settings.ApplyVisuals(); CS.Settings.Save(true)
	end)
	CS.UI.ActionRow(theme, 166, "Red", "Black and red accent preset.", "Apply", function()
		CS.Theme.Accent = Color3.fromRGB(255, 55, 70); CS.Theme.Stroke = Color3.fromRGB(255, 55, 70); CS.Settings.ApplyVisuals(); CS.Settings.Save(true)
	end)
	CS.UI.ActionRow(theme, 220, "Reset Theme", "Restore default colors and transparency.", "Reset", function()
		CS.Settings.ResetThemeDefaults()
	end)

	local live = CS.UI.OverlayCard(right, "Live Overlay", "◎", 250)
	CS.UI.Labels.SettingsLivePreview = CS.UI.OverlayText(live, 58, 170,
		"FPS: " .. tostring(CS.Runtime.FPS) ..
		"\nPing: " .. tostring(CS.Runtime.Ping) .. " ms" ..
		"\nPlayers: " .. tostring(#CS.Services.Players:GetPlayers()) .. "/" .. tostring(CS.Services.Players.MaxPlayers) ..
		"\nCurrent Page: " .. tostring(CS.Runtime.CurrentPage or "Dashboard")
	)

	local maintenance = CS.UI.OverlayCard(right, "Maintenance", "☰", 300)
	CS.UI.ActionRow(maintenance, 58, "Refresh UI", "Rebuild all pages and update live labels.", "Refresh", function()
		CS.RefreshAll(); CS.Settings.ApplyVisuals(); CS.Notify.Push("Settings", "UI refreshed.", CS.Theme.Success)
	end)
	CS.UI.ActionRow(maintenance, 112, "Save Config", "Save current menu settings.", "Save", function()
		local ok = CS.Settings.Save(false)
		CS.Notify.Push("Settings", ok and "Settings saved." or "Save unavailable.", ok and CS.Theme.Success or CS.Theme.Warning)
	end)
	CS.UI.ActionRow(maintenance, 166, "Load Config", "Reload saved menu settings.", "Load", function()
		local ok = CS.Settings.Load(); CS.Settings.ApplyVisuals()
		CS.Notify.Push("Settings", ok and "Settings loaded." or "No saved settings found.", ok and CS.Theme.Info or CS.Theme.Warning)
	end)
	CS.UI.ActionRow(maintenance, 220, "Test Notice", "Send one sample notification.", "Test", function()
		CS.Notify.Push("CS Test", "Notification system is connected.", CS.Theme.Info)
	end)

	local info = CS.UI.OverlayCard(right, "Clean Settings Info", "✓", 170)
	CS.UI.OverlayText(info, 58, 90, "Settings is now limited to connected controls only. The old visual playground controls were removed because they cluttered the tab and several only changed previews instead of the real overlay.")
end

function CS.PlayerDetails.RefreshList()
	return CS.PlayerDetails.Refresh()
end

function CS.PlayerDetails.Select(player)
	CS.Runtime.SelectedPlayer = player or CS.LocalPlayer
	return CS.PlayerDetails.UpdateSelected()
end

local CS_OriginalPlayerDetailsBuild_382 = CS.PlayerDetails.Build
function CS.PlayerDetails.Build()
	CS_OriginalPlayerDetailsBuild_382()
	if CS.UI.Objects.PlayerList and not CS.UI.Objects.PlayerListScroll then
		CS.UI.Objects.PlayerListScroll = CS.UI.Objects.PlayerList
	end
	CS.PlayerDetails.Refresh()
	CS.PlayerDetails.Select(CS.Runtime.SelectedPlayer or CS.LocalPlayer)
end

function CS.PlayerDetails.UpdateSelected()
	local player = CS.PlayerDetails.GetSelected()
	local humanoid = CS.Util.Humanoid(player)
	local root = CS.Util.Root(player)
	local myRoot = CS.Util.Root(CS.LocalPlayer)

	if CS.UI.Objects.SelectedAvatar then
		pcall(function()
			CS.UI.Objects.SelectedAvatar.Image = CS.Services.Players:GetUserThumbnailAsync(player.UserId, Enum.ThumbnailType.AvatarThumbnail, Enum.ThumbnailSize.Size420x420)
		end)
	end

	CS.Util.SafeSet(CS.UI.Labels.SelectedName, player.DisplayName)
	CS.Util.SafeSet(CS.UI.Labels.SelectedUser, "@" .. player.Name)
	CS.Util.SafeSet(CS.UI.Labels.SelectedDistance, (root and myRoot) and (tostring(math.floor((root.Position - myRoot.Position).Magnitude)) .. " studs") or "Unavailable")

	local friendState = player == CS.LocalPlayer and "You" or "No"
	if player ~= CS.LocalPlayer then pcall(function() if CS.LocalPlayer:IsFriendsWith(player.UserId) then friendState = "Yes" end end) end
	CS.Util.SafeSet(CS.UI.Labels.AccountInfo, "Display Name: " .. player.DisplayName .. "\nUsername: @" .. player.Name .. "\nUserId: " .. tostring(player.UserId) .. "\nAccount Age: " .. tostring(player.AccountAge) .. " days\nMembership: " .. player.MembershipType.Name .. "\nFriend: " .. friendState)
	CS.Util.SafeSet(CS.UI.Labels.CharacterInfo, humanoid and ("Health: " .. math.floor(humanoid.Health) .. " / " .. math.floor(humanoid.MaxHealth) .. "\nState: " .. humanoid:GetState().Name .. "\nRig Type: " .. humanoid.RigType.Name .. "\nTeam: " .. (player.Team and player.Team.Name or "None")) or "Character humanoid unavailable.")
end

function CS.ServerBrowser.Rejoin()
	CS.Notify.Push("Server", "Rejoining current server...", CS.Theme.Info)
	CS.Services.TeleportService:TeleportToPlaceInstance(game.PlaceId, game.JobId, CS.LocalPlayer)
end

function CS.ServerBrowser.Hop()
	CS.Notify.Push("Server", "Searching for another public server...", CS.Theme.Info)
	pcall(function() CS.ServerBrowser.Fetch() end)
	for _, server in ipairs(CS.Runtime.ServerData or {}) do
		if server.id and server.id ~= game.JobId and tonumber(server.playing or 0) < tonumber(server.maxPlayers or 0) then
			CS.Services.TeleportService:TeleportToPlaceInstance(game.PlaceId, server.id, CS.LocalPlayer)
			return
		end
	end
	CS.Services.TeleportService:Teleport(game.PlaceId, CS.LocalPlayer)
end

local CS_OriginalServerBrowserBuild_382 = CS.ServerBrowser.Build
function CS.ServerBrowser.Build()
	CS_OriginalServerBrowserBuild_382()
	if CS.UI.Objects.ServerList and not CS.UI.Objects.ServerListScroll then
		CS.UI.Objects.ServerListScroll = CS.UI.Objects.ServerList
	end
	CS.ServerBrowser.Rebuild(CS.Runtime.ServerData or {})
	CS.ServerBrowser.UpdateLive()
end

function CS.ServerBrowser.Fetch()
	if not CS.UI.Objects.ServerListScroll and CS.UI.Objects.ServerList then CS.UI.Objects.ServerListScroll = CS.UI.Objects.ServerList end
	if not CS.Request then
		CS.Notify.Push("Server Browser", "HTTP request unavailable in this environment.", CS.Theme.Warning)
		CS.ServerBrowser.Rebuild({})
		return
	end
	CS.Util.SafeSet(CS.UI.Labels.CurrentServerInfo, "Fetching public servers...")
	local success, response = pcall(function()
		return CS.Request({Url = "https://[Log in to view URL]" .. tostring(game.PlaceId) .. "/servers/Public?sortOrder=Asc&limit=100", Method = "GET"})
	end)
	if not success or not response or not response.Body then
		CS.Notify.Push("Server Browser", "Server fetch failed.", CS.Theme.Warning)
		return
	end
	local decoded
	local ok = pcall(function() decoded = CS.Services.HttpService:JSONDecode(response.Body) end)
	if not ok or not decoded or not decoded.data then
		CS.Notify.Push("Server Browser", "Invalid server response.", CS.Theme.Warning)
		return
	end
	CS.Runtime.ServerData = decoded.data
	CS.Runtime.LastServerFetch = os.clock()
	CS.ServerBrowser.Rebuild(CS.Runtime.ServerData)
	CS.Notify.Push("Server Browser", "Loaded " .. tostring(#decoded.data) .. " public servers.", CS.Theme.Success)
end

function CS.ServerBrowser.UpdateLive()
	local ping = CS.Runtime.Ping or 0
	local status = (select(1, CS.Util.PingStatus(ping)))
	local players = #CS.Services.Players:GetPlayers()
	local maxPlayers = CS.Services.Players.MaxPlayers or 0
	CS.Util.SafeSet(CS.UI.Labels.CurrentServerInfo, "Players: " .. players .. "/" .. maxPlayers .. "\nPing: " .. tostring(ping) .. " ms\nJob: " .. tostring(game.JobId):sub(1, 18) .. "...")
	CS.Util.SafeSet(CS.UI.Labels.ServerPingData, tostring(ping) .. " ms / " .. tostring(status))
	CS.Util.SafeSet(CS.UI.Labels.ServerPlayerData, tostring(players) .. "/" .. tostring(maxPlayers))
end

function CS.GameInfo.Load()
	local info = {Name = "Unavailable", Creator = "Unavailable"}
	pcall(function()
		local data = CS.Services.MarketplaceService:GetProductInfo(game.PlaceId)
		info.Name = tostring(data.Name or "Unavailable")
		info.Creator = data.Creator and tostring(data.Creator.Name) or "Unavailable"
	end)
	CS.Util.SafeSet(CS.UI.Labels.GameName, info.Name)
	CS.Util.SafeSet(CS.UI.Labels.GameCreator, info.Creator)
	CS.Util.SafeSet(CS.UI.Labels.GamePlaceId, tostring(game.PlaceId))
	CS.Util.SafeSet(CS.UI.Labels.GameJobId, game.JobId ~= "" and game.JobId:sub(1, 12) .. "..." or "Unavailable")
	CS.Util.SafeSet(CS.UI.Labels.GameServerState, tostring(#CS.Services.Players:GetPlayers()) .. "/" .. tostring(CS.Services.Players.MaxPlayers))
	CS.Util.SafeSet(CS.UI.Labels.GameSupport, "HTTP: " .. tostring(CS.Request ~= nil) .. "\nTeleport: true\nMarketplace: Loaded")
	CS.Friends.UpdateGameFriends()
end

function CS.Friends.UpdateGameFriends()
	local sameGame = {}
	local friends = CS.Runtime.FriendsOnlineCache or CS.Friends.GetOnlineFriends()
	for _, friendData in ipairs(friends) do
		local placeId = tonumber(friendData.PlaceId or friendData.PlaceID or 0)
		if placeId == game.PlaceId then table.insert(sameGame, friendData) end
	end
	if CS.UI.Labels.GameFriends then
		if #sameGame == 0 then
			CS.UI.Labels.GameFriends.Text = "No online friends detected in this same game through Roblox online-friend data."
		else
			local lines = {"Friends in this game, possibly different server:"}
			for _, friendData in ipairs(sameGame) do
				table.insert(lines, tostring(friendData.DisplayName or friendData.UserName or "Unknown") .. "  @" .. tostring(friendData.UserName or "Unknown"))
				table.insert(lines, "Location: " .. tostring(friendData.LastLocation or "Unknown"))
				table.insert(lines, "Join data: " .. ((friendData.GameId or friendData.JobId) and "available" or "limited"))
			end
			CS.UI.Labels.GameFriends.Text = table.concat(lines, "\n")
		end
	end
end

function CS.Diagnostics.Run()
	local char = CS.LocalPlayer.Character
	local humanoid = char and char:FindFirstChildOfClass("Humanoid")
	local root = char and char:FindFirstChild("HumanoidRootPart")
	local warnings = {}
	if not CS.Request then table.insert(warnings, "HTTP request unavailable; public server fetching may not work.") end
	if not setclipboard then table.insert(warnings, "Clipboard unavailable; copy buttons may not work.") end
	if not root then table.insert(warnings, "Character root is not loaded yet.") end
	CS.Util.SafeSet(CS.UI.Labels.DiagnosticsClient, "FPS: " .. tostring(CS.Runtime.FPS) .. "\nPing: " .. tostring(CS.Runtime.Ping) .. " ms\nPlayers: " .. tostring(#CS.Services.Players:GetPlayers()) .. "/" .. tostring(CS.Services.Players.MaxPlayers) .. "\nCharacter: " .. tostring(char ~= nil) .. "\nHumanoid: " .. tostring(humanoid ~= nil) .. "\nHumanoidRootPart: " .. tostring(root ~= nil) .. "\nHTTP Request: " .. tostring(CS.Request ~= nil) .. "\nClipboard: " .. tostring(setclipboard ~= nil))
	CS.Util.SafeSet(CS.UI.Labels.DiagnosticsNotes, #warnings == 0 and "No major warnings detected." or table.concat(warnings, "\n"), #warnings == 0 and CS.Theme.Success or CS.Theme.Warning)
end

function CS.Dashboard.UpdateOverlayLabels()
	local players = #CS.Services.Players:GetPlayers()
	local maxPlayers = CS.Services.Players.MaxPlayers or 0
	local ping = tostring(CS.Runtime.Ping or "?") .. "ms"
	local fps = tostring(CS.Runtime.FPS or "?")
	CS.Util.SafeSet(CS.UI.Labels.DashPlayers, tostring(players) .. "/" .. tostring(maxPlayers))
	CS.Util.SafeSet(CS.UI.Labels.DashPing, ping)
	CS.Util.SafeSet(CS.UI.Labels.DashFPS, fps)
	CS.Util.SafeSet(CS.UI.Labels.DashClock, os.date("%H:%M:%S"))
	CS.Util.SafeSet(CS.UI.Labels.DashNotif, tostring(CS.Flags.Notifications))
	CS.Util.SafeSet(CS.UI.Labels.CurrentServerInfo, "Players: " .. players .. "/" .. maxPlayers .. " | Ping: " .. ping .. " | Job: " .. tostring(game.JobId):sub(1, 8) .. "...")
	CS.Util.SafeSet(CS.UI.Labels.ServerPlayerData, tostring(players) .. "/" .. tostring(maxPlayers))
	CS.Util.SafeSet(CS.UI.Labels.ServerPingData, ping)
	CS.Util.SafeSet(CS.UI.Labels.GameServerState, tostring(players) .. "/" .. tostring(maxPlayers))
	CS.Util.SafeSet(CS.UI.Labels.UtilitySession, fps)
	CS.Util.SafeSet(CS.UI.Labels.UtilityPing, ping)
	CS.Util.SafeSet(CS.UI.Labels.UtilityPlayers, tostring(players))
	if CS.UI.Labels.SettingsLivePreview then
		CS.UI.Labels.SettingsLivePreview.Text = "FPS: " .. fps .. "\nPing: " .. ping .. "\nPlayers: " .. tostring(players) .. "/" .. tostring(maxPlayers) .. "\nCurrent Page: " .. tostring(CS.Runtime.CurrentPage or "Dashboard")
	end
end

local CS_OriginalDashboardUpdate_382 = CS.Dashboard.Update
function CS.Dashboard.Update()
	if CS_OriginalDashboardUpdate_382 then pcall(CS_OriginalDashboardUpdate_382) end
	CS.Dashboard.UpdateOverlayLabels()
end

function CS.Settings.ApplyVisuals()
	CS.Theme.Accent2 = CS.Theme.Accent
	CS.Theme.Accent3 = CS.Theme.Accent
	if CS.UI.Objects.Main then CS.UI.Objects.Main.BackgroundColor3 = CS.Theme.Background; CS.UI.Objects.Main.BackgroundTransparency = CS.Flags.Transparency end
	if CS.UI.Objects.Sidebar then CS.UI.Objects.Sidebar.BackgroundColor3 = CS.Theme.Panel; CS.UI.Objects.Sidebar.BackgroundTransparency = CS.Flags.PanelTransparency end
	if CS.UI.Objects.Content then CS.UI.Objects.Content.BackgroundColor3 = CS.Theme.Panel; CS.UI.Objects.Content.BackgroundTransparency = CS.Flags.PanelTransparency end
	if CS.UI.Objects.AccentRail then CS.UI.Objects.AccentRail.BackgroundColor3 = CS.Theme.Accent end
	if CS.UI.Objects.GUI then
		for _, obj in ipairs(CS.UI.Objects.GUI:GetDescendants()) do
			if obj:IsA("UIStroke") then obj.Color = CS.Theme.Stroke end
		end
	end
	for pageName, tab in pairs(CS.UI.Tabs) do
		local selected = CS.UI.Pages[pageName] and CS.UI.Pages[pageName].Visible
		tab.BackgroundColor3 = selected and CS.Theme.Accent or CS.Theme.Card
		tab.BackgroundTransparency = selected and 0.10 or 0.18
	end
end

function CS.Start()
	CS.Settings.Load()
	CS.Build()
	CS.Settings.ApplyVisuals()
	CS.Settings.SetScale(CS.Flags.ScaleMode or "Default")
	CS.Connect()
	CS.Dashboard.UpdatePingStats()
	CS.GameInfo.Load()
	CS.PlayerDetails.Refresh()
	CS.ServerBrowser.Rebuild(CS.Runtime.ServerData or {})
	CS.Friends.Update()
	pcall(function() CS.Friends.RefreshFriendList() end)
	CS.Diagnostics.Run()
	CS.Flags.ExampleNotification = false
	CS.UI.SwitchPage("Dashboard")
	CS.Notify.Push("CS Loaded", "Central Settings v" .. CS.Version .. " is ready.", CS.Theme.Success)
	print("CS | Central Settings v" .. CS.Version .. " loaded.")
end

CS.Start()

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: