Overlapping String-Blocks Challenge:

Given a list of multi-line strings, overlap them (in the top-left) and output the result.

Example:

Input: ["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]
Output:

cbaa
bbaa
bbaa
aaaa


Challenge rules:


Input-format is flexible. You are allowed to get the input as a 2D list of lines (i.e. [["aaaa","aaaa","aaaa","aaaa"],["bb","bb","bb"],["c"]]) or 3D list of characters (i.e. [[["a","a","a","a"],["a","a","a","a"],["a","a","a","a"],["a","a","a","a"]],[["b","b"],["b","b"],["b","b"]],[["c"]]]). You are allowed to take all the inputs one by one through STDIN. Etc.
Output format is strict. You can choose to print or return the multi-line string. (If your language doesn't have any strings, outputting as a 2D list of characters is allowed as alternative. But only if your language doesn't have strings at all.)
The order of the input-list is of course important (but you are allowed to take the input in reverse if you choose to).
Inputs will only contain printable ASCII in the unicode range \$[33,126]\$ (!"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~).
Inputs will only be rectangles (so no weird shapes). The output aren't necessary rectangles, though.
Trailing spaces and a single trailing newline is allowed. Leading spaces and/or newlines not.


General rules:


This is code-golf, so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
Default Loopholes are forbidden.
If possible, please add a link with a test for your code (i.e. TIO).
Also, adding an explanation for your answer is highly recommended.


Test cases:

Input: ["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]
Output:

cbaa
bbaa
bbaa
aaaa


Input: ["12345\n54321","00\n00\n00\n00","001\n011\n012"]
Output:

00145
01121
012
00


Input: ["sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&amp;*()_+\nqwerty\nuiopas","this\nis_a\ntest"]
Output:

this%^
is_a_+
testty
uiopas
t!
h_
i_
n_
g_
JavaScript (Node.js), 24 bytes

Saved 2 bytes thanks to @Grimy

Assumes that the returned string is printed on a terminal that supports ANSI escape codes. Contains the unprintable character ESC, which is escaped (no pun intended) as \x1B below.



a=&gt;`\x1B[2J\x1B[H`+a.join`\x1B[H`


This doesn't work on TIO, but you can Try it online! to see the raw output instead.

How?

The CSI sequences used are:


ED (Erase in Display):

ESC[2J

where \$2\$ means "clear entire screen"
CUP (Cursor Position):

ESC[H

which means "moves the cursor to row \$n\$, column \$m\$" where both \$n\$ and \$m\$ are omitted and implicitly set to \$1\$ (top-left corner of the screen).


Example output