From 7a221972639dad85f0f673f7b5d003b57a3be139 Mon Sep 17 00:00:00 2001 From: noradefitero Date: Mon, 19 Oct 2026 05:11:15 +0200 Subject: [PATCH 1/8] ci(publish): resolve tag name for workflow_call runs --- .github/workflows/publish.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 794fbb9..5868f12 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,8 +7,14 @@ on: workflow_dispatch: # Called by release-please: tags/releases made with GITHUB_TOKEN - # do not trigger push/release events (recursive trigger guard) + # do not trigger push/release events (recursive trigger guard), + # so the tag name must be passed in as an input. workflow_call: + inputs: + tag: + description: Tag created by release-please + type: string + required: false permissions: contents: write @@ -31,3 +37,6 @@ jobs: with: working_directory: dist body_path: CHANGELOG.md + # workflow_call has no tag ref (runs on main), so use the + # release-please input; direct tag pushes use github.ref_name. + tag_name: ${{ inputs.tag || startsWith(github.ref, 'refs/tags/') && github.ref_name || '' }} From 896c1d8adfa4dc006fa20be97b1051430245dd16 Mon Sep 17 00:00:00 2001 From: noradefitero Date: Mon, 19 Oct 2026 05:11:17 +0200 Subject: [PATCH 2/8] ci(release-please): pass tag_name output to publish --- .github/workflows/release-please.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 6c81102..b998924 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -15,6 +15,7 @@ jobs: pull-requests: write outputs: release_created: ${{ steps.release.outputs.release_created }} + tag_name: ${{ steps.release.outputs.tag_name }} steps: - id: release uses: googleapis/release-please-action@v5 @@ -30,6 +31,8 @@ jobs: needs: release-please if: needs.release-please.outputs.release_created == 'true' uses: $/.github/workflows/publish.yml + with: + tag: ${{ needs.release-please.outputs.tag_name }} permissions: contents: write From eaa041bd031ba01c1f8fd46e9b39ce10175b2768 Mon Sep 17 00:00:00 2001 From: noradefitero Date: Mon, 19 Oct 2026 05:12:28 +0200 Subject: [PATCH 3/8] ci(pages): pin setup-uv to a hash and disable caching --- .github/workflows/page.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/page.yml b/.github/workflows/page.yml index 40a8be3..3ff5e0d 100644 --- a/.github/workflows/page.yml +++ b/.github/workflows/page.yml @@ -38,7 +38,11 @@ jobs: run: sudo apt-get update && sudo apt-get install -y pandoc - uses: actions/setup-python@v5 - name: Install uv - uses: astral-sh/setup-uv@v6 + # Pinned to hash (blanket policy); bump comment when updating + uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0 + with: + # Publish workflow: never read from the Actions cache + enable-cache: false - name: Make docs run: make web - uses: actions/configure-pages@v5 From f4743fc2e307b7810cc0edf72641c871982af22f Mon Sep 17 00:00:00 2001 From: noradefitero Date: Mon, 19 Oct 2026 05:25:22 +0200 Subject: [PATCH 4/8] ci: pin pandoc 3.12.1 so gfm alerts render Ubuntu 24.04 ships pandoc 3.1.3, which predates the gfm alerts extension (3.1.10): > [!NOTE] callouts were built as literal blockquotes, so yeti.lua never turned them into styled alerts on the web, and the release PDF/MD hit the same path. Install the official 3.12.1 tarball instead of the apt package in page, publish and readme; publish keeps apt for texlive and librsvg. --- .github/workflows/page.yml | 10 +++++++++- .github/workflows/publish.yml | 12 +++++++++++- .github/workflows/readme.yml | 10 ++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.github/workflows/page.yml b/.github/workflows/page.yml index 3ff5e0d..7793f17 100644 --- a/.github/workflows/page.yml +++ b/.github/workflows/page.yml @@ -35,7 +35,15 @@ jobs: with: persist-credentials: false - name: Install pandoc - run: sudo apt-get update && sudo apt-get install -y pandoc + env: + # Pinned: Ubuntu's apt pandoc predates the gfm `alerts` extension, + # so > [!NOTE] callouts would ship as literal text. + PANDOC_VERSION: "3.12.1" + run: | + curl -fsSL -o /tmp/pandoc.tar.gz \ + "https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-linux-amd64.tar.gz" + sudo tar -xzf /tmp/pandoc.tar.gz -C /usr/local --strip-components=1 + pandoc --version - uses: actions/setup-python@v5 - name: Install uv # Pinned to hash (blanket policy); bump comment when updating diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5868f12..93866c9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -27,9 +27,19 @@ jobs: with: persist-credentials: false - name: Install pandoc + env: + # Pinned: Ubuntu's apt pandoc predates the gfm `alerts` extension, + # so > [!NOTE] callouts would ship as literal text. + PANDOC_VERSION: "3.12.1" + run: | + curl -fsSL -o /tmp/pandoc.tar.gz \ + "https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-linux-amd64.tar.gz" + sudo tar -xzf /tmp/pandoc.tar.gz -C /usr/local --strip-components=1 + pandoc --version + - name: Install LaTeX run: | sudo apt-get update - sudo apt-get install -y pandoc texlive texlive-latex-extra texlive-fonts-extra texlive-fonts-recommended librsvg2-bin + sudo apt-get install -y texlive texlive-latex-extra texlive-fonts-extra texlive-fonts-recommended librsvg2-bin - name: Make docs run: make pdf markdown - name: Release MD and PDF diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml index a1e0da4..7f26f78 100644 --- a/.github/workflows/readme.yml +++ b/.github/workflows/readme.yml @@ -24,9 +24,15 @@ jobs: ref: ${{ github.event.repository.default_branch }} persist-credentials: false - name: Install pandoc + env: + # Pinned: Ubuntu's apt pandoc predates the gfm `alerts` extension, + # so > [!NOTE] callouts would ship as literal text. + PANDOC_VERSION: "3.12.1" run: | - sudo apt-get update - sudo apt-get install -y pandoc + curl -fsSL -o /tmp/pandoc.tar.gz \ + "https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-linux-amd64.tar.gz" + sudo tar -xzf /tmp/pandoc.tar.gz -C /usr/local --strip-components=1 + pandoc --version - name: Generate README.md run: make readme - name: Commit README.md From 67c3315082cb1aaefcbf73a00670cb37d7b6c8d2 Mon Sep 17 00:00:00 2001 From: noradefitero Date: Mon, 19 Oct 2026 05:32:33 +0200 Subject: [PATCH 5/8] feat: links to pdf and web version in markdown targets --- src/template/md.tex | 5 +++++ src/template/readme_md.tex | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/template/md.tex b/src/template/md.tex index 667c605..fc20ad9 100644 --- a/src/template/md.tex +++ b/src/template/md.tex @@ -1,4 +1,9 @@ +

+ PDF Version +Web Version +

+

$if(titlepage-logo)$ $title$ diff --git a/src/template/readme_md.tex b/src/template/readme_md.tex index 63980bc..81d9f86 100644 --- a/src/template/readme_md.tex +++ b/src/template/readme_md.tex @@ -1,7 +1,9 @@

- Get the PDF version of this documentation! Download manual.pdf + PDF Version +Web Version

+

$if(titlepage-logo)$ $title$ From fe5b269aa9b7c064ef02586a13c7bc5719a486dc Mon Sep 17 00:00:00 2001 From: noradefitero Date: Mon, 19 Oct 2026 06:52:15 +0200 Subject: [PATCH 6/8] ci(readme): restore push credentials for add-and-commit persist-credentials: false leaves add-and-commit's git push with no credentials (its github_token input is API-only), so re-add the auth header checkout omits before the commit step. --- .github/workflows/readme.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml index 7f26f78..c78ba35 100644 --- a/.github/workflows/readme.yml +++ b/.github/workflows/readme.yml @@ -35,6 +35,15 @@ jobs: pandoc --version - name: Generate README.md run: make readme + - name: Configure push credentials + # add-and-commit pushes with plain git, and its github_token input is + # API-only, so restore the auth header that checkout omits when + # persist-credentials is false. + env: + GH_TOKEN: ${{ github.token }} + run: | + git config --local http.https://github.com/.extraheader \ + "AUTHORIZATION: basic $(printf 'x-access-token:%s' "$GH_TOKEN" | base64 | tr -d '\n')" - name: Commit README.md uses: EndBug/add-and-commit@v11 with: From 4912efa183043aca44bb16957b4f8cb81b746613 Mon Sep 17 00:00:00 2001 From: noradefitero Date: Mon, 19 Oct 2026 06:53:08 +0200 Subject: [PATCH 7/8] fix(web): repair mobile layout in the manual template Two root causes made the site unusable on phones: - The contents was a Yi/e/Yeti .card, whose author rule (display: flex) outranks the user-agent rule that hides a closed popover, so the shut drawer painted as a full-screen card over the page. Declare the closed state explicitly (#toc:not(:popover-open) { display: none }) and keep the sticky sidebar only from 64rem up. - The build minifier escapes "<" inside inlined CSS, deleting whole @media (width < Nrem) blocks; the hamburger vanished on landscape phones and tablets. Rewrite every condition in the "at least" form so it survives minification. Also hide the nav actions (GitHub, Download PDF) below 48rem so the brand and hamburger fit, and drop leftover draft CSS from style.css. --- src/template/web/index.html | 2 +- src/template/web/style.css | 43 +++++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/template/web/index.html b/src/template/web/index.html index fb3153b..b632b32 100644 --- a/src/template/web/index.html +++ b/src/template/web/index.html @@ -32,7 +32,7 @@ -

+
button[popovertarget] { - display: inline-flex; - } +/* Keep the contents hamburger visible below 64rem. Yeti shows it from its nav + base rules, but drops it again once the nav's own container passes 32rem — + which would strand the drawer on a landscape phone or small tablet. */ +.nav > button[popovertarget] { + display: inline-flex; } @media (width >= 64rem) { @@ -37,6 +38,22 @@ } } +/* Nav actions (GitHub, Download PDF) belong to 48rem and up; on a phone only + the brand and the hamburger fit. This is what Yeti's [data-show="lg"] + utility would do, but the build's minifier mangles the less-than sign in + that utility's container query — and turns a less-than sign in a media + query here into an escaped one that drops the whole block — so every + condition in this file has to be written the "at least" way round. */ +.nav > [data-actions] { + display: none; +} + +@media (width >= 48rem) { + .nav > [data-actions] { + display: flex; + } +} + /* ---------- 3. Page head ---------- */ .page-head { border-block-end: var(--yeti-border-width) solid var(--yeti-color-border); @@ -103,6 +120,17 @@ border-inline-start-width: 0; /* no marker bar on the entry being read */ } +/* Closed state. The browser hides a closed popover itself, but only with a + user-agent rule — and #toc is a .card, whose author rule (display: flex) + outranks it, which used to leave a full-screen contents card in the page on + a phone. So the closed state is declared here; at 64rem and up the rule + below turns the same element into the sticky sidebar instead. */ +#toc:not(:popover-open) { + display: none; +} + +/* Open state on a phone: a drawer down the left edge, over a dimmed backdrop. + Light dismiss, Escape and the inlined link handler close it. */ #toc:popover-open { display: block; position: fixed; @@ -142,7 +170,7 @@ var(--yeti-space-md) ); } - #toc { + #toc:not(:popover-open) { display: block; max-block-size: calc( 100dvh - var(--yeti-scroll-padding) - var(--yeti-space-lg) @@ -235,7 +263,7 @@ /* ---------- 7. Figures ---------- */ .manual > p:has(> img) { margin-block-start: var(--yeti-space-xl); - padding: var(--yeti-space-lg); + padding: var(--yeti-space-sm); border: var(--yeti-border-width) solid var(--yeti-color-border); border-radius: var(--yeti-radius-md); background-color: light-dark( @@ -347,9 +375,6 @@ .site-footer .card::before { display: none; } - .manual > p:has(> img) { - box-shadow: none; - } .manual pre.sourceCode { white-space: pre-wrap; overflow: visible; From 7283117e168572403dce412e4f936c82d5f89db5 Mon Sep 17 00:00:00 2001 From: noradefitero Date: Mon, 19 Oct 2026 06:53:08 +0200 Subject: [PATCH 8/8] fix(web): repair mobile layout in the manual template Two root causes made the site unusable on phones: - The contents was a Yeti .card, whose author rule (display: flex) outranks the user-agent rule that hides a closed popover, so the shut drawer painted as a full-screen card over the page. Declare the closed state explicitly (#toc:not(:popover-open) { display: none }) and keep the sticky sidebar only from 64rem up. - The build minifier escapes "<" inside inlined CSS, deleting whole @media (width < Nrem) blocks; the hamburger vanished on landscape phones and tablets. Rewrite every condition in the "at least" form so it survives minification. Also hide the nav actions (GitHub, Download PDF) below 48rem so the brand and hamburger fit, and drop leftover draft CSS from style.css. --- src/template/web/index.html | 2 +- src/template/web/style.css | 43 +++++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/template/web/index.html b/src/template/web/index.html index fb3153b..b632b32 100644 --- a/src/template/web/index.html +++ b/src/template/web/index.html @@ -32,7 +32,7 @@ -
+
button[popovertarget] { - display: inline-flex; - } +/* Keep the contents hamburger visible below 64rem. Yeti shows it from its nav + base rules, but drops it again once the nav's own container passes 32rem — + which would strand the drawer on a landscape phone or small tablet. */ +.nav > button[popovertarget] { + display: inline-flex; } @media (width >= 64rem) { @@ -37,6 +38,22 @@ } } +/* Nav actions (GitHub, Download PDF) belong to 48rem and up; on a phone only + the brand and the hamburger fit. This is what Yeti's [data-show="lg"] + utility would do, but the build's minifier mangles the less-than sign in + that utility's container query — and turns a less-than sign in a media + query here into an escaped one that drops the whole block — so every + condition in this file has to be written the "at least" way round. */ +.nav > [data-actions] { + display: none; +} + +@media (width >= 48rem) { + .nav > [data-actions] { + display: flex; + } +} + /* ---------- 3. Page head ---------- */ .page-head { border-block-end: var(--yeti-border-width) solid var(--yeti-color-border); @@ -103,6 +120,17 @@ border-inline-start-width: 0; /* no marker bar on the entry being read */ } +/* Closed state. The browser hides a closed popover itself, but only with a + user-agent rule — and #toc is a .card, whose author rule (display: flex) + outranks it, which used to leave a full-screen contents card in the page on + a phone. So the closed state is declared here; at 64rem and up the rule + below turns the same element into the sticky sidebar instead. */ +#toc:not(:popover-open) { + display: none; +} + +/* Open state on a phone: a drawer down the left edge, over a dimmed backdrop. + Light dismiss, Escape and the inlined link handler close it. */ #toc:popover-open { display: block; position: fixed; @@ -142,7 +170,7 @@ var(--yeti-space-md) ); } - #toc { + #toc:not(:popover-open) { display: block; max-block-size: calc( 100dvh - var(--yeti-scroll-padding) - var(--yeti-space-lg) @@ -235,7 +263,7 @@ /* ---------- 7. Figures ---------- */ .manual > p:has(> img) { margin-block-start: var(--yeti-space-xl); - padding: var(--yeti-space-lg); + padding: var(--yeti-space-sm); border: var(--yeti-border-width) solid var(--yeti-color-border); border-radius: var(--yeti-radius-md); background-color: light-dark( @@ -347,9 +375,6 @@ .site-footer .card::before { display: none; } - .manual > p:has(> img) { - box-shadow: none; - } .manual pre.sourceCode { white-space: pre-wrap; overflow: visible;