diff --git a/frontend-web/src/core/utils/markdown.ts b/frontend-web/src/core/utils/markdown.ts
index 96060708..4ab819ce 100644
--- a/frontend-web/src/core/utils/markdown.ts
+++ b/frontend-web/src/core/utils/markdown.ts
@@ -100,9 +100,16 @@ function candidateTextFromHref(href: string): string {
/**
* Injects a small runtime script into generated HTML so that clicking an
- * in-page anchor (``) scrolls within the iframe instead of
- * navigating it. The preview iframe loads from a sandboxed `blob:` URL, where a
- * fragment navigation blanks the frame; intercepting the click avoids that.
+ * in-page anchor (``) works inside the preview iframe.
+ *
+ * The hash MUST really change on click: multi-page documents (the
+ * html-multipage skill) show/hide their sub-page ``
+ * blocks with CSS `:target` rules, which only fire on a fragment navigation.
+ * Intercepting with preventDefault + scrollIntoView alone leaves the hash
+ * untouched, so sub-pages stay `display:none` and clicks look dead. The
+ * handler therefore syncs `location.hash` (a same-document navigation —
+ * safe in the sandboxed blob: frame) and only smooth-scrolls afterwards when
+ * the target is actually rendered.
*/
export function injectInPageAnchorHandler(html: string): string {
const script = ``;
if (/<\/body>/i.test(html)) {