# cached_property works on normal classes; frozen dataclass is fine because # cached_property stores on the instance via object.__setattr__ internally.