Combining Global and Local Space?

In my game I have a car. Originally I was only using:

transform.position += transform.forward * Time.deltaTime * -speed;

This works, until the car stops facing forward. If it goes up a ramp or points up, it takes off like a rocket into the air.
I’m trying to move my car forward using its local forward, but the global up and down rotation. I think this has something to do with Vector3, but I can’t seem to figure out the combination of the two. Any help would be welcome, thanks.

I can give you a different approach. You probably already have some way of collision detection.
To test for the surface orientation we are currently on, shoot a ray downwards.

Ray downwards = new Ray(transform.position, Vector3.down)

use that to make a test against the surface you are driving on.

RaycastHit hit;

if (Physics.Raycast(downwards , out hit, 1))
{
	// code for on the road
	// hit contains a lot of info, but especially we want to use the normal
	// that way we orient our object always along the normal we are driving on
	transform.up = hit.normal;
}

This will always align our car with the surface we are on. This is pretty rough when you go up or down slopes, you are better off with 2 downwards vectors and interpolate between them to smoothly go up or down slopes but you get the idea.

This is very basic and will not work in more complex cases, but then you would be better of with actual driving physics imo.