From 7a3bb67307392ad33da377de0dd2bc2bddfbeebb Mon Sep 17 00:00:00 2001 From: onmax Date: Thu, 12 Nov 2026 13:13:28 +0100 Subject: [PATCH 1/5] fix(docs): draw the landing tabs' raised pill before hydration Reka positions the tabs' indicator in the browser, so the server's HTML has none. Until then Nuxt UI draws a pill behind the active trigger with the color's default, bg-inverted, which made a black block over "For humans" and "pnpm" until the app hydrated. That pill now gets the indicator's look. --- docs/app/components/content/LandingHero.vue | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/app/components/content/LandingHero.vue b/docs/app/components/content/LandingHero.vue index 8241cf74..098e357e 100644 --- a/docs/app/components/content/LandingHero.vue +++ b/docs/app/components/content/LandingHero.vue @@ -20,10 +20,17 @@ const command = computed(() => { ]; return `${add} ${packages.value}`; }); -// A raised pill on a muted track, as a segmented control. +// A raised pill on a muted track, as a segmented control. The indicator renders only in the browser. Until then Nuxt +// UI draws the active tab's pill behind its trigger, so that pill gets the same look. Tailwind finds classes by their +// full text, so the variant is written out each time. const segmented = { indicator: "bg-default shadow-xs ring ring-default", - trigger: "data-[state=active]:text-highlighted!", + trigger: [ + "data-[state=active]:text-highlighted!", + "in-[[data-slot=list]:not(:has([data-slot=indicator]))]:data-[state=active]:before:bg-default", + "in-[[data-slot=list]:not(:has([data-slot=indicator]))]:data-[state=active]:before:ring", + "in-[[data-slot=list]:not(:has([data-slot=indicator]))]:data-[state=active]:before:ring-default", + ].join(" "), }; const copied = ref(false); let copiedTimer: ReturnType | undefined; From 3c6fd2080f624441c8b24deea6dfadd8933fdb27 Mon Sep 17 00:00:00 2001 From: onmax Date: Thu, 12 Nov 2026 13:13:28 +0100 Subject: [PATCH 2/5] fix(docs): draw an HTML-only block inside a paragraph in a span @vite-hub/docs marks an HTML-only block inside a paragraph, such as a comments suggestion, as inline. The site's own ComarkHtml ignored that and drew a div, which ends the paragraph in the server's HTML, so the comments pages logged a hydration mismatch. It also wrote blockProps as a "[object Object]" attribute. --- docs/app/components/ComarkHtml.vue | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/app/components/ComarkHtml.vue b/docs/app/components/ComarkHtml.vue index d2a0e7f9..da00a50f 100644 --- a/docs/app/components/ComarkHtml.vue +++ b/docs/app/components/ComarkHtml.vue @@ -2,8 +2,15 @@ import { onMounted, ref, watch } from "vue"; // A block that has only an HTML renderer (annotate, diff, quiz, comments), drawn on the server by docs/markdown.ts. -// `block` is its tag, so a page's styles can tell a diff from a screenshot without looking inside. -const props = defineProps<{ html: string; block?: string }>(); +// `block` is its tag, so a page's styles can tell a diff from a screenshot without looking inside. A block inside a +// paragraph, such as a suggestion, is `inline` and draws in a `span`, since a `div` would end the paragraph. +// `blockProps` holds the block's attributes, which the HTML already carries, so they don't land on the element. +const props = defineProps<{ + html: string; + block?: string; + blockProps?: Record; + inline?: boolean; +}>(); const root = ref(); // Scripts inserted by v-html are inert. Recreate them after mounting or replacing the HTML; the package runtimes @@ -21,5 +28,6 @@ watch(() => props.html, runScripts, { flush: "post" }); From 651c74674daf8159302023bc8cba9b311abef633 Mon Sep 17 00:00:00 2001 From: onmax Date: Thu, 12 Nov 2026 13:13:28 +0100 Subject: [PATCH 3/5] fix(cast): keep a blank first line in the server's HTML An HTML parser drops a newline right after
. A cast whose screen starts with a blank line lost it in server
HTML and got it back once Vue hydrated, which /cast logged as a mismatch. The first newline now goes in a span.
---
 packages/cast/src/term.ts       | 4 +++-
 packages/cast/test/cast.test.ts | 5 +++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/packages/cast/src/term.ts b/packages/cast/src/term.ts
index 164ce7c3..d6d11bac 100644
--- a/packages/cast/src/term.ts
+++ b/packages/cast/src/term.ts
@@ -368,7 +368,9 @@ const classOf = (pen: Pen) => {
 export function toNodes(lines: Cell[][]): (string | ElementNode)[] {
   const nodes: (string | ElementNode)[] = [];
   for (const [index, line] of lines.entries()) {
-    if (index) nodes.push("\n");
+    // An HTML parser drops a newline right after `
`, so a blank first line goes in a span, where server HTML keeps
+    // it too.
+    if (index) nodes.push(nodes.length ? "\n" : ["span", {}, "\n"]);
     // Blanks at the end of a line with no background are padding, not output.
     let end = line.length;
     while (
diff --git a/packages/cast/test/cast.test.ts b/packages/cast/test/cast.test.ts
index ea6c74c9..54557c67 100644
--- a/packages/cast/test/cast.test.ts
+++ b/packages/cast/test/cast.test.ts
@@ -73,6 +73,11 @@ describe("comark-cast", () => {
     expect(await replay("\u001b[41m  \u001b[0m")).toBe('  ');
   });
 
+  it("keeps a blank first line, which the parser drops after the pre's start tag", async () => {
+    const term = await screen(inline(header, '[0, "o", "\\r\\nok"]'));
+    expect(term).toBe("\nok");
+  });
+
   it("escapes what it prints", async () => {
     expect(await screen(inline(header, '[0, "o", "&"]'))).toBe("<b>&</b>");
   });

From 4c2584bd85afbb505d976f9739488a1c14417c01 Mon Sep 17 00:00:00 2001
From: onmax 
Date: Thu, 12 Nov 2026 13:13:28 +0100
Subject: [PATCH 4/5] fix(github): leave references in a chip's label as text

comark-chips turns a link into a chip, which draws as a link. The references plugin then linked
`comarkdown/comark#525` inside it, a link inside a link, which the HTML parser splits. /remark-to-comark/testing
logged a hydration mismatch from it.
---
 packages/github/src/references.ts | 5 +++--
 packages/ui/test/ui.test.ts       | 9 +++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/packages/github/src/references.ts b/packages/github/src/references.ts
index 9349b0f3..20bbebbc 100644
--- a/packages/github/src/references.ts
+++ b/packages/github/src/references.ts
@@ -8,8 +8,9 @@ export interface ReferencesOptions {
   repo?: string;
 }
 
-// Text that is already a link, or is code, keeps its characters.
-const SKIP = new Set(["a", "code", "pre", "script", "style"]);
+// Text that is already a link, or is code, keeps its characters. comark-chips turns a link into a `chip`, which draws
+// as a link, so a reference in its label would put a link inside a link.
+const SKIP = new Set(["a", "chip", "code", "pre", "script", "style"]);
 const REPO = /^[a-z\d-]+\/[\w.-]+$/i;
 // `owner/name#123`, `#123`, or `@user`, not inside a word, a path, or an email address. A name followed by a slash
 // is an npm scope such as `@comark/html`, so it isn't a mention.
diff --git a/packages/ui/test/ui.test.ts b/packages/ui/test/ui.test.ts
index 88943f88..38bb4d92 100644
--- a/packages/ui/test/ui.test.ts
+++ b/packages/ui/test/ui.test.ts
@@ -76,6 +76,15 @@ describe("comark-ui", () => {
     }
   });
 
+  it("keeps a reference that is a chip's label as text, so no link holds another", async () => {
+    const out = await renderHtml(
+      "See [comarkdown/comark#525](https://github.com/comarkdown/comark/issues/525).",
+      { github: { references: { repo: "onmax/comark-ui" } } },
+    );
+    expect(out).toContain('class="cp"');
+    expect(out.match(/ {
     const { plugins, components } = html({ ...offline, zoom: false, github: { callouts: false } });
     expect(Object.keys(components)).not.toContain("zoom");

From 193d55f5587d20c0d6462c3d9ff8a1d475130f34 Mon Sep 17 00:00:00 2001
From: onmax 
Date: Thu, 12 Nov 2026 13:13:28 +0100
Subject: [PATCH 5/5] docs(doctor): show real images in the annotate and xref
 examples

The annotate examples pointed at /pond.png, /pond-before.png, and /pond-after.png, and the xref ones at relative
files, none of which exist, so their previews showed broken images and 404s. They now use a drawn pond (pond.svg),
the same pond with a fence (pond-fence.svg), and the dashboard image. chips/invalid-avatar keeps its 404, which is
the point of that example.
---
 .../doctor/annotate/annotation-outside-screenshot.md      | 4 ++--
 docs/pages/doctor/annotate/box-as-fraction.md             | 4 ++--
 docs/pages/doctor/annotate/box-outside-image.md           | 4 ++--
 docs/pages/doctor/annotate/compare-content.md             | 8 ++++----
 docs/pages/doctor/annotate/compare-same-image.md          | 8 ++++----
 docs/pages/doctor/annotate/compare-screenshot-count.md    | 6 +++---
 docs/pages/doctor/annotate/compare-viewport-mismatch.md   | 8 ++++----
 docs/pages/doctor/annotate/invalid-color.md               | 4 ++--
 docs/pages/doctor/annotate/invalid-href.md                | 4 ++--
 docs/pages/doctor/annotate/invalid-mode.md                | 8 ++++----
 docs/pages/doctor/annotate/invalid-position.md            | 4 ++--
 docs/pages/doctor/annotate/invalid-side.md                | 4 ++--
 docs/pages/doctor/annotate/invalid-viewport.md            | 4 ++--
 docs/pages/doctor/annotate/invisible-mark.md              | 4 ++--
 docs/pages/doctor/annotate/missing-alt.md                 | 4 ++--
 docs/pages/doctor/annotate/missing-note.md                | 4 ++--
 docs/pages/doctor/annotate/missing-src.md                 | 2 +-
 docs/pages/doctor/annotate/needs-side.md                  | 4 ++--
 docs/pages/doctor/annotate/nested-block.md                | 4 ++--
 docs/pages/doctor/annotate/numbers-overlap.md             | 4 ++--
 docs/pages/doctor/annotate/side-notes-overlap.md          | 4 ++--
 docs/pages/doctor/annotate/undefined-binding.md           | 4 ++--
 docs/pages/doctor/annotate/unknown-mark.md                | 4 ++--
 docs/pages/doctor/annotate/unknown-prop.md                | 4 ++--
 docs/pages/doctor/annotate/unsafe-bound-url.md            | 4 ++--
 docs/pages/doctor/xref/inline-figure.md                   | 6 +++---
 docs/pages/doctor/xref/missing-id.md                      | 4 ++--
 docs/pages/doctor/xref/ref-content.md                     | 4 ++--
 docs/pages/doctor/xref/unknown-label.md                   | 4 ++--
 docs/public/pond-fence.svg                                | 1 +
 docs/public/pond.svg                                      | 1 +
 31 files changed, 69 insertions(+), 67 deletions(-)
 create mode 100644 docs/public/pond-fence.svg
 create mode 100644 docs/public/pond.svg

diff --git a/docs/pages/doctor/annotate/annotation-outside-screenshot.md b/docs/pages/doctor/annotate/annotation-outside-screenshot.md
index 5fe3576c..3dff27a2 100644
--- a/docs/pages/doctor/annotate/annotation-outside-screenshot.md
+++ b/docs/pages/doctor/annotate/annotation-outside-screenshot.md
@@ -6,14 +6,14 @@ An `::annotation` marks a spot on the screenshot it sits in. Outside one, it has
 The duck without a name tag.
 ::
 
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 ::
 ```
 ::
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/box-as-fraction.md b/docs/pages/doctor/annotate/box-as-fraction.md
index fc3d14bd..75d2b756 100644
--- a/docs/pages/doctor/annotate/box-as-fraction.md
+++ b/docs/pages/doctor/annotate/box-as-fraction.md
@@ -2,7 +2,7 @@ The values are percentages, so `x=0.25` is a quarter of one percent of the image
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=0.2 y=0.3 w=0.15 h=0.1}
 The duck without a name tag.
 :::
@@ -12,7 +12,7 @@ The duck without a name tag.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/box-outside-image.md b/docs/pages/doctor/annotate/box-outside-image.md
index cbd3c287..acf804e3 100644
--- a/docs/pages/doctor/annotate/box-outside-image.md
+++ b/docs/pages/doctor/annotate/box-outside-image.md
@@ -2,7 +2,7 @@ A box that runs past the right or bottom edge of the image is cut off there, and
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=90 y=30 w=20 h=10}
 The duck at the far bank.
 :::
@@ -12,7 +12,7 @@ The duck at the far bank.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=80 y=30 w=20 h=10}
 The duck at the far bank.
 :::
diff --git a/docs/pages/doctor/annotate/compare-content.md b/docs/pages/doctor/annotate/compare-content.md
index 5c0fe044..615ba07b 100644
--- a/docs/pages/doctor/annotate/compare-content.md
+++ b/docs/pages/doctor/annotate/compare-content.md
@@ -5,10 +5,10 @@ A `::compare` lays out its two screenshots and nothing else, so text or other bl
 ::compare
 The pond before and after the fence.
 
-:::screenshot{src="/pond-before.png" alt="The pond with no fence"}
+:::screenshot{src="/pond.svg" alt="The pond with no fence"}
 :::
 
-:::screenshot{src="/pond-after.png" alt="The pond with a fence"}
+:::screenshot{src="/pond-fence.svg" alt="The pond with a fence"}
 :::
 ::
 ```
@@ -19,10 +19,10 @@ The pond before and after the fence.
 The pond before and after the fence.
 
 ::compare
-:::screenshot{src="/pond-before.png" alt="The pond with no fence"}
+:::screenshot{src="/pond.svg" alt="The pond with no fence"}
 :::
 
-:::screenshot{src="/pond-after.png" alt="The pond with a fence"}
+:::screenshot{src="/pond-fence.svg" alt="The pond with a fence"}
 :::
 ::
 ```
diff --git a/docs/pages/doctor/annotate/compare-same-image.md b/docs/pages/doctor/annotate/compare-same-image.md
index 770d4012..f9f1e5e3 100644
--- a/docs/pages/doctor/annotate/compare-same-image.md
+++ b/docs/pages/doctor/annotate/compare-same-image.md
@@ -3,10 +3,10 @@ A compare whose two screenshots are the same image shows no change, which usuall
 ::incorrect
 ```md
 ::compare
-:::screenshot{src="/pond.png" alt="The pond with no fence"}
+:::screenshot{src="/pond.svg" alt="The pond with no fence"}
 :::
 
-:::screenshot{src="/pond.png" alt="The pond with a fence"}
+:::screenshot{src="/pond.svg" alt="The pond with a fence"}
 :::
 ::
 ```
@@ -15,10 +15,10 @@ A compare whose two screenshots are the same image shows no change, which usuall
 ::correct
 ```md
 ::compare
-:::screenshot{src="/pond-before.png" alt="The pond with no fence"}
+:::screenshot{src="/pond.svg" alt="The pond with no fence"}
 :::
 
-:::screenshot{src="/pond-after.png" alt="The pond with a fence"}
+:::screenshot{src="/pond-fence.svg" alt="The pond with a fence"}
 :::
 ::
 ```
diff --git a/docs/pages/doctor/annotate/compare-screenshot-count.md b/docs/pages/doctor/annotate/compare-screenshot-count.md
index 2aab18fc..22bbbff1 100644
--- a/docs/pages/doctor/annotate/compare-screenshot-count.md
+++ b/docs/pages/doctor/annotate/compare-screenshot-count.md
@@ -3,7 +3,7 @@ A `::compare` shows a before and an after, so it takes exactly two screenshots.
 ::incorrect
 ```md
 ::compare
-:::screenshot{src="/pond-after.png" alt="The pond with a fence"}
+:::screenshot{src="/pond-fence.svg" alt="The pond with a fence"}
 :::
 ::
 ```
@@ -12,10 +12,10 @@ A `::compare` shows a before and an after, so it takes exactly two screenshots.
 ::correct
 ```md
 ::compare
-:::screenshot{src="/pond-before.png" alt="The pond with no fence"}
+:::screenshot{src="/pond.svg" alt="The pond with no fence"}
 :::
 
-:::screenshot{src="/pond-after.png" alt="The pond with a fence"}
+:::screenshot{src="/pond-fence.svg" alt="The pond with a fence"}
 :::
 ::
 ```
diff --git a/docs/pages/doctor/annotate/compare-viewport-mismatch.md b/docs/pages/doctor/annotate/compare-viewport-mismatch.md
index d07dce2e..a24c0aa7 100644
--- a/docs/pages/doctor/annotate/compare-viewport-mismatch.md
+++ b/docs/pages/doctor/annotate/compare-viewport-mismatch.md
@@ -3,10 +3,10 @@ Screenshots captured at different sizes lay the page out differently, so what mo
 ::incorrect
 ```md
 ::compare
-:::screenshot{src="/pond-before.png" alt="The pond with no fence" viewport="1440x900"}
+:::screenshot{src="/pond.svg" alt="The pond with no fence" viewport="1440x900"}
 :::
 
-:::screenshot{src="/pond-after.png" alt="The pond with a fence" viewport="1280x800"}
+:::screenshot{src="/pond-fence.svg" alt="The pond with a fence" viewport="1280x800"}
 :::
 ::
 ```
@@ -15,10 +15,10 @@ Screenshots captured at different sizes lay the page out differently, so what mo
 ::correct
 ```md
 ::compare
-:::screenshot{src="/pond-before.png" alt="The pond with no fence" viewport="1440x900"}
+:::screenshot{src="/pond.svg" alt="The pond with no fence" viewport="1440x900"}
 :::
 
-:::screenshot{src="/pond-after.png" alt="The pond with a fence" viewport="1440x900"}
+:::screenshot{src="/pond-fence.svg" alt="The pond with a fence" viewport="1440x900"}
 :::
 ::
 ```
diff --git a/docs/pages/doctor/annotate/invalid-color.md b/docs/pages/doctor/annotate/invalid-color.md
index 79e8a969..aba9027e 100644
--- a/docs/pages/doctor/annotate/invalid-color.md
+++ b/docs/pages/doctor/annotate/invalid-color.md
@@ -2,7 +2,7 @@ Each named color means one thing: `violet`, the default, points something out, `
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 color="orange"}
 The duck without a name tag.
 :::
@@ -12,7 +12,7 @@ The duck without a name tag.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 color="amber"}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/invalid-href.md b/docs/pages/doctor/annotate/invalid-href.md
index 02070e01..6892c70d 100644
--- a/docs/pages/doctor/annotate/invalid-href.md
+++ b/docs/pages/doctor/annotate/invalid-href.md
@@ -2,14 +2,14 @@
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks" href="pond.example.com/map"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks" href="pond.example.com/map"}
 ::
 ```
 ::
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks" href="https://pond.example.com/map"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks" href="https://pond.example.com/map"}
 ::
 ```
 ::
diff --git a/docs/pages/doctor/annotate/invalid-mode.md b/docs/pages/doctor/annotate/invalid-mode.md
index 865acc66..731feadb 100644
--- a/docs/pages/doctor/annotate/invalid-mode.md
+++ b/docs/pages/doctor/annotate/invalid-mode.md
@@ -3,10 +3,10 @@
 ::incorrect
 ```md
 ::compare{mode="overlay"}
-:::screenshot{src="/pond-before.png" alt="The pond with no fence"}
+:::screenshot{src="/pond.svg" alt="The pond with no fence"}
 :::
 
-:::screenshot{src="/pond-after.png" alt="The pond with a fence"}
+:::screenshot{src="/pond-fence.svg" alt="The pond with a fence"}
 :::
 ::
 ```
@@ -15,10 +15,10 @@
 ::correct
 ```md
 ::compare{mode="slider"}
-:::screenshot{src="/pond-before.png" alt="The pond with no fence"}
+:::screenshot{src="/pond.svg" alt="The pond with no fence"}
 :::
 
-:::screenshot{src="/pond-after.png" alt="The pond with a fence"}
+:::screenshot{src="/pond-fence.svg" alt="The pond with a fence"}
 :::
 ::
 ```
diff --git a/docs/pages/doctor/annotate/invalid-position.md b/docs/pages/doctor/annotate/invalid-position.md
index ec50049b..26b62954 100644
--- a/docs/pages/doctor/annotate/invalid-position.md
+++ b/docs/pages/doctor/annotate/invalid-position.md
@@ -2,7 +2,7 @@
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x="20%" y=30 w=15 h=10}
 The duck without a name tag.
 :::
@@ -12,7 +12,7 @@ The duck without a name tag.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/invalid-side.md b/docs/pages/doctor/annotate/invalid-side.md
index 4af12860..9afe8bdf 100644
--- a/docs/pages/doctor/annotate/invalid-side.md
+++ b/docs/pages/doctor/annotate/invalid-side.md
@@ -2,7 +2,7 @@ A side note sits to the left of the image, to its right, above it, or below it,
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 side="under"}
 The duck without a name tag.
 :::
@@ -12,7 +12,7 @@ The duck without a name tag.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 side="bottom"}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/invalid-viewport.md b/docs/pages/doctor/annotate/invalid-viewport.md
index 8108ad31..312f7c00 100644
--- a/docs/pages/doctor/annotate/invalid-viewport.md
+++ b/docs/pages/doctor/annotate/invalid-viewport.md
@@ -2,14 +2,14 @@
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks" viewport="1440 by 900"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks" viewport="1440 by 900"}
 ::
 ```
 ::
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks" viewport="1440x900"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks" viewport="1440x900"}
 ::
 ```
 ::
diff --git a/docs/pages/doctor/annotate/invisible-mark.md b/docs/pages/doctor/annotate/invisible-mark.md
index fde864ac..8493f50e 100644
--- a/docs/pages/doctor/annotate/invisible-mark.md
+++ b/docs/pages/doctor/annotate/invisible-mark.md
@@ -2,7 +2,7 @@
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 mark="none"}
 The duck without a name tag.
 :::
@@ -12,7 +12,7 @@ The duck without a name tag.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 mark="none" side="left"}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/missing-alt.md b/docs/pages/doctor/annotate/missing-alt.md
index 64351538..e06dbf41 100644
--- a/docs/pages/doctor/annotate/missing-alt.md
+++ b/docs/pages/doctor/annotate/missing-alt.md
@@ -2,14 +2,14 @@
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png"}
+::screenshot{src="/pond.svg"}
 ::
 ```
 ::
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 ::
 ```
 ::
diff --git a/docs/pages/doctor/annotate/missing-note.md b/docs/pages/doctor/annotate/missing-note.md
index 5f00f5d6..e80ce8a3 100644
--- a/docs/pages/doctor/annotate/missing-note.md
+++ b/docs/pages/doctor/annotate/missing-note.md
@@ -2,7 +2,7 @@ An annotation's content is its note. Without one, the mark has a number and noth
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10}
 :::
 ::
@@ -11,7 +11,7 @@ An annotation's content is its note. Without one, the mark has a number and noth
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/missing-src.md b/docs/pages/doctor/annotate/missing-src.md
index 1201ff4b..22daf3b1 100644
--- a/docs/pages/doctor/annotate/missing-src.md
+++ b/docs/pages/doctor/annotate/missing-src.md
@@ -9,7 +9,7 @@ A `::screenshot` without `src` has no image, so its marks and notes point at not
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 ::
 ```
 ::
diff --git a/docs/pages/doctor/annotate/needs-side.md b/docs/pages/doctor/annotate/needs-side.md
index 2e44688b..ae01bcd3 100644
--- a/docs/pages/doctor/annotate/needs-side.md
+++ b/docs/pages/doctor/annotate/needs-side.md
@@ -2,7 +2,7 @@
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 mark="circle" at=60 to="27,35"}
 The duck without a name tag.
 :::
@@ -12,7 +12,7 @@ The duck without a name tag.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 mark="none" side="top" at=60 to="27,35"}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/nested-block.md b/docs/pages/doctor/annotate/nested-block.md
index 53179d9c..0e579844 100644
--- a/docs/pages/doctor/annotate/nested-block.md
+++ b/docs/pages/doctor/annotate/nested-block.md
@@ -2,7 +2,7 @@ Screenshots, compares, and annotations are read only where they belong: an annot
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10}
 The duck without a name tag.
 
@@ -16,7 +16,7 @@ The duck with two.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/numbers-overlap.md b/docs/pages/doctor/annotate/numbers-overlap.md
index 4c1e880e..7cd9d295 100644
--- a/docs/pages/doctor/annotate/numbers-overlap.md
+++ b/docs/pages/doctor/annotate/numbers-overlap.md
@@ -2,7 +2,7 @@ Each number sits on a corner of its mark, on the first corner that's clear of th
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=40 y=40 w=10 h=10}
 Duck 1 on the rock.
 :::
@@ -24,7 +24,7 @@ Duck 5 on the rock.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=40 y=40 w=10 h=10}
 Five ducks share the rock.
 :::
diff --git a/docs/pages/doctor/annotate/side-notes-overlap.md b/docs/pages/doctor/annotate/side-notes-overlap.md
index fa2dc158..c03caa57 100644
--- a/docs/pages/doctor/annotate/side-notes-overlap.md
+++ b/docs/pages/doctor/annotate/side-notes-overlap.md
@@ -2,7 +2,7 @@ Notes on one side line up with their marks. When two marks on the same side sit
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=10 y=10 w=10 h=10 side="left"}
 The first duck in line.
 :::
@@ -15,7 +15,7 @@ The second duck in line.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=10 y=10 w=10 h=10 side="left"}
 The first duck in line.
 :::
diff --git a/docs/pages/doctor/annotate/undefined-binding.md b/docs/pages/doctor/annotate/undefined-binding.md
index e1750cb5..cf616277 100644
--- a/docs/pages/doctor/annotate/undefined-binding.md
+++ b/docs/pages/doctor/annotate/undefined-binding.md
@@ -8,7 +8,7 @@ duck:
   y: 30
 ---
 
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{:x="frontmatter.duck.x" :y="frontmatter.duck.why" w=15 h=10}
 The duck without a name tag.
 :::
@@ -24,7 +24,7 @@ duck:
   y: 30
 ---
 
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{:x="frontmatter.duck.x" :y="frontmatter.duck.y" w=15 h=10}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/unknown-mark.md b/docs/pages/doctor/annotate/unknown-mark.md
index e4d49e66..f7438e2a 100644
--- a/docs/pages/doctor/annotate/unknown-mark.md
+++ b/docs/pages/doctor/annotate/unknown-mark.md
@@ -2,7 +2,7 @@
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 mark="arrow"}
 The duck without a name tag.
 :::
@@ -12,7 +12,7 @@ The duck without a name tag.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 mark="circle"}
 The duck without a name tag.
 :::
diff --git a/docs/pages/doctor/annotate/unknown-prop.md b/docs/pages/doctor/annotate/unknown-prop.md
index 4435e4e0..6f9ebc5c 100644
--- a/docs/pages/doctor/annotate/unknown-prop.md
+++ b/docs/pages/doctor/annotate/unknown-prop.md
@@ -2,7 +2,7 @@ Each block reads its own props and ignores every other one, so a misspelled prop
 
 ::incorrect
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 colour="red"}
 This duck has no name tag.
 :::
@@ -12,7 +12,7 @@ This duck has no name tag.
 
 ::correct
 ```md
-::screenshot{src="/pond.png" alt="The pond map with three ducks"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks"}
 :::annotation{x=20 y=30 w=15 h=10 color="red"}
 This duck has no name tag.
 :::
diff --git a/docs/pages/doctor/annotate/unsafe-bound-url.md b/docs/pages/doctor/annotate/unsafe-bound-url.md
index 4cca8dfa..4a5eb62b 100644
--- a/docs/pages/doctor/annotate/unsafe-bound-url.md
+++ b/docs/pages/doctor/annotate/unsafe-bound-url.md
@@ -6,7 +6,7 @@ Comark drops a bound `src` or `href` that resolves to a script URL, such as `jav
 pond: "javascript:alert('quack')"
 ---
 
-::screenshot{src="/pond.png" alt="The pond map with three ducks" :href="frontmatter.pond"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks" :href="frontmatter.pond"}
 ::
 ```
 ::
@@ -17,7 +17,7 @@ pond: "javascript:alert('quack')"
 pond: "https://pond.example.com/map"
 ---
 
-::screenshot{src="/pond.png" alt="The pond map with three ducks" :href="frontmatter.pond"}
+::screenshot{src="/pond.svg" alt="The pond map with three ducks" :href="frontmatter.pond"}
 ::
 ```
 ::
diff --git a/docs/pages/doctor/xref/inline-figure.md b/docs/pages/doctor/xref/inline-figure.md
index fb44893f..818fd37b 100644
--- a/docs/pages/doctor/xref/inline-figure.md
+++ b/docs/pages/doctor/xref/inline-figure.md
@@ -2,14 +2,14 @@ Only an image alone in its paragraph becomes a numbered figure, since a caption
 
 ::incorrect
 ```md
-The pigeons land here ![The roof after the deploy](roof.png){#fig-roof} every morning.
+The ducks swim here ![The duck pond](/pond.svg){#fig-pond} every morning.
 ```
 ::
 
 ::correct
 ```md
-The pigeons land on the roof every morning.
+The ducks swim in the pond every morning.
 
-![The roof after the deploy](roof.png){#fig-roof}
+![The duck pond](/pond.svg){#fig-pond}
 ```
 ::
diff --git a/docs/pages/doctor/xref/missing-id.md b/docs/pages/doctor/xref/missing-id.md
index 49d580d0..ad053b75 100644
--- a/docs/pages/doctor/xref/missing-id.md
+++ b/docs/pages/doctor/xref/missing-id.md
@@ -2,7 +2,7 @@
 
 ::incorrect
 ```md
-![Three ducks on the pond](ducks.png){#fig-ducks}
+![Three ducks on the pond](/pond.svg){#fig-ducks}
 
 As :ref{fig-ducks} shows, the ducks stay near the reeds.
 ```
@@ -10,7 +10,7 @@ As :ref{fig-ducks} shows, the ducks stay near the reeds.
 
 ::correct
 ```md
-![Three ducks on the pond](ducks.png){#fig-ducks}
+![Three ducks on the pond](/pond.svg){#fig-ducks}
 
 As :ref{#fig-ducks} shows, the ducks stay near the reeds.
 ```
diff --git a/docs/pages/doctor/xref/ref-content.md b/docs/pages/doctor/xref/ref-content.md
index 6533f3d0..601b61a4 100644
--- a/docs/pages/doctor/xref/ref-content.md
+++ b/docs/pages/doctor/xref/ref-content.md
@@ -2,7 +2,7 @@ A `:ref` always reads as its label's number, such as "Figure 2", so the text wri
 
 ::incorrect
 ```md
-![The pond after the cleanup](pond.png){#fig-pond}
+![The pond after the cleanup](/pond.svg){#fig-pond}
 
 Compare it with :ref[the clean pond]{#fig-pond}.
 ```
@@ -10,7 +10,7 @@ Compare it with :ref[the clean pond]{#fig-pond}.
 
 ::correct
 ```md
-![The pond after the cleanup](pond.png){#fig-pond}
+![The pond after the cleanup](/pond.svg){#fig-pond}
 
 Compare it with the clean pond in :ref{#fig-pond}.
 ```
diff --git a/docs/pages/doctor/xref/unknown-label.md b/docs/pages/doctor/xref/unknown-label.md
index fed52769..a4506050 100644
--- a/docs/pages/doctor/xref/unknown-label.md
+++ b/docs/pages/doctor/xref/unknown-label.md
@@ -2,7 +2,7 @@ A `:ref` to a label that nothing in the document has renders as the bare id in b
 
 ::incorrect
 ```md
-![A pigeon on the deploy dashboard](pigeon.png){#fig-pigeon}
+![A pigeon on the deploy dashboard](/dashboard.png){#fig-pigeon}
 
 See :ref{#fig-pidgeon} for where it sat.
 ```
@@ -10,7 +10,7 @@ See :ref{#fig-pidgeon} for where it sat.
 
 ::correct
 ```md
-![A pigeon on the deploy dashboard](pigeon.png){#fig-pigeon}
+![A pigeon on the deploy dashboard](/dashboard.png){#fig-pigeon}
 
 See :ref{#fig-pigeon} for where it sat.
 ```
diff --git a/docs/public/pond-fence.svg b/docs/public/pond-fence.svg
new file mode 100644
index 00000000..b6cabcd0
--- /dev/null
+++ b/docs/public/pond-fence.svg
@@ -0,0 +1 @@
+AdaBo
\ No newline at end of file
diff --git a/docs/public/pond.svg b/docs/public/pond.svg
new file mode 100644
index 00000000..ce8861dd
--- /dev/null
+++ b/docs/public/pond.svg
@@ -0,0 +1 @@
+AdaBo
\ No newline at end of file