Help With Rotating Server Viewmodel Around Shoulder Height

I’m currently working on an FPS game, and for the server sided visuals, I didn’t want to have to reanimate a bunch of viewmodel animations for the actual character, so I came up with a system that effectively creates a clone of the client’s viewmodel via serialization and remote events. It works great, it covers animations without me having to do any extra work, but I’m having trouble with making the viewmodel rotate up and down around a part that I have set in the character to be around shoulder height.

Current behavior:
https://streamable.com/8is2em

Current script (for context, sv is the part in the character that the viewmodel gets positioned to and rotated to on the z axis only, and rot is the part in the character at shoulder height I want the viewmodel to rotate up and down around):

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SerialBit = require(ReplicatedStorage:WaitForChild("SerialBit"))
local event = ReplicatedStorage:WaitForChild("ViewmodelUpdate")

event.OnServerEvent:Connect(function(player, serializedData)
	local char = player.Character
	if not char then return end


	if game.Workspace:FindFirstChild("ServerArms".. player.Name) then
		game.Workspace:FindFirstChild("ServerArms".. player.Name):Destroy()
	end
	local deserializedArms : Model = SerialBit.reconstruct(serializedData)[1]
	deserializedArms.Name = "ServerArms".. player.Name
	deserializedArms.Parent = workspace
	deserializedArms.VMArms["Left Arm"].Transparency = 1 
	deserializedArms.VMArms["Right Arm"].Transparency = 1
	deserializedArms["Left Arm"].Transparency = 0
	deserializedArms["Right Arm"].Transparency = 0


	deserializedArms:MoveTo(char.sv.Position)
	local currentCFrame = deserializedArms.PrimaryPart.CFrame 
	local _, _, currentZ = currentCFrame:ToEulerAnglesXYZ()
	local _, _, svZ = char.sv.CFrame:ToEulerAnglesXYZ()

	deserializedArms.PrimaryPart.CFrame = CFrame.new(currentCFrame.Position) * CFrame.Angles(0, 0, svZ)
	deserializedArms:ScaleTo(0.8)

	for _, limbName in pairs({"Left Arm", "Right Arm"}) do
		local limb = char:FindFirstChild(limbName)
		if limb and limb:IsA("BasePart") then
			limb.Transparency = 1
			limb.CanCollide = false
		end
	end
end)