([]<>){({}{}(({}[()])))}{}{({}()<(({})<{({}()<<>({}<>)>)}{}((()()()()()){})>)>)}{}{}{({}<>)<>}<>
Try it online!
Second solution, 96 bytes
(([]<>)<{({}({})({}[()]))}{}>){({}(({})<{({}()<<>({}<>)>)}{}((()()()()()){})>))}{}{}{({}<>)<>}<>
Try it online!
Explanation
Here I explain the first solution, both are the same length but I like the first one because it is cooler and employs some nice tricks.
The most important part of the code is a modified square root function I wrote some time ago. The original version was
{({}[({})({}())])}{}
And this works, but we actually want two copies of the negative square root.
Why? We need two copies because we are looping through the string at two levels, one to make the lines and one to count the number of lines. We want it to be negative because looping with negatives is cheaper.
To make this negative we move around the [...]
so it looks like this
{({}({})({}[()]))}{}
To make two copies we change when pops occur
{({}{}(({}[()])))}{}
Now that we have that bit we can put it together with a stack height to get the first chunk of code we need.
([]<>){({}{}(({}[()])))}{}
We move to the offstack because our square root function needs two free zeros for computation, and because it makes stuff a little bit cheaper int he future in terms of stack switching.
Now we construct the main loop
{({}()<(({})<{({}()<<>({}<>)>)}{}((()()()()()){})>)>)}{}{}
This is pretty straight forward, we loop n times each time moving n items and capping it with a new line (ASCII 10).
Once the loop is done we need to reverse the order of our output so we just tack on a standard reverse construct.
{({}<>)<>}<>