A bracket amphitheater Specification
Write the shortest possible code in any language that does the following:
It takes two arguments, x and y, and generates x + y lines of text.
The first x lines should consist of y nested pairs of square brackets separated by a space surrounding a single digit, which cycles from 1 to 9, then 0 to 9, etc. from line to line.
The following y lines have the letter X in place of the digit and successively replace the innermost remaining pair of square brackets with spaces. The last line only contains the X, surrounded by spaces.
All output is ASCII.
You may choose to output a final newline (following a space), but you may also choose not to.
You may use either CR, CRLF, or LF as newline sequences.
The last line must contain an appropriate number of spaces following the central X.
The only valid inputs are positive integers. Zero is not a valid input.
You’re free to impose a reasonable, technically-driven limit on input size, even if the problem is solvable without. For instance, if there’s some function available for 16 bit integers that isn’t for bigints for some reason, and using it makes your program shorter, that’s a valid reason for a input size constraint.
Your code may reject invalid input or simply behave in any way on invalid input.
Examples
Example with x = 12, y = 8:
[ [ [ [ [ [ [ [ 1 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 2 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 3 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 4 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 5 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 6 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 7 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 8 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 9 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 0 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 1 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ 2 ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [   X   ] ] ] ] ] ] ]
[ [ [ [ [ [     X     ] ] ] ] ] ]
[ [ [ [ [       X       ] ] ] ] ]
[ [ [ [         X         ] ] ] ]
[ [ [           X           ] ] ]
[ [             X             ] ]
[               X               ]
                X                

Example with x = 5, y = 1
[ 1 ]
[ 2 ]
[ 3 ]
[ 4 ]
[ 5 ]
  X  

Example with x = 1, y = 10:
[ [ [ [ [ [ [ [ [ [ 1 ] ] ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [ [   X   ] ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [ [     X     ] ] ] ] ] ] ] ]
[ [ [ [ [ [ [       X       ] ] ] ] ] ] ]
[ [ [ [ [ [         X         ] ] ] ] ] ]
[ [ [ [ [           X           ] ] ] ] ]
[ [ [ [             X             ] ] ] ]
[ [ [               X               ] ] ]
[ [                 X                 ] ]
[                   X                   ]
                    X
Jelly,  33  27 bytes
-1 thanks to caird coinheringaahing (use of ))
Ø[j
%⁵Ç¡);”XÇ¡⁶i”];C$$¦ƬḊ¤G

A full program that accepts \$x\$ and \$y\$ and prints the result.
Try it online!
How?
Ø[j - Link 1, wrap in []: a
Ø[  - list of characters = ['[', ']']
  j - join (with a) = ['[', a, ']']

%⁵Ç¡);”XÇ¡⁶i”];C$$¦ƬḊ¤G - Main Link: x, y
    )                   - for each (v in [1..x]):
 ⁵                      -   ten
%                       -   (v) modulo (10)
   ¡                    -   repeat (y times):
  Ç                     -     call last Link (1) as a monad
                     ¤  - nilad followed by link(s) as a nilad:
      ”X                -   character = 'X'
         ¡              -   repeat (y times):
        Ç               -     call last Link (1) as a monad
                   Ƭ    -   loop until no change, collecting up inputs:
                  ¦     -     sparse application...
                 $      -     ...to (1-based) indices: last two links as a monad:
           i”]          -       first index of character ']' (call this i)
                $       -       last two links as a monad:
               C        -         complement -&gt; 1-i
              ;         -         concatenate -&gt; [i, 1-i]
          ⁶             -     ...of: space character (replaces innermost [] with spaces)
                    Ḋ   -   dequeue (remove the leading one with all []s present)
     ;                  - concatenate
                      G - format as a grid
                        - implicit print