-- BuildGUI Studio Plugin MVP
-- Paste a BUILDGUI/1 interface or BUILDGUIKIT/1 kit from buildgui.com, then import it into StarterGui.

assert(plugin, "BuildGUI must run as a Roblox Studio plugin")

local ChangeHistoryService = game:GetService("ChangeHistoryService")
local HttpService = game:GetService("HttpService")
local Selection = game:GetService("Selection")
local StarterGui = game:GetService("StarterGui")
local RunService = game:GetService("RunService")

local toolbar = plugin:CreateToolbar("BuildGUI")
local toolbarButton = toolbar:CreateButton("BuildGUI", "Import editable BuildGUI interfaces", "")
toolbarButton.ClickableWhenViewportHidden = true

local info = DockWidgetPluginGuiInfo.new(
	Enum.InitialDockState.Right,
	false,
	false,
	360,
	520,
	300,
	400
)
local widget = plugin:CreateDockWidgetPluginGuiAsync("BuildGUIImporterV1", info)
widget.Title = "BuildGUI · Studio Import"

local COLORS = {
	background = Color3.fromRGB(12, 18, 30),
	surface = Color3.fromRGB(19, 29, 46),
	surface2 = Color3.fromRGB(27, 41, 64),
	line = Color3.fromRGB(48, 65, 92),
	text = Color3.fromRGB(240, 247, 255),
	muted = Color3.fromRGB(142, 157, 180),
	accent = Color3.fromRGB(72, 214, 255),
	success = Color3.fromRGB(54, 211, 153),
	danger = Color3.fromRGB(255, 111, 125),
}

local function corner(parent, radius)
	local value = Instance.new("UICorner")
	value.CornerRadius = UDim.new(0, radius or 8)
	value.Parent = parent
	return value
end

local function stroke(parent, color, thickness, transparency)
	local value = Instance.new("UIStroke")
	value.Color = color or COLORS.line
	value.Thickness = thickness or 1
	value.Transparency = transparency or 0
	value.Parent = parent
	return value
end

local function label(parent, text, size, bold)
	local value = Instance.new("TextLabel")
	value.BackgroundTransparency = 1
	value.Text = text or ""
	value.TextColor3 = COLORS.text
	value.Font = bold and Enum.Font.GothamBold or Enum.Font.Gotham
	value.TextSize = size or 13
	value.TextWrapped = true
	value.Parent = parent
	return value
end

local root = Instance.new("Frame")
root.Size = UDim2.fromScale(1, 1)
root.BackgroundColor3 = COLORS.background
root.BorderSizePixel = 0
root.Parent = widget

local padding = Instance.new("UIPadding")
padding.PaddingTop = UDim.new(0, 18)
padding.PaddingBottom = UDim.new(0, 18)
padding.PaddingLeft = UDim.new(0, 18)
padding.PaddingRight = UDim.new(0, 18)
padding.Parent = root

local layout = Instance.new("UIListLayout")
layout.Padding = UDim.new(0, 10)
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Parent = root

local brand = label(root, "BUILDGUI", 11, true)
brand.LayoutOrder = 1
brand.Size = UDim2.new(1, 0, 0, 18)
brand.TextColor3 = COLORS.accent
brand.TextXAlignment = Enum.TextXAlignment.Left

local title = label(root, "Ship editable UI to Studio", 20, true)
title.LayoutOrder = 2
title.Size = UDim2.new(1, 0, 0, 50)
title.TextXAlignment = Enum.TextXAlignment.Left

local description = label(root, "On buildgui.com, copy one interface or a complete UI Kit. Paste it below. No HTTP permission or account is required.", 12, false)
description.LayoutOrder = 3
description.Size = UDim2.new(1, 0, 0, 58)
description.TextColor3 = COLORS.muted
description.TextXAlignment = Enum.TextXAlignment.Left
description.TextYAlignment = Enum.TextYAlignment.Top

local input = Instance.new("TextBox")
input.Name = "TransferCode"
input.LayoutOrder = 4
input.Size = UDim2.new(1, 0, 0, 180)
input.BackgroundColor3 = COLORS.surface
input.BorderSizePixel = 0
input.ClearTextOnFocus = false
input.MultiLine = true
input.Text = ""
input.PlaceholderText = "BUILDGUI/1 or BUILDGUIKIT/1\n{...}"
input.PlaceholderColor3 = Color3.fromRGB(93, 109, 134)
input.TextColor3 = COLORS.text
input.Font = Enum.Font.Code
input.TextSize = 12
input.TextWrapped = true
input.TextXAlignment = Enum.TextXAlignment.Left
input.TextYAlignment = Enum.TextYAlignment.Top
corner(input, 9)
stroke(input)
local inputPadding = Instance.new("UIPadding")
inputPadding.PaddingTop = UDim.new(0, 11)
inputPadding.PaddingBottom = UDim.new(0, 11)
inputPadding.PaddingLeft = UDim.new(0, 11)
inputPadding.PaddingRight = UDim.new(0, 11)
inputPadding.Parent = input
input.Parent = root

local importButton = Instance.new("TextButton")
importButton.LayoutOrder = 5
importButton.Size = UDim2.new(1, 0, 0, 44)
importButton.BackgroundColor3 = COLORS.accent
importButton.BorderSizePixel = 0
importButton.Text = "IMPORT INTO STARTERGUI"
importButton.TextColor3 = Color3.fromRGB(5, 14, 24)
importButton.Font = Enum.Font.GothamBold
importButton.TextSize = 13
corner(importButton, 9)
importButton.Parent = root

local status = label(root, "Ready for a BuildGUI transfer code.", 11, false)
status.LayoutOrder = 6
status.Size = UDim2.new(1, 0, 0, 40)
status.TextColor3 = COLORS.muted
status.TextXAlignment = Enum.TextXAlignment.Left
status.TextYAlignment = Enum.TextYAlignment.Top

local undoButton = Instance.new("TextButton")
undoButton.LayoutOrder = 7
undoButton.Size = UDim2.new(1, 0, 0, 36)
undoButton.BackgroundColor3 = COLORS.surface2
undoButton.BorderSizePixel = 0
undoButton.Text = "Undo last Studio change"
undoButton.TextColor3 = COLORS.muted
undoButton.Font = Enum.Font.GothamMedium
undoButton.TextSize = 11
corner(undoButton, 8)
stroke(undoButton)
undoButton.Parent = root

local supported = label(root, "SUPPORTED · Shop · Inventory · HUD · Main Menu · Settings · Codes", 9, true)
supported.LayoutOrder = 8
supported.Size = UDim2.new(1, 0, 0, 30)
supported.TextColor3 = Color3.fromRGB(87, 103, 128)
supported.TextXAlignment = Enum.TextXAlignment.Left

local function fromHex(value, fallback)
	if type(value) ~= "string" or not value:match("^#%x%x%x%x%x%x$") then
		return fallback
	end
	return Color3.fromHex(value)
end

local function sanitizeName(value, fallback)
	value = tostring(value or fallback or "Element")
	value = value:gsub("[^%w_ ]", ""):gsub("%s+", "")
	return value ~= "" and value:sub(1, 40) or (fallback or "Element")
end

local function makeText(parent, className, name, text)
	local value = Instance.new(className)
	value.Name = name
	value.BackgroundTransparency = 1
	value.Text = tostring(text or "")
	value.TextColor3 = Color3.new(1, 1, 1)
	value.Font = Enum.Font.GothamBold
	value.TextSize = 15
	value.TextWrapped = true
	value.Parent = parent
	return value
end

local function makePanel(spec, guiName, width)
	local theme = type(spec.theme) == "table" and spec.theme or {}
	local accent = fromHex(theme.accent, COLORS.accent)
	local background = fromHex(theme.bg, Color3.fromRGB(17, 26, 42))
	local cell = fromHex(theme.cell, Color3.fromRGB(27, 41, 64))
	local radius = math.clamp(tonumber(theme.corner) or 12, 0, 24)
	local panelOpacity = math.clamp(tonumber(theme.panel_opacity) or 1, 0.55, 1)

	local gui = Instance.new("ScreenGui")
	gui.Name = guiName
	gui.ResetOnSpawn = false
	gui.IgnoreGuiInset = true
	gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
	gui:SetAttribute("BuildGUIVersion", 1)
	gui:SetAttribute("BuildGUIType", spec.type)
	local actionEvent = Instance.new("BindableEvent")
	actionEvent.Name = "ActionTriggered"
	actionEvent.Parent = gui

	local panel = Instance.new("Frame")
	panel.Name = "Panel"
	panel.AnchorPoint = Vector2.new(0.5, 0.5)
	panel.Position = UDim2.fromScale(0.5, 0.5)
	panel.Size = UDim2.new(0, width or 390, 0, 0)
	panel.AutomaticSize = Enum.AutomaticSize.Y
	panel.BackgroundColor3 = background
	panel.BackgroundTransparency = 1 - panelOpacity
	panel.BorderSizePixel = 0
	panel.Parent = gui
	corner(panel, radius)
	stroke(panel, accent, 2)

	local panelPadding = Instance.new("UIPadding")
	panelPadding.PaddingTop = UDim.new(0, 16)
	panelPadding.PaddingBottom = UDim.new(0, 16)
	panelPadding.PaddingLeft = UDim.new(0, 16)
	panelPadding.PaddingRight = UDim.new(0, 16)
	panelPadding.Parent = panel

	local panelLayout = Instance.new("UIListLayout")
	panelLayout.Padding = UDim.new(0, 10)
	panelLayout.SortOrder = Enum.SortOrder.LayoutOrder
	panelLayout.Parent = panel

	return gui, panel, accent, background, cell
end

local function addController(gui, name, source)
	local scriptObject = Instance.new("LocalScript")
	scriptObject.Name = name
	scriptObject.Source = source
	scriptObject.Parent = gui
end

local function addRuntimePolish(gui)
	local panel = gui:FindFirstChild("Panel")
	if panel and not panel:FindFirstChild("ResponsiveScale") then
		local responsiveScale = Instance.new("UIScale")
		responsiveScale.Name = "ResponsiveScale"
		responsiveScale.Parent = panel
	end
	addController(gui, "BuildGUIEffects", [[
local TweenService=game:GetService("TweenService")
local gui=script.Parent
local panel=gui:WaitForChild("Panel")
local actions=gui:WaitForChild("ActionTriggered")
local responsive=panel:WaitForChild("ResponsiveScale")
local camera=workspace.CurrentCamera

local function resize()
	local width=camera and camera.ViewportSize.X or 1280
	responsive.Scale=math.clamp(width/520,0.68,1)
end
resize()
if camera then camera:GetPropertyChangedSignal("ViewportSize"):Connect(resize) end

local function polish(button)
	if not button:IsA("GuiButton") or button:FindFirstChild("InteractionScale") then return end
	button.AutoButtonColor=false
	button.Selectable=true
	local scale=Instance.new("UIScale")
	scale.Name="InteractionScale"
	scale.Parent=button
	local function tween(value,time)
		TweenService:Create(scale,TweenInfo.new(time,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{Scale=value}):Play()
	end
	button.MouseEnter:Connect(function() tween(1.025,0.12) end)
	button.MouseLeave:Connect(function() tween(1,0.12) end)
	button.MouseButton1Down:Connect(function() tween(0.97,0.06) end)
	button.Activated:Connect(function() tween(1,0.1) end)
end
for _,item in ipairs(gui:GetDescendants()) do polish(item) end
gui.DescendantAdded:Connect(polish)]])
end

local function buildShop(spec)
	local gui, panel, accent, _, cell = makePanel(spec, "ShopGui", 470)
	local titleLabel = makeText(panel, "TextLabel", "Title", spec.title or "Shop")
	titleLabel.LayoutOrder = 1
	titleLabel.Size = UDim2.new(1, 0, 0, 34)
	titleLabel.TextSize = 24

	local items = Instance.new("Frame")
	items.Name = "Items"
	items.LayoutOrder = 2
	items.Size = UDim2.new(1, 0, 0, 210)
	items.BackgroundTransparency = 1
	items.Parent = panel
	local grid = Instance.new("UIGridLayout")
	grid.CellSize = UDim2.new(0.31, 0, 0, 96)
	grid.CellPadding = UDim2.new(0.03, 0, 0, 8)
	grid.HorizontalAlignment = Enum.HorizontalAlignment.Center
	grid.SortOrder = Enum.SortOrder.LayoutOrder
	grid.Parent = items

	for index, item in ipairs(type(spec.items) == "table" and spec.items or {}) do
		if index > 12 then break end
		local button = Instance.new("TextButton")
		button.Name = sanitizeName(item.label, "Item" .. index)
		button.LayoutOrder = index
		button.BackgroundColor3 = cell
		button.BorderSizePixel = 0
		button.Text = (item.icon and tostring(item.icon) .. "\n" or "") .. tostring(item.label or "Item") .. "\n" .. tostring(item.price or "")
		button.TextColor3 = Color3.new(1, 1, 1)
		button.Font = Enum.Font.GothamBold
		button.TextSize = 14
		button.TextWrapped = true
		button:SetAttribute("Price", tostring(item.price or ""))
		corner(button, 9)
		button.Parent = items
	end

	local selection = makeText(panel, "TextLabel", "SelectionStatus", "Select an item")
	selection.LayoutOrder = 3
	selection.Size = UDim2.new(1, 0, 0, 24)
	selection.TextColor3 = COLORS.muted
	selection.TextSize = 12

	local buy = Instance.new("TextButton")
	buy.Name = "BuyButton"
	buy.LayoutOrder = 4
	buy.Size = UDim2.new(1, 0, 0, 42)
	buy.BackgroundColor3 = accent
	buy.BackgroundTransparency = 0.45
	buy.BorderSizePixel = 0
	buy.Text = "SELECT AN ITEM"
	buy.TextColor3 = Color3.new(1, 1, 1)
	buy.Font = Enum.Font.GothamBold
	buy.TextSize = 15
	buy.Active = false
	corner(buy, 8)
	buy.Parent = panel

	local close = Instance.new("TextButton")
	close.Name = "CloseButton"
	close.LayoutOrder = 5
	close.Size = UDim2.new(1, 0, 0, 40)
	close.BackgroundColor3 = accent
	close.BorderSizePixel = 0
	close.Text = tostring(spec.close and spec.close.label or "Close")
	close.TextColor3 = Color3.new(1, 1, 1)
	close.Font = Enum.Font.GothamBold
	close.TextSize = 16
	corner(close, 8)
	close.Parent = panel
addController(gui, "ShopController", [[
local gui=script.Parent
local panel=gui:WaitForChild("Panel")
local actions=gui:WaitForChild("ActionTriggered")
local selectedName=nil
local selectedPrice=nil
panel.CloseButton.Activated:Connect(function()
	gui.Enabled=false
	local menu=gui.Parent:FindFirstChild("MainMenuGui")
	if menu then menu.Enabled=true end
end)
for _,button in ipairs(panel.Items:GetChildren()) do
	if button:IsA("TextButton") then button.Activated:Connect(function()
		selectedName=button.Name
		selectedPrice=button:GetAttribute("Price")
		panel.SelectionStatus.Text="Selected: "..selectedName.."  "..tostring(selectedPrice or "")
		panel.BuyButton.Text="BUY "..string.upper(selectedName)
		panel.BuyButton.BackgroundTransparency=0
		panel.BuyButton.Active=true
		actions:Fire("shop_select",button.Name,button:GetAttribute("Price"))
	end) end
end
panel.BuyButton.Activated:Connect(function()
	if selectedName then actions:Fire("shop_purchase",selectedName,selectedPrice) end
end)]])
	return gui
end

local function buildInventory(spec)
	local gui, panel, _, _, cell = makePanel(spec, "InventoryGui", 420)
	local titleLabel = makeText(panel, "TextLabel", "Title", spec.title or "Inventory")
	titleLabel.LayoutOrder = 1
	titleLabel.Size = UDim2.new(1, 0, 0, 34)
	titleLabel.TextSize = 24
	local slots = Instance.new("Frame")
	slots.Name = "Slots"
	slots.LayoutOrder = 2
	slots.Size = UDim2.new(1, 0, 0, 170)
	slots.BackgroundTransparency = 1
	slots.Parent = panel
	local grid = Instance.new("UIGridLayout")
	grid.CellSize = UDim2.fromOffset(72, 72)
	grid.CellPadding = UDim2.fromOffset(8, 8)
	grid.HorizontalAlignment = Enum.HorizontalAlignment.Center
	grid.Parent = slots
	for index, item in ipairs(type(spec.slots) == "table" and spec.slots or {}) do
		if index > 16 then break end
		local className = item.empty and "Frame" or "TextButton"
		local slot = Instance.new(className)
		slot.Name = item.empty and ("Empty" .. index) or sanitizeName(item.label, "Item" .. index)
		slot.BackgroundColor3 = cell
		slot.BackgroundTransparency = item.empty and 0.45 or 0
		slot.BorderSizePixel = 0
		if slot:IsA("TextButton") then
			slot.Text = tostring(item.icon or "◇") .. ((tonumber(item.qty) or 1) > 1 and ("\n×" .. tostring(item.qty)) or "")
			slot.TextColor3 = Color3.new(1, 1, 1)
			slot.Font = Enum.Font.GothamBold
			slot.TextSize = 22
		end
		corner(slot, 8)
		slot.Parent = slots
	end
	local close = Instance.new("TextButton")
	close.Name = "CloseButton"
	close.LayoutOrder = 3
	close.Size = UDim2.new(1, 0, 0, 38)
	close.BackgroundTransparency = 1
	close.Text = tostring(spec.close and spec.close.label or "Close")
	close.TextColor3 = COLORS.text
	close.Font = Enum.Font.GothamBold
	close.Parent = panel
addController(gui, "InventoryController", [[
local gui=script.Parent
local actions=gui:WaitForChild("ActionTriggered")
gui.Panel.CloseButton.Activated:Connect(function()
	gui.Enabled=false
	local menu=gui.Parent:FindFirstChild("MainMenuGui")
	if menu then menu.Enabled=true end
end)
for _,button in ipairs(gui.Panel.Slots:GetChildren()) do
	if button:IsA("TextButton") then button.Activated:Connect(function()
		actions:Fire("inventory_select",button.Name)
	end) end
end]])
	return gui
end

local function buildHud(spec)
	local gui, panel, _, _, cell = makePanel(spec, "PlayerHud", 300)
	panel.AnchorPoint = Vector2.new(0, 1)
	panel.Position = UDim2.new(0, 16, 1, -16)
	local titleLabel = makeText(panel, "TextLabel", "PlayerName", spec.title or "Player")
	titleLabel.LayoutOrder = 1
	titleLabel.Size = UDim2.new(1, 0, 0, 30)
	titleLabel.TextXAlignment = Enum.TextXAlignment.Left
	local bars = Instance.new("Frame")
	bars.Name = "Bars"
	bars.LayoutOrder = 2
	bars.Size = UDim2.new(1, 0, 0, 0)
	bars.AutomaticSize = Enum.AutomaticSize.Y
	bars.BackgroundTransparency = 1
	bars.Parent = panel
	local list = Instance.new("UIListLayout")
	list.Padding = UDim.new(0, 8)
	list.Parent = bars
	for index, item in ipairs(type(spec.bars) == "table" and spec.bars or {}) do
		if index > 4 then break end
		local row = Instance.new("Frame")
		row.Name = sanitizeName(item.label, "Bar" .. index)
		row.Size = UDim2.new(1, 0, 0, 34)
		row.BackgroundTransparency = 1
		row.Parent = bars
		local nameLabel = makeText(row, "TextLabel", "BarName", item.label or "Stat")
		nameLabel.Size = UDim2.new(1, 0, 0, 15)
		nameLabel.TextSize = 12
		nameLabel.TextXAlignment = Enum.TextXAlignment.Left
		local track = Instance.new("Frame")
		track.Name = "Track"
		track.Position = UDim2.new(0, 0, 0, 20)
		track.Size = UDim2.new(1, 0, 0, 11)
		track.BackgroundColor3 = cell
		track.BorderSizePixel = 0
		corner(track, 6)
		track.Parent = row
		local fill = Instance.new("Frame")
		fill.Name = "Fill"
		local maximum = math.max(tonumber(item.max) or 100, 1)
		fill.Size = UDim2.new(math.clamp((tonumber(item.value) or 0) / maximum, 0, 1), 0, 1, 0)
		fill.BackgroundColor3 = fromHex(item.color, COLORS.danger)
		fill.BorderSizePixel = 0
		corner(fill, 6)
		fill.Parent = track
	end
	addController(gui, "HudController", "-- Bind these bars to your real player stats.")
	return gui
end

local function buildAction(spec)
	local guiName = spec.type == "main_menu" and "MainMenuGui" or spec.type == "settings_panel" and "SettingsGui" or "CodesGui"
	local gui, panel, accent, _, cell = makePanel(spec, guiName, 360)
	local titleLabel = makeText(panel, "TextLabel", "Title", spec.title or "MENU")
	titleLabel.LayoutOrder = 1
	titleLabel.Size = UDim2.new(1, 0, 0, 38)
	titleLabel.TextSize = 26
	if spec.subtitle then
		local subtitle = makeText(panel, "TextLabel", "Subtitle", spec.subtitle)
		subtitle.LayoutOrder = 2
		subtitle.Size = UDim2.new(1, 0, 0, 22)
		subtitle.TextColor3 = COLORS.muted
		subtitle.TextSize = 12
	end

	if spec.type == "codes_panel" then
		local codeInput = Instance.new("TextBox")
		codeInput.Name = "CodeInput"
		codeInput.LayoutOrder = 3
		codeInput.Size = UDim2.new(1, 0, 0, 44)
		codeInput.BackgroundColor3 = cell
		codeInput.BorderSizePixel = 0
		codeInput.PlaceholderText = tostring(spec.placeholder or "ENTER CODE")
		codeInput.Text = ""
		codeInput.TextColor3 = COLORS.text
		codeInput.Font = Enum.Font.GothamBold
		codeInput.TextSize = 14
		corner(codeInput, 9)
		codeInput.Parent = panel
		local redeem = Instance.new("TextButton")
		redeem.Name = "RedeemButton"
		redeem.LayoutOrder = 4
		redeem.Size = UDim2.new(1, 0, 0, 44)
		redeem.BackgroundColor3 = accent
		redeem.BorderSizePixel = 0
		redeem.Text = tostring(spec.button_label or "REDEEM")
		redeem.TextColor3 = Color3.fromRGB(5, 14, 24)
		redeem.Font = Enum.Font.GothamBold
		corner(redeem, 9)
		redeem.Parent = panel
		local codeStatus = makeText(panel, "TextLabel", "Status", "Enter a code to continue")
		codeStatus.LayoutOrder = 5
		codeStatus.Size = UDim2.new(1, 0, 0, 22)
		codeStatus.TextColor3 = COLORS.muted
		codeStatus.TextSize = 12
		local close = Instance.new("TextButton")
		close.Name = "CloseButton"
		close.LayoutOrder = 6
		close.Size = UDim2.new(1, 0, 0, 40)
		close.BackgroundTransparency = 1
		close.Text = "BACK"
		close.TextColor3 = COLORS.text
		close.Font = Enum.Font.GothamBold
		corner(close, 9)
		close.Parent = panel
	else
		local rows = Instance.new("Frame")
		rows.Name = "Rows"
		rows.LayoutOrder = 3
		rows.Size = UDim2.new(1, 0, 0, 0)
		rows.AutomaticSize = Enum.AutomaticSize.Y
		rows.BackgroundTransparency = 1
		rows.Parent = panel
		local rowsLayout = Instance.new("UIListLayout")
		rowsLayout.Padding = UDim.new(0, 8)
		rowsLayout.Parent = rows
		local sourceRows = spec.type == "main_menu" and spec.actions or spec.toggles
		for index, item in ipairs(type(sourceRows) == "table" and sourceRows or {}) do
			if index > 8 then break end
			local text = tostring(item.label or "Action")
			if spec.type == "settings_panel" then text ..= "     " .. (item.enabled == false and "OFF" or "ON") end
			local button = Instance.new("TextButton")
			button.Name = sanitizeName(item.label, "Action" .. index)
			button.Size = UDim2.new(1, 0, 0, 44)
			button.BackgroundColor3 = cell
			button.BorderSizePixel = 0
			button.Text = text
			button.TextColor3 = COLORS.text
			button.Font = Enum.Font.GothamBold
			button.TextSize = 14
			button:SetAttribute("Action", tostring(item.action or item.label or "action"):lower())
			if spec.type == "settings_panel" then button:SetAttribute("Enabled", item.enabled ~= false) end
			corner(button, 9)
			button.Parent = rows
		end
		if spec.type == "settings_panel" then
			local close = Instance.new("TextButton")
			close.Name = "CloseButton"
			close.LayoutOrder = 4
			close.Size = UDim2.new(1, 0, 0, 40)
			close.BackgroundColor3 = accent
			close.BorderSizePixel = 0
			close.Text = "BACK"
			close.TextColor3 = Color3.fromRGB(5, 14, 24)
			close.Font = Enum.Font.GothamBold
			corner(close, 9)
			close.Parent = panel
		end
	end
	if spec.type == "main_menu" then
		addController(gui, "MenuController", [[
local gui=script.Parent
local actions=gui:WaitForChild("ActionTriggered")
local targets={shop="ShopGui",inventory="InventoryGui",loadout="InventoryGui",settings="SettingsGui",codes="CodesGui"}
for _,button in ipairs(gui.Panel.Rows:GetChildren()) do
	if button:IsA("TextButton") then button.Activated:Connect(function()
		local action=tostring(button:GetAttribute("Action") or button.Name):lower()
		actions:Fire(action,button.Name)
		if action=="play" or action=="start" or action=="continue" then
			gui.Enabled=false
			local hud=gui.Parent:FindFirstChild("PlayerHud")
			if hud then hud.Enabled=true end
			return
		end
		local targetName=targets[action]
		local target=targetName and gui.Parent:FindFirstChild(targetName)
		if target and target:IsA("ScreenGui") then target.Enabled=true gui.Enabled=false
		else warn("[BuildGUI] No installed screen for action: "..action..". Import a complete UI Kit or connect this action.") end
	end) end
end]])
	elseif spec.type == "settings_panel" then
		addController(gui, "SettingsController", [[
local gui=script.Parent
local actions=gui:WaitForChild("ActionTriggered")
for _,button in ipairs(gui.Panel.Rows:GetChildren()) do
	if button:IsA("TextButton") then button.Activated:Connect(function()
		local enabled=not button:GetAttribute("Enabled")
		button:SetAttribute("Enabled",enabled)
		button.Text=button.Name.."     "..(enabled and "ON" or "OFF")
		actions:Fire("setting_changed",button.Name,enabled)
	end) end
end
gui.Panel.CloseButton.Activated:Connect(function()
	gui.Enabled=false
	local menu=gui.Parent:FindFirstChild("MainMenuGui")
	if menu then menu.Enabled=true end
end)]])
	else
		addController(gui, "CodesController", [[
local gui=script.Parent
local panel=gui.Panel
local actions=gui:WaitForChild("ActionTriggered")
panel.RedeemButton.Activated:Connect(function()
	local code=panel.CodeInput.Text:match("^%s*(.-)%s*$")
	if code=="" then panel.Status.Text="Enter a valid code" return end
	panel.Status.Text="Checking "..code.."…"
	actions:Fire("redeem_code",code)
end)
panel.CloseButton.Activated:Connect(function()
	gui.Enabled=false
	local menu=gui.Parent:FindFirstChild("MainMenuGui")
	if menu then menu.Enabled=true end
end)]])
	end
	return gui
end

local builders = {
	shop_panel = buildShop,
	inventory_grid = buildInventory,
	status_hud = buildHud,
	main_menu = buildAction,
	settings_panel = buildAction,
	codes_panel = buildAction,
}

local function decodeTransfer(raw)
	if type(raw) ~= "string" then return nil, "Transfer code is missing." end
	raw = raw:gsub("^%s+", "")
	if #raw > 500000 then return nil, "Transfer code is too large." end
	local payload, isKit
	if raw:sub(1, 11) == "BUILDGUI/1\n" then
		payload = raw:sub(12)
		isKit = false
	elseif raw:sub(1, 14) == "BUILDGUIKIT/1\n" then
		payload = raw:sub(15)
		isKit = true
	else
		return nil, "Expected a BUILDGUI/1 or BUILDGUIKIT/1 transfer code."
	end
	local ok, decoded = pcall(HttpService.JSONDecode, HttpService, payload)
	if not ok or type(decoded) ~= "table" then return nil, "The transfer JSON is invalid." end
	local specs = isKit and decoded or { decoded }
	if #specs < 1 or #specs > 12 then return nil, "A UI Kit must contain 1–12 interfaces." end
	for index, spec in ipairs(specs) do
		if type(spec) ~= "table" or type(spec.type) ~= "string" or not builders[spec.type] then
			return nil, "Unsupported or missing GUI type at item " .. index .. "."
		end
	end
	return specs, nil, isKit
end

local function setStatus(message, kind)
	status.Text = message
	status.TextColor3 = kind == "success" and COLORS.success or kind == "error" and COLORS.danger or COLORS.muted
end

local busy = false
importButton.MouseButton1Click:Connect(function()
	if busy then return end
	busy = true
	importButton.Text = "IMPORTING…"
	local specs, decodeError, isKit = decodeTransfer(input.Text)
	if not specs then
		setStatus(decodeError, "error")
		importButton.Text = "IMPORT INTO STARTERGUI"
		busy = false
		return
	end
	if RunService:IsRunning() then
		setStatus("Stop Play/Test before importing. Studio cannot record persistent plugin changes during a playtest.", "error")
		importButton.Text = "IMPORT INTO STARTERGUI"
		busy = false
		return
	end

	local recording = ChangeHistoryService:TryBeginRecording(isKit and "Import BuildGUI UI Kit" or "Import BuildGUI interface")
	if not recording then
		setStatus("BuildGUI could not start an Undo recording. Restart Studio once, then import again.", "error")
		importButton.Text = "IMPORT INTO STARTERGUI"
		busy = false
		return
	end

	local results = {}
	local importOk, importError = pcall(function()
		for _, spec in ipairs(specs) do
			local result = builders[spec.type](spec)
			assert(result, "Builder returned no ScreenGui for " .. spec.type)
			addRuntimePolish(result)
			table.insert(results, result)
		end
		for _, result in ipairs(results) do
			local existing = StarterGui:FindFirstChild(result.Name)
			if existing and existing:GetAttribute("BuildGUIVersion") then existing:Destroy() end
			if isKit then
				-- A complete kit starts at its main menu. Routed screens stay hidden until opened.
				result.Enabled = result.Name == "MainMenuGui"
			end
			result.Parent = StarterGui
		end
		Selection:Set(results)
	end)
	if not importOk then
		ChangeHistoryService:FinishRecording(recording, Enum.FinishRecordingOperation.Cancel)
		setStatus("Import failed safely: " .. tostring(importError), "error")
		importButton.Text = "IMPORT INTO STARTERGUI"
		busy = false
		return
	end
	ChangeHistoryService:FinishRecording(recording, Enum.FinishRecordingOperation.Commit)
	plugin:SetSetting("BuildGUI.LastType", isKit and "ui_kit" or specs[1].type)
	setStatus(isKit and ("Imported " .. #results .. " UI Kit screens. They are selected and can be undone together.") or ("Imported " .. results[1].Name .. ". It is selected in StarterGui and can be undone."), "success")
	importButton.Text = "IMPORTED ✓"
	task.delay(1.4, function()
		importButton.Text = "IMPORT INTO STARTERGUI"
		busy = false
	end)
end)

undoButton.MouseButton1Click:Connect(function()
	if ChangeHistoryService:GetCanUndo() then
		ChangeHistoryService:Undo()
		setStatus("Undid the last Studio change.", "success")
	else
		setStatus("There is no Studio change to undo.", "error")
	end
end)

toolbarButton.Click:Connect(function()
	widget.Enabled = not widget.Enabled
end)

widget:BindToClose(function()
	widget.Enabled = false
end)
