There are two issues in afw::coord that I find confusing:
1) A plain Coord can be instantiated and converted to any other coordinate system, with the assumption being made that the plain Coord has the same coordinate system as the target system (hence the conversion will, at most, involve a precession).
2) Coord is being used as a generic spherical point in some places. For example Coord.offset and Coord.rotate both take a coord of any type, but the coordinate system and date are ignored. The implementation of afw::coord also contains a lot of usage of Coord as a spherical point, and the code would be cleaner we had a dedicated spherical point class.
My proposed solution is to make Coord pure virtual (so it cannot be instantiated) and to add a new class afw::geom::SphPoint that represents a spherical point.
I further propose that Coord contain a SphPoint rather than inherit from it. This allows Coord.offset and Coord.rotate to take a SphPoint, without the confusion of allowing the user to provide a Coord.
One question is whether SphPoint should be a unit vector or be a spatial vector with encoded distance (e.g. in au, with an upper limit on distance for objects at infinity). Supporting distance permits simple handling of parallax, proper motion and radial velocity. On the other hand, unit vectors are simple and suffice for our needs, and we should probably be using 3rd party packages for such fancy coordinate conversions. Thus I lean towards unit vectors, though I am happy to support distance. If we do support distance then may wish to make SphPoint a subclass of Point<double, 3>, to inherit useful methods.