Are you sure you need to reproject? NAVD88 should be in Survey (US) Feet, last I checked. We use the same here, as well.
I also see that you used to just use the attribute table, rather than the back-end Z-coordinates. First dumb question: Are you actually using the back-end coordinates, now?
One quick way to check would be with an arcpy cursor:
Change lines 1 & 5 with the path to your FC and the name of your attribute table elevation field, respectively.
fc = 'path_to_your_feature_class'
max_features = 50 # This is just to run on a subset, rather than everything
count = 0 # Subset testing
with arcpy.da.SearchCursor(fc, ['OID@', 'SHAPE@', 'ElevationField']) as cursor:
for oid, geo, elevAttr in cursor:
count += 1 # Subset testing
if count >= max_features: # Subset testing
break # Subset testing
arcpy.AddMessage(f'{oid}\n ({geo.firstPoint.X}, {geo.firstPoint.Y}, {geo.firstPoint.Z})\n ({elevAttr})\n')
You should get something like the following:
(I ran this on a test dataset that doesn't have any elevation values populated, so the 0.0 is expected, in my case).
The first row is the actual X, Y, Z of a point in your feature class. If it's a line or polygon, it'll be the first vertex.
The second row is the Z value in your elevation attribute field.
If that last value on row 1 doesn't match the number that's by itself, then that's your problem. ArcGIS can only project things based on those hidden back-end coordinates. Anything in the attribute table is just for show.