#let counter-family(id) = {
  let parent = counter(id)
  let parent-step() = parent.step()
  let get-child() = counter(id + str(parent.get().at(0)))
  return (parent-step, get-child)
}

#let default-border = (
  // The starting and ending lines
  above: line(length: 100%),
  below: line(length: 100%),
  // Lines to put between the box over multiple pages
  btwn-above: line(length: 100%, stroke: (dash:"dotted")),
  btwn-below: line(length: 100%, stroke: (dash:"dotted")),
  // Left/right lines
  // These *must* use `grid.vline()`, otherwise you will get an error.
  // To remove the lines, set them to: `grid.vline(stroke: none)`.
  // You could probably configure this better with a rowspan, but I'm lazy.
  left: grid.vline(),
  right: grid.vline(),
)

// Create a box for content which spans multiple pages/columns and
// has custom borders above and below the column-break.
#let split-box(
  // Set the border dictionary, see `default-border` above for options
  border: default-border,
  // The cell to place content in, this should resolve to a `grid.cell`
  cell: grid.cell.with(inset: 5pt),
  // The last positional arg or args are your actual content
  // Any extra named args will be sent to the underlying grid when called
  // This is useful for fill, align, etc.
  ..args
) = {
  // See `utils.typ` for more info.
  let (parent-step, get-child) = counter-family("split-box-unique-counter-string")
  parent-step() // Place the parent counter once.
  // Keep track of each time the header is placed on a page.
  // Then check if we're at the first placement (for header) or the last (footer)
  // If not, we'll use the 'between' forms of the  border lines.
  let border-above = context {
    let header-count = get-child()
    header-count.step()
    context if header-count.get() == (1,) { border.above } else { border.btwn-above }
  }
  let border-below = context {
    let header-count = get-child()
    if header-count.get() == header-count.final() { border.below } else { border.btwn-below }
  }
  // Place the grid!
  grid(
    ..args.named(),
    columns: 3,
    border.left,
    grid.header(border-above , repeat: true),
    ..args.pos().map(cell),
    grid.footer(border-below, repeat: true),
    border.right,
  )
}
