Bike stay upright based on surface normal

I’m having issues thinking of a good way to align my bike to the surface its riding on by modify the local z axis, without messing up the rigidbody simulation. I am able to get my bike to balance by modifying the transforms local euler angles as such:

var euler = transform.localEulerAngles;

// Only works for staying upright relative to ground plane
transform.localEulerAngles = new Vector3(euler.x, euler.y,  -steerLean);

The issue here is that when I go up a vert ramp the bike aligns, obviously, straight upwards. I cannot think of / recall a good way to keep the object upright but keep the rigidbody simulation intact otherwise.

I have tried to use Quaternion.FromtoRotation but this does not seem to want to play nicely. The object flops from left to right and eventually just falls over.

My bike uses WheelColliders and is working fine other than this issue.

Picture above for reference. The bike is moving and should be leaning to the right.

You can get the normal with WheelCollider.GetGroundHit.

You pass it a WheelHit and it fills it up with the current physics information, including the normal.

If both wheels are on the ground, to get the actually vector you want, you will have to average the two normal vectors.
Otherwise, just use the normal for the wheel that is touch the ground.(WheelCollider.GetGroundHit return false if the wheel is not touching the ground.)

Or…

Add mass for the bike and a possible rider and place at their respective centers of mass. If tuned correctly, gravity will pull the the bike to the right angle, balanced by the bikes force against the surface.

Set the local up angle of the bike to the above calculated normal.