Загрузка данных


--// kara ui
--// LocalScript (переливающаяся обводка, мерцающие снежинки, отступы)

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")

-- ================= ЭКРАН ЗАГРУЗКИ =================
local loadingGui = Instance.new("ScreenGui")
loadingGui.Name = "KaraLoading"
loadingGui.IgnoreGuiInset = true
loadingGui.Parent = playerGui

local loadingFrame = Instance.new("Frame")
loadingFrame.Size = UDim2.new(0, 200, 0, 80)
loadingFrame.Position = UDim2.new(0.5, -100, 0.5, -40)
loadingFrame.BackgroundColor3 = Color3.fromRGB(20,20,20)
loadingFrame.BorderSizePixel = 0
loadingFrame.Parent = loadingGui
Instance.new("UICorner", loadingFrame).CornerRadius = UDim.new(0,10)

local loadingText = Instance.new("TextLabel")
loadingText.Size = UDim2.new(1,0,0.4,0)
loadingText.BackgroundTransparency = 1
loadingText.Text = "kara loading..."
loadingText.Font = Enum.Font.GothamBold
loadingText.TextSize = 16
loadingText.TextColor3 = Color3.new(1,1,1)
loadingText.Parent = loadingFrame

local barBg = Instance.new("Frame")
barBg.Size = UDim2.new(0.8, 0, 0, 10)
barBg.Position = UDim2.new(0.1, 0, 0.6, 0)
barBg.BackgroundColor3 = Color3.fromRGB(50,50,50)
barBg.BorderSizePixel = 0
barBg.Parent = loadingFrame
Instance.new("UICorner", barBg).CornerRadius = UDim.new(1,0)

local barFill = Instance.new("Frame")
barFill.Size = UDim2.new(0,0,1,0)
barFill.BackgroundColor3 = Color3.fromRGB(255,255,255)
barFill.BorderSizePixel = 0
barFill.Parent = barBg
Instance.new("UICorner", barFill).CornerRadius = UDim.new(1,0)

local progress = 0
while progress < 1 do
	progress = math.min(1, progress + 0.01)
	barFill.Size = UDim2.new(progress, 0, 1, 0)
	task.wait(0.02)
end
task.wait(0.3)
loadingGui:Destroy()

-- ================= ОСНОВНОЙ GUI =================
if playerGui:FindFirstChild("KaraUI") then
	playerGui.KaraUI:Destroy()
end

local gui = Instance.new("ScreenGui")
gui.Name = "KaraUI"
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.Parent = playerGui

-- Настройки
local currentTheme = "Dark"
local menuScale = 1
local opened = true

local snowEnabled = true
local snowAmount = 40
local snowSize = 7
local snowSpeed = 1

local BASE_WIDTH = 420
local BASE_HEIGHT = 260

local themes = {
	Dark = {
		main = Color3.fromRGB(12,12,12),
		top = Color3.fromRGB(18,18,18),
		button = Color3.fromRGB(24,24,24),
		hover = Color3.fromRGB(38,38,38),
		text = Color3.fromRGB(255,255,255),
		stroke = Color3.fromRGB(40,40,40),
		sliderFill = Color3.fromRGB(255,255,255),
	},
	Light = {
		main = Color3.fromRGB(220,220,220),
		top = Color3.fromRGB(235,235,235),
		button = Color3.fromRGB(245,245,245),
		hover = Color3.fromRGB(255,255,255),
		text = Color3.fromRGB(20,20,20),
		stroke = Color3.fromRGB(180,180,180),
		sliderFill = Color3.fromRGB(80,80,80),
	}
}

-- Звук клика
local clickSound = Instance.new("Sound")
clickSound.SoundId = "rbxassetid://9116335663"
clickSound.Volume = 0.6
clickSound.Parent = gui

local function playClick()
	clickSound:Play()
end

-- Затемнение фона
local dim = Instance.new("Frame")
dim.Size = UDim2.new(1,0,1,0)
dim.BackgroundColor3 = Color3.new(0,0,0)
dim.BackgroundTransparency = 0.4
dim.BorderSizePixel = 0
dim.Parent = gui

-- Снежный холст
local snowHolder = Instance.new("Frame")
snowHolder.Size = UDim2.new(1,0,1,0)
snowHolder.BackgroundTransparency = 1
snowHolder.Parent = gui

-- ================= ГЛАВНОЕ ОКНО С АНИМИРОВАННОЙ ОБВОДКОЙ =================
local main = Instance.new("Frame")
main.Size = UDim2.new(0, BASE_WIDTH, 0, BASE_HEIGHT)
main.Position = UDim2.new(0.5, -BASE_WIDTH/2, 0.5, -BASE_HEIGHT/2)
main.BackgroundColor3 = themes.Dark.main
main.BorderSizePixel = 0
main.ClipsDescendants = true
main.Parent = gui

local mainCorner = Instance.new("UICorner")
mainCorner.CornerRadius = UDim.new(0,12)
mainCorner.Parent = main

local mainStroke = Instance.new("UIStroke")
mainStroke.Color = themes.Dark.stroke
mainStroke.Thickness = 1.5
mainStroke.Parent = main

-- Анимация переливания обводки
local function animateStroke()
	local targetWhite = Color3.fromRGB(220,220,220)
	local targetGray = Color3.fromRGB(80,80,80)
	while true do
		-- Из серого в белый
		local tween = TweenService:Create(mainStroke, TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {Color = targetWhite})
		tween:Play()
		task.wait(1.5)
		-- Из белого в серый
		tween = TweenService:Create(mainStroke, TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {Color = targetGray})
		tween:Play()
		task.wait(1.5)
	end
end
coroutine.wrap(animateStroke)()

-- Верхняя панель
local top = Instance.new("Frame")
top.Size = UDim2.new(1,0,0,40)
top.BackgroundColor3 = themes.Dark.top
top.BorderSizePixel = 0
top.Parent = main

local topCorner = Instance.new("UICorner")
topCorner.CornerRadius = UDim.new(0,12)
topCorner.Parent = top

local fix = Instance.new("Frame")
fix.Size = UDim2.new(1,0,0,12)
fix.Position = UDim2.new(0,0,1,-12)
fix.BackgroundColor3 = top.BackgroundColor3
fix.BorderSizePixel = 0
fix.Parent = top

local title = Instance.new("TextLabel")
title.Size = UDim2.new(1,0,1,0)
title.BackgroundTransparency = 1
title.Text = "kara"
title.Font = Enum.Font.GothamBold
title.TextSize = 21
title.TextColor3 = themes.Dark.text
title.Parent = top

-- Левая панель (кнопки)
local left = Instance.new("Frame")
left.Size = UDim2.new(0.35, 0, 1, -55)          -- чуть уже, даём место правой части
left.Position = UDim2.new(0, 8, 0, 45)
left.BackgroundTransparency = 1
left.Parent = main

local leftLayout = Instance.new("UIListLayout")
leftLayout.Padding = UDim.new(0, 8)
leftLayout.Parent = left

-- Правая область контента (увеличена)
local contentHolder = Instance.new("Frame")
contentHolder.Size = UDim2.new(0.6, 0, 1, -55)   -- было 0.55, стало 0.6
contentHolder.Position = UDim2.new(0.37, 0, 0, 45)
contentHolder.BackgroundTransparency = 1
contentHolder.Parent = main

-- Функция создания панели с прокруткой и отступами
local function createPanel()
	local panel = Instance.new("Frame")
	panel.Size = UDim2.new(1, 0, 1, 0)
	panel.BackgroundTransparency = 1
	panel.Visible = false
	panel.ClipsDescendants = true
	panel.Parent = contentHolder

	local scroll = Instance.new("ScrollingFrame")
	scroll.Size = UDim2.new(1, 0, 1, 0)
	scroll.BackgroundTransparency = 1
	scroll.CanvasSize = UDim2.new(0, 0, 0, 0)
	scroll.AutomaticCanvasSize = Enum.AutomaticSize.Y
	scroll.ScrollingDirection = Enum.ScrollingDirection.Y
	scroll.ScrollBarThickness = 3
	scroll.ScrollBarImageColor3 = themes[currentTheme].text
	scroll.Parent = panel

	local list = Instance.new("UIListLayout")
	list.Padding = UDim.new(0, 10)
	list.Parent = scroll

	-- Отступы внутри панели, чтобы контент не прилипал к краям
	local padding = Instance.new("UIPadding")
	padding.PaddingLeft = UDim.new(0, 6)
	padding.PaddingRight = UDim.new(0, 6)
	padding.PaddingTop = UDim.new(0, 6)
	padding.PaddingBottom = UDim.new(0, 6)
	padding.Parent = scroll

	return panel, scroll
end

local rightPanel, rightScroll = createPanel()
local mainPanel, mainScroll = createPanel()
local visualsPanel, visualsScroll = createPanel()

-- ================= СНЕЖИНКИ (мерцающие) =================
local snowflakes = {}

local function createSnowflake(startY)
	local dot = Instance.new("Frame")
	local size = math.random(snowSize - 2, snowSize + 2)

	local yScale = startY or (math.random() * 1.2 - 0.1)
	dot.Size = UDim2.new(0, size, 0, size)
	dot.Position = UDim2.new(math.random(), 0, yScale, -size)
	dot.BackgroundColor3 = Color3.new(1,1,1)
	dot.BackgroundTransparency = 0.6   -- стартовая прозрачность (будет меняться)
	dot.BorderSizePixel = 0
	dot.Parent = snowHolder

	local corner = Instance.new("UICorner")
	corner.CornerRadius = UDim.new(1,0)
	corner.Parent = dot

	table.insert(snowflakes, {
		object = dot,
		speed = math.random(40, 80) * snowSpeed,
		phase = math.random() * math.pi * 2,   -- случайная фаза для мерцания
	})
end

local function refreshSnow()
	for _, v in pairs(snowflakes) do
		v.object:Destroy()
	end
	table.clear(snowflakes)

	if not snowEnabled then return end

	for _ = 1, snowAmount do
		createSnowflake(nil)
	end
end

refreshSnow()

RunService.RenderStepped:Connect(function(dt)
	if not snowEnabled or not snowHolder.Visible then return end

	local safeDt = math.min(dt, 0.05)
	local holderHeight = snowHolder.AbsoluteSize.Y
	local time = os.clock()

	for _, flake in pairs(snowflakes) do
		local obj = flake.object
		-- Движение
		obj.Position = obj.Position + UDim2.new(0, 0, 0, flake.speed * safeDt)

		-- Мерцание: прозрачность плавно колеблется между 0.4 и 0.8
		local alpha = 0.6 + 0.2 * math.sin(time * 3 + flake.phase)
		obj.BackgroundTransparency = alpha

		-- Сброс наверх, если ушла за экран
		if obj.AbsolutePosition.Y > holderHeight + 20 then
			local size = obj.Size.Y.Offset
			obj.Position = UDim2.new(math.random(), 0, -0.1, -size * 2)
		end
	end
end)

-- ================= КНОПКИ / СЛАЙДЕРЫ =================
local buttons = {}

local function makeButton(text, parent)
	local button = Instance.new("TextButton")
	button.Size = UDim2.new(1, 0, 0, 38)
	button.BackgroundColor3 = themes[currentTheme].button
	button.BorderSizePixel = 0
	button.Text = text
	button.Font = Enum.Font.Gotham
	button.TextSize = 14
	button.TextColor3 = themes[currentTheme].text
	button.AutoButtonColor = false
	button.TextTruncate = Enum.TextTruncate.None   -- показываем текст полностью
	button.Parent = parent

	local corner = Instance.new("UICorner")
	corner.CornerRadius = UDim.new(0, 8)
	corner.Parent = button

	local stroke = Instance.new("UIStroke")
	stroke.Color = themes[currentTheme].stroke
	stroke.Parent = button

	button.MouseEnter:Connect(function()
		TweenService:Create(button, TweenInfo.new(0.15), {
			BackgroundColor3 = themes[currentTheme].hover
		}):Play()
	end)
	button.MouseLeave:Connect(function()
		TweenService:Create(button, TweenInfo.new(0.15), {
			BackgroundColor3 = themes[currentTheme].button
		}):Play()
	end)
	button.MouseButton1Click:Connect(function()
		playClick()
	end)

	table.insert(buttons, button)
	return button
end

local function makeLabel(text, parent)
	local label = Instance.new("TextLabel")
	label.Size = UDim2.new(1, 0, 0, 18)
	label.BackgroundTransparency = 1
	label.Text = text
	label.Font = Enum.Font.GothamBold
	label.TextSize = 13
	label.TextXAlignment = Enum.TextXAlignment.Left
	label.TextColor3 = themes[currentTheme].text
	label.TextTruncate = Enum.TextTruncate.AtEnd
	label.Parent = parent
	return label
end

local function makeSlider(name, min, max, default, callback, parent)
	local group = Instance.new("Frame")
	group.Size = UDim2.new(1, 0, 0, 40)
	group.BackgroundTransparency = 1
	group.Parent = parent

	local label = makeLabel(name, group)
	label.Size = UDim2.new(1, 0, 0, 16)

	local bg = Instance.new("Frame")
	bg.Size = UDim2.new(1, 0, 0, 20)
	bg.Position = UDim2.new(0, 0, 0, 20)
	bg.BackgroundColor3 = themes[currentTheme].button
	bg.BorderSizePixel = 0
	bg.Parent = group

	local bgCorner = Instance.new("UICorner")
	bgCorner.CornerRadius = UDim.new(1, 0)
	bgCorner.Parent = bg

	local fill = Instance.new("Frame")
	fill.Size = UDim2.new((default - min) / (max - min), 0, 1, 0)
	fill.BackgroundColor3 = themes[currentTheme].sliderFill
	fill.BorderSizePixel = 0
	fill.Name = "SliderFill"
	fill.Parent = bg

	local fillCorner = Instance.new("UICorner")
	fillCorner.CornerRadius = UDim.new(1, 0)
	fillCorner.Parent = fill

	local dragging = false

	bg.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = true
			playClick()
		end
	end)
	UserInputService.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = false
		end
	end)
	UserInputService.InputChanged:Connect(function(input)
		if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
			local percent = math.clamp(
				(input.Position.X - bg.AbsolutePosition.X) / bg.AbsoluteSize.X,
				0, 1
			)
			fill.Size = UDim2.new(percent, 0, 1, 0)
			local value = math.floor(min + (max - min) * percent)
			callback(value)
		end
	end)
end

-- ================= КНОПКИ ЛЕВОГО МЕНЮ =================
local mainTab = makeButton("Main", left)
local visualsTab = makeButton("Visuals", left)
local settingsTab = makeButton("Settings", left)

-- ================= ТЕМЫ =================
local allPanels = {rightPanel, mainPanel, visualsPanel}
local allScrolls = {rightScroll, mainScroll, visualsScroll}

function applyTheme(themeName)
	currentTheme = themeName
	local theme = themes[themeName]

	main.BackgroundColor3 = theme.main
	top.BackgroundColor3 = theme.top
	fix.BackgroundColor3 = theme.top
	-- mainStroke управляется анимацией, не меняем статично
	title.TextColor3 = theme.text

	for _, button in pairs(buttons) do
		button.BackgroundColor3 = theme.button
		button.TextColor3 = theme.text
		for _, child in pairs(button:GetChildren()) do
			if child:IsA("UIStroke") then
				child.Color = theme.stroke
			end
		end
	end

	for _, scroll in pairs(allScrolls) do
		scroll.ScrollBarImageColor3 = theme.text
		for _, child in pairs(scroll:GetDescendants()) do
			if child:IsA("TextLabel") then
				child.TextColor3 = theme.text
			elseif child:IsA("TextButton") then
				child.BackgroundColor3 = theme.button
				child.TextColor3 = theme.text
			elseif child:IsA("Frame") and child.Name ~= "SliderFill" then
				child.BackgroundColor3 = theme.button
			elseif child:IsA("UIStroke") then
				child.Color = theme.stroke
			elseif child.Name == "SliderFill" then
				child.BackgroundColor3 = theme.sliderFill
			end
		end
	end
end

-- ================= КОНТЕНТ =================
-- Settings
makeSlider("Menu Size", 50, 250, 100, function(value)
	menuScale = math.max(0.5, value / 100)
	main:TweenSize(
		UDim2.new(0, BASE_WIDTH * menuScale, 0, BASE_HEIGHT * menuScale),
		Enum.EasingDirection.Out,
		Enum.EasingStyle.Quint,
		0.15,
		true
	)
	updateMenuPosition()
end, rightScroll)

local darkBtn = makeButton("Dark Theme", rightScroll)
local lightBtn = makeButton("Light Theme", rightScroll)
darkBtn.MouseButton1Click:Connect(function() applyTheme("Dark") end)
lightBtn.MouseButton1Click:Connect(function() applyTheme("Light") end)

local snowToggle = makeButton("Toggle Snow (ON)", rightScroll)
snowToggle.MouseButton1Click:Connect(function()
	snowEnabled = not snowEnabled
	snowToggle.Text = snowEnabled and "Toggle Snow (ON)" or "Toggle Snow (OFF)"
	refreshSnow()
end)

makeSlider("Snow Amount", 5, 100, snowAmount, function(value)
	snowAmount = value
	refreshSnow()
end, rightScroll)

makeSlider("Snow Size", 2, 15, snowSize, function(value)
	snowSize = value
	refreshSnow()
end, rightScroll)

makeSlider("Snow Speed", 1, 5, snowSpeed, function(value)
	snowSpeed = value
	for _, flake in pairs(snowflakes) do
		flake.speed = math.random(40, 80) * snowSpeed
	end
end, rightScroll)

-- Main
makeLabel("Welcome to kara", mainScroll)
makeLabel("This is the main menu.", mainScroll)

-- Visuals
makeSlider("Background Dim", 0, 100, 40, function(value)
	dim.BackgroundTransparency = value / 100
end, visualsScroll)

-- ================= ПЕРЕКЛЮЧЕНИЕ ВКЛАДОК =================
local activePanel = mainPanel
mainPanel.Visible = true

local function switchTab(panel)
	if activePanel == panel then return end
	activePanel.Visible = false
	panel.Visible = true
	activePanel = panel
	playClick()
end

mainTab.MouseButton1Click:Connect(function() switchTab(mainPanel) end)
visualsTab.MouseButton1Click:Connect(function() switchTab(visualsPanel) end)
settingsTab.MouseButton1Click:Connect(function() switchTab(rightPanel) end)

-- ================= ПЕРЕТАСКИВАНИЕ =================
local dragging = false
local dragStart, startPos, dragInput

top.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		dragging = true
		dragStart = input.Position
		startPos = main.Position

		input.Changed:Connect(function()
			if input.UserInputState == Enum.UserInputState.End then
				dragging = false
			end
		end)
	end
end)

top.InputChanged:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseMovement then
		dragInput = input
	end
end)

UserInputService.InputChanged:Connect(function(input)
	if dragging and input == dragInput then
		local delta = input.Position - dragStart
		main.Position = UDim2.new(
			startPos.X.Scale,
			startPos.X.Offset + delta.X,
			startPos.Y.Scale,
			startPos.Y.Offset + delta.Y
		)
	end
end)

-- ================= СКРЫТИЕ / ПОКАЗ =================
local visiblePos, hiddenPos

function updateMenuPosition()
	local w = BASE_WIDTH * menuScale
	local h = BASE_HEIGHT * menuScale
	visiblePos = UDim2.new(0.5, -w/2, 0.5, -h/2)
	hiddenPos = UDim2.new(0.5, -w/2, 1, 40)
	if opened then
		main.Position = visiblePos
	else
		main.Position = hiddenPos
	end
end
updateMenuPosition()

UserInputService.InputBegan:Connect(function(input, gp)
	if gp then return end
	if input.KeyCode == Enum.KeyCode.RightShift then
		opened = not opened
		if opened then
			dim.Visible = true
			snowHolder.Visible = true
			TweenService:Create(main, TweenInfo.new(0.35, Enum.EasingStyle.Quint), {
				Position = visiblePos
			}):Play()
		else
			TweenService:Create(main, TweenInfo.new(0.35, Enum.EasingStyle.Quint), {
				Position = hiddenPos
			}):Play()
			task.wait(0.2)
			dim.Visible = false
			snowHolder.Visible = false
		end
	end
end)