This is driving me crazy :) I find it extraordinarily challenging to determine the absolute simplest way to specify that headings must be typeset in color, and switch to a different heading color at arbitrary points throughout the document.
Tue Dec 9 17:32:17 CET 2025: ... error: expected color, gradient, or tiling, found content
┌─ temp2.typ:3:30
│
3 │ #show heading: set text(fill: context mycolor.get())
│ ^^^^^^^^^^^^^^^^^^^^^
What am I missing? I just want to set things up so that I add a few lines of code wherever I want to change an accent/theme color that will apply to various types of content (including headings, as above).
The show-set rules are one-time rules, so after you apply it, it will not change anything. text.fill doesn’t take content, so you can’t inject dynamic content values. Which leaves you with show rule, that is applied for each element instance, but since it’s a callback/wrapper function, you can do dynamic stuff there, at the expense of the same show-set rules not working because of it.
#let mycolor = state("mycolor", red)
#mycolor.update(green)
#show heading: it => {
set text(fill: mycolor.get())
it
}
= #lorem(4)
#lorem(100)
#mycolor.update(blue)
= #lorem(4)
#lorem(100)
@Andrew’s answer is great and gets your code working as you expect, but I can’t help but think the code so far is not “the absolute simplest way to specify that headings must be typeset in color, and switch to a different heading color”.
Yeah, since I don’t know where else the mycolor state is used, I didn’t remove it. But if nowhere, then for sure it should be removed and just the show-set rule or its wrapper should be used directly instead.