marksites 0.1.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,6 +30,7 @@ function renderTableOfContentsScript() {
30
30
  if (entries.length === 0) return;
31
31
 
32
32
  let scheduled = false;
33
+ let currentLink = null;
33
34
  const update = () => {
34
35
  scheduled = false;
35
36
  const marker = Math.min(160, window.innerHeight * 0.25);
@@ -44,11 +45,15 @@ function renderTableOfContentsScript() {
44
45
  if (entry === active) entry.link.setAttribute('aria-current', 'location');
45
46
  else entry.link.removeAttribute('aria-current');
46
47
  }
47
- const navigationRect = navigation.getBoundingClientRect();
48
- const activeRect = active.link.getBoundingClientRect();
49
- if (!navigation.hidden && (activeRect.top < navigationRect.top || activeRect.bottom > navigationRect.bottom)) {
50
- navigation.scrollTop += activeRect.top - navigationRect.top - navigation.clientHeight / 2;
48
+ if (!navigation.hidden && active.link !== currentLink) {
49
+ const navigationRect = navigation.getBoundingClientRect();
50
+ const activeRect = active.link.getBoundingClientRect();
51
+ const outside = activeRect.top < navigationRect.top + 12 || activeRect.bottom > navigationRect.bottom - 12;
52
+ if (outside) {
53
+ navigation.scrollTop += activeRect.top - navigationRect.top - navigation.clientHeight / 2 + activeRect.height / 2;
54
+ }
51
55
  }
56
+ currentLink = active.link;
52
57
  };
53
58
  const schedule = () => {
54
59
  if (scheduled) return;
@@ -5,6 +5,7 @@ import { createAnnotationsFeature } from "./features/annotations/index.js";
5
5
  import { renderBreadcrumbs, renderFileSidebar, renderFileTree, renderFileTreeScript, renderModifiedAt, renderModifiedAtScript, } from "./features/file-tree/index.js";
6
6
  import { createTableOfContentsFeature } from "./features/table-of-contents/index.js";
7
7
  import { createSidebarFeature } from "./features/sidebar/index.js";
8
+ import { createImageViewerFeature } from "./features/image-viewer/index.js";
8
9
  import { renderDocument } from "./template/document.js";
9
10
  import { escapeHtml } from "./utils/html.js";
10
11
  /** Convert Markdown into a standalone HTML document styled like GitHub. */
@@ -13,7 +14,8 @@ export function markdownToHtml(markdown, options = {}) {
13
14
  }
14
15
  export function renderMarkdown(markdown, options = {}, annotations) {
15
16
  const rawTitle = options.title ?? "Markdown文書";
16
- const title = escapeHtml(rawTitle);
17
+ const currentFileName = options.fileTree?.breadcrumbs?.find((breadcrumb) => breadcrumb.current)?.name;
18
+ const title = escapeHtml(`marksites | ${currentFileName ?? rawTitle}`);
17
19
  const language = escapeHtml(options.language ?? "ja");
18
20
  const highlight = options.highlight ?? true;
19
21
  const tocOptions = typeof options.tableOfContents === "object" ? options.tableOfContents : {};
@@ -25,7 +27,6 @@ export function renderMarkdown(markdown, options = {}, annotations) {
25
27
  maxDepth: tocOptions.maxDepth ?? 6,
26
28
  });
27
29
  const codeBlocks = createCodeBlocksFeature(renderer, highlight);
28
- const header = createHeaderFeature();
29
30
  const content = marked.parse(markdown, {
30
31
  ...options.markedOptions,
31
32
  renderer,
@@ -37,11 +38,15 @@ export function renderMarkdown(markdown, options = {}, annotations) {
37
38
  const fileTreeScript = renderFileTreeScript(fileTree !== "");
38
39
  const modifiedAt = renderModifiedAt(options.modifiedAt);
39
40
  const breadcrumbs = fileTree
40
- ? renderBreadcrumbs(options.fileTree?.breadcrumbs, options.modifiedAt)
41
- : modifiedAt
42
- ? `<div class="document-metadata">${modifiedAt}</div>\n`
43
- : "";
41
+ ? renderBreadcrumbs(options.fileTree?.breadcrumbs)
42
+ : `<nav class="file-breadcrumbs" aria-label="ファイルパス"><span aria-current="page">${escapeHtml(rawTitle)}</span></nav>\n`;
43
+ const header = createHeaderFeature({
44
+ documentNavigation: breadcrumbs,
45
+ documentMetadata: modifiedAt,
46
+ fileTree,
47
+ });
44
48
  const annotationFeature = createAnnotationsFeature(annotations);
49
+ const imageViewer = createImageViewerFeature(/<img\b/i.test(content));
45
50
  const sidebar = createSidebarFeature({
46
51
  tableOfContents: toc.markup,
47
52
  tableOfContentsTitle: toc.title,
@@ -55,14 +60,17 @@ export function renderMarkdown(markdown, options = {}, annotations) {
55
60
  highlight,
56
61
  regions: {
57
62
  header: header.markup,
58
- breadcrumbs,
59
- fileTree,
60
63
  fileSidebar,
61
64
  sidebar: sidebar.markup,
62
- overlays: annotationFeature.markup,
65
+ overlays: `${annotationFeature.markup}${imageViewer.markup}`,
63
66
  },
64
67
  assets: {
65
- styles: [sidebar.styles, annotationFeature.styles, header.styles],
68
+ styles: [
69
+ sidebar.styles,
70
+ annotationFeature.styles,
71
+ imageViewer.styles,
72
+ header.styles,
73
+ ],
66
74
  scripts: [
67
75
  header.script,
68
76
  fileTreeScript,
@@ -71,6 +79,7 @@ export function renderMarkdown(markdown, options = {}, annotations) {
71
79
  toc.script,
72
80
  `\n${codeBlocks.renderScript()}\n`,
73
81
  `${annotationFeature.script}\n`,
82
+ ...(imageViewer.script ? [`${imageViewer.script}\n`] : []),
74
83
  ],
75
84
  },
76
85
  });
@@ -4,6 +4,7 @@ import { emptyAnnotationDocument } from "../annotations/model.js";
4
4
  import { createAnnotationsFeature } from "../features/annotations/index.js";
5
5
  import { createCodeBlocksFeature } from "../features/code-blocks/index.js";
6
6
  import { createHeaderFeature } from "../features/header/index.js";
7
+ import { createImageViewerFeature } from "../features/image-viewer/index.js";
7
8
  import { renderFileTreeScript, renderModifiedAtScript, } from "../features/file-tree/index.js";
8
9
  import { createSidebarFeature } from "../features/sidebar/index.js";
9
10
  import { createTableOfContentsFeature } from "../features/table-of-contents/index.js";
@@ -34,6 +35,7 @@ function generatedScriptBodies() {
34
35
  scriptBody(renderModifiedAtScript(true)),
35
36
  scriptBody(renderedToc.script),
36
37
  scriptBody(annotations.script),
38
+ scriptBody(createImageViewerFeature(true).script),
37
39
  scriptBody(createSidebarFeature({
38
40
  tableOfContents: renderedToc.markup,
39
41
  tableOfContentsTitle: renderedToc.title,
@@ -33,6 +33,11 @@ export async function handleStaticFile(request, response, url, root, rootReal, e
33
33
  return sendJson(response, 403, "Invalid path");
34
34
  }
35
35
  const requestedPath = decoded === "/" && entryPath ? `/${entryPath}` : decoded;
36
+ if (requestedPath === "/favicon.ico") {
37
+ response.writeHead(204, { "cache-control": "public, max-age=86400" });
38
+ response.end();
39
+ return;
40
+ }
36
41
  let path = resolve(root, `.${normalize(requestedPath)}`);
37
42
  if (!path.startsWith(root + sep) && path !== root)
38
43
  return sendJson(response, 403, "Invalid path");
@@ -5,8 +5,6 @@ interface DocumentParts {
5
5
  highlight: boolean;
6
6
  regions: {
7
7
  header: string;
8
- breadcrumbs: string;
9
- fileTree: string;
10
8
  fileSidebar: string;
11
9
  sidebar: string;
12
10
  overlays: string;
@@ -1,6 +1,6 @@
1
1
  import { documentStyles, fileTreeStyles, githubMarkdownCss, highlightCss, highlightThemeStyles, } from "./styles.js";
2
2
  export function renderDocument(parts) {
3
- const bodyClass = parts.regions.fileTree
3
+ const bodyClass = parts.regions.fileSidebar
4
4
  ? "markdown-body has-file-tree"
5
5
  : "markdown-body";
6
6
  const trustedScript = (script) => script.replace("<script>", '<script data-marksites-script="true">');
@@ -13,16 +13,14 @@ export function renderDocument(parts) {
13
13
  <style>${githubMarkdownCss}</style>
14
14
  ${parts.highlight ? `<style>${highlightCss}\n${highlightThemeStyles}</style>` : ""}
15
15
  <style>
16
- ${documentStyles}${parts.regions.fileTree ? `\n${fileTreeStyles}` : ""}${parts.assets.styles.join("")}
16
+ ${documentStyles}${parts.regions.fileSidebar ? `\n${fileTreeStyles}` : ""}${parts.assets.styles.join("")}
17
17
  </style>
18
18
  </head>
19
19
  <body class="${bodyClass}">
20
20
  ${parts.regions.header}
21
21
  ${parts.regions.fileSidebar}
22
22
  <main class="markdown-content">
23
- ${parts.regions.fileTree ? `<div class="file-navigation">
24
- ${parts.regions.breadcrumbs}${parts.regions.fileTree}</div>
25
- ` : parts.regions.breadcrumbs}${parts.content}
23
+ ${parts.content}
26
24
  </main>
27
25
  ${parts.regions.sidebar}
28
26
  ${parts.regions.overlays}
@@ -1,5 +1,5 @@
1
1
  export declare const githubMarkdownCss: string;
2
2
  export declare const highlightCss: string;
3
3
  export declare const highlightThemeStyles = "body[data-theme=\"dark\"] .hljs{color:var(--codeBlock-fgColor);background:var(--codeBlock-bgColor)}\nbody[data-theme=\"dark\"] :is(.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_){color:var(--color-prettylights-syntax-keyword)}\nbody[data-theme=\"dark\"] :is(.hljs-title,.hljs-title.class_,.hljs-title.function_){color:var(--color-prettylights-syntax-entity)}\nbody[data-theme=\"dark\"] :is(.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id){color:var(--color-prettylights-syntax-constant)}\nbody[data-theme=\"dark\"] :is(.hljs-regexp,.hljs-string,.hljs-meta .hljs-string){color:var(--color-prettylights-syntax-string)}\nbody[data-theme=\"dark\"] :is(.hljs-built_in,.hljs-symbol){color:var(--color-prettylights-syntax-variable)}\nbody[data-theme=\"dark\"] :is(.hljs-comment,.hljs-code,.hljs-formula){color:var(--color-prettylights-syntax-comment)}\nbody[data-theme=\"dark\"] :is(.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo){color:var(--color-prettylights-syntax-entity-tag)}";
4
- export declare const documentStyles = " body.markdown-body { box-sizing: border-box; min-width: 200px; width: calc(100% - 64px); max-width: none; margin: 0 32px; padding: 32px 0 0; display: grid; grid-template-columns: minmax(0, 1fr) 300px; grid-template-areas: \"content toc\"; column-gap: 32px; align-items: start; }\n .markdown-content, .document-sidebar { box-sizing: border-box; }\n .markdown-content { grid-area: content; min-width: 0; margin-bottom: 72px; padding: clamp(28px, 3vw, 52px); border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; box-shadow: 0 1px 2px rgba(31, 35, 40, 0.04); }\n .markdown-content :is(h1, h2, h3, h4, h5, h6) { scroll-margin-top: 32px; }\n .document-metadata { display: flex; justify-content: flex-end; margin: -12px 0 28px; padding-bottom: 14px; border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .document-modified { margin-left: auto; color: var(--fgColor-muted, #59636e); font-size: 0.75rem; line-height: 28px; white-space: nowrap; }\n .code-block { margin-bottom: 16px; overflow: hidden; border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; }\n .code-toolbar { display: flex; min-height: 38px; align-items: center; justify-content: space-between; padding: 0 8px 0 14px; color: var(--fgColor-muted, #59636e); background: var(--bgColor-muted, #f6f8fa); border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .code-language { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }\n .code-tools { display: flex; gap: 2px; }\n .code-tool { display: inline-flex; min-height: 30px; align-items: center; justify-content: center; gap: 5px; padding: 4px 8px; color: inherit; font: inherit; font-size: 0.75rem; line-height: 1; background: transparent; border: 0; border-radius: 5px; cursor: pointer; }\n .code-tool-label, [data-copy-label] { display: inline-flex; align-items: center; line-height: 1; }\n .code-tool:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .code-tool:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .code-tool[aria-pressed=\"true\"] { color: var(--fgColor-accent, #0969da); background: var(--bgColor-accent-muted, #ddf4ff); }\n .code-block pre { margin: 0; border-radius: 0; }\n .code-block pre, .code-block pre code { color: var(--codeBlock-fgColor, #24292f); background: var(--codeBlock-bgColor, #fff); }\n .code-block pre code { display: block; }\n .code-block.is-wrapped pre code { white-space: pre-wrap; overflow-wrap: anywhere; }\n .panel-toggle-icon { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: transform 120ms ease; }\n .action-icon { display: block; width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }\n .table-of-contents ul { margin: 0; padding: 0; list-style: none; }\n .table-of-contents li { margin: 2px 0 2px calc(var(--toc-level) * 12px); }\n .table-of-contents a { position: relative; display: block; padding: 6px 10px; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 1.4; overflow-wrap: anywhere; text-decoration: none; border-radius: 0 6px 6px 0; transition: color 120ms ease, background-color 120ms ease; }\n .table-of-contents a::before { position: absolute; top: 0; bottom: 0; left: 0; width: 2px; background: transparent; content: \"\"; }\n .table-of-contents a:hover { color: var(--fgColor-default, #1f2328); background: var(--bgColor-muted, #f6f8fa); text-decoration: none; }\n .table-of-contents a:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .table-of-contents a[aria-current=\"location\"] { color: var(--fgColor-accent, #0969da); font-weight: 600; background: linear-gradient(90deg, var(--bgColor-accent-muted, #ddf4ff), transparent); }\n .table-of-contents a[aria-current=\"location\"]::before { background: var(--borderColor-accent-emphasis, #0969da); }\n @media (max-width: 900px) {\n body.markdown-body { width: calc(100% - 24px); max-width: none; margin: 0 12px; padding: 12px 0 0; grid-template-columns: minmax(0, 1fr); grid-template-areas: \"toc\" \"content\"; gap: 16px; }\n .markdown-content { margin-bottom: 32px; }\n }\n @media (max-width: 600px) { .markdown-content { padding: 24px 20px; border-radius: 6px; } }\n @media (prefers-reduced-motion: reduce) { .table-of-contents a, .panel-toggle-icon { transition: none; } }";
5
- export declare const fileTreeStyles = " body.markdown-body.has-file-tree { width: 100%; margin: 0; padding: 32px 32px 0 0; grid-template-columns: 280px minmax(0, 1fr) 300px; grid-template-areas: \"files content toc\"; column-gap: 32px; }\n body.markdown-body.has-file-tree.file-sidebar-collapsed { width: calc(100% - 64px); margin: 0 32px; padding: 32px 0 0; grid-template-columns: minmax(0, 1fr) 300px; grid-template-areas: \"content toc\"; }\n .file-sidebar { grid-area: files; position: fixed; z-index: 45; top: 0; bottom: 0; left: 0; box-sizing: border-box; display: flex; width: 280px; min-height: 0; flex-direction: column; color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); border: 0; border-right: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 0; overflow: hidden; }\n .file-sidebar-header { display: flex; min-height: 52px; flex: none; align-items: center; gap: 9px; padding: 0 12px; font-size: 0.875rem; font-weight: 700; border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .file-sidebar-header > span { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-sidebar[hidden], .file-sidebar-open[hidden], .file-sidebar-close[hidden] { display: none; }\n .file-sidebar-close { position: fixed; z-index: 50; top: 13px; left: 12px; display: inline-flex; width: 30px; height: 30px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 6px; cursor: pointer; }\n .file-sidebar-close:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .file-sidebar-close:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .file-navigation { position: relative; margin: -12px 0 28px; }\n .file-breadcrumbs { display: flex; align-items: center; gap: 8px; margin: 0; padding-bottom: 14px; border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .file-breadcrumbs ol { display: flex; min-width: 0; min-height: 28px; flex: 0 1 auto; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 0; padding: 0; list-style: none; }\n .file-breadcrumbs li { display: inline-block; min-width: 0; height: 28px; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 28px; }\n .file-breadcrumbs li + li::before { margin-right: 6px; color: var(--fgColor-muted, #818b98); content: \"/\"; }\n .file-breadcrumb-separator { height: 28px; margin-right: -2px; color: var(--fgColor-muted, #818b98); font-size: 0.875rem; line-height: 28px; }\n .file-breadcrumbs a { display: inline-block; height: 28px; color: var(--fgColor-accent, #0969da); font-weight: 500; line-height: 28px; text-decoration: none; vertical-align: baseline; }\n .file-breadcrumbs a:hover { text-decoration: underline; }\n .file-breadcrumbs [aria-current=\"page\"] { color: var(--fgColor-default, #1f2328); font-weight: 600; white-space: nowrap; }\n .file-sidebar-open { position: fixed; z-index: 50; top: 13px; left: 12px; display: inline-flex; width: 30px; height: 30px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 6px; cursor: pointer; }\n .file-tree-popover-toggle { position: relative; top: 1px; display: inline-flex; height: 28px; min-width: 0; flex: none; align-items: center; justify-content: center; gap: 3px; padding: 0; color: var(--fgColor-accent, #0969da); font: inherit; font-size: 0.875rem; font-weight: 600; line-height: 28px; background: transparent; border: 0; border-radius: 4px; cursor: pointer; }\n .file-tree-popover-toggle span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-sidebar-toggle-icon { display: block; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }\n .file-sidebar-open:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .file-sidebar-open:focus-visible, .file-tree-popover-toggle:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 2px; }\n .file-tree-popover-toggle:hover { color: var(--fgColor-accent, #0969da); text-decoration: underline; background: transparent; }\n .file-tree-popover-toggle .panel-toggle-icon { width: 13px; height: 13px; flex: none; transform: translateY(1px); }\n .copy-file-path .copy-icon { transform: none; }\n .file-tree-popover-toggle[aria-expanded=\"true\"] .panel-toggle-icon { transform: translateY(1px) rotate(180deg); }\n .copy-file-path { display: inline-flex; width: 28px; height: 28px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 5px; cursor: pointer; }\n .copy-file-path:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .copy-file-path:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 2px; }\n .file-tree { box-sizing: border-box; overflow: auto; padding: 12px; color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); scrollbar-width: thin; scrollbar-color: var(--borderColor-default, #d0d7de) transparent; }\n .file-tree-sidebar { min-height: 0; flex: 1; padding: 10px 12px 16px; }\n .file-tree-popover { position: absolute; z-index: 15; top: calc(100% + 6px); left: 0; width: min(360px, calc(100vw - 48px)); max-height: min(520px, calc(100vh - 96px)); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 8px; box-shadow: 0 8px 24px rgba(31,35,40,.16); }\n .file-tree-filter { margin: 0 0 8px; }\n .file-tree-filter-input { box-sizing: border-box; width: 100%; min-height: 32px; padding: 5px 9px; color: var(--fgColor-default, #1f2328); font: inherit; font-size: 0.8125rem; line-height: 1.4; background: var(--bgColor-default, #fff); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 6px; outline: none; }\n .file-tree-filter-input::placeholder { color: var(--fgColor-muted, #59636e); }\n .file-tree-filter-input:focus { border-color: var(--borderColor-accent-emphasis, #0969da); box-shadow: 0 0 0 2px var(--bgColor-accent-muted, #ddf4ff); }\n .file-tree-filter-empty { margin: 10px 4px 2px; color: var(--fgColor-muted, #59636e); font-size: 0.8125rem; text-align: center; }\n .file-tree ul { margin: 0; padding: 0; list-style: none; }\n .file-tree details { margin: 0; }\n .file-tree details > ul { margin-left: 10px; padding-left: 10px; border-left: 1px solid var(--borderColor-muted, #d8dee4); }\n .file-tree summary { padding: 5px 7px; color: var(--fgColor-default, #1f2328); font-size: 0.875rem; font-weight: 600; line-height: 1.35; border-radius: 5px; cursor: pointer; user-select: none; }\n .folder-icon { display: inline-block; width: 14px; height: 14px; margin-right: 5px; vertical-align: -2px; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }\n .file-tree summary:hover { background: var(--bgColor-muted, #f6f8fa); }\n .file-tree summary::marker { color: var(--fgColor-muted, #59636e); }\n .file-tree a { display: flex; margin: 1px 0; padding: 5px 8px; align-items: center; gap: 6px; overflow: hidden; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 1.35; text-decoration: none; white-space: nowrap; border-radius: 5px; }\n .file-tree-name { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; }\n .file-tree-comment-count { display: inline-flex; min-width: 18px; height: 18px; flex: none; align-items: center; justify-content: center; padding: 0 5px; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 600; line-height: 18px; background: var(--bgColor-neutral-muted, #818b981f); border-radius: 9px; }\n .file-tree-directory-comment-count { float: right; margin-left: 6px; }\n .file-tree details[open] > summary > .file-tree-directory-comment-count { display: none; }\n .file-tree a[aria-current=\"page\"] .file-tree-comment-count { color: var(--fgColor-accent, #0969da); background: var(--bgColor-default, #fff); }\n .file-tree a:hover { color: var(--fgColor-default, #1f2328); background: var(--bgColor-muted, #f6f8fa); text-decoration: none; }\n .file-tree a:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .file-tree a[aria-current=\"page\"] { color: var(--fgColor-accent, #0969da); font-weight: 600; background: var(--bgColor-accent-muted, #ddf4ff); }\n @media (max-width: 900px) {\n body.markdown-body.has-file-tree, body.markdown-body.has-file-tree.file-sidebar-collapsed { width: calc(100% - 24px); margin: 0 12px; padding: 12px 0 0; grid-template-columns: minmax(0, 1fr); grid-template-areas: \"toc\" \"content\"; gap: 16px; }\n .file-sidebar { width: min(280px, calc(100vw - 24px)); box-shadow: 8px 0 24px rgba(31,35,40,.18); }\n }\n @media (max-width: 600px) { .file-tree-popover { width: calc(100vw - 40px); max-height: calc(100vh - 80px); } }\n ";
4
+ export declare const documentStyles = " body.markdown-body { box-sizing: border-box; min-width: 200px; width: calc(100% - 64px); max-width: none; margin: 0 32px; padding: 32px 0 0; display: grid; grid-template-columns: minmax(0, 1fr) 300px; grid-template-areas: \"content toc\"; column-gap: 32px; align-items: start; }\n .markdown-content, .document-sidebar { box-sizing: border-box; }\n .markdown-content { grid-area: content; min-width: 0; margin-bottom: 72px; padding: clamp(28px, 3vw, 52px); border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; box-shadow: 0 1px 2px rgba(31, 35, 40, 0.04); }\n .markdown-content :is(h1, h2, h3, h4, h5, h6) { scroll-margin-top: 32px; }\n .code-block { margin-bottom: 16px; overflow: hidden; border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; }\n .code-toolbar { display: flex; min-height: 38px; align-items: center; justify-content: space-between; padding: 0 8px 0 14px; color: var(--fgColor-muted, #59636e); background: var(--bgColor-muted, #f6f8fa); border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .code-language { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }\n .code-tools { display: flex; gap: 2px; }\n .code-tool { display: inline-flex; min-height: 30px; align-items: center; justify-content: center; gap: 5px; padding: 4px 8px; color: inherit; font: inherit; font-size: 0.75rem; line-height: 1; background: transparent; border: 0; border-radius: 5px; cursor: pointer; }\n .code-tool-label, [data-copy-label] { display: inline-flex; align-items: center; line-height: 1; }\n .code-tool:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .code-tool:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .code-tool[aria-pressed=\"true\"] { color: var(--fgColor-accent, #0969da); background: var(--bgColor-accent-muted, #ddf4ff); }\n .code-block pre { margin: 0; border-radius: 0; }\n .code-block pre, .code-block pre code { color: var(--codeBlock-fgColor, #24292f); background: var(--codeBlock-bgColor, #fff); }\n .code-block pre code { display: block; }\n .code-block.is-wrapped pre code { white-space: pre-wrap; overflow-wrap: anywhere; }\n .panel-toggle-icon { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: transform 120ms ease; }\n .action-icon { display: block; width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }\n .table-of-contents ul { margin: 0; padding: 0; list-style: none; }\n .table-of-contents li { margin: 2px 0 2px calc(var(--toc-level) * 12px); }\n .table-of-contents a { position: relative; display: block; padding: 6px 10px; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 1.4; overflow-wrap: anywhere; text-decoration: none; border-radius: 0 6px 6px 0; transition: color 120ms ease, background-color 120ms ease; }\n .table-of-contents a::before { position: absolute; top: 0; bottom: 0; left: 0; width: 2px; background: transparent; content: \"\"; }\n .table-of-contents a:hover { color: var(--fgColor-default, #1f2328); background: var(--bgColor-muted, #f6f8fa); text-decoration: none; }\n .table-of-contents a:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .table-of-contents a[aria-current=\"location\"] { color: var(--fgColor-accent, #0969da); font-weight: 600; background: linear-gradient(90deg, var(--bgColor-accent-muted, #ddf4ff), transparent); }\n .table-of-contents a[aria-current=\"location\"]::before { background: var(--borderColor-accent-emphasis, #0969da); }\n @media (max-width: 900px) {\n body.markdown-body { width: calc(100% - 24px); max-width: none; margin: 0 12px; padding: 12px 0 0; grid-template-columns: minmax(0, 1fr); grid-template-areas: \"toc\" \"content\"; gap: 16px; }\n .markdown-content { margin-bottom: 32px; }\n }\n @media (max-width: 600px) { .markdown-content { padding: 24px 20px; border-radius: 6px; } }\n @media (prefers-reduced-motion: reduce) { .table-of-contents a, .panel-toggle-icon { transition: none; } }";
5
+ export declare const fileTreeStyles = " body.markdown-body.has-file-tree { width: 100%; margin: 0; padding: 32px 32px 0 0; grid-template-columns: 280px minmax(0, 1fr) 300px; grid-template-areas: \"files content toc\"; column-gap: 32px; }\n body.markdown-body.has-file-tree.file-sidebar-collapsed { width: calc(100% - 64px); margin: 0 32px; padding: 32px 0 0; grid-template-columns: minmax(0, 1fr) 300px; grid-template-areas: \"content toc\"; }\n .file-sidebar { grid-area: files; position: fixed; z-index: 45; top: 0; bottom: 0; left: 0; box-sizing: border-box; display: flex; width: 280px; min-height: 0; flex-direction: column; color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); border: 0; border-right: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 0; overflow: hidden; }\n .file-sidebar-header { display: flex; min-height: 52px; flex: none; align-items: center; gap: 9px; padding: 0 12px; font-size: 0.875rem; font-weight: 700; border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .file-sidebar-header > span { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-sidebar[hidden], .file-sidebar-open[hidden], .file-sidebar-close[hidden] { display: none; }\n .file-sidebar-close { position: fixed; z-index: 50; top: 13px; left: 12px; display: inline-flex; width: 30px; height: 30px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 6px; cursor: pointer; }\n .file-sidebar-close:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .file-sidebar-close:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .file-breadcrumbs { display: flex; align-items: center; gap: 8px; margin: 0; padding-bottom: 14px; border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .file-breadcrumbs ol { display: flex; min-width: 0; min-height: 28px; flex: 0 1 auto; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 0; padding: 0; list-style: none; }\n .file-breadcrumbs li { display: inline-block; min-width: 0; height: 28px; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 28px; }\n .file-breadcrumbs li + li::before { margin-right: 6px; color: var(--fgColor-muted, #818b98); content: \"/\"; }\n .file-breadcrumb-separator { height: 28px; margin-right: -2px; color: var(--fgColor-muted, #818b98); font-size: 0.875rem; line-height: 28px; }\n .file-breadcrumbs a { display: inline-block; height: 28px; color: var(--fgColor-accent, #0969da); font-weight: 500; line-height: 28px; text-decoration: none; vertical-align: baseline; }\n .file-breadcrumbs a:hover { text-decoration: underline; }\n .file-breadcrumbs [aria-current=\"page\"] { color: var(--fgColor-default, #1f2328); font-weight: 600; white-space: nowrap; }\n .file-sidebar-open { position: fixed; z-index: 50; top: 13px; left: 12px; display: inline-flex; width: 30px; height: 30px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 6px; cursor: pointer; }\n .file-tree-popover-toggle { position: relative; top: 1px; display: inline-flex; height: 28px; min-width: 0; flex: none; align-items: center; justify-content: center; gap: 3px; padding: 0; color: var(--fgColor-accent, #0969da); font: inherit; font-size: 0.875rem; font-weight: 600; line-height: 28px; background: transparent; border: 0; border-radius: 4px; cursor: pointer; }\n .file-tree-popover-toggle span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-sidebar-toggle-icon { display: block; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }\n .file-sidebar-open:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .file-sidebar-open:focus-visible, .file-tree-popover-toggle:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 2px; }\n .file-tree-popover-toggle:hover { color: var(--fgColor-accent, #0969da); text-decoration: underline; background: transparent; }\n .file-tree-popover-toggle:disabled { color: var(--fgColor-default, #1f2328); text-decoration: none; cursor: default; }\n .file-tree-popover-toggle:disabled .panel-toggle-icon { display: none; }\n .file-tree-popover-toggle .panel-toggle-icon { width: 13px; height: 13px; flex: none; transform: translateY(1px); }\n .copy-file-path .copy-icon { transform: none; }\n .file-tree-popover-toggle[aria-expanded=\"true\"] .panel-toggle-icon { transform: translateY(1px) rotate(180deg); }\n .copy-file-path { display: inline-flex; width: 28px; height: 28px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 5px; cursor: pointer; }\n .copy-file-path:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .copy-file-path:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 2px; }\n .file-tree { box-sizing: border-box; overflow: auto; padding: 12px; color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); scrollbar-width: thin; scrollbar-color: var(--borderColor-default, #d0d7de) transparent; }\n .file-tree-sidebar { min-height: 0; flex: 1; padding: 10px 12px 16px; }\n .file-tree-popover { position: absolute; z-index: 15; top: calc(100% + 6px); left: 0; width: min(360px, calc(100vw - 48px)); max-height: min(520px, calc(100vh - 96px)); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 8px; box-shadow: 0 8px 24px rgba(31,35,40,.16); }\n .file-tree-view-tabs { display: grid; grid-template-columns: 1fr 1fr; margin: 0 0 8px; padding: 2px; background: var(--bgColor-muted, #f6f8fa); border-radius: 6px; }\n .file-tree-view-tabs button { min-height: 28px; padding: 3px 8px; color: var(--fgColor-muted, #59636e); font: inherit; font-size: 0.75rem; font-weight: 600; background: transparent; border: 0; border-radius: 4px; cursor: pointer; }\n .file-tree-view-tabs button[aria-selected=\"true\"] { color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); box-shadow: 0 1px 2px rgba(31,35,40,.12); }\n .file-tree-view-tabs button:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 1px; }\n .file-tree-filter { margin: 0 0 8px; }\n .file-tree-filter-input { box-sizing: border-box; width: 100%; min-height: 32px; padding: 5px 9px; color: var(--fgColor-default, #1f2328); font: inherit; font-size: 0.8125rem; line-height: 1.4; background: var(--bgColor-default, #fff); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 6px; outline: none; }\n .file-tree-filter-input::placeholder { color: var(--fgColor-muted, #59636e); }\n .file-tree-filter-input:focus { border-color: var(--borderColor-accent-emphasis, #0969da); box-shadow: 0 0 0 2px var(--bgColor-accent-muted, #ddf4ff); }\n .file-tree-filter-empty { margin: 10px 4px 2px; color: var(--fgColor-muted, #59636e); font-size: 0.8125rem; text-align: center; }\n .file-tree ul { margin: 0; padding: 0; list-style: none; }\n .file-tree [hidden] { display: none; }\n .file-tree details { margin: 0; }\n .file-tree details > ul { margin-left: 10px; padding-left: 10px; border-left: 1px solid var(--borderColor-muted, #d8dee4); }\n .file-tree summary { padding: 5px 7px; color: var(--fgColor-default, #1f2328); font-size: 0.875rem; font-weight: 600; line-height: 1.35; border-radius: 5px; cursor: pointer; user-select: none; }\n .folder-icon { display: inline-block; width: 14px; height: 14px; margin-right: 5px; vertical-align: -2px; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }\n .file-tree summary:hover { background: var(--bgColor-muted, #f6f8fa); }\n .file-tree summary::marker { color: var(--fgColor-muted, #59636e); }\n .file-tree a { display: flex; margin: 1px 0; padding: 5px 8px; align-items: center; gap: 6px; overflow: hidden; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 1.35; text-decoration: none; white-space: nowrap; border-radius: 5px; }\n .file-tree-name { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; }\n .file-tree-comment-count { display: inline-flex; min-width: 18px; height: 18px; flex: none; align-items: center; justify-content: center; padding: 0 5px; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 600; line-height: 18px; background: var(--bgColor-neutral-muted, #818b981f); border-radius: 9px; }\n .file-tree-directory-comment-count { float: right; margin-left: 6px; }\n .file-tree details[open] > summary > .file-tree-directory-comment-count { display: none; }\n .file-tree a[aria-current=\"page\"] .file-tree-comment-count { color: var(--fgColor-accent, #0969da); background: var(--bgColor-default, #fff); }\n .file-tree a:hover { color: var(--fgColor-default, #1f2328); background: var(--bgColor-muted, #f6f8fa); text-decoration: none; }\n .file-tree a:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .file-tree a[aria-current=\"page\"] { color: var(--fgColor-accent, #0969da); font-weight: 600; background: var(--bgColor-accent-muted, #ddf4ff); }\n .file-tree-date { margin: 10px 0 3px; }\n .file-tree-date:first-child { margin-top: 4px; }\n .file-tree-date button { display: flex; width: 100%; min-height: 28px; align-items: center; gap: 4px; padding: 4px 7px; color: var(--fgColor-default, #1f2328); font: inherit; font-size: 0.75rem; font-weight: 600; text-align: left; background: transparent; border: 0; border-radius: 5px; cursor: pointer; }\n .file-tree-date button:hover { background: var(--bgColor-muted, #f6f8fa); }\n .file-tree-date button:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .file-tree-date button svg { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: transform 120ms ease; }\n .file-tree-date button[aria-expanded=\"false\"] svg { transform: rotate(-90deg); }\n .file-tree-date button span { min-width: 18px; margin-left: auto; padding: 1px 5px; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 600; line-height: 16px; text-align: center; background: var(--bgColor-neutral-muted, #818b981f); border-radius: 9px; }\n .file-tree-recent .is-date-collapsed { display: none; }\n .file-tree-directory-group { display: flex; min-width: 0; align-items: center; gap: 5px; margin: 7px 4px 2px; padding: 4px 6px; overflow: hidden; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 600; line-height: 1.25; background: var(--bgColor-muted, #f6f8fa); border-radius: 4px; }\n .file-tree-directory-group .folder-icon { width: 13px; height: 13px; flex: none; }\n .file-tree-directory-group span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-tree-recent-file a { align-items: flex-start; gap: 7px; }\n .file-tree-recent-label { display: flex; min-width: 0; flex: 1; flex-direction: column; gap: 1px; }\n .file-tree-recent-label .file-tree-name { width: 100%; color: var(--fgColor-default, #1f2328); font-size: 0.8125rem; font-weight: 600; }\n .file-tree-recent-file a:hover .file-tree-name { text-decoration: underline; text-underline-offset: 2px; }\n .file-tree-directory-path { display: flex; width: 100%; min-width: 0; align-items: center; gap: 4px; overflow: hidden; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 400; line-height: 1.25; white-space: nowrap; }\n .file-tree-directory-path .folder-icon { width: 11px; height: 11px; flex: none; margin: 0; }\n .file-tree-directory-path > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }\n .file-tree-recent-file.is-grouped .file-tree-directory-path { display: none; }\n .file-tree-recent-file .file-tree-comment-count { margin-top: 1px; }\n .file-tree-recent-file > a > time { width: 34px; flex: none; padding-top: 1px; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-variant-numeric: tabular-nums; line-height: 1.35; }\n .file-tree-recent-empty { margin: 10px 4px 2px; color: var(--fgColor-muted, #59636e); font-size: 0.8125rem; text-align: center; }\n @media (max-width: 900px) {\n body.markdown-body.has-file-tree, body.markdown-body.has-file-tree.file-sidebar-collapsed { width: calc(100% - 24px); margin: 0 12px; padding: 12px 0 0; grid-template-columns: minmax(0, 1fr); grid-template-areas: \"toc\" \"content\"; gap: 16px; }\n .file-sidebar { width: min(280px, calc(100vw - 24px)); box-shadow: 8px 0 24px rgba(31,35,40,.18); }\n }\n @media (max-width: 600px) { .file-tree-popover { width: calc(100vw - 40px); max-height: calc(100vh - 80px); } }\n ";
@@ -15,8 +15,6 @@ export const documentStyles = ` body.markdown-body { box-sizing: border-box;
15
15
  .markdown-content, .document-sidebar { box-sizing: border-box; }
16
16
  .markdown-content { grid-area: content; min-width: 0; margin-bottom: 72px; padding: clamp(28px, 3vw, 52px); border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; box-shadow: 0 1px 2px rgba(31, 35, 40, 0.04); }
17
17
  .markdown-content :is(h1, h2, h3, h4, h5, h6) { scroll-margin-top: 32px; }
18
- .document-metadata { display: flex; justify-content: flex-end; margin: -12px 0 28px; padding-bottom: 14px; border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }
19
- .document-modified { margin-left: auto; color: var(--fgColor-muted, #59636e); font-size: 0.75rem; line-height: 28px; white-space: nowrap; }
20
18
  .code-block { margin-bottom: 16px; overflow: hidden; border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; }
21
19
  .code-toolbar { display: flex; min-height: 38px; align-items: center; justify-content: space-between; padding: 0 8px 0 14px; color: var(--fgColor-muted, #59636e); background: var(--bgColor-muted, #f6f8fa); border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }
22
20
  .code-language { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
@@ -55,7 +53,6 @@ export const fileTreeStyles = ` body.markdown-body.has-file-tree { width: 100
55
53
  .file-sidebar-close { position: fixed; z-index: 50; top: 13px; left: 12px; display: inline-flex; width: 30px; height: 30px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 6px; cursor: pointer; }
56
54
  .file-sidebar-close:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }
57
55
  .file-sidebar-close:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }
58
- .file-navigation { position: relative; margin: -12px 0 28px; }
59
56
  .file-breadcrumbs { display: flex; align-items: center; gap: 8px; margin: 0; padding-bottom: 14px; border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }
60
57
  .file-breadcrumbs ol { display: flex; min-width: 0; min-height: 28px; flex: 0 1 auto; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 0; padding: 0; list-style: none; }
61
58
  .file-breadcrumbs li { display: inline-block; min-width: 0; height: 28px; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 28px; }
@@ -71,6 +68,8 @@ export const fileTreeStyles = ` body.markdown-body.has-file-tree { width: 100
71
68
  .file-sidebar-open:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }
72
69
  .file-sidebar-open:focus-visible, .file-tree-popover-toggle:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 2px; }
73
70
  .file-tree-popover-toggle:hover { color: var(--fgColor-accent, #0969da); text-decoration: underline; background: transparent; }
71
+ .file-tree-popover-toggle:disabled { color: var(--fgColor-default, #1f2328); text-decoration: none; cursor: default; }
72
+ .file-tree-popover-toggle:disabled .panel-toggle-icon { display: none; }
74
73
  .file-tree-popover-toggle .panel-toggle-icon { width: 13px; height: 13px; flex: none; transform: translateY(1px); }
75
74
  .copy-file-path .copy-icon { transform: none; }
76
75
  .file-tree-popover-toggle[aria-expanded="true"] .panel-toggle-icon { transform: translateY(1px) rotate(180deg); }
@@ -80,12 +79,17 @@ export const fileTreeStyles = ` body.markdown-body.has-file-tree { width: 100
80
79
  .file-tree { box-sizing: border-box; overflow: auto; padding: 12px; color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); scrollbar-width: thin; scrollbar-color: var(--borderColor-default, #d0d7de) transparent; }
81
80
  .file-tree-sidebar { min-height: 0; flex: 1; padding: 10px 12px 16px; }
82
81
  .file-tree-popover { position: absolute; z-index: 15; top: calc(100% + 6px); left: 0; width: min(360px, calc(100vw - 48px)); max-height: min(520px, calc(100vh - 96px)); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 8px; box-shadow: 0 8px 24px rgba(31,35,40,.16); }
82
+ .file-tree-view-tabs { display: grid; grid-template-columns: 1fr 1fr; margin: 0 0 8px; padding: 2px; background: var(--bgColor-muted, #f6f8fa); border-radius: 6px; }
83
+ .file-tree-view-tabs button { min-height: 28px; padding: 3px 8px; color: var(--fgColor-muted, #59636e); font: inherit; font-size: 0.75rem; font-weight: 600; background: transparent; border: 0; border-radius: 4px; cursor: pointer; }
84
+ .file-tree-view-tabs button[aria-selected="true"] { color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); box-shadow: 0 1px 2px rgba(31,35,40,.12); }
85
+ .file-tree-view-tabs button:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 1px; }
83
86
  .file-tree-filter { margin: 0 0 8px; }
84
87
  .file-tree-filter-input { box-sizing: border-box; width: 100%; min-height: 32px; padding: 5px 9px; color: var(--fgColor-default, #1f2328); font: inherit; font-size: 0.8125rem; line-height: 1.4; background: var(--bgColor-default, #fff); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 6px; outline: none; }
85
88
  .file-tree-filter-input::placeholder { color: var(--fgColor-muted, #59636e); }
86
89
  .file-tree-filter-input:focus { border-color: var(--borderColor-accent-emphasis, #0969da); box-shadow: 0 0 0 2px var(--bgColor-accent-muted, #ddf4ff); }
87
90
  .file-tree-filter-empty { margin: 10px 4px 2px; color: var(--fgColor-muted, #59636e); font-size: 0.8125rem; text-align: center; }
88
91
  .file-tree ul { margin: 0; padding: 0; list-style: none; }
92
+ .file-tree [hidden] { display: none; }
89
93
  .file-tree details { margin: 0; }
90
94
  .file-tree details > ul { margin-left: 10px; padding-left: 10px; border-left: 1px solid var(--borderColor-muted, #d8dee4); }
91
95
  .file-tree summary { padding: 5px 7px; color: var(--fgColor-default, #1f2328); font-size: 0.875rem; font-weight: 600; line-height: 1.35; border-radius: 5px; cursor: pointer; user-select: none; }
@@ -101,6 +105,29 @@ export const fileTreeStyles = ` body.markdown-body.has-file-tree { width: 100
101
105
  .file-tree a:hover { color: var(--fgColor-default, #1f2328); background: var(--bgColor-muted, #f6f8fa); text-decoration: none; }
102
106
  .file-tree a:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }
103
107
  .file-tree a[aria-current="page"] { color: var(--fgColor-accent, #0969da); font-weight: 600; background: var(--bgColor-accent-muted, #ddf4ff); }
108
+ .file-tree-date { margin: 10px 0 3px; }
109
+ .file-tree-date:first-child { margin-top: 4px; }
110
+ .file-tree-date button { display: flex; width: 100%; min-height: 28px; align-items: center; gap: 4px; padding: 4px 7px; color: var(--fgColor-default, #1f2328); font: inherit; font-size: 0.75rem; font-weight: 600; text-align: left; background: transparent; border: 0; border-radius: 5px; cursor: pointer; }
111
+ .file-tree-date button:hover { background: var(--bgColor-muted, #f6f8fa); }
112
+ .file-tree-date button:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }
113
+ .file-tree-date button svg { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: transform 120ms ease; }
114
+ .file-tree-date button[aria-expanded="false"] svg { transform: rotate(-90deg); }
115
+ .file-tree-date button span { min-width: 18px; margin-left: auto; padding: 1px 5px; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 600; line-height: 16px; text-align: center; background: var(--bgColor-neutral-muted, #818b981f); border-radius: 9px; }
116
+ .file-tree-recent .is-date-collapsed { display: none; }
117
+ .file-tree-directory-group { display: flex; min-width: 0; align-items: center; gap: 5px; margin: 7px 4px 2px; padding: 4px 6px; overflow: hidden; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 600; line-height: 1.25; background: var(--bgColor-muted, #f6f8fa); border-radius: 4px; }
118
+ .file-tree-directory-group .folder-icon { width: 13px; height: 13px; flex: none; }
119
+ .file-tree-directory-group span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
120
+ .file-tree-recent-file a { align-items: flex-start; gap: 7px; }
121
+ .file-tree-recent-label { display: flex; min-width: 0; flex: 1; flex-direction: column; gap: 1px; }
122
+ .file-tree-recent-label .file-tree-name { width: 100%; color: var(--fgColor-default, #1f2328); font-size: 0.8125rem; font-weight: 600; }
123
+ .file-tree-recent-file a:hover .file-tree-name { text-decoration: underline; text-underline-offset: 2px; }
124
+ .file-tree-directory-path { display: flex; width: 100%; min-width: 0; align-items: center; gap: 4px; overflow: hidden; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 400; line-height: 1.25; white-space: nowrap; }
125
+ .file-tree-directory-path .folder-icon { width: 11px; height: 11px; flex: none; margin: 0; }
126
+ .file-tree-directory-path > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
127
+ .file-tree-recent-file.is-grouped .file-tree-directory-path { display: none; }
128
+ .file-tree-recent-file .file-tree-comment-count { margin-top: 1px; }
129
+ .file-tree-recent-file > a > time { width: 34px; flex: none; padding-top: 1px; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-variant-numeric: tabular-nums; line-height: 1.35; }
130
+ .file-tree-recent-empty { margin: 10px 4px 2px; color: var(--fgColor-muted, #59636e); font-size: 0.8125rem; text-align: center; }
104
131
  @media (max-width: 900px) {
105
132
  body.markdown-body.has-file-tree, body.markdown-body.has-file-tree.file-sidebar-collapsed { width: calc(100% - 24px); margin: 0 12px; padding: 12px 0 0; grid-template-columns: minmax(0, 1fr); grid-template-areas: "toc" "content"; gap: 16px; }
106
133
  .file-sidebar { width: min(280px, calc(100vw - 24px)); box-shadow: 8px 0 24px rgba(31,35,40,.18); }
package/dist/types.d.ts CHANGED
@@ -39,6 +39,10 @@ export interface FileTreeFile {
39
39
  name: string;
40
40
  href: string;
41
41
  current?: boolean;
42
+ /** Path relative to the converted collection root. Defaults to name. */
43
+ path?: string;
44
+ /** ISO 8601 timestamp used by the optional recently updated view. */
45
+ modifiedAt?: string;
42
46
  /** Number of comments associated with the file. Omitted when unavailable. */
43
47
  commentCount?: number;
44
48
  }
@@ -1 +1 @@
1
- export declare function atomicWriteFile(path: string, content: string): Promise<void>;
1
+ export declare function atomicWriteFile(path: string, content: string | Uint8Array): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marksites",
3
- "version": "0.1.0",
3
+ "version": "0.2.2",
4
4
  "description": "Convert Markdown into standalone GitHub-styled HTML.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -10,7 +10,7 @@
10
10
  }
11
11
  },
12
12
  "bin": {
13
- "marksites": "./dist/cli.js"
13
+ "marksites": "dist/cli.js"
14
14
  },
15
15
  "files": [
16
16
  "dist"
@@ -30,14 +30,14 @@
30
30
  "node": ">=20"
31
31
  },
32
32
  "dependencies": {
33
- "github-markdown-css": "latest",
33
+ "github-markdown-css": "5.9.0",
34
34
  "github-slugger": "^2.0.0",
35
35
  "highlight.js": "^11.11.1",
36
36
  "ignore": "^7.0.6",
37
- "marked": "latest"
37
+ "marked": "18.0.6"
38
38
  },
39
39
  "devDependencies": {
40
- "@types/node": "latest",
41
- "typescript": "latest"
40
+ "@types/node": "26.1.1",
41
+ "typescript": "7.0.2"
42
42
  }
43
43
  }