Sticky note placement system wont hover over surfaces properly + Gui issue

I’m trying to make it so my ghostStickyNoteModel (its called that but it’s a part) hovers over where my mouse is but essentially rotates to the surface its on.

For example, if my mouse is pointed and hovering over the ground, it should place the note horizontally and flat on the ground, instead, it places it upright for some reason and also if I hover for too long it for some reason flies up and places in mid air like in the screenshot below:
(Please help me out with this issue because I already posted about this issue and nobody saw my post)

My code should be ok but these bugs are ruining the experience completely. If im hovering my mouse on a wall, then it should place upright on the wall.

Here’s the script I call “StickyNoteScript” that handles most of the positioning:

-- StickyNote Tool Script
-- Important: Ensure that the sticky note tool has "RequiresHandle" unchecked

local tool = script.Parent
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local replicatedStorage = game:GetService("ReplicatedStorage")

local stickyNoteModel = replicatedStorage:WaitForChild("StickyNoteModel")
local ghostStickyNoteModel = replicatedStorage:WaitForChild("GhostStickyNoteModel")

local ghostNote
local lastPlacedTime = 0
local cooldownTime = 10
local toolEquipped = false

local function isSurface(target)
	return target and target:IsA("Part") and not target:IsA("MeshPart") and target.CanCollide
end

local function updateGhostNote(mouseHit)
	if not ghostNote then
		ghostNote = ghostStickyNoteModel:Clone()
		ghostNote.Parent = workspace
	end

	-- Position the ghost note directly above the surface
	local ghostPosition = mouseHit.Position + Vector3.new(0, 0.05, 0) -- Adjust to be just above the surface
	ghostNote.CFrame = CFrame.new(ghostPosition) * CFrame.Angles(math.rad(-90), 0, 0) -- Keep it flat
	ghostNote.Transparency = 0.5
end

local function removeGhostNote()
	if ghostNote then
		ghostNote:Destroy()
		ghostNote = nil
	end
end

local function placeStickyNote(mouseHit)
	local currentTime = tick()
	if currentTime - lastPlacedTime < cooldownTime then
		return
	end

	local target = mouse.Target
	if not isSurface(target) then
		return
	end
	
	local stickyNotePosition = mouseHit.Position + Vector3.new(0, 0.05, 0) 

	-- Create the sticky note
	local newStickyNote = stickyNoteModel:Clone()
	newStickyNote.CFrame = CFrame.new(stickyNotePosition) * CFrame.Angles(math.rad(-90), 0, 0) 
	newStickyNote.Parent = workspace
	newStickyNote.Name = "StickyNote"
	lastPlacedTime = currentTime
end

tool.Equipped:Connect(function()
	toolEquipped = true
	mouse.Move:Connect(function()
		if toolEquipped then
			updateGhostNote(mouse.Hit)
		end
	end)

	mouse.Button1Down:Connect(function()
		if toolEquipped then
			placeStickyNote(mouse.Hit)
		end
	end)
end)

tool.Unequipped:Connect(function()
	removeGhostNote()
	toolEquipped = false
end)

Here’s the script I call “StickyNoteGuiScript” that handles the placement:

-- LocalScript for Sticky Note GUI

local player = game.Players.LocalPlayer
local screenGui = script.Parent
local noteFrame = screenGui:WaitForChild("NoteFrame")
local textBox = noteFrame:WaitForChild("TextBox")
local confirmButton = noteFrame:WaitForChild("ConfirmButton")
local cancelButton = noteFrame:WaitForChild("CancelButton")

local tool = player.Backpack:WaitForChild("StickyNote")

local tempStickyNote -- Variable to hold reference to the temporary sticky note being created
local ghostNote -- Reference to the ghost sticky note
local clickPosition -- Variable to hold the position where the note will be placed

local function hideGhostNote()
	if ghostNote then
		ghostNote:Destroy() -- Removes the ghost note
		ghostNote = nil
	end
end

local function createStickyNote(position, noteText)
	local stickyNoteModel = game.ReplicatedStorage:WaitForChild("StickyNoteModel"):Clone()
	stickyNoteModel.Position = position
	stickyNoteModel.Parent = workspace

	local surfaceGui = stickyNoteModel:FindFirstChild("SurfaceGui")
	if surfaceGui then
		local textLabel = surfaceGui:FindFirstChild("TextLabel") 
		if textLabel then
			textLabel.Text = noteText -- Sets the text of the sticky note
		end
	end

	return stickyNoteModel
end

local function onConfirmButtonClicked()
	local noteText = textBox.Text
	if noteText and noteText ~= "" and clickPosition then
		-- Create and place the sticky note
		local placedStickyNote = createStickyNote(clickPosition, noteText)
		noteFrame.Visible = false -- Close the note frame after confirming
		textBox.Text = "" -- Clear the text box
		hideGhostNote() -- Hide the ghost note when done
		tempStickyNote = nil -- Reset the temporary sticky note reference
	end
end

local function onCancelButtonClicked()
	if tempStickyNote then
		tempStickyNote:Destroy() -- Remove only the temporary sticky note if it exists
	end
	noteFrame.Visible = false -- Hides the note frame
	textBox.Text = "" -- Clears the text box
	hideGhostNote() -- Hides the ghost note when canceled
end

local function showNoteFrame(position)
	noteFrame.Visible = true -- Shows the note frame
	textBox.Visible = true -- Shows the TextBox
	confirmButton.Visible = true -- Shows the ConfirmButton
	cancelButton.Visible = true -- Shows the CancelButton
	clickPosition = position -- Stores the position where the sticky note will be placed
	tempStickyNote = createStickyNote(position, "") -- Creates a temporary sticky note with no text
	hideGhostNote() -- Hides the ghost note when editing
end

tool.Activated:Connect(function()
	if not noteFrame.Visible then -- Checks if the note frame is already visible
		local mouse = player:GetMouse()
		local target = mouse.Target

		if target then
			local targetPosition = mouse.Hit.Position + Vector3.new(0, 1, 0) -- Adjusts Y to position above the surface
			showNoteFrame(targetPosition) -- Shows the note frame with the position
		end
	end
end)

confirmButton.MouseButton1Click:Connect(onConfirmButtonClicked) -- Connects the confirm button click
cancelButton.MouseButton1Click:Connect(onCancelButtonClicked) -- Connects the cancel button click

Here’s my explorer:

Bonus bug challenge:

This other script isn’t taking the text from my stickynotemodels’s text label in the surfacegui inside the stickynotemodel.

-- LocalScript for Opening the Sticky Note GUI

local openNoteFrame = script.Parent -- Reference to the GUI
local closeButton = openNoteFrame:WaitForChild("CloseButton") -- Reference to the close button
local noteTextLabel = openNoteFrame:WaitForChild("TextLabel") -- Reference to the TextLabel that will show the note's contents

-- Function to open the GUI and set the note text
local function openNoteGUI(noteText)
	openNoteFrame.Visible = true -- Show the note frame
	noteTextLabel.Text = noteText -- Set the note text in the GUI
end

-- Function to connect the ClickDetector to the openNoteGUI function
local function setupClickDetector(stickyNote)
	local clickDetector = stickyNote:FindFirstChild("ClickDetector")
	if clickDetector then
		clickDetector.MouseClick:Connect(function(player)
			local surfaceGui = stickyNote:FindFirstChild("SurfaceGui") -- Find the SurfaceGui in the sticky note
			if surfaceGui then
				local textLabel = surfaceGui:FindFirstChild("TextLabel") -- Find the TextLabel in the SurfaceGui
				if textLabel then
					openNoteGUI(textLabel.Text) -- Open the GUI with the text from the sticky note
				end
			end
		end)
	end
end

-- Set up the click detectors for existing StickyNoteModels in workspace
local function setupClickDetectors()
	for _, child in ipairs(workspace:GetChildren()) do
		if child:IsA("Part") and child.Name == "StickyNoteModel" then -- Check if it's a sticky note
			setupClickDetector(child)
		end
	end
end

-- Set up the click detectors initially
setupClickDetectors()

-- Hide the GUI when the close button is clicked
closeButton.MouseButton1Click:Connect(function()
	openNoteFrame.Visible = false
end)

-- Update the setupClickDetectors function to work with new notes
workspace.ChildAdded:Connect(function(child)
	if child:IsA("Part") and child.Name == "StickyNoteModel" then -- Ensure it's the correct model
		setupClickDetector(child)
	end
end)

So when I click on a note to see it more clearly in my opennotegui, its an empty note and the text isn’t displayed.

Any help is highly appreciated! I’ve spent over 4 hours trying to fix this without ever figuring it out so please lend me a hand with these bugs.