Make it more generic
Summing is a very specific operation. What if you want to calculate the product of all elements instead? Or get the minimum or maximum value? Instead of hardcoding the operation, create a recursive_reduce() that works like std::reduce(). You can still have it sum by default if you don't specify which operation to perform.
Associativity and initial values
Note that the order in which you perform operations matters. While operator+ is often associative, it doesn't have to be. That's why in C++23, std::ranges::fold_left() and std::ranges::fold_right() were introduced.
Furthermore, some value types might not have a default constructor, thus sun_output{} might not compile. This is why most algorithms in the STL that perform some kind of reduction take an initial value as a parameter. I recommend you add that here as well.
Sometimes you know the input is non-empty, and you want to avoid providing an initial values. C++23 introduced std::ranges::fold_left_first() and related functions for this purpose.
Meaning of the unwrap level
I was surprised by the fact that your recursive_sum() uses recursive_transform() internally, and by the output from your example code. I would rather have expected the following:
std::vector<std::string> words = {"foo", "bar", "baz", "quux"};
std::cout << recursive_sum<2>(words) << '\n';
std::cout << recursive_sum<1>(words) << '\n';
To output:
:
foobarbazquux
Basically, the call to recursive_sum<2>(words) would unwrap two levels, so it would iterate over the characters in each string, whereas recursive_sum<1>(words) would unwrap only the vector, and add the strings together.
I think that would be more logical. Also consider math libraries that have vector and matrix types that can be iterated over; sometimes you want to sum the elements of a matrix, sometimes you want to sum matrices together, but your code will always sum the innermost elements.
If you want your original behavior, the caller could combine recursive_transform() and recursive_sum() themselves.