With 0.12, we got the ability to add multi-column floats, and using set page(columns: ..)
is now the recommended way of styling things, even when there are page-spanning elements on the page – see e.g. Line numbering behavior and page layout - #2 by xkevio or this comment on a related Github issue.
This means that the question can now be cleanly answered like this (also demonstrating how to style the outline heading):
// this is only to make the outline's columns fill up
// more quickly, so that I need to generate fewer headings
#set page(paper: "a5", flipped: true)
#set page(columns: 2)
#set heading(numbering: "1.")
#place(top, float: true, scope: "parent")[
(you can even have stuff before the outline' heading,
just also `place()` it at the top before the outline)
]
#{
// this show rule is scoped to the outline, which means
// it only affects a single heading
show heading: it => {
set block(
stroke: (top: 2pt),
inset: (top: 0.4em),
width: 100%,
)
// THE IMPORTANT BIT: place the outline heading at
// the top of the page, spanning both columns
place(top, float: true, scope: "parent", upper(it))
}
outline()
}
#pagebreak()
// uncomment this if only the outline show be two-column
// #set page(columns: 1)
// some example content
#for section in lorem(5).split(" ") [
= #section
#for subsection in lorem(6).split(" ") [
== #subsection
#lorem(10)
]
]