How can I style list bullets and enum numbers so that their layout matches exactly?

I would like to style the enum to give numbers in colored blocks which align with those from the list:

#import "@preview/polylux:0.4.0": *

#set page(height: auto, width: 3cm)

#set list(
  spacing: 0.0em,
  indent: 0.5em,
  body-indent: 0.5em,
  marker: (
    sym.square.filled,
    sym.square
  ),
)

#set enum(
  spacing: 0.0em,
  indent: 0.57em,
  body-indent: 0.56em,
  numbering: n =>
    box(baseline: 0.66em,
      rect(
        fill: blue,
        width: 0.45em,
        height: 0.45em,
        inset: 0em,
      text(
          fill: white,
          weight: 900,
          size: 0.5em,
          style: "italic",
          [#n]
      )
    )
  )
)

#slide[
  #only(1)[
    #grid(columns: (1fr,1fr))[
    - a
    - a
    - a
    - a
    - a
    - a
    ][
    + a
    + a
    + a
    + a
    + a
    + a
    ]
  ]
  #only(2)[
    #grid(columns: (1fr,1fr))[
    + a
    + a
    + a
    + a
    + a
    + a
    ][
    - a
    - a
    - a
    - a
    - a
    - a
    ]
  ]
]

Which yields something quite close, but (in slides) it’s clear that these are not exactly right. I have tweaked this manually, but suspect there is a better way. Is there a better way for each colored block to precisely align across lists and enum (for the same content, obviously), so that each colored block should appear in both slides in the precise same spot? I realize this is a very specific kind of issue.

I’m sure there’s a better syntax out here (by writing a show rule specifically for lists and enums in grids, but you can just rely on the grid for alignment instead.

Writing the boxed number is a bit tricky due to baseline/size, which I am not familiar with but you can get away with the following:

#import "@preview/polylux:0.4.0": *
#set page(height: auto, width: 3cm)

#let m(body) = (sym.square.filled, body)
#let n(i, body) = (
  place(bottom+left, dx: .8pt,
    rect(
    fill: blue,
    width: .165cm,
    height: .165cm,
    inset: 0pt,
    outset: 0pt,
    place(top+right, dy: 1pt,
      text(
          fill: white,
          weight: 900,
          size: 0.5em,
          style: "italic",
          top-edge: "x-height",
          [#i]
      )
    )
  )),
  body
)
#slide[
  #only(1)[
    #grid(columns: (1fr,1fr,1fr,1fr), row-gutter: .2em,
      ..m[a], ..n(1)[a],
      ..m[a], ..n(2)[a],
      ..m[a], ..n(3)[a],
      ..m[a], ..n(4)[a],
      ..m[a], ..n(5)[a],
    )
  ]
  #only(2)[
    #grid(columns: (1fr,1fr,1fr,1fr), row-gutter: .2em,
      ..n(1)[a], ..m[a], 
      ..n(2)[a], ..m[a], 
      ..n(3)[a], ..m[a], 
      ..n(4)[a], ..m[a], 
      ..n(5)[a], ..m[a], 
    )
  ]
]


You could use an enum for both the list and the actual enum. In the “list” you would then just hide the regular numbering and replace it with a symbol of your choice. This will automatically give you the perfect alignment. I used the function highlight() here to style the numbers, but you could also use your custom rectangle here instead. By using hide(num) for the “list”, the positioning should always work.

#let enum-numbering(n, show-num: true) = {
  let num = highlight(fill: blue, extent: 3pt, text(style: "italic", fill: white, str(n)))
  if show-num {
    num
  } else {
    hide(num)
    place(center + horizon, sym.square.filled)
  }
}

#set enum(spacing: 0.5em, numbering: enum-numbering)
#let dot-enum = enum.with(numbering: enum-numbering.with(show-num: false))


#slide[
  #only(1)[
    #grid(columns: (1fr,1fr))[
      #dot-enum(..("a",) * 6)
    ][
      #enum(..("a",) * 6)
    ]
  ]
  #only(2)[
    #grid(columns: (1fr,1fr))[
      #enum(..("a",) * 6)
    ][
      #dot-enum(..("a",) * 6)
    ]
  ]
]
This is what it will actually look like