Get angle between a vector and horizon (x,z plane)

So, I have a Vector3 vector v and I need to get the angle phi (in degrees) between it and the horizon (x,z plane). Obviously the correct way to do it would be to get v projection in x,z plane (Vector2(v.x , v.z)) and then calculate the angle between those 2 vectors.

However, the way I do it right now is:

float phi = Mathf.Asin(v.y / v.magnitude) * Mathf.Rad2Deg;

Height of a right-angle triangle divided by its hypotenuse equals sin of angle at its base. So, the angle at its base equals arcsin of height divided by hypotenuse.

Of course it gives an error when v.magnitude = 0.

So, I am asking, is there any better method of doing this?

This will get you the angle off level with the horizontal. with perfectly upright being 0 and upside down being 180. Does this meet your requirements?

    void Update()
    {
        Debug.Log(GetHorizonAngle());
    }

    float GetHorizonAngle()
    {
        return Math.Abs(Vector3.SignedAngle(Vector3.up, transform.up, transform.forward));
    }

Note:

If you want it to start at 90 at the poles are reduce to 0 as you rotate closer to the horizon you can do this instead:

Math.Abs(Vector3.SignedAngle(Vector3.up, transform.up, transform.forward) - 90.0f);