Transparent grid shader issue

I have 2 planes (default mesh filter) with a custom shader to render. The shader should render it as a transparent grid, and generally it does, but it bugs out.

When looking at them from the side, they look just fine. However, if I slightly tilt the camera, the front pane becomes (semi?)opaque and back pane loses it’s horizontal stripes.

This is my first attempt at shaders, so I’m most likely doing something incredibly stupid, this is what happens.

In play mode, even without having a back panel, it’s fully opaque no matter the settings.

This is my shader code:

Shader "Custom/GridShader" {
	Properties {
		_CellSize ("Grid cell size", Float) = 0.5
		_LineWidth ("Grid line width", Float) = 0.1
		_GridColor ("Color", Color) = (1, 1, 1, 1)
	}
	SubShader {
		Tags { "RenderType" = "Transparent" "Queue" = "Transparent" }
		pass
		{
			Cull Back
			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
 
			struct VertIn
			{
				float4 vertex : POSITION;
			};
 
			struct VertOut
			{
				float4 position : POSITION;
				float3 locpos : TEXCOORD0;
			};

			float _CellSize;
			float _LineWidth;
			float4 _GridColor;
 
			VertOut vert(VertIn input)
			{
				VertOut output;
				output.position = mul(UNITY_MATRIX_MVP, input.vertex);
				output.locpos = input.vertex.xyz;
				return output;
			}

			float getGridFact(float pos)
			{
				float snapPos = round(pos / _CellSize) * _CellSize;
				float dist = abs(snapPos - pos);
				return 1 - min(1.f, dist * 2.f / _LineWidth);
			}

			float4 frag(VertOut i) : COLOR
			{
				float factX = getGridFact(i.locpos.x);
				float factZ = getGridFact(i.locpos.z);
				return _GridColor * float4(1.f, 1.f, 1.f, factX + factZ - (factX * factZ));
			}
			ENDCG
		}
	} 
	FallBack "Diffuse"
}

Does anybody know what’s going on, and why this is happening?

Best I can tell, the z-coordinate is getting messed up somewhere between the vertex and fragment shaders. But I have no idea why… That code should work, to the best of my knowledge.

Maybe try storing it as a float2, and passing input.vertex.xz in the vertex shader and modify the fragment shader to use xy instead of xz?