I need help with my deceleration only working with move direction and help with dash jumping

Godot Version

godot 4.2.2

Question

im trying to make a momentum based dash system but the decelaration is jagged and goes diagonally i suspect its he decelaration that uses the player movement vector oter than the velocity and i want to know how to fix it

thanks in advance :3

extends CharacterBody3D

#jump variables
var time_to_peak : float = 0.35
var j_height : float = 2.75
var descent : float = 0.3

var jumpvel : float = (2.0 * j_height) / time_to_peak
var grav : float = (-2.0 * j_height) / (descent * descent)
var jumpgrav : float = (-2.0 * j_height) / (time_to_peak * time_to_peak)

#walk variables
var currwalkspeed : float

var mwalkspeed : float = 8
var walkaccel : float = 0.6
var walkdecel : float = 0.8

var decel_dir : Vector2

#dash variables
var can_dash : bool = false
var dash_vel : float = 20

#debug variables
var debugged : bool = false

#cam variables
var sens : float = 0.003
@onready var pivot : Node3D = $neck
@onready var cam : Camera3D = $neck/giraffe_pivot/Camera3D

func getgrav():
	return jumpgrav if velocity.y > 0 else grav

# Called when the node enters the scene tree for the first time.
func _ready():
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _unhandled_input(event):
	if event is InputEventMouseMotion:
		pivot.rotate_y(-event.relative.x * sens)
		$neck/giraffe_pivot.rotate_x(-event.relative.y * sens)

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):

	var input_dir = Input.get_vector("a","d","w","s")
	var move_dir : Vector3 = (pivot.transform.basis * Vector3(input_dir.x,0,input_dir.y)).normalized()

	if move_dir:
		velocity.z = move_toward(velocity.z,mwalkspeed * move_dir.z,walkaccel)
		velocity.x = move_toward(velocity.x,mwalkspeed * move_dir.x,walkaccel)
	else:
		velocity.z = move_toward(velocity.z,0 * move_dir.z,walkdecel)
		velocity.x = move_toward(velocity.x,0 * move_dir.x,walkdecel) 

#jmp 
	if !is_on_floor():
		velocity.y += getgrav() * delta

	if is_on_floor() and Input.is_action_pressed("space"):
		velocity.y = jumpvel

	if Input.is_action_just_pressed("shift"):
		velocity.z = -pivot.global_basis.z.z * dash_vel
		velocity.x = -pivot.global_basis.z.x * dash_vel

	$CollisionShape3D.rotation.y = pivot.rotation.y
	$MeshInstance3D.rotation.y = pivot.rotation.y

	print(round(velocity))

	move_and_slide()

Separate the vertical velocity and operate over the entire vector instead of component-wise

var vertical_velocity := velocity.project(up_direction)
var horizontal_velocity := velocity - vertical_velocity

# for walking/stopping movement
var accel: float = walkaccel if move_dir else walkdecel
horizontal_velocity = horizontal_velocity.move_toward(mwalk_speed * move_dir, accel * delta)

# for setting speed by dash
var flat_forward := pivot.global_basis.z
flat_forward.y = 0
flat_forward = flat_forward.normalize()
# or just use -pivot.global_basis.z if you don't tilt the pivot object 
horizontal_velocity = -flat_forward * dash_vel

# re-combine into velocity before using `move_and_slide()`
velocity = horizontal_velocity + vertical_velocity
move_and_slide()

The jagged diagonal movement comes from decelerating velocity.x and velocity.z separately. Instead, decelerate the horizontal velocity as one Vector3, so its direction stays consistent while the speed decreases. This should make the dash slowdown much smoother.