@domphy/press 0.19.2 → 0.20.1

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.
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/build.ts
4
+ import { execSync } from "child_process";
4
5
  import {
5
6
  cpSync,
6
7
  existsSync,
@@ -11,7 +12,6 @@ import {
11
12
  } from "fs";
12
13
  import { dirname as dirname2, join as join2, relative as relative2, resolve as resolve2 } from "path";
13
14
  import { fileURLToPath } from "url";
14
- import { execSync } from "child_process";
15
15
  import { createApp, defineRoutes } from "@domphy/app";
16
16
  import { themeCSS } from "@domphy/theme";
17
17
 
@@ -52,8 +52,8 @@ var ALIASES = {
52
52
  py: "python"
53
53
  };
54
54
  var pending = null;
55
- function escapeHtml(text2) {
56
- return text2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
55
+ function escapeHtml(text3) {
56
+ return text3.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
57
57
  }
58
58
  function unwrapCode(html) {
59
59
  const match = html.match(/<code[^>]*>([\s\S]*)<\/code>/);
@@ -65,13 +65,15 @@ function parseFenceInfo(info) {
65
65
  const lineNumbers = info.includes(":line-numbers");
66
66
  const titleMatch = info.match(/\[([^\]]*[a-zA-Z.][^\]]*)\]/);
67
67
  const title = titleMatch ? titleMatch[1] : null;
68
- const rangeMatch = info.match(/\{([0-9,\s\-]+)\}/);
68
+ const rangeMatch = info.match(/\{([0-9,\s-]+)\}/);
69
69
  const highlightLines = /* @__PURE__ */ new Set();
70
70
  if (rangeMatch) {
71
71
  for (const part of rangeMatch[1].split(",")) {
72
72
  const range = part.trim().split("-").map(Number);
73
- if (range.length === 1 && !isNaN(range[0])) highlightLines.add(range[0]);
74
- else if (range.length === 2) for (let i = range[0]; i <= range[1]; i++) highlightLines.add(i);
73
+ if (range.length === 1 && !Number.isNaN(range[0]))
74
+ highlightLines.add(range[0]);
75
+ else if (range.length === 2)
76
+ for (let i = range[0]; i <= range[1]; i++) highlightLines.add(i);
75
77
  }
76
78
  }
77
79
  return { lang, highlightLines, lineNumbers, title };
@@ -126,7 +128,9 @@ async function createHighlighter() {
126
128
  return (code, lang) => {
127
129
  const resolved = ALIASES[lang?.toLowerCase()] ?? lang?.toLowerCase();
128
130
  if (!resolved || !loaded.has(resolved)) return escapeHtml(code);
129
- return unwrapCode(highlighter.codeToHtml(code, { lang: resolved, theme: THEME }));
131
+ return unwrapCode(
132
+ highlighter.codeToHtml(code, { lang: resolved, theme: THEME })
133
+ );
130
134
  };
131
135
  }
132
136
  function renderFence(code, info, highlight) {
@@ -136,7 +140,13 @@ function renderFence(code, info, highlight) {
136
140
  }
137
141
  const { cleanCode, lineClasses, hasFocus } = extractAnnotations(code);
138
142
  const innerHtml = highlight(cleanCode.trimEnd(), lang);
139
- const annotated = annotateLines(innerHtml, lineClasses, highlightLines, hasFocus, lineNumbers);
143
+ const annotated = annotateLines(
144
+ innerHtml,
145
+ lineClasses,
146
+ highlightLines,
147
+ hasFocus,
148
+ lineNumbers
149
+ );
140
150
  const hasAnnotations = highlightLines.size > 0 || lineClasses.size > 0;
141
151
  const titleHtml = title ? `<div class="code-block-title"><span>${escapeHtml(title)}</span></div>` : "";
142
152
  const preClass = [
@@ -150,52 +160,10 @@ function renderFence(code, info, highlight) {
150
160
 
151
161
  // src/layout.ts
152
162
  import { navLink } from "@domphy/app";
163
+ import { themeColor, themeSpacing } from "@domphy/theme";
153
164
  import { toolbar, toolbarSpacer } from "@domphy/ui";
154
165
 
155
- // src/routes.ts
156
- import { readdirSync, statSync } from "fs";
157
- import { join, posix, relative, sep } from "path";
158
- var NON_PAGE_DIRS = /* @__PURE__ */ new Set(["snippets", "demos", "node_modules", ".git"]);
159
- function routeForFile(srcRelativePath) {
160
- const posixPath = srcRelativePath.split(sep).join(posix.sep);
161
- const withoutExt = posixPath.replace(/\.md$/, "");
162
- const segments = withoutExt.split("/");
163
- const last = segments[segments.length - 1];
164
- if (last === "index") {
165
- segments.pop();
166
- return segments.length === 0 ? "/" : `/${segments.join("/")}/`;
167
- }
168
- return `/${segments.join("/")}`;
169
- }
170
- function outFileForRoute(route) {
171
- if (route === "/") return "index.html";
172
- const trimmed = route.replace(/^\/+/, "").replace(/\/+$/, "");
173
- return `${trimmed}/index.html`;
174
- }
175
- function listMarkdown(dir) {
176
- const found = [];
177
- for (const name of readdirSync(dir)) {
178
- const full = join(dir, name);
179
- const stats = statSync(full);
180
- if (stats.isDirectory()) {
181
- if (NON_PAGE_DIRS.has(name) || name.startsWith(".")) continue;
182
- found.push(...listMarkdown(full));
183
- } else if (name.endsWith(".md") && name.toLowerCase() !== "readme.md") {
184
- found.push(full);
185
- }
186
- }
187
- return found;
188
- }
189
- function discoverPages(srcDir) {
190
- const files = listMarkdown(srcDir);
191
- const pages = files.map((filePath) => {
192
- const rel = relative(srcDir, filePath);
193
- const route = routeForFile(rel);
194
- return { route, outFile: outFileForRoute(route), filePath };
195
- });
196
- pages.sort((a, b) => a.route.localeCompare(b.route));
197
- return pages;
198
- }
166
+ // src/routes-browser.ts
199
167
  function flattenSidebar(items) {
200
168
  const out = [];
201
169
  for (const item of items) {
@@ -226,6 +194,22 @@ function prevNextForRoute(route, config) {
226
194
  }
227
195
 
228
196
  // src/layout.ts
197
+ var style = (obj) => obj;
198
+ var tc = (tone, color) => themeColor(null, tone, color);
199
+ var ts = (n) => themeSpacing(n);
200
+ var bg = tc("inherit");
201
+ var bgSoft = tc("shift-1");
202
+ var bgMute = tc("shift-2");
203
+ var border = tc("shift-3");
204
+ var textSoft = tc("shift-6");
205
+ var text = tc("shift-9");
206
+ var textStrong = tc("shift-11");
207
+ var brand = tc("shift-9", "primary");
208
+ var brandHover = tc("shift-10", "primary");
209
+ var headerH = ts(14);
210
+ var sidebarW = ts(62);
211
+ var asideW = ts(56);
212
+ var contentMax = ts(190);
229
213
  var SOCIAL_LABELS = {
230
214
  github: "GitHub",
231
215
  twitter: "Twitter",
@@ -239,42 +223,140 @@ var SOCIAL_LABELS = {
239
223
  function socialLinkEl(social) {
240
224
  const name = social.icon.toLowerCase();
241
225
  const isUrl = social.icon.startsWith("http") || social.icon.startsWith("/");
242
- const innerEl = isUrl ? { img: null, src: social.icon, alt: social.ariaLabel ?? name, width: "18", height: "18" } : { span: "", class: `dp-social-icon dp-icon-${name}`, ariaHidden: "true" };
226
+ const innerEl = isUrl ? {
227
+ img: null,
228
+ src: social.icon,
229
+ alt: social.ariaLabel ?? name,
230
+ width: "18",
231
+ height: "18"
232
+ } : (
233
+ // dp-social-icon dp-icon-* classes drive SVG mask-image in pressCSS
234
+ {
235
+ span: "",
236
+ class: `dp-social-icon dp-icon-${name}`,
237
+ ariaHidden: "true"
238
+ }
239
+ );
243
240
  return {
244
241
  a: [innerEl],
245
242
  href: social.link,
246
- class: `dp-social-link dp-social-${name}`,
247
243
  ariaLabel: social.ariaLabel ?? SOCIAL_LABELS[name] ?? social.icon,
248
244
  target: "_blank",
249
- rel: "noopener noreferrer"
245
+ rel: "noopener noreferrer",
246
+ style: {
247
+ display: "inline-flex",
248
+ alignItems: "center",
249
+ justifyContent: "center",
250
+ width: ts(8.5),
251
+ height: ts(8.5),
252
+ borderRadius: ts(2),
253
+ color: textSoft,
254
+ background: bgSoft,
255
+ border: `1px solid ${border}`,
256
+ fontSize: "10px",
257
+ fontWeight: "700",
258
+ flexShrink: "0",
259
+ "&:hover": { color: text, borderColor: textSoft, textDecoration: "none" }
260
+ }
250
261
  };
251
262
  }
252
- function pageLink(text2, href, className) {
253
- return { a: text2, href, class: className, $: [navLink({ href })] };
263
+ function pageLink(text3, href) {
264
+ return { a: text3, href, $: [navLink({ href })] };
254
265
  }
255
266
  function navDropdown(item) {
267
+ const menuStyle = style({
268
+ display: "none",
269
+ position: "absolute",
270
+ top: `calc(100% + ${ts(2)})`,
271
+ right: "0",
272
+ background: bgSoft,
273
+ border: `1px solid ${border}`,
274
+ borderRadius: ts(2),
275
+ padding: ts(1.5),
276
+ minWidth: ts(40),
277
+ zIndex: "100",
278
+ flexDirection: "column",
279
+ gap: ts(0.5),
280
+ boxShadow: "0 4px 16px rgba(0,0,0,.1)",
281
+ "& a": {
282
+ display: "block",
283
+ padding: `${ts(1.25)} ${ts(2.5)}`,
284
+ borderRadius: ts(1.25),
285
+ fontSize: "13px"
286
+ },
287
+ "& a:hover": { background: bgMute }
288
+ });
256
289
  return {
257
290
  div: [
258
- { span: item.text, class: "dp-nav-dropdown-label" },
259
- { div: item.items.map((child) => pageLink(child.text, child.link)), class: "dp-nav-dropdown-menu" }
291
+ {
292
+ span: item.text,
293
+ style: {
294
+ color: textSoft,
295
+ fontSize: "14px",
296
+ fontWeight: "500",
297
+ cursor: "pointer",
298
+ userSelect: "none",
299
+ "&::after": { content: '" \u25BE"', fontSize: "10px", opacity: ".6" }
300
+ }
301
+ },
302
+ {
303
+ div: item.items.map((child) => pageLink(child.text, child.link)),
304
+ style: menuStyle
305
+ }
260
306
  ],
261
- class: "dp-nav-dropdown"
307
+ style: {
308
+ position: "relative",
309
+ display: "flex",
310
+ alignItems: "center",
311
+ "&:hover > div:last-child, &:focus-within > div:last-child": {
312
+ display: "flex"
313
+ }
314
+ }
262
315
  };
263
316
  }
264
317
  function announcementBar(config) {
265
318
  const bar = config.themeConfig.announcementBar;
266
319
  if (!bar) return null;
267
320
  const idAttr = bar.id ? bar.id : "";
268
- const children = [
269
- { span: bar.text, class: "dp-announcement-text" }
270
- ];
321
+ const children = [{ span: bar.text }];
271
322
  if (bar.dismissible !== false) {
272
- children.push({ button: "\u2715", type: "button", class: "dp-announcement-close", dataDismissAnnouncement: "", ariaLabel: "Dismiss" });
323
+ children.push({
324
+ button: "\u2715",
325
+ type: "button",
326
+ dataDismissAnnouncement: "",
327
+ ariaLabel: "Dismiss",
328
+ style: {
329
+ background: "none",
330
+ border: "none",
331
+ color: bg,
332
+ cursor: "pointer",
333
+ fontSize: "14px",
334
+ opacity: ".7",
335
+ padding: `${ts(0.5)} ${ts(1.5)}`,
336
+ borderRadius: ts(1),
337
+ flexShrink: "0",
338
+ "&:hover": { opacity: "1" }
339
+ }
340
+ });
273
341
  }
274
342
  return {
275
343
  div: children,
276
344
  class: "dp-announcement",
277
- ...idAttr ? { dataId: idAttr } : {}
345
+ // kept: JS uses querySelector('.dp-announcement')
346
+ ...idAttr ? { dataId: idAttr } : {},
347
+ style: {
348
+ display: "flex",
349
+ alignItems: "center",
350
+ justifyContent: "center",
351
+ gap: ts(3),
352
+ padding: `${ts(2.5)} ${ts(6)}`,
353
+ background: brand,
354
+ color: bg,
355
+ fontSize: "14px",
356
+ fontWeight: "500",
357
+ textAlign: "center",
358
+ "& a": { color: bg, fontWeight: "700" }
359
+ }
278
360
  };
279
361
  }
280
362
  function localeSwitcher(ctx) {
@@ -296,33 +378,116 @@ function localeSwitcher(ctx) {
296
378
  const links = entries.map(([key, locale]) => {
297
379
  const prefix = key === "/" ? "" : key.replace(/\/$/, "");
298
380
  const href = prefix + (barePath === "/" ? "/" : barePath);
381
+ const isActive = key === currentKey;
299
382
  return {
300
383
  a: locale.label,
301
384
  href,
302
- class: `dp-locale-option${key === currentKey ? " active" : ""}`,
303
- ...key === currentKey ? { ariaCurrent: "true" } : {},
304
- lang: locale.lang
385
+ ...isActive ? { ariaCurrent: "true" } : {},
386
+ lang: locale.lang,
387
+ style: {
388
+ display: "block",
389
+ padding: `${ts(1.25)} ${ts(2.5)}`,
390
+ borderRadius: ts(1.25),
391
+ fontSize: "13px",
392
+ color: textSoft,
393
+ ...isActive ? { color: brand, fontWeight: "600" } : {},
394
+ "&:hover": { background: bgMute, color: text, textDecoration: "none" }
395
+ }
305
396
  };
306
397
  });
398
+ const menuStyle = style({
399
+ display: "none",
400
+ position: "absolute",
401
+ top: `calc(100% + ${ts(2)})`,
402
+ right: "0",
403
+ background: bgSoft,
404
+ border: `1px solid ${border}`,
405
+ borderRadius: ts(2),
406
+ padding: ts(1.5),
407
+ minWidth: ts(32),
408
+ zIndex: "200",
409
+ flexDirection: "column",
410
+ gap: ts(0.5),
411
+ boxShadow: "0 4px 16px rgba(0,0,0,.1)"
412
+ });
307
413
  return {
308
414
  div: [
309
- { span: ["\u{1F310} ", currentLocale.label], class: "dp-locale-current" },
310
- { div: links, class: "dp-locale-menu" }
415
+ {
416
+ span: ["\u{1F310} ", currentLocale.label],
417
+ style: {
418
+ color: textSoft,
419
+ fontSize: "13px",
420
+ fontWeight: "500",
421
+ cursor: "pointer",
422
+ userSelect: "none",
423
+ padding: `${ts(1)} ${ts(2)}`,
424
+ border: `1px solid ${border}`,
425
+ borderRadius: ts(1.5),
426
+ background: bgSoft,
427
+ whiteSpace: "nowrap",
428
+ display: "flex",
429
+ alignItems: "center",
430
+ gap: ts(1),
431
+ "&::after": { content: '" \u25BE"', fontSize: "10px", opacity: ".6" }
432
+ }
433
+ },
434
+ { div: links, style: menuStyle }
311
435
  ],
312
- class: "dp-locale-switcher",
313
- ariaLabel: "Select language"
436
+ ariaLabel: "Select language",
437
+ style: {
438
+ position: "relative",
439
+ display: "flex",
440
+ alignItems: "center",
441
+ "&:hover > div:last-child, &:focus-within > div:last-child": {
442
+ display: "flex"
443
+ }
444
+ }
314
445
  };
315
446
  }
316
447
  function header(ctx) {
317
448
  const { config } = ctx;
318
449
  const searchEnabled = config.themeConfig.search !== false;
319
450
  const logo = config.themeConfig.logo;
320
- const logoInner = logo ? typeof logo === "string" ? [{ img: null, src: logo, alt: config.title, class: "dp-logo-img" }] : [
321
- { img: null, src: logo.light, alt: config.title, class: "dp-logo-img dp-logo-light" },
322
- { img: null, src: logo.dark, alt: config.title, class: "dp-logo-img dp-logo-dark" }
451
+ const logoInner = logo ? typeof logo === "string" ? [
452
+ {
453
+ img: null,
454
+ src: logo,
455
+ alt: config.title,
456
+ style: { height: ts(7), width: "auto", display: "block" }
457
+ }
458
+ ] : [
459
+ {
460
+ img: null,
461
+ src: logo.light,
462
+ alt: config.title,
463
+ class: "dp-logo-light",
464
+ style: { height: ts(7), width: "auto", display: "block" }
465
+ },
466
+ {
467
+ img: null,
468
+ src: logo.dark,
469
+ alt: config.title,
470
+ class: "dp-logo-dark",
471
+ style: { height: ts(7), width: "auto", display: "block" }
472
+ }
323
473
  ] : [];
324
- const logoEl = logo ? { a: logoInner, href: config.base, class: "dp-logo" } : { a: config.title, href: config.base, class: "dp-logo" };
325
- const socialEls = (config.themeConfig.socialLinks ?? []).map(socialLinkEl);
474
+ const logoStyle = {
475
+ fontWeight: "700",
476
+ fontSize: "18px",
477
+ color: textStrong,
478
+ whiteSpace: "nowrap",
479
+ flexShrink: "0",
480
+ textDecoration: "none",
481
+ "&:hover": { textDecoration: "none" }
482
+ };
483
+ const logoEl = logo ? { a: logoInner, href: config.base, style: logoStyle } : {
484
+ a: config.title,
485
+ href: config.base,
486
+ style: logoStyle
487
+ };
488
+ const socialEls = (config.themeConfig.socialLinks ?? []).map(
489
+ socialLinkEl
490
+ );
326
491
  const localeEl = localeSwitcher(ctx);
327
492
  return {
328
493
  header: [
@@ -330,48 +495,153 @@ function header(ctx) {
330
495
  toolbarSpacer(),
331
496
  {
332
497
  nav: config.themeConfig.nav.map(
333
- (item) => item.items ? navDropdown(item) : pageLink(item.text, item.link)
498
+ (item) => item.items ? navDropdown(
499
+ item
500
+ ) : pageLink(item.text, item.link)
334
501
  ),
335
502
  $: [toolbar({ gap: 4 })],
336
- class: "dp-nav",
337
- ariaLabel: "Primary"
503
+ ariaLabel: "Primary",
504
+ style: {
505
+ "& a": {
506
+ color: textSoft,
507
+ fontSize: "14px",
508
+ fontWeight: "500",
509
+ whiteSpace: "nowrap",
510
+ lineHeight: "1"
511
+ },
512
+ "& a:hover, & a[aria-current='page']": {
513
+ color: brand,
514
+ textDecoration: "none"
515
+ },
516
+ "@media (max-width: 860px)": { display: "none" }
517
+ }
338
518
  },
339
519
  {
340
520
  div: [
341
- ...searchEnabled ? [{
342
- div: [{
343
- input: null,
344
- type: "search",
345
- placeholder: typeof config.themeConfig.search === "object" && config.themeConfig.search.placeholder || "Search...",
346
- class: "dp-search-static",
347
- ariaLabel: "Search documentation"
348
- }],
349
- dataIsland: "search",
350
- class: "dp-search-slot"
351
- }] : [],
521
+ ...searchEnabled ? [
522
+ {
523
+ div: [
524
+ {
525
+ input: null,
526
+ type: "search",
527
+ placeholder: typeof config.themeConfig.search === "object" && config.themeConfig.search.placeholder || "Search...",
528
+ ariaLabel: "Search documentation",
529
+ style: {
530
+ width: "100%",
531
+ height: ts(8),
532
+ padding: `0 ${ts(2.5)}`,
533
+ border: `1px solid ${border}`,
534
+ borderRadius: ts(1.5),
535
+ background: bgSoft,
536
+ color: textSoft,
537
+ fontSize: "13px",
538
+ fontFamily: "inherit",
539
+ outline: "none",
540
+ cursor: "pointer",
541
+ "&::placeholder": { color: textSoft }
542
+ }
543
+ }
544
+ ],
545
+ dataIsland: "search",
546
+ style: {
547
+ width: ts(50),
548
+ "@media (max-width: 860px)": { width: ts(35) }
549
+ }
550
+ }
551
+ ] : [],
352
552
  ...socialEls,
353
553
  ...localeEl ? [localeEl] : [],
354
- { button: "\u25D0", type: "button", class: "dp-theme-toggle", ariaLabel: "Toggle dark mode", dataThemeToggle: "" },
355
- { button: "\u2630", type: "button", class: "dp-menu-toggle", ariaLabel: "Toggle menu", dataMenuToggle: "" }
554
+ {
555
+ button: "\u25D0",
556
+ type: "button",
557
+ ariaLabel: "Toggle dark mode",
558
+ dataThemeToggle: "",
559
+ style: {
560
+ border: `1px solid ${border}`,
561
+ background: bgSoft,
562
+ color: text,
563
+ borderRadius: ts(2),
564
+ width: ts(8.5),
565
+ height: ts(8.5),
566
+ cursor: "pointer",
567
+ fontSize: "16px",
568
+ flexShrink: "0"
569
+ }
570
+ },
571
+ {
572
+ button: "\u2630",
573
+ type: "button",
574
+ ariaLabel: "Toggle menu",
575
+ dataMenuToggle: "",
576
+ style: {
577
+ border: `1px solid ${border}`,
578
+ background: bgSoft,
579
+ color: text,
580
+ borderRadius: ts(2),
581
+ width: ts(8.5),
582
+ height: ts(8.5),
583
+ cursor: "pointer",
584
+ fontSize: "16px",
585
+ flexShrink: "0",
586
+ display: "none",
587
+ "@media (max-width: 860px)": { display: "block" }
588
+ }
589
+ }
356
590
  ],
357
591
  $: [toolbar({ gap: 2 })],
358
- class: "dp-header-actions"
592
+ style: { flexShrink: "0" }
359
593
  }
360
594
  ],
361
595
  $: [toolbar({ gap: 4 })],
362
- class: "dp-header"
596
+ style: {
597
+ position: "sticky",
598
+ top: "0",
599
+ height: headerH,
600
+ background: bg,
601
+ borderBottom: `1px solid ${border}`,
602
+ zIndex: "100",
603
+ padding: `0 ${ts(6)}`,
604
+ "@media (max-width: 860px)": { padding: `0 ${ts(3)}` }
605
+ }
363
606
  };
364
607
  }
365
- function sidebarBadge(badge) {
366
- return { span: badge.text, class: `dp-badge dp-badge-${badge.type ?? "tip"}` };
608
+ function badgeEl(badge) {
609
+ const colorMap = {
610
+ tip: brand,
611
+ info: textSoft,
612
+ warning: tc("shift-9", "warning"),
613
+ danger: tc("shift-9", "danger")
614
+ };
615
+ const bgMap = {
616
+ tip: `color-mix(in srgb,${brand} 12%,${bg})`,
617
+ info: bgMute,
618
+ warning: `color-mix(in srgb,${tc("shift-9", "warning")} 12%,${bg})`,
619
+ danger: `color-mix(in srgb,${tc("shift-9", "danger")} 12%,${bg})`
620
+ };
621
+ const type = badge.type ?? "tip";
622
+ return {
623
+ span: badge.text,
624
+ style: {
625
+ display: "inline-block",
626
+ padding: `${ts(0.5)} ${ts(1.75)}`,
627
+ borderRadius: ts(2.5),
628
+ fontSize: "11px",
629
+ fontWeight: "700",
630
+ lineHeight: "1.4",
631
+ whiteSpace: "nowrap",
632
+ verticalAlign: "middle",
633
+ background: bgMap[type] ?? bgMute,
634
+ color: colorMap[type] ?? textSoft
635
+ }
636
+ };
367
637
  }
368
- function pageLinkWithBadge(text2, href, badge) {
369
- if (!badge) return pageLink(text2, href);
638
+ function pageLinkWithBadge(text3, href, badge) {
639
+ if (!badge) return pageLink(text3, href);
370
640
  return {
371
- a: [{ span: text2 }, sidebarBadge(badge)],
641
+ a: [{ span: text3 }, badgeEl(badge)],
372
642
  href,
373
643
  $: [navLink({ href })],
374
- class: "dp-sidebar-link-with-badge"
644
+ style: { display: "flex", alignItems: "center" }
375
645
  };
376
646
  }
377
647
  function sidebarGroup(group) {
@@ -383,63 +653,215 @@ function sidebarGroup(group) {
383
653
  const titleChildren = [
384
654
  { span: group.text }
385
655
  ];
386
- if (group.badge) titleChildren.push(sidebarBadge(group.badge));
656
+ if (group.badge) titleChildren.push(badgeEl(group.badge));
387
657
  if (isCollapsible) {
388
658
  titleChildren.push({
389
659
  button: group.collapsed ? "\u203A" : "\u2039",
390
660
  type: "button",
391
- class: "dp-sidebar-toggle",
392
661
  ariaLabel: group.collapsed ? "Expand" : "Collapse",
393
- dataSidebarToggle: ""
662
+ dataSidebarToggle: "",
663
+ style: {
664
+ marginLeft: "auto",
665
+ background: "none",
666
+ border: "none",
667
+ cursor: "pointer",
668
+ color: textSoft,
669
+ fontSize: "14px",
670
+ padding: `0 ${ts(1)}`,
671
+ lineHeight: "1",
672
+ "&:hover": { color: text }
673
+ }
394
674
  });
395
675
  }
396
- children.push({ div: titleChildren, class: "dp-sidebar-title" });
676
+ children.push({
677
+ div: titleChildren,
678
+ style: {
679
+ display: "flex",
680
+ alignItems: "center",
681
+ gap: ts(1.5),
682
+ fontSize: "13px",
683
+ fontWeight: "700",
684
+ color: textStrong,
685
+ margin: `${ts(2)} 0 ${ts(1)}`
686
+ }
687
+ });
397
688
  }
398
689
  if (group.items) {
399
690
  const itemsEl = [];
400
691
  for (const item of group.items) {
401
692
  if (item.items) {
402
- itemsEl.push({ div: item.text, class: "dp-sidebar-subtitle" });
693
+ itemsEl.push({
694
+ div: item.text,
695
+ style: {
696
+ fontSize: "12px",
697
+ color: textSoft,
698
+ padding: `${ts(1)} ${ts(3)}`,
699
+ fontWeight: "600"
700
+ }
701
+ });
403
702
  for (const leaf of item.items) {
404
- if (leaf.link) itemsEl.push(pageLinkWithBadge(leaf.text, leaf.link, leaf.badge));
703
+ if (leaf.link)
704
+ itemsEl.push(pageLinkWithBadge(leaf.text, leaf.link, leaf.badge));
405
705
  }
406
706
  } else if (item.link) {
407
707
  itemsEl.push(pageLinkWithBadge(item.text, item.link, item.badge));
408
708
  }
409
709
  }
410
- children.push({ div: itemsEl, class: "dp-sidebar-items" });
710
+ children.push({
711
+ div: itemsEl,
712
+ class: "dp-sidebar-items",
713
+ style: { display: "flex", flexDirection: "column" }
714
+ });
411
715
  }
412
- const groupClass = ["dp-sidebar-group", isCollapsible && group.collapsed ? "collapsed" : ""].filter(Boolean).join(" ");
413
- return { div: children, class: groupClass };
716
+ const groupClass = [
717
+ "dp-sidebar-group",
718
+ isCollapsible && group.collapsed ? "collapsed" : ""
719
+ ].filter(Boolean).join(" ");
720
+ return {
721
+ div: children,
722
+ class: groupClass,
723
+ style: { marginBottom: ts(3.5) }
724
+ };
414
725
  }
415
726
  function sidebar(ctx) {
416
727
  const groups = sidebarForRoute(ctx.route, ctx.config);
417
- return { nav: groups.map(sidebarGroup), class: "dp-sidebar", ariaLabel: "Documentation" };
728
+ return {
729
+ nav: groups.map(sidebarGroup),
730
+ ariaLabel: "Documentation",
731
+ // used as stable selector in pressCSS mobile-open rule
732
+ style: {
733
+ position: "sticky",
734
+ top: headerH,
735
+ maxHeight: `calc(100vh - ${headerH})`,
736
+ overflowY: "auto",
737
+ padding: `${ts(6)} ${ts(3)} ${ts(12)} ${ts(6)}`,
738
+ borderRight: `1px solid ${border}`,
739
+ "& a": {
740
+ display: "flex",
741
+ alignItems: "center",
742
+ gap: ts(1.5),
743
+ padding: `${ts(1.25)} ${ts(3)}`,
744
+ fontSize: "14px",
745
+ color: textSoft,
746
+ borderRadius: ts(1.5)
747
+ },
748
+ "& a:hover": { color: text, textDecoration: "none" },
749
+ "& a[aria-current='page']": {
750
+ color: brand,
751
+ fontWeight: "600",
752
+ background: bgSoft
753
+ },
754
+ "@media (max-width: 860px)": {
755
+ position: "fixed",
756
+ top: headerH,
757
+ left: "0",
758
+ bottom: "0",
759
+ width: "80%",
760
+ maxWidth: ts(80),
761
+ background: bg,
762
+ zIndex: "25",
763
+ transform: "translateX(-100%)",
764
+ transition: "transform .2s ease",
765
+ maxHeight: "none"
766
+ }
767
+ }
768
+ };
418
769
  }
419
770
  function tocAside(ctx) {
420
771
  if (ctx.frontmatter.aside === false) return null;
421
772
  const [minLevel, maxLevel] = ctx.config.themeConfig.outline?.level ?? [2, 3];
422
- const entries = ctx.toc.filter((e) => e.level >= minLevel && e.level <= maxLevel);
773
+ const entries = ctx.toc.filter(
774
+ (e) => e.level >= minLevel && e.level <= maxLevel
775
+ );
423
776
  if (entries.length === 0) return null;
424
777
  const tocTitle = ctx.config.themeConfig.tocTitle ?? "On this page";
778
+ const indentMap = { 2: "0", 3: ts(3), 4: ts(6) };
425
779
  return {
426
780
  aside: [
427
- { div: tocTitle, class: "dp-aside-title" },
428
- { nav: entries.map((e) => ({ a: e.text, href: `#${e.slug}`, class: `dp-toc-${e.level}` })), class: "dp-toc" }
781
+ {
782
+ div: tocTitle,
783
+ style: { fontWeight: "700", marginBottom: ts(2), color: text }
784
+ },
785
+ {
786
+ nav: entries.map((e) => ({
787
+ a: e.text,
788
+ href: `#${e.slug}`,
789
+ style: {
790
+ display: "block",
791
+ padding: `${ts(0.75)} 0`,
792
+ color: textSoft,
793
+ paddingLeft: indentMap[e.level] ?? "0",
794
+ "&:hover": { color: brand, textDecoration: "none" }
795
+ }
796
+ }))
797
+ }
429
798
  ],
430
- class: "dp-aside"
799
+ style: {
800
+ position: "sticky",
801
+ top: headerH,
802
+ maxHeight: `calc(100vh - ${headerH})`,
803
+ overflowY: "auto",
804
+ padding: `${ts(8)} ${ts(6)}`,
805
+ fontSize: "13px"
806
+ }
431
807
  };
432
808
  }
433
809
  function prevNext(ctx) {
434
810
  const { prev, next } = prevNextForRoute(ctx.route, ctx.config);
435
811
  if (!prev && !next) return null;
812
+ const linkStyle = style({
813
+ display: "block",
814
+ padding: `${ts(3)} ${ts(4)}`,
815
+ border: `1px solid ${border}`,
816
+ borderRadius: ts(2),
817
+ fontWeight: "600",
818
+ flex: "1",
819
+ "&:hover": { borderColor: brand, textDecoration: "none" }
820
+ });
436
821
  return {
437
822
  nav: [
438
- prev ? { a: [{ small: "Previous" }, { span: prev.text }], href: prev.link, class: "prev" } : { span: "" },
439
- next ? { a: [{ small: "Next" }, { span: next.text }], href: next.link, class: "next" } : { span: "" }
823
+ prev ? {
824
+ a: [
825
+ {
826
+ small: "Previous",
827
+ style: {
828
+ display: "block",
829
+ color: textSoft,
830
+ fontWeight: "400",
831
+ fontSize: "12px"
832
+ }
833
+ },
834
+ { span: prev.text }
835
+ ],
836
+ href: prev.link,
837
+ style: linkStyle
838
+ } : { span: "" },
839
+ next ? {
840
+ a: [
841
+ {
842
+ small: "Next",
843
+ style: {
844
+ display: "block",
845
+ color: textSoft,
846
+ fontWeight: "400",
847
+ fontSize: "12px"
848
+ }
849
+ },
850
+ { span: next.text }
851
+ ],
852
+ href: next.link,
853
+ style: { ...linkStyle, textAlign: "right" }
854
+ } : { span: "" }
440
855
  ],
441
- class: "dp-prevnext",
442
- ariaLabel: "Page navigation"
856
+ ariaLabel: "Page navigation",
857
+ style: {
858
+ display: "flex",
859
+ justifyContent: "space-between",
860
+ gap: ts(4),
861
+ marginTop: ts(12),
862
+ paddingTop: ts(6),
863
+ borderTop: `1px solid ${border}`
864
+ }
443
865
  };
444
866
  }
445
867
  function docFooter(ctx) {
@@ -451,82 +873,361 @@ function docFooter(ctx) {
451
873
  const children = [];
452
874
  if (hasDate) {
453
875
  const date = new Date(ctx.lastUpdated);
454
- const formatted = date.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
455
- children.push({ span: [`Last updated: `, { time: formatted, dateTime: ctx.lastUpdated, class: "dp-last-updated-date" }], class: "dp-last-updated" });
876
+ const formatted = date.toLocaleDateString("en-US", {
877
+ year: "numeric",
878
+ month: "long",
879
+ day: "numeric"
880
+ });
881
+ children.push({
882
+ span: [`Last updated: `, { time: formatted, dateTime: ctx.lastUpdated }]
883
+ });
456
884
  }
457
885
  if (ctx.readingTime) {
458
- children.push({ span: `${ctx.readingTime} min read`, class: "dp-reading-time" });
886
+ children.push({ span: `\u{1F4D6} ${ctx.readingTime} min read` });
459
887
  }
460
888
  if (hasEdit) {
461
889
  const pattern = editLink.pattern;
462
890
  const href = pattern.replace(/:path/g, ctx.filePath);
463
- children.push({ a: editLink.text ?? "Edit this page", href, class: "dp-edit-link", target: "_blank", rel: "noopener noreferrer" });
891
+ children.push({
892
+ a: editLink.text ?? "Edit this page",
893
+ href,
894
+ target: "_blank",
895
+ rel: "noopener noreferrer",
896
+ style: { fontWeight: "500", fontSize: "13px" }
897
+ });
464
898
  }
465
- return { div: children, class: "dp-doc-footer" };
899
+ return {
900
+ div: children,
901
+ style: {
902
+ display: "flex",
903
+ alignItems: "center",
904
+ gap: ts(4),
905
+ flexWrap: "wrap",
906
+ marginTop: ts(8),
907
+ paddingTop: ts(5),
908
+ borderTop: `1px solid ${border}`,
909
+ fontSize: "13px",
910
+ color: textSoft
911
+ }
912
+ };
466
913
  }
467
914
  function pageBadge(frontmatter) {
468
915
  const badge = frontmatter.badge;
469
916
  if (!badge) return null;
470
- const text2 = typeof badge === "string" ? badge : badge.text ?? "";
917
+ const text22 = typeof badge === "string" ? badge : badge.text ?? "";
471
918
  const type = typeof badge === "object" ? badge.type ?? "tip" : "tip";
472
- if (!text2) return null;
473
- return { span: text2, class: `dp-badge dp-badge-${type} dp-page-badge` };
919
+ if (!text22) return null;
920
+ return badgeEl({
921
+ text: text22,
922
+ type
923
+ });
474
924
  }
475
925
  function resolveSlot(ctx, key, fallback) {
476
926
  const override = ctx.config.themeConfig.slots?.[key];
477
927
  return override ? override(ctx) : fallback(ctx);
478
928
  }
929
+ function contentDiv(body) {
930
+ return {
931
+ div: body,
932
+ style: {
933
+ maxWidth: contentMax,
934
+ "& h1": {
935
+ fontSize: "30px",
936
+ fontWeight: "700",
937
+ lineHeight: "1.25",
938
+ margin: `0 0 ${ts(6)}`,
939
+ letterSpacing: "-.02em",
940
+ color: textStrong
941
+ },
942
+ "& h2": {
943
+ fontSize: "22px",
944
+ fontWeight: "700",
945
+ margin: `${ts(11)} 0 ${ts(4)}`,
946
+ paddingTop: ts(5),
947
+ borderTop: `1px solid ${border}`,
948
+ letterSpacing: "-.01em",
949
+ color: textStrong
950
+ },
951
+ "& h3": {
952
+ fontSize: "18px",
953
+ fontWeight: "600",
954
+ margin: `${ts(7)} 0 ${ts(3)}`,
955
+ color: textStrong
956
+ },
957
+ "& h4": {
958
+ fontSize: "16px",
959
+ fontWeight: "600",
960
+ margin: `${ts(5.5)} 0 ${ts(2)}`,
961
+ color: textStrong
962
+ },
963
+ "& p": { margin: `${ts(4)} 0` },
964
+ "& ul, & ol": { margin: `${ts(4)} 0`, paddingLeft: "1.4em" },
965
+ "& li": { margin: `${ts(1.5)} 0` },
966
+ "& a": { fontWeight: "500" },
967
+ "& a[target='_blank']::after": {
968
+ content: '" \u2197"',
969
+ fontSize: ".75em",
970
+ opacity: ".6"
971
+ },
972
+ "& strong": { fontWeight: "600", color: textStrong },
973
+ "& em": { fontStyle: "italic" },
974
+ "& mark": {
975
+ background: `color-mix(in srgb,${tc("shift-6", "warning")} 40%,${bg})`,
976
+ color: "inherit",
977
+ padding: `${ts(0.25)} ${ts(0.75)}`,
978
+ borderRadius: ts(0.75)
979
+ },
980
+ "& sup": { fontSize: ".75em", verticalAlign: "super" },
981
+ "& sub": { fontSize: ".75em", verticalAlign: "sub" },
982
+ "& del": { opacity: ".5" },
983
+ "& blockquote": {
984
+ margin: `${ts(4)} 0`,
985
+ padding: `0 ${ts(4)}`,
986
+ borderLeft: `3px solid ${border}`,
987
+ color: textSoft
988
+ },
989
+ "& img": { maxWidth: "100%", height: "auto", borderRadius: ts(1.5) },
990
+ "& hr": {
991
+ border: "none",
992
+ borderTop: `1px solid ${border}`,
993
+ margin: `${ts(8)} 0`
994
+ },
995
+ "& :not(pre)>code": {
996
+ fontFamily: `ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace`,
997
+ fontSize: ".85em",
998
+ background: bgMute,
999
+ padding: `${ts(0.75)} ${ts(1.5)}`,
1000
+ borderRadius: ts(1)
1001
+ },
1002
+ "& pre": {
1003
+ margin: `${ts(4)} 0`,
1004
+ padding: `${ts(4)} ${ts(5)}`,
1005
+ background: bgSoft,
1006
+ border: `1px solid ${border}`,
1007
+ borderRadius: ts(2),
1008
+ overflowX: "auto",
1009
+ fontSize: "13.5px",
1010
+ lineHeight: "1.5"
1011
+ },
1012
+ "& pre code": {
1013
+ fontFamily: `ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace`,
1014
+ background: "none",
1015
+ padding: "0"
1016
+ },
1017
+ "& table": {
1018
+ borderCollapse: "collapse",
1019
+ margin: `${ts(4)} 0`,
1020
+ display: "block",
1021
+ overflowX: "auto"
1022
+ },
1023
+ "& th, & td": {
1024
+ border: `1px solid ${border}`,
1025
+ padding: `${ts(2)} ${ts(3.5)}`,
1026
+ textAlign: "left"
1027
+ },
1028
+ "& th": { background: bgSoft, fontWeight: "600" }
1029
+ }
1030
+ };
1031
+ }
479
1032
  function pageShell(ctx) {
480
- const slots = ctx.config.themeConfig.slots;
481
1033
  const showSidebar = ctx.frontmatter.sidebar !== false;
482
1034
  const main = [];
483
1035
  const badge = pageBadge(ctx.frontmatter);
484
- if (badge) main.push({ div: [badge], class: "dp-page-badge-row" });
485
- main.push({ div: ctx.body, class: "dp-content" });
1036
+ if (badge)
1037
+ main.push({
1038
+ div: [badge],
1039
+ style: { marginBottom: ts(-2) }
1040
+ });
1041
+ main.push(contentDiv(ctx.body));
486
1042
  const pn = resolveSlot(ctx, "prevNext", prevNext);
487
1043
  if (pn) main.push(pn);
488
1044
  const docFooterEl = resolveSlot(ctx, "docFooter", docFooter);
489
1045
  if (docFooterEl) main.push(docFooterEl);
490
1046
  const sidebarEl = showSidebar ? resolveSlot(ctx, "sidebar", sidebar) : null;
1047
+ const mainStyle = showSidebar ? {
1048
+ padding: `${ts(8)} ${ts(12)} ${ts(20)}`,
1049
+ minWidth: "0",
1050
+ "@media (max-width: 860px)": { padding: `${ts(6)} ${ts(5)} ${ts(16)}` }
1051
+ } : {
1052
+ padding: `${ts(8)} ${ts(12)} ${ts(20)}`,
1053
+ gridColumn: "1 / -1",
1054
+ maxWidth: contentMax,
1055
+ margin: "0 auto",
1056
+ "@media (max-width: 860px)": { padding: `${ts(6)} ${ts(5)} ${ts(16)}` }
1057
+ };
491
1058
  const shellChildren = [
492
1059
  ...sidebarEl ? [sidebarEl] : [],
493
- { main, class: `dp-main${showSidebar ? "" : " dp-main-full"}` }
1060
+ { main, style: mainStyle }
494
1061
  ];
495
1062
  const asideEl = resolveSlot(ctx, "aside", tocAside);
496
1063
  if (asideEl && showSidebar) shellChildren.push(asideEl);
497
1064
  const headerEl = resolveSlot(ctx, "header", header);
498
1065
  const bar = announcementBar(ctx.config);
499
- const footerContent = slots?.footer ? slots.footer(ctx) : { footer: ctx.config.themeConfig.footerMessage ?? "", class: "dp-footer" };
1066
+ const slots = ctx.config.themeConfig.slots;
1067
+ const footerContent = slots?.footer ? slots.footer(ctx) : {
1068
+ footer: ctx.config.themeConfig.footerMessage ?? "",
1069
+ style: {
1070
+ padding: `${ts(6)} ${ts(12)}`,
1071
+ borderTop: `1px solid ${border}`,
1072
+ color: textSoft,
1073
+ fontSize: "13px"
1074
+ }
1075
+ };
500
1076
  return {
501
1077
  div: [
502
1078
  ...bar ? [bar] : [],
503
1079
  ...headerEl ? [headerEl] : [],
504
- { div: shellChildren, class: "dp-shell" },
1080
+ {
1081
+ div: shellChildren,
1082
+ style: {
1083
+ display: "grid",
1084
+ gridTemplateColumns: showSidebar ? `${sidebarW} minmax(0,1fr) ${asideW}` : "1fr",
1085
+ alignItems: "start",
1086
+ maxWidth: "1440px",
1087
+ margin: "0 auto",
1088
+ "@media (max-width: 1200px)": showSidebar ? { gridTemplateColumns: `${sidebarW} minmax(0,1fr)` } : {},
1089
+ "@media (max-width: 860px)": { gridTemplateColumns: "1fr" }
1090
+ }
1091
+ },
505
1092
  ...footerContent ? [footerContent] : []
506
1093
  ]
507
1094
  };
508
1095
  }
509
1096
  function heroSection(hero) {
510
1097
  const children = [];
511
- if (hero.name) children.push({ div: hero.name, class: "dp-hero-name" });
512
- if (hero.text) children.push({ h1: hero.text, class: "dp-hero-text" });
513
- if (hero.tagline) children.push({ p: hero.tagline, class: "dp-hero-tagline" });
1098
+ if (hero.name)
1099
+ children.push({
1100
+ div: hero.name,
1101
+ style: {
1102
+ fontSize: "56px",
1103
+ fontWeight: "800",
1104
+ lineHeight: "1.1",
1105
+ letterSpacing: "-.03em",
1106
+ background: `linear-gradient(120deg,${brand},${tc("shift-7", "secondary")})`,
1107
+ WebkitBackgroundClip: "text",
1108
+ backgroundClip: "text",
1109
+ color: "transparent"
1110
+ }
1111
+ });
1112
+ if (hero.text)
1113
+ children.push({
1114
+ h1: hero.text,
1115
+ style: {
1116
+ fontSize: "30px",
1117
+ fontWeight: "700",
1118
+ margin: `${ts(3)} 0 0`,
1119
+ color: textStrong
1120
+ }
1121
+ });
1122
+ if (hero.tagline)
1123
+ children.push({
1124
+ p: hero.tagline,
1125
+ style: {
1126
+ fontSize: "18px",
1127
+ color: textSoft,
1128
+ maxWidth: ts(160),
1129
+ margin: `${ts(5)} auto 0`
1130
+ }
1131
+ });
514
1132
  if (hero.actions?.length) {
515
- children.push({ div: hero.actions.map((a) => ({ a: a.text, href: a.link, class: `dp-hero-action ${a.theme ?? "brand"}` })), class: "dp-hero-actions" });
1133
+ const actionStyle = (theme) => {
1134
+ if (!theme || theme === "brand")
1135
+ return {
1136
+ padding: `${ts(2.5)} ${ts(5.5)}`,
1137
+ borderRadius: ts(5.5),
1138
+ fontWeight: "600",
1139
+ fontSize: "15px",
1140
+ background: brand,
1141
+ color: bg,
1142
+ "&:hover": { background: brandHover, textDecoration: "none" }
1143
+ };
1144
+ return {
1145
+ padding: `${ts(2.5)} ${ts(5.5)}`,
1146
+ borderRadius: ts(5.5),
1147
+ fontWeight: "600",
1148
+ fontSize: "15px",
1149
+ background: bgSoft,
1150
+ color: text,
1151
+ border: `1px solid ${border}`,
1152
+ "&:hover": { borderColor: brand, textDecoration: "none" }
1153
+ };
1154
+ };
1155
+ children.push({
1156
+ div: hero.actions.map(
1157
+ (a) => ({
1158
+ a: a.text,
1159
+ href: a.link,
1160
+ style: actionStyle(a.theme)
1161
+ })
1162
+ ),
1163
+ style: {
1164
+ display: "flex",
1165
+ gap: ts(3),
1166
+ justifyContent: "center",
1167
+ marginTop: ts(7),
1168
+ flexWrap: "wrap"
1169
+ }
1170
+ });
516
1171
  }
517
- return { section: children, class: "dp-hero" };
1172
+ return {
1173
+ section: children,
1174
+ style: { textAlign: "center", padding: `${ts(10)} 0 ${ts(6)}` }
1175
+ };
518
1176
  }
519
1177
  function featuresSection(features) {
520
1178
  return {
521
1179
  div: features.map((f) => {
522
1180
  const inner = [];
523
- if (f.icon) inner.push({ div: f.icon, class: "dp-feature-icon" });
524
- inner.push({ div: f.title, class: "dp-feature-title" });
525
- inner.push({ p: f.details, class: "dp-feature-details" });
526
- const el = { div: inner, class: "dp-feature" };
527
- return f.link ? { a: [el], href: f.link, class: "dp-feature-link" } : el;
1181
+ if (f.icon)
1182
+ inner.push({
1183
+ div: f.icon,
1184
+ style: { fontSize: "28px", marginBottom: ts(3) }
1185
+ });
1186
+ inner.push({
1187
+ div: f.title,
1188
+ style: {
1189
+ fontWeight: "700",
1190
+ fontSize: "17px",
1191
+ marginBottom: ts(2),
1192
+ color: textStrong
1193
+ }
1194
+ });
1195
+ inner.push({
1196
+ p: f.details,
1197
+ style: {
1198
+ fontSize: "14px",
1199
+ color: textSoft,
1200
+ margin: "0",
1201
+ lineHeight: "1.5"
1202
+ }
1203
+ });
1204
+ const featureStyle = {
1205
+ padding: ts(5),
1206
+ background: bgSoft,
1207
+ border: `1px solid ${border}`,
1208
+ borderRadius: ts(3)
1209
+ };
1210
+ const el = {
1211
+ div: inner,
1212
+ style: featureStyle
1213
+ };
1214
+ return f.link ? {
1215
+ a: [el],
1216
+ href: f.link,
1217
+ style: {
1218
+ display: "block",
1219
+ color: "inherit",
1220
+ "&:hover": { textDecoration: "none" },
1221
+ "&:hover > div": { borderColor: brand }
1222
+ }
1223
+ } : el;
528
1224
  }),
529
- class: "dp-features"
1225
+ style: {
1226
+ display: "grid",
1227
+ gridTemplateColumns: `repeat(auto-fit,minmax(${ts(60)},1fr))`,
1228
+ gap: ts(4),
1229
+ margin: `${ts(10)} 0`
1230
+ }
530
1231
  };
531
1232
  }
532
1233
  function homeShell(ctx) {
@@ -535,14 +1236,29 @@ function homeShell(ctx) {
535
1236
  const features = ctx.frontmatter.features;
536
1237
  if (hero) main.push(heroSection(hero));
537
1238
  if (features?.length) main.push(featuresSection(features));
538
- main.push({ div: ctx.body, class: "dp-content dp-home" });
1239
+ main.push(contentDiv(ctx.body));
539
1240
  const bar = announcementBar(ctx.config);
540
1241
  return {
541
1242
  div: [
542
1243
  ...bar ? [bar] : [],
543
1244
  header(ctx),
544
- { main, class: "dp-main dp-main-home" },
545
- { footer: ctx.config.themeConfig.footerMessage ?? "", class: "dp-footer" }
1245
+ {
1246
+ main,
1247
+ style: {
1248
+ maxWidth: "1100px",
1249
+ margin: "0 auto",
1250
+ padding: `${ts(12)} ${ts(6)} ${ts(20)}`
1251
+ }
1252
+ },
1253
+ {
1254
+ footer: ctx.config.themeConfig.footerMessage ?? "",
1255
+ style: {
1256
+ padding: `${ts(6)} ${ts(12)}`,
1257
+ borderTop: `1px solid ${border}`,
1258
+ color: textSoft,
1259
+ fontSize: "13px"
1260
+ }
1261
+ }
546
1262
  ]
547
1263
  };
548
1264
  }
@@ -550,14 +1266,17 @@ function homeShell(ctx) {
550
1266
  // src/pipeline.ts
551
1267
  import { readFileSync } from "fs";
552
1268
  import { dirname, extname, isAbsolute, resolve } from "path";
553
- import { splitFrontmatter, tokensToDomphy } from "@domphy/markdown";
1269
+ import {
1270
+ splitFrontmatter,
1271
+ tokensToDomphy
1272
+ } from "@domphy/markdown";
554
1273
  import MarkdownIt from "markdown-it";
555
1274
  import container from "markdown-it-container";
1275
+ import emojiPkg from "markdown-it-emoji";
1276
+ import includeUntyped from "markdown-it-include";
556
1277
  import markUntyped from "markdown-it-mark";
557
1278
  import subUntyped from "markdown-it-sub";
558
1279
  import supUntyped from "markdown-it-sup";
559
- import includeUntyped from "markdown-it-include";
560
- import emojiPkg from "markdown-it-emoji";
561
1280
  var include = includeUntyped;
562
1281
  var markPlugin = markUntyped;
563
1282
  var subPlugin = subUntyped;
@@ -591,19 +1310,22 @@ function resolveSpecifier(spec, fileDir, docsDir) {
591
1310
  return resolve(fileDir, spec);
592
1311
  }
593
1312
  function expandCodeImports(body, fileDir, docsDir) {
594
- return body.replace(CODE_IMPORT_PATTERN, (_whole, rawPath, label) => {
595
- const absolute = resolveSpecifier(rawPath, fileDir, docsDir);
596
- const fence = "```";
597
- let contents;
598
- try {
599
- contents = readFileSync(absolute, "utf8");
600
- } catch {
601
- return [fence, `Could not import: ${rawPath}`, fence].join("\n");
1313
+ return body.replace(
1314
+ CODE_IMPORT_PATTERN,
1315
+ (_whole, rawPath, label) => {
1316
+ const absolute = resolveSpecifier(rawPath, fileDir, docsDir);
1317
+ const fence = "```";
1318
+ let contents;
1319
+ try {
1320
+ contents = readFileSync(absolute, "utf8");
1321
+ } catch {
1322
+ return [fence, `Could not import: ${rawPath}`, fence].join("\n");
1323
+ }
1324
+ const language = EXT_LANG[extname(absolute).toLowerCase()] ?? "";
1325
+ const info = label ? `${language} [${label}]` : language;
1326
+ return [fence + info, contents.trimEnd(), fence].join("\n");
602
1327
  }
603
- const language = EXT_LANG[extname(absolute).toLowerCase()] ?? "";
604
- const info = label ? `${language} [${label}]` : language;
605
- return [fence + info, contents.trimEnd(), fence].join("\n");
606
- });
1328
+ );
607
1329
  }
608
1330
  function stripScriptBlocks(source) {
609
1331
  return source.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").replace(/^\s*\n/, "");
@@ -632,9 +1354,9 @@ function buildTitleTokens(Token, tag, openType, closeType, className, title) {
632
1354
  const inline = new Token("inline", "", 0);
633
1355
  inline.content = title;
634
1356
  inline.children = [];
635
- const text2 = new Token("text", "", 0);
636
- text2.content = title;
637
- inline.children.push(text2);
1357
+ const text3 = new Token("text", "", 0);
1358
+ text3.content = title;
1359
+ inline.children.push(text3);
638
1360
  const close = new Token(closeType, tag, -1);
639
1361
  close.block = true;
640
1362
  return [open, inline, close];
@@ -658,7 +1380,10 @@ function buildCodeGroupTokens(Token, tokens, openIndex, closeIndex, groupId) {
658
1380
  const info = (token.info ?? "").trim();
659
1381
  const labelMatch = info.match(/\[([^\]]+)\]/);
660
1382
  const language = info.split(/\s+/, 1)[0] ?? "";
661
- fences.push({ token, label: labelMatch ? labelMatch[1] : language || "Code" });
1383
+ fences.push({
1384
+ token,
1385
+ label: labelMatch ? labelMatch[1] : language || "Code"
1386
+ });
662
1387
  }
663
1388
  if (fences.length === 0) return tokens.slice(openIndex, closeIndex + 1);
664
1389
  const inputsHtml = fences.map(
@@ -685,7 +1410,9 @@ function shapeContainers(tokens) {
685
1410
  let groupCounter = 0;
686
1411
  const ALL_ADMONITIONS = Object.keys(ADMONITION_TITLES).join("|");
687
1412
  const admonitionRe = new RegExp(`^container_(${ALL_ADMONITIONS})_open$`);
688
- const admonitionCloseRe = new RegExp(`^container_(${ALL_ADMONITIONS})_close$`);
1413
+ const admonitionCloseRe = new RegExp(
1414
+ `^container_(${ALL_ADMONITIONS})_close$`
1415
+ );
689
1416
  for (let i = 0; i < tokens.length; i++) {
690
1417
  const token = tokens[i];
691
1418
  const admonition = token.type.match(admonitionRe);
@@ -695,7 +1422,16 @@ function shapeContainers(tokens) {
695
1422
  token.attrSet("class", `custom-block ${type}`);
696
1423
  const custom = containerTitle(token.info.trim(), type);
697
1424
  output.push(token);
698
- output.push(...buildTitleTokens(Token, "p", "paragraph_open", "paragraph_close", "custom-block-title", custom || ADMONITION_TITLES[type] || type.toUpperCase()));
1425
+ output.push(
1426
+ ...buildTitleTokens(
1427
+ Token,
1428
+ "p",
1429
+ "paragraph_open",
1430
+ "paragraph_close",
1431
+ "custom-block-title",
1432
+ custom || ADMONITION_TITLES[type] || type.toUpperCase()
1433
+ )
1434
+ );
699
1435
  continue;
700
1436
  }
701
1437
  if (admonitionCloseRe.test(token.type)) {
@@ -707,7 +1443,16 @@ function shapeContainers(tokens) {
707
1443
  token.tag = "details";
708
1444
  token.attrSet("class", "custom-block details");
709
1445
  output.push(token);
710
- output.push(...buildTitleTokens(Token, "summary", "summary_open", "summary_close", null, containerTitle(token.info.trim(), "details") || "Details"));
1446
+ output.push(
1447
+ ...buildTitleTokens(
1448
+ Token,
1449
+ "summary",
1450
+ "summary_open",
1451
+ "summary_close",
1452
+ null,
1453
+ containerTitle(token.info.trim(), "details") || "Details"
1454
+ )
1455
+ );
711
1456
  continue;
712
1457
  }
713
1458
  if (token.type === "container_details_close") {
@@ -742,7 +1487,17 @@ function shapeContainers(tokens) {
742
1487
  token.attrSet("class", "custom-block card");
743
1488
  const title = containerTitle(token.info.trim(), "card");
744
1489
  output.push(token);
745
- if (title) output.push(...buildTitleTokens(Token, "p", "paragraph_open", "paragraph_close", "card-title", title));
1490
+ if (title)
1491
+ output.push(
1492
+ ...buildTitleTokens(
1493
+ Token,
1494
+ "p",
1495
+ "paragraph_open",
1496
+ "paragraph_close",
1497
+ "card-title",
1498
+ title
1499
+ )
1500
+ );
746
1501
  continue;
747
1502
  }
748
1503
  if (token.type === "container_card_close") {
@@ -759,7 +1514,17 @@ function shapeContainers(tokens) {
759
1514
  token.attrSet("class", "custom-block link-card");
760
1515
  token.attrSet("href", href);
761
1516
  output.push(token);
762
- if (title) output.push(...buildTitleTokens(Token, "p", "paragraph_open", "paragraph_close", "link-card-title", title));
1517
+ if (title)
1518
+ output.push(
1519
+ ...buildTitleTokens(
1520
+ Token,
1521
+ "p",
1522
+ "paragraph_open",
1523
+ "paragraph_close",
1524
+ "link-card-title",
1525
+ title
1526
+ )
1527
+ );
763
1528
  continue;
764
1529
  }
765
1530
  if (token.type === "container_link-card_close") {
@@ -783,7 +1548,9 @@ function shapeContainers(tokens) {
783
1548
  output.push(token);
784
1549
  continue;
785
1550
  }
786
- output.push(...buildCodeGroupTokens(Token, tokens, i, closeIndex, groupCounter++));
1551
+ output.push(
1552
+ ...buildCodeGroupTokens(Token, tokens, i, closeIndex, groupCounter++)
1553
+ );
787
1554
  i = closeIndex;
788
1555
  continue;
789
1556
  }
@@ -801,13 +1568,16 @@ function shapeTaskLists(tokens) {
801
1568
  if (prev?.type !== "list_item_open") continue;
802
1569
  const firstChild = token.children[0];
803
1570
  if (firstChild.type !== "text") continue;
804
- const text2 = firstChild.content;
805
- const isTask = text2.startsWith("[ ] ") || text2.startsWith("[x] ") || text2.startsWith("[X] ");
1571
+ const text3 = firstChild.content;
1572
+ const isTask = text3.startsWith("[ ] ") || text3.startsWith("[x] ") || text3.startsWith("[X] ");
806
1573
  if (!isTask) continue;
807
- const checked = text2[1].toLowerCase() === "x";
808
- firstChild.content = text2.slice(4);
1574
+ const checked = text3[1].toLowerCase() === "x";
1575
+ firstChild.content = text3.slice(4);
809
1576
  token.content = token.content.replace(/^\[[ xX]\] /, "");
810
- prev.attrSet("class", ((prev.attrGet("class") ?? "") + " task-list-item").trim());
1577
+ prev.attrSet(
1578
+ "class",
1579
+ `${prev.attrGet("class") ?? ""} task-list-item`.trim()
1580
+ );
811
1581
  const checkToken = new Token("html_inline", "", 0);
812
1582
  checkToken.content = `<input type="checkbox"${checked ? " checked" : ""} disabled class="task-list-check" aria-label="${checked ? "done" : "todo"}">`;
813
1583
  token.children.unshift(checkToken);
@@ -824,7 +1594,15 @@ function createParser(docsDir, highlight) {
824
1594
  md.use(emojiPlugin);
825
1595
  const noopRender = () => "";
826
1596
  const ADMONITION_NAMES = Object.keys(ADMONITION_TITLES);
827
- for (const name of [...ADMONITION_NAMES, "details", "code-group", "steps", "card", "card-grid", "link-card"]) {
1597
+ for (const name of [
1598
+ ...ADMONITION_NAMES,
1599
+ "details",
1600
+ "code-group",
1601
+ "steps",
1602
+ "card",
1603
+ "card-grid",
1604
+ "link-card"
1605
+ ]) {
828
1606
  md.use(container, name, { render: noopRender });
829
1607
  }
830
1608
  md.core.ruler.push("press_containers", (state) => {
@@ -890,12 +1668,22 @@ function injectHeadingAnchors(elements) {
890
1668
  if (tag && typeof rec.id === "string") {
891
1669
  const id = rec.id;
892
1670
  const children = Array.isArray(rec[tag]) ? [...rec[tag]] : rec[tag] != null ? [rec[tag]] : [];
893
- children.push({ a: "#", href: `#${id}`, class: "header-anchor", ariaHidden: "true" });
1671
+ children.push({
1672
+ a: "#",
1673
+ href: `#${id}`,
1674
+ class: "header-anchor",
1675
+ ariaHidden: "true"
1676
+ });
894
1677
  return { ...rec, [tag]: children };
895
1678
  }
896
- const tag2 = Object.keys(rec).find((k) => /^[a-z][a-z0-9]*$/.test(k) && k !== "style" && k !== "class" && !k.startsWith("data") && !k.startsWith("on") && !k.startsWith("aria") && !k.startsWith("_") && k !== "$" && k !== "href" && k !== "src" && k !== "id" && k !== "type" && k !== "name");
1679
+ const tag2 = Object.keys(rec).find(
1680
+ (k) => /^[a-z][a-z0-9]*$/.test(k) && k !== "style" && k !== "class" && !k.startsWith("data") && !k.startsWith("on") && !k.startsWith("aria") && !k.startsWith("_") && k !== "$" && k !== "href" && k !== "src" && k !== "id" && k !== "type" && k !== "name"
1681
+ );
897
1682
  if (tag2 && Array.isArray(rec[tag2])) {
898
- return { ...rec, [tag2]: injectHeadingAnchors(rec[tag2]) };
1683
+ return {
1684
+ ...rec,
1685
+ [tag2]: injectHeadingAnchors(rec[tag2])
1686
+ };
899
1687
  }
900
1688
  return el;
901
1689
  });
@@ -915,29 +1703,80 @@ async function renderDoc(source, options) {
915
1703
  return { frontmatter, body: withAnchors, toc, islands: [], title };
916
1704
  }
917
1705
 
1706
+ // src/routes.ts
1707
+ import { readdirSync, statSync } from "fs";
1708
+ import { join, relative } from "path";
1709
+ function listMarkdown(dir) {
1710
+ const found = [];
1711
+ for (const name of readdirSync(dir)) {
1712
+ const full = join(dir, name);
1713
+ const stats = statSync(full);
1714
+ if (stats.isDirectory()) {
1715
+ const NON_PAGE_DIRS = /* @__PURE__ */ new Set([
1716
+ "snippets",
1717
+ "demos",
1718
+ "node_modules",
1719
+ ".git"
1720
+ ]);
1721
+ if (NON_PAGE_DIRS.has(name) || name.startsWith(".")) continue;
1722
+ found.push(...listMarkdown(full));
1723
+ } else if (name.endsWith(".md") && name.toLowerCase() !== "readme.md") {
1724
+ found.push(full);
1725
+ }
1726
+ }
1727
+ return found;
1728
+ }
1729
+ function routeForFile(srcRelativePath) {
1730
+ const posixPath = srcRelativePath.replace(/\\/g, "/");
1731
+ const withoutExt = posixPath.replace(/\.md$/, "");
1732
+ const segments = withoutExt.split("/");
1733
+ const last = segments[segments.length - 1];
1734
+ if (last === "index") {
1735
+ segments.pop();
1736
+ return segments.length === 0 ? "/" : `/${segments.join("/")}/`;
1737
+ }
1738
+ return `/${segments.join("/")}`;
1739
+ }
1740
+ function outFileForRoute(route) {
1741
+ if (route === "/") return "index.html";
1742
+ const trimmed = route.replace(/^\/+/, "").replace(/\/+$/, "");
1743
+ return `${trimmed}/index.html`;
1744
+ }
1745
+ function discoverPages(srcDir) {
1746
+ const files = listMarkdown(srcDir);
1747
+ const pages = files.map((filePath) => {
1748
+ const rel = relative(srcDir, filePath);
1749
+ const route = routeForFile(rel);
1750
+ return { route, outFile: outFileForRoute(route), filePath };
1751
+ });
1752
+ pages.sort((a, b) => a.route.localeCompare(b.route));
1753
+ return pages;
1754
+ }
1755
+
918
1756
  // src/search.ts
919
1757
  import { ElementNode, RecordState } from "@domphy/core";
920
- import { themeColor, themeSpacing } from "@domphy/theme";
1758
+ import { themeColor as themeColor2, themeSpacing as themeSpacing2 } from "@domphy/theme";
921
1759
  import { card, inputSearch, link, menu, small } from "@domphy/ui";
922
1760
  var FIELD_TITLE = 3;
923
1761
  var FIELD_HEADING = 2;
924
1762
  var FIELD_BODY = 1;
925
- function tokenize(text2) {
1763
+ function tokenize(text3) {
926
1764
  const tokens = [];
927
- for (const raw of text2.toLowerCase().split(/[^\p{L}\p{N}]+/u)) {
1765
+ for (const raw of text3.toLowerCase().split(/[^\p{L}\p{N}]+/u)) {
928
1766
  if (raw.length >= 2) tokens.push(raw);
929
1767
  }
930
1768
  return tokens;
931
1769
  }
932
- function indexText(postings, entryIndex, text2, fieldWeight) {
933
- for (const term of tokenize(text2)) {
1770
+ function indexText(postings, entryIndex, text3, fieldWeight) {
1771
+ for (const term of tokenize(text3)) {
934
1772
  let perEntry = postings.get(term);
935
1773
  if (!perEntry) {
936
1774
  perEntry = /* @__PURE__ */ new Map();
937
1775
  postings.set(term, perEntry);
938
1776
  }
939
1777
  const existing = perEntry.get(entryIndex);
940
- if (existing === void 0 || fieldWeight > existing) perEntry.set(entryIndex, fieldWeight);
1778
+ if (existing === void 0 || fieldWeight > existing)
1779
+ perEntry.set(entryIndex, fieldWeight);
941
1780
  }
942
1781
  }
943
1782
  function buildSearchIndex(docs) {
@@ -945,284 +1784,155 @@ function buildSearchIndex(docs) {
945
1784
  const postings = /* @__PURE__ */ new Map();
946
1785
  for (const doc of docs) {
947
1786
  const pageIndex = entries.length;
948
- entries.push({ route: doc.route, pageTitle: doc.title, heading: doc.title, slug: "", isPage: true });
1787
+ entries.push({
1788
+ route: doc.route,
1789
+ pageTitle: doc.title,
1790
+ heading: doc.title,
1791
+ slug: "",
1792
+ isPage: true
1793
+ });
949
1794
  indexText(postings, pageIndex, doc.title, FIELD_TITLE);
950
1795
  indexText(postings, pageIndex, doc.text, FIELD_BODY);
951
1796
  for (const entry of doc.toc) {
952
1797
  const sectionIndex = entries.length;
953
- entries.push({ route: doc.route, pageTitle: doc.title, heading: entry.text, slug: entry.slug, isPage: false });
1798
+ entries.push({
1799
+ route: doc.route,
1800
+ pageTitle: doc.title,
1801
+ heading: entry.text,
1802
+ slug: entry.slug,
1803
+ isPage: false
1804
+ });
954
1805
  indexText(postings, sectionIndex, entry.text, FIELD_HEADING);
955
1806
  }
956
1807
  }
957
1808
  const serializedPostings = {};
958
- for (const [term, perEntry] of Array.from(postings.entries()).sort((a, b) => a[0] < b[0] ? -1 : 1)) {
1809
+ for (const [term, perEntry] of Array.from(postings.entries()).sort(
1810
+ (a, b) => a[0] < b[0] ? -1 : 1
1811
+ )) {
959
1812
  serializedPostings[term] = Array.from(perEntry.entries()).sort((a, b) => a[0] - b[0]).map(([i, w]) => [i, w]);
960
1813
  }
961
- return JSON.stringify({ entries, postings: serializedPostings });
1814
+ return JSON.stringify({
1815
+ entries,
1816
+ postings: serializedPostings
1817
+ });
962
1818
  }
963
1819
 
964
1820
  // src/theme.ts
965
- import { themeColor as themeColor2, themeSpacing as themeSpacing2 } from "@domphy/theme";
966
- var tc = (tone, color) => themeColor2(null, tone, color);
967
- var ts = (n) => themeSpacing2(n);
968
- var bg = tc("inherit");
969
- var bgSoft = tc("shift-1");
970
- var bgMute = tc("shift-2");
971
- var border = tc("shift-3");
972
- var textSoft = tc("shift-6");
973
- var text = tc("shift-9");
974
- var textStrong = tc("shift-11");
975
- var brand = tc("shift-9", "primary");
976
- var brandHover = tc("shift-10", "primary");
977
- var headerH = ts(14);
978
- var sidebarW = ts(62);
979
- var asideW = ts(56);
980
- var contentMax = ts(190);
1821
+ import { themeColor as themeColor3, themeSpacing as themeSpacing3 } from "@domphy/theme";
1822
+ var tc2 = (tone, color) => themeColor3(null, tone, color);
1823
+ var ts2 = (n) => themeSpacing3(n);
1824
+ var bg2 = tc2("inherit");
1825
+ var bgSoft2 = tc2("shift-1");
1826
+ var bgMute2 = tc2("shift-2");
1827
+ var border2 = tc2("shift-3");
1828
+ var textSoft2 = tc2("shift-6");
1829
+ var text2 = tc2("shift-9");
1830
+ var textStrong2 = tc2("shift-11");
1831
+ var brand2 = tc2("shift-9", "primary");
1832
+ var headerH2 = ts2(14);
981
1833
  function pressCSS() {
982
1834
  return `
983
1835
  /* ------------------------------------------------------------------ reset */
984
1836
  *,*::before,*::after{box-sizing:border-box}
985
- html{scroll-behavior:smooth;scroll-padding-top:calc(${headerH} + ${ts(4)})}
986
- body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;background:${bg};color:${text};line-height:1.6;font-size:16px}
987
- a{color:${brand};text-decoration:none}
1837
+ html{scroll-behavior:smooth;scroll-padding-top:calc(${headerH2} + ${ts2(4)})}
1838
+ body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;background:${bg2};color:${text2};line-height:1.6;font-size:16px}
1839
+ a{color:${brand2};text-decoration:none}
988
1840
  a:hover{text-decoration:underline}
989
1841
 
990
- /* -------------------------------------------------------- announcement bar */
991
- .dp-announcement{display:flex;align-items:center;justify-content:center;gap:${ts(3)};padding:${ts(2.5)} ${ts(6)};background:${brand};color:${bg};font-size:14px;font-weight:500;text-align:center}
992
- .dp-announcement a{color:${bg};font-weight:700}
993
- .dp-announcement-close{background:none;border:none;color:${bg};cursor:pointer;font-size:14px;opacity:.7;padding:${ts(0.5)} ${ts(1.5)};border-radius:${ts(1)};flex-shrink:0}
994
- .dp-announcement-close:hover{opacity:1}
995
-
996
- /* ------------------------------------------------------------------ header */
997
- .dp-logo{font-weight:700;font-size:18px;color:${textStrong};white-space:nowrap;flex-shrink:0}
998
- .dp-logo:hover{text-decoration:none}
999
- .dp-logo-img{height:${ts(7)};width:auto;display:block}
1000
- .dp-nav a{color:${textSoft};font-size:14px;font-weight:500;white-space:nowrap;line-height:1}
1001
- .dp-nav a:hover,.dp-nav a[aria-current="page"]{color:${brand};text-decoration:none}
1002
- .dp-nav-dropdown{position:relative;display:flex;align-items:center}
1003
- .dp-nav-dropdown-label{color:${textSoft};font-size:14px;font-weight:500;cursor:pointer;user-select:none}
1004
- .dp-nav-dropdown-label::after{content:" \u25BE";font-size:10px;opacity:.6}
1005
- .dp-nav-dropdown-menu{display:none;position:absolute;top:calc(100% + ${ts(2)});right:0;background:${bgSoft};border:1px solid ${border};border-radius:${ts(2)};padding:${ts(1.5)};min-width:${ts(40)};z-index:100;flex-direction:column;gap:${ts(0.5)};box-shadow:0 4px 16px rgba(0,0,0,.1)}
1006
- .dp-nav-dropdown-menu a{display:block;padding:${ts(1.25)} ${ts(2.5)};border-radius:${ts(1.25)};font-size:13px}
1007
- .dp-nav-dropdown-menu a:hover{background:${bgMute}}
1008
- .dp-nav-dropdown:hover .dp-nav-dropdown-menu,.dp-nav-dropdown:focus-within .dp-nav-dropdown-menu{display:flex}
1009
- .dp-header-actions{flex-shrink:0}
1010
- .dp-search-slot{width:${ts(50)}}
1011
- .dp-search-static{width:100%;height:${ts(8)};padding:0 ${ts(2.5)};border:1px solid ${border};border-radius:${ts(1.5)};background:${bgSoft};color:${textSoft};font-size:13px;font-family:inherit;outline:none;cursor:pointer}
1012
- .dp-search-static::placeholder{color:${textSoft}}
1013
- .dp-theme-toggle,.dp-menu-toggle{border:1px solid ${border};background:${bgSoft};color:${text};border-radius:${ts(2)};width:${ts(8.5)};height:${ts(8.5)};cursor:pointer;font-size:16px}
1014
- .dp-menu-toggle{display:none}
1015
-
1016
- /* --------------------------------------------------------- locale switcher */
1017
- .dp-locale-switcher{position:relative;display:flex;align-items:center}
1018
- .dp-locale-current{color:${textSoft};font-size:13px;font-weight:500;cursor:pointer;user-select:none;padding:${ts(1)} ${ts(2)};border:1px solid ${border};border-radius:${ts(1.5)};background:${bgSoft};white-space:nowrap;display:flex;align-items:center;gap:${ts(1)}}
1019
- .dp-locale-current::after{content:" \u25BE";font-size:10px;opacity:.6}
1020
- .dp-locale-menu{display:none;position:absolute;top:calc(100% + ${ts(2)});right:0;background:${bgSoft};border:1px solid ${border};border-radius:${ts(2)};padding:${ts(1.5)};min-width:${ts(32)};z-index:200;flex-direction:column;gap:${ts(0.5)};box-shadow:0 4px 16px rgba(0,0,0,.1)}
1021
- .dp-locale-switcher:hover .dp-locale-menu,.dp-locale-switcher:focus-within .dp-locale-menu{display:flex}
1022
- .dp-locale-option{display:block;padding:${ts(1.25)} ${ts(2.5)};border-radius:${ts(1.25)};font-size:13px;color:${textSoft}}
1023
- .dp-locale-option:hover{background:${bgMute};color:${text};text-decoration:none}
1024
- .dp-locale-option.active{color:${brand};font-weight:600}
1025
-
1026
- /* -------------------------------------------------- logo light/dark variant */
1842
+ /* -------------------------------------------------------- logo theme variants */
1843
+ /* dp-logo-light/dark classes set in layout.ts img elements */
1027
1844
  [data-theme="dark"] .dp-logo-light{display:none}
1028
1845
  [data-theme="light"] .dp-logo-dark,.dp-logo-dark{display:none}
1029
1846
  [data-theme="dark"] .dp-logo-dark{display:block}
1030
1847
 
1031
- /* ------------------------------------------------------------ social links */
1032
- .dp-social-link{display:inline-flex;align-items:center;justify-content:center;width:${ts(8.5)};height:${ts(8.5)};border-radius:${ts(2)};color:${textSoft};background:${bgSoft};border:1px solid ${border};font-size:10px;font-weight:700;flex-shrink:0}
1033
- .dp-social-link:hover{color:${text};border-color:${textSoft};text-decoration:none}
1034
- .dp-social-icon{display:block;width:${ts(4)};height:${ts(4)};background:currentColor;flex-shrink:0}
1848
+ /* ---------------------------------------------------------- social icon masks */
1849
+ /* dp-social-icon + dp-icon-* classes set in layout.ts socialLinkEl */
1850
+ .dp-social-icon{display:block;width:${ts2(4)};height:${ts2(4)};background:currentColor;flex-shrink:0}
1035
1851
  .dp-icon-github{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.17 6.839 9.49.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.603-3.369-1.342-3.369-1.342-.454-1.155-1.11-1.463-1.11-1.463-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.578 9.578 0 0 1 12 6.836c.85.004 1.705.115 2.504.337 1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.202 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.741 0 .267.18.578.688.48C19.138 20.167 22 16.418 22 12c0-5.523-4.477-10-10-10z'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.17 6.839 9.49.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.603-3.369-1.342-3.369-1.342-.454-1.155-1.11-1.463-1.11-1.463-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.578 9.578 0 0 1 12 6.836c.85.004 1.705.115 2.504.337 1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.202 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.741 0 .267.18.578.688.48C19.138 20.167 22 16.418 22 12c0-5.523-4.477-10-10-10z'/%3E%3C/svg%3E") center/contain no-repeat}
1036
1852
  .dp-icon-twitter{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.744l7.737-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.744l7.737-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'/%3E%3C/svg%3E") center/contain no-repeat}
1037
1853
  .dp-icon-discord{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057c.01.044.032.084.064.107a19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01 10.2 10.2 0 0 0 .373.292.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057c.01.044.032.084.064.107a19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01 10.2 10.2 0 0 0 .373.292.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z'/%3E%3C/svg%3E") center/contain no-repeat}
1038
1854
 
1039
- /* ------------------------------------------------------------------ layout */
1040
- .dp-shell{display:grid;grid-template-columns:${sidebarW} minmax(0,1fr) ${asideW};align-items:start;max-width:1440px;margin:0 auto}
1041
- .dp-sidebar{position:sticky;top:${headerH};max-height:calc(100vh - ${headerH});overflow-y:auto;padding:${ts(6)} ${ts(3)} ${ts(12)} ${ts(6)};border-right:1px solid ${border}}
1042
- .dp-sidebar-group{margin-bottom:${ts(3.5)}}
1043
- .dp-sidebar-title{display:flex;align-items:center;gap:${ts(1.5)};font-size:13px;font-weight:700;color:${textStrong};margin:${ts(2)} 0 ${ts(1)}}
1044
- .dp-sidebar-subtitle{font-size:12px;color:${textSoft};padding:${ts(1)} ${ts(3)};font-weight:600}
1045
- .dp-sidebar-items{display:flex;flex-direction:column}
1046
- .dp-sidebar-toggle{margin-left:auto;background:none;border:none;cursor:pointer;color:${textSoft};font-size:14px;padding:0 ${ts(1)};line-height:1}
1047
- .dp-sidebar-toggle:hover{color:${text}}
1855
+ /* ------- sidebar collapsed state (JS toggles 'collapsed' class on group) ------- */
1048
1856
  .dp-sidebar-group.collapsed .dp-sidebar-items{display:none}
1049
- .dp-sidebar a{display:flex;align-items:center;gap:${ts(1.5)};padding:${ts(1.25)} ${ts(3)};font-size:14px;color:${textSoft};border-radius:${ts(1.5)}}
1050
- .dp-sidebar a:hover{color:${text};text-decoration:none}
1051
- .dp-sidebar a[aria-current="page"]{color:${brand};font-weight:600;background:${bgSoft}}
1052
- .dp-sidebar-link-with-badge{display:flex;align-items:center}
1053
- .dp-main{padding:${ts(8)} ${ts(12)} ${ts(20)};min-width:0}
1054
- .dp-main-full{grid-column:1 / -1;max-width:${contentMax};margin:0 auto}
1055
- .dp-content{max-width:${contentMax}}
1056
- .dp-aside{position:sticky;top:${headerH};max-height:calc(100vh - ${headerH});overflow-y:auto;padding:${ts(8)} ${ts(6)};font-size:13px}
1057
- .dp-aside-title{font-weight:700;margin-bottom:${ts(2)};color:${text}}
1058
- .dp-toc a{display:block;padding:${ts(0.75)} 0;color:${textSoft}}
1059
- .dp-toc a:hover{color:${brand};text-decoration:none}
1060
- .dp-toc-2{padding-left:0}
1061
- .dp-toc-3{padding-left:${ts(3)}}
1062
- .dp-toc-4{padding-left:${ts(6)}}
1063
1857
 
1064
- /* -------------------------------------------------- card / link-card / card-grid */
1065
- .custom-block.card{background:${bgSoft};border:1px solid ${border};border-radius:${ts(3)};padding:${ts(5)} ${ts(6)};margin:${ts(3)} 0}
1066
- .custom-block.card .card-title{font-size:16px;font-weight:600;color:${textStrong};margin:0 0 ${ts(2)}}
1067
- .custom-block.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(${ts(56)},1fr));gap:${ts(4)};margin:${ts(4)} 0}
1068
- a.custom-block.link-card{display:block;background:${bgSoft};border:1px solid ${border};border-radius:${ts(3)};padding:${ts(5)} ${ts(6)};margin:${ts(3)} 0;transition:border-color .15s,background .15s;text-decoration:none;color:${text}}
1069
- a.custom-block.link-card:hover{border-color:${brand};background:${bgMute};text-decoration:none}
1070
- a.custom-block.link-card .link-card-title{font-size:16px;font-weight:600;color:${brand};margin:0 0 ${ts(2)}}
1071
- .custom-block.card-grid .custom-block.card,.custom-block.card-grid a.custom-block.link-card{margin:0}
1072
-
1073
- /* ------------------------------------------------------------------ badges */
1074
- .dp-badge{display:inline-block;padding:${ts(0.5)} ${ts(1.75)};border-radius:${ts(2.5)};font-size:11px;font-weight:700;line-height:1.4;white-space:nowrap;vertical-align:middle}
1075
- .dp-badge-tip{background:color-mix(in srgb,${brand} 12%,${bg});color:${brand}}
1076
- .dp-badge-info{background:${bgMute};color:${textSoft}}
1077
- .dp-badge-warning{background:color-mix(in srgb,${tc("shift-9", "warning")} 12%,${bg});color:${tc("shift-9", "warning")}}
1078
- .dp-badge-danger{background:color-mix(in srgb,${tc("shift-9", "danger")} 12%,${bg});color:${tc("shift-9", "danger")}}
1079
- .dp-page-badge{margin-left:${ts(2)}}
1080
- .dp-page-badge-row{margin-bottom:${ts(-2)}}
1081
-
1082
- /* ------------------------------------------------------------------- prose */
1083
- .dp-content h1{font-size:30px;font-weight:700;line-height:1.25;margin:0 0 ${ts(6)};letter-spacing:-.02em;color:${textStrong}}
1084
- .dp-content h2{font-size:22px;font-weight:700;margin:${ts(11)} 0 ${ts(4)};padding-top:${ts(5)};border-top:1px solid ${border};letter-spacing:-.01em;color:${textStrong}}
1085
- .dp-content h3{font-size:18px;font-weight:600;margin:${ts(7)} 0 ${ts(3)};color:${textStrong}}
1086
- .dp-content h4{font-size:16px;font-weight:600;margin:${ts(5.5)} 0 ${ts(2)};color:${textStrong}}
1087
- .dp-content p{margin:${ts(4)} 0}
1088
- .dp-content ul,.dp-content ol{margin:${ts(4)} 0;padding-left:1.4em}
1089
- .dp-content li{margin:${ts(1.5)} 0}
1090
- .dp-content a{font-weight:500}
1091
- .dp-content strong{font-weight:600;color:${textStrong}}
1092
- .dp-content em{font-style:italic}
1093
- .dp-content mark{background:color-mix(in srgb,${tc("shift-6", "warning")} 40%,${bg});color:inherit;padding:${ts(0.25)} ${ts(0.75)};border-radius:${ts(0.75)}}
1094
- .dp-content sup{font-size:.75em;vertical-align:super}
1095
- .dp-content sub{font-size:.75em;vertical-align:sub}
1096
- .dp-content del{opacity:.5}
1097
- .dp-content blockquote{margin:${ts(4)} 0;padding:0 ${ts(4)};border-left:3px solid ${border};color:${textSoft}}
1098
- .dp-content img{max-width:100%;height:auto;border-radius:${ts(1.5)}}
1099
- .dp-content hr{border:none;border-top:1px solid ${border};margin:${ts(8)} 0}
1100
- .dp-content :not(pre)>code{font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;font-size:.85em;background:${bgMute};padding:${ts(0.75)} ${ts(1.5)};border-radius:${ts(1)}}
1101
- .dp-content pre{margin:${ts(4)} 0;padding:${ts(4)} ${ts(5)};background:${bgSoft};border:1px solid ${border};border-radius:${ts(2)};overflow-x:auto;font-size:13.5px;line-height:1.5}
1102
- .dp-content pre code{font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;background:none;padding:0}
1103
- .dp-content table{border-collapse:collapse;margin:${ts(4)} 0;display:block;overflow-x:auto}
1104
- .dp-content th,.dp-content td{border:1px solid ${border};padding:${ts(2)} ${ts(3.5)};text-align:left}
1105
- .dp-content th{background:${bgSoft};font-weight:600}
1858
+ /* ------- sidebar open state on mobile (JS sets html[data-sidebar="open"]) ------ */
1859
+ @media(max-width:860px){
1860
+ html[data-sidebar="open"] nav[aria-label="Documentation"]{transform:translateX(0)}
1861
+ }
1106
1862
 
1107
1863
  /* -------------------------------------------------------- heading anchors */
1108
- .header-anchor{opacity:0;margin-left:${ts(2)};font-weight:400;font-size:.85em;color:${textSoft};transition:opacity .15s}
1864
+ .header-anchor{opacity:0;margin-left:${ts2(2)};font-weight:400;font-size:.85em;color:${textSoft2};transition:opacity .15s}
1109
1865
  :is(h1,h2,h3,h4,h5,h6):hover .header-anchor{opacity:1}
1110
- .header-anchor:hover{color:${brand};text-decoration:none}
1111
-
1112
- /* -------------------------------------------------------- external links */
1113
- .dp-content a[target="_blank"]::after{content:" \u2197";font-size:.75em;opacity:.6}
1114
-
1115
- /* --------------------------------------------------------------- task lists */
1116
- .task-list-item{list-style:none;margin-left:-1.4em;padding-left:1.8em;position:relative}
1117
- .task-list-check{position:absolute;left:0;top:.25em;width:14px;height:14px;cursor:default;accent-color:${brand}}
1866
+ .header-anchor:hover{color:${brand2};text-decoration:none}
1118
1867
 
1119
1868
  /* ------------------------------------------------------------ code blocks */
1120
- .code-block{margin:${ts(4)} 0;border:1px solid ${border};border-radius:${ts(2)};overflow:hidden}
1121
- .code-block-title{display:flex;align-items:center;padding:${ts(1.5)} ${ts(4)};background:${bgMute};border-bottom:1px solid ${border};font-size:12px;font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;color:${textSoft}}
1869
+ .code-block{margin:${ts2(4)} 0;border:1px solid ${border2};border-radius:${ts2(2)};overflow:hidden}
1870
+ .code-block-title{display:flex;align-items:center;padding:${ts2(1.5)} ${ts2(4)};background:${bgMute2};border-bottom:1px solid ${border2};font-size:12px;font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;color:${textSoft2}}
1122
1871
  .code-block-inner{position:relative}
1123
- .code-block pre{margin:0;padding:${ts(4)} ${ts(5)};background:${bgSoft};border:none;border-radius:0;overflow-x:auto;font-size:13.5px;line-height:1.5;font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace}
1872
+ .code-block pre{margin:0;padding:${ts2(4)} ${ts2(5)};background:${bgSoft2};border:none;border-radius:0;overflow-x:auto;font-size:13.5px;line-height:1.5;font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace}
1124
1873
  .code-block code{font-family:inherit;background:none;padding:0;font-size:inherit}
1125
1874
  .code-block .line{display:inline-block;width:100%}
1126
- .code-block .line.highlighted{background:color-mix(in srgb,${brand} 10%,transparent)}
1127
- .code-block .line.diff.add{background:color-mix(in srgb,${tc("shift-7", "success")} 12%,transparent)}
1128
- .code-block .line.diff.add::before{content:"+ ";color:${tc("shift-7", "success")}}
1129
- .code-block .line.diff.remove{background:color-mix(in srgb,${tc("shift-9", "danger")} 10%,transparent);opacity:.7}
1130
- .code-block .line.diff.remove::before{content:"- ";color:${tc("shift-9", "danger")}}
1131
- .code-block .line.highlighted.error{background:color-mix(in srgb,${tc("shift-9", "error")} 10%,transparent)}
1132
- .code-block .line.highlighted.warning{background:color-mix(in srgb,${tc("shift-7", "warning")} 10%,transparent)}
1875
+ .code-block .line.highlighted{background:color-mix(in srgb,${brand2} 10%,transparent)}
1876
+ .code-block .line.diff.add{background:color-mix(in srgb,${tc2("shift-7", "success")} 12%,transparent)}
1877
+ .code-block .line.diff.add::before{content:"+ ";color:${tc2("shift-7", "success")}}
1878
+ .code-block .line.diff.remove{background:color-mix(in srgb,${tc2("shift-9", "danger")} 10%,transparent);opacity:.7}
1879
+ .code-block .line.diff.remove::before{content:"- ";color:${tc2("shift-9", "danger")}}
1880
+ .code-block .line.highlighted.error{background:color-mix(in srgb,${tc2("shift-9", "error")} 10%,transparent)}
1881
+ .code-block .line.highlighted.warning{background:color-mix(in srgb,${tc2("shift-7", "warning")} 10%,transparent)}
1133
1882
  .code-block pre.has-focus .line:not(.focus){opacity:.4;filter:blur(.4px);transition:opacity .2s,filter .2s}
1134
1883
  .code-block pre.has-focus:hover .line{opacity:1;filter:none}
1135
- .code-block .line-number{display:inline-block;min-width:2.5em;margin-right:1em;color:${textSoft};text-align:right;user-select:none;font-size:.9em}
1136
- .code-copy-btn{position:absolute;top:${ts(2)};right:${ts(2)};padding:${ts(1)} ${ts(2)};border-radius:${ts(1.25)};border:1px solid ${border};background:${bgSoft};color:${textSoft};cursor:pointer;font-size:13px;opacity:0;transition:opacity .15s}
1884
+ .code-block .line-number{display:inline-block;min-width:2.5em;margin-right:1em;color:${textSoft2};text-align:right;user-select:none;font-size:.9em}
1885
+ .code-copy-btn{position:absolute;top:${ts2(2)};right:${ts2(2)};padding:${ts2(1)} ${ts2(2)};border-radius:${ts2(1.25)};border:1px solid ${border2};background:${bgSoft2};color:${textSoft2};cursor:pointer;font-size:13px;opacity:0;transition:opacity .15s}
1137
1886
  .code-block-inner:hover .code-copy-btn{opacity:1}
1138
- .code-copy-btn:hover{background:${bgMute};color:${text}}
1887
+ .code-copy-btn:hover{background:${bgMute2};color:${text2}}
1139
1888
 
1140
1889
  /* ------------------------------------------------------------- code groups */
1141
- .code-group{margin:${ts(4)} 0;border:1px solid ${border};border-radius:${ts(2)};overflow:hidden}
1890
+ .code-group{margin:${ts2(4)} 0;border:1px solid ${border2};border-radius:${ts2(2)};overflow:hidden}
1142
1891
  .code-group>input[type="radio"]{position:absolute;opacity:0;pointer-events:none;width:0;height:0}
1143
- .code-group .tabs{display:flex;gap:${ts(0.5)};padding:${ts(1.5)} ${ts(2)};background:${bgSoft};border-bottom:1px solid ${border};flex-wrap:wrap}
1144
- .code-group .tabs label{padding:${ts(1)} ${ts(3)};font-size:13px;font-weight:500;color:${textSoft};border-radius:${ts(1.25)};cursor:pointer}
1892
+ .code-group .tabs{display:flex;gap:${ts2(0.5)};padding:${ts2(1.5)} ${ts2(2)};background:${bgSoft2};border-bottom:1px solid ${border2};flex-wrap:wrap}
1893
+ .code-group .tabs label{padding:${ts2(1)} ${ts2(3)};font-size:13px;font-weight:500;color:${textSoft2};border-radius:${ts2(1.25)};cursor:pointer}
1145
1894
  .code-group .blocks>.code-block{display:none;margin:0;border:none;border-radius:0}
1146
1895
  .code-group .blocks>.code-block pre{border-radius:0}
1147
1896
  ${Array.from({ length: 8 }, (_, i) => `.code-group>input:nth-of-type(${i + 1}):checked~.blocks>.code-block:nth-child(${i + 1})`).join(",\n")}{display:block}
1148
- ${Array.from({ length: 8 }, (_, i) => `.code-group>input:nth-of-type(${i + 1}):checked~.tabs>label:nth-child(${i + 1})`).join(",\n")}{color:${brand};background:${bgMute}}
1897
+ ${Array.from({ length: 8 }, (_, i) => `.code-group>input:nth-of-type(${i + 1}):checked~.tabs>label:nth-child(${i + 1})`).join(",\n")}{color:${brand2};background:${bgMute2}}
1898
+
1899
+ /* ---------------------------------------------------------- card containers */
1900
+ .custom-block.card{background:${bgSoft2};border:1px solid ${border2};border-radius:${ts2(3)};padding:${ts2(5)} ${ts2(6)};margin:${ts2(3)} 0}
1901
+ .custom-block.card .card-title{font-size:16px;font-weight:600;color:${textStrong2};margin:0 0 ${ts2(2)}}
1902
+ .custom-block.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(${ts2(56)},1fr));gap:${ts2(4)};margin:${ts2(4)} 0}
1903
+ a.custom-block.link-card{display:block;background:${bgSoft2};border:1px solid ${border2};border-radius:${ts2(3)};padding:${ts2(5)} ${ts2(6)};margin:${ts2(3)} 0;transition:border-color .15s,background .15s;text-decoration:none;color:${text2}}
1904
+ a.custom-block.link-card:hover{border-color:${brand2};background:${bgMute2};text-decoration:none}
1905
+ a.custom-block.link-card .link-card-title{font-size:16px;font-weight:600;color:${brand2};margin:0 0 ${ts2(2)}}
1906
+ .custom-block.card-grid .custom-block.card,.custom-block.card-grid a.custom-block.link-card{margin:0}
1149
1907
 
1150
1908
  /* --------------------------------------------------------- custom blocks */
1151
- .custom-block{margin:${ts(4)} 0;padding:${ts(3)} ${ts(4)};border-radius:${ts(2)};border:1px solid transparent;font-size:14.5px}
1152
- .custom-block p{margin:${ts(2)} 0}
1153
- .custom-block-title{font-weight:700;margin:0 0 ${ts(1)} !important;font-size:13px}
1154
- .custom-block.tip,.custom-block.success{background:color-mix(in srgb,${brand} 8%,${bg});border-color:color-mix(in srgb,${brand} 28%,transparent)}
1155
- .custom-block.info,.custom-block.note,.custom-block.abstract{background:${bgSoft};border-color:${border}}
1156
- .custom-block.warning,.custom-block.question{background:color-mix(in srgb,${tc("shift-6", "warning")} 10%,${bg});border-color:${tc("shift-6", "warning")}}
1157
- .custom-block.danger,.custom-block.failure,.custom-block.bug{background:color-mix(in srgb,${tc("shift-7", "danger")} 10%,${bg});border-color:${tc("shift-7", "danger")}}
1158
- .custom-block.example{background:color-mix(in srgb,${tc("shift-7", "secondary")} 10%,${bg});border-color:${tc("shift-7", "secondary")}}
1159
- .custom-block.quote{background:${bgSoft};border-color:${border};border-left-width:4px;border-radius:0 ${ts(2)} ${ts(2)} 0}
1909
+ .custom-block{margin:${ts2(4)} 0;padding:${ts2(3)} ${ts2(4)};border-radius:${ts2(2)};border:1px solid transparent;font-size:14.5px}
1910
+ .custom-block p{margin:${ts2(2)} 0}
1911
+ .custom-block-title{font-weight:700;margin:0 0 ${ts2(1)} !important;font-size:13px}
1912
+ .custom-block.tip,.custom-block.success{background:color-mix(in srgb,${brand2} 8%,${bg2});border-color:color-mix(in srgb,${brand2} 28%,transparent)}
1913
+ .custom-block.info,.custom-block.note,.custom-block.abstract{background:${bgSoft2};border-color:${border2}}
1914
+ .custom-block.warning,.custom-block.question{background:color-mix(in srgb,${tc2("shift-6", "warning")} 10%,${bg2});border-color:${tc2("shift-6", "warning")}}
1915
+ .custom-block.danger,.custom-block.failure,.custom-block.bug{background:color-mix(in srgb,${tc2("shift-7", "danger")} 10%,${bg2});border-color:${tc2("shift-7", "danger")}}
1916
+ .custom-block.example{background:color-mix(in srgb,${tc2("shift-7", "secondary")} 10%,${bg2});border-color:${tc2("shift-7", "secondary")}}
1917
+ .custom-block.quote{background:${bgSoft2};border-color:${border2};border-left-width:4px;border-radius:0 ${ts2(2)} ${ts2(2)} 0}
1160
1918
  details.custom-block summary{cursor:pointer;font-weight:600}
1161
1919
 
1162
1920
  /* ------------------------------------------------------------------- steps */
1163
1921
  .custom-block.steps{background:none;border:none;padding:0}
1164
1922
  .custom-block.steps>ol{counter-reset:step;list-style:none;padding:0;margin:0}
1165
- .custom-block.steps>ol>li{counter-increment:step;display:grid;grid-template-columns:${ts(9)} 1fr;gap:0 ${ts(4)};margin-bottom:${ts(6)}}
1166
- .custom-block.steps>ol>li::before{content:counter(step);display:flex;align-items:center;justify-content:center;width:${ts(7.5)};height:${ts(7.5)};border-radius:50%;background:${brand};color:${bg};font-size:13px;font-weight:700;flex-shrink:0}
1923
+ .custom-block.steps>ol>li{counter-increment:step;display:grid;grid-template-columns:${ts2(9)} 1fr;gap:0 ${ts2(4)};margin-bottom:${ts2(6)}}
1924
+ .custom-block.steps>ol>li::before{content:counter(step);display:flex;align-items:center;justify-content:center;width:${ts2(7.5)};height:${ts2(7.5)};border-radius:50%;background:${brand2};color:${bg2};font-size:13px;font-weight:700;flex-shrink:0}
1167
1925
 
1168
1926
  /* ----------------------------------------------------------------- mermaid */
1169
- .dp-mermaid{margin:${ts(5)} 0;text-align:center;overflow-x:auto}
1927
+ .dp-mermaid{margin:${ts2(5)} 0;text-align:center;overflow-x:auto}
1170
1928
  .dp-mermaid svg{max-width:100%;height:auto}
1171
1929
 
1172
- /* --------------------------------------------------------------- doc footer */
1173
- .dp-doc-footer{display:flex;align-items:center;gap:${ts(4)};flex-wrap:wrap;margin-top:${ts(8)};padding-top:${ts(5)};border-top:1px solid ${border};font-size:13px;color:${textSoft}}
1174
- .dp-edit-link{font-weight:500;font-size:13px}
1175
- .dp-reading-time::before{content:"\u{1F4D6} "}
1176
-
1177
- /* --------------------------------------------------------------- prev/next */
1178
- .dp-prevnext{display:flex;justify-content:space-between;gap:${ts(4)};margin-top:${ts(12)};padding-top:${ts(6)};border-top:1px solid ${border}}
1179
- .dp-prevnext a{display:block;padding:${ts(3)} ${ts(4)};border:1px solid ${border};border-radius:${ts(2)};font-weight:600;flex:1}
1180
- .dp-prevnext a:hover{border-color:${brand};text-decoration:none}
1181
- .dp-prevnext .next{text-align:right}
1182
- .dp-prevnext small{display:block;color:${textSoft};font-weight:400;font-size:12px}
1183
-
1184
- /* ----------------------------------------------------------------- footer */
1185
- .dp-footer{padding:${ts(6)} ${ts(12)};border-top:1px solid ${border};color:${textSoft};font-size:13px}
1186
-
1187
- /* ---------------------------------------------------------------- home page */
1188
- .dp-main-home{max-width:1100px;margin:0 auto;padding:${ts(12)} ${ts(6)} ${ts(20)}}
1189
- .dp-hero{text-align:center;padding:${ts(10)} 0 ${ts(6)}}
1190
- .dp-hero-name{font-size:56px;font-weight:800;line-height:1.1;letter-spacing:-.03em;background:linear-gradient(120deg,${brand},${tc("shift-7", "secondary")});-webkit-background-clip:text;background-clip:text;color:transparent}
1191
- .dp-hero-text{font-size:30px;font-weight:700;margin:${ts(3)} 0 0;color:${textStrong}}
1192
- .dp-hero-tagline{font-size:18px;color:${textSoft};max-width:${ts(160)};margin:${ts(5)} auto 0}
1193
- .dp-hero-actions{display:flex;gap:${ts(3)};justify-content:center;margin-top:${ts(7)};flex-wrap:wrap}
1194
- .dp-hero-action{padding:${ts(2.5)} ${ts(5.5)};border-radius:${ts(5.5)};font-weight:600;font-size:15px}
1195
- .dp-hero-action.brand{background:${brand};color:${bg}}
1196
- .dp-hero-action.brand:hover{background:${brandHover};text-decoration:none}
1197
- .dp-hero-action.alt{background:${bgSoft};color:${text};border:1px solid ${border}}
1198
- .dp-hero-action.alt:hover{border-color:${brand};text-decoration:none}
1199
- .dp-features{display:grid;grid-template-columns:repeat(auto-fit,minmax(${ts(60)},1fr));gap:${ts(4)};margin:${ts(10)} 0}
1200
- .dp-feature{padding:${ts(5)};background:${bgSoft};border:1px solid ${border};border-radius:${ts(3)}}
1201
- .dp-feature-icon{font-size:28px;margin-bottom:${ts(3)}}
1202
- .dp-feature-title{font-weight:700;font-size:17px;margin-bottom:${ts(2)};color:${textStrong}}
1203
- .dp-feature-details{font-size:14px;color:${textSoft};margin:0;line-height:1.5}
1204
- .dp-feature-link{display:block;color:inherit}
1205
- .dp-feature-link:hover{text-decoration:none}
1206
- .dp-feature-link:hover .dp-feature{border-color:${brand}}
1207
- .dp-home{max-width:${contentMax};margin:0 auto}
1930
+ /* --------------------------------------------------------------- task lists */
1931
+ .task-list-item{list-style:none;margin-left:-1.4em;padding-left:1.8em;position:relative}
1932
+ .task-list-check{position:absolute;left:0;top:.25em;width:14px;height:14px;cursor:default;accent-color:${brand2}}
1208
1933
 
1209
1934
  /* ---------------------------------------------------------------- shiki dark */
1210
1935
  html[data-theme="dark"] .shiki,html[data-theme="dark"] .shiki span{color:var(--shiki-dark,inherit) !important}
1211
-
1212
- /* -------------------------------------------------------------- responsive */
1213
- @media(max-width:1200px){
1214
- .dp-shell{grid-template-columns:${sidebarW} minmax(0,1fr)}
1215
- .dp-aside{display:none}
1216
- }
1217
- @media(max-width:860px){
1218
- .dp-shell{grid-template-columns:1fr}
1219
- .dp-menu-toggle{display:block}
1220
- .dp-sidebar{position:fixed;top:${headerH};left:0;bottom:0;width:80%;max-width:${ts(80)};background:${bg};z-index:25;transform:translateX(-100%);transition:transform .2s ease;max-height:none}
1221
- html[data-sidebar="open"] .dp-sidebar{transform:translateX(0)}
1222
- .dp-nav{display:none}
1223
- .dp-main{padding:${ts(6)} ${ts(5)} ${ts(16)}}
1224
- .dp-search-slot{width:${ts(35)}}
1225
- }
1226
1936
  `;
1227
1937
  }
1228
1938
 
@@ -1243,24 +1953,27 @@ function flattenText(node, out) {
1243
1953
  return;
1244
1954
  }
1245
1955
  if (typeof node === "object") {
1246
- for (const [key, value] of Object.entries(node)) {
1956
+ for (const [key, value] of Object.entries(
1957
+ node
1958
+ )) {
1247
1959
  if (key.startsWith("_") || key === "$" || key === "style") continue;
1248
- if (key === "class" || key.startsWith("data") || key === "href" || key === "id") continue;
1960
+ if (key === "class" || key.startsWith("data") || key === "href" || key === "id")
1961
+ continue;
1249
1962
  flattenText(value, out);
1250
1963
  }
1251
1964
  }
1252
1965
  }
1253
1966
  function parseStyleString(value) {
1254
- const style = {};
1967
+ const style2 = {};
1255
1968
  for (const decl of value.split(";")) {
1256
1969
  const colon = decl.indexOf(":");
1257
1970
  if (colon === -1) continue;
1258
1971
  const prop = decl.slice(0, colon).trim();
1259
1972
  const val = decl.slice(colon + 1).trim();
1260
1973
  if (!prop || !val) continue;
1261
- style[prop.replace(/-([a-z])/g, (_m, c) => c.toUpperCase())] = val;
1974
+ style2[prop.replace(/-([a-z])/g, (_m, c) => c.toUpperCase())] = val;
1262
1975
  }
1263
- return style;
1976
+ return style2;
1264
1977
  }
1265
1978
  function sanitizeStyles(node) {
1266
1979
  if (Array.isArray(node)) {
@@ -1269,9 +1982,11 @@ function sanitizeStyles(node) {
1269
1982
  }
1270
1983
  if (!node || typeof node !== "object") return;
1271
1984
  const record = node;
1272
- if (typeof record.style === "string") record.style = parseStyleString(record.style);
1985
+ if (typeof record.style === "string")
1986
+ record.style = parseStyleString(record.style);
1273
1987
  for (const value of Object.values(record)) {
1274
- if (value && (typeof value === "object" || Array.isArray(value))) sanitizeStyles(value);
1988
+ if (value && (typeof value === "object" || Array.isArray(value)))
1989
+ sanitizeStyles(value);
1275
1990
  }
1276
1991
  }
1277
1992
  function firstParagraphText(body) {
@@ -1281,8 +1996,8 @@ function firstParagraphText(body) {
1281
1996
  if ("p" in record) {
1282
1997
  const parts = [];
1283
1998
  flattenText(record.p, parts);
1284
- const text2 = parts.join(" ").replace(/\s+/g, " ").trim();
1285
- if (text2.length > 10) return text2.slice(0, 160);
1999
+ const text3 = parts.join(" ").replace(/\s+/g, " ").trim();
2000
+ if (text3.length > 10) return text3.slice(0, 160);
1286
2001
  }
1287
2002
  }
1288
2003
  return "";
@@ -1327,7 +2042,7 @@ async function buildIslandsBundle(outDir, searchEnabled) {
1327
2042
  }
1328
2043
  function buildSitemap(routes, hostname) {
1329
2044
  const urls = routes.map((route) => {
1330
- const loc = route === "/" ? `${hostname}/` : `${hostname}${route}`.replace(/\/+$/, "") + "/";
2045
+ const loc = route === "/" ? `${hostname}/` : `${`${hostname}${route}`.replace(/\/+$/, "")}/`;
1331
2046
  return ` <url><loc>${loc}</loc></url>`;
1332
2047
  });
1333
2048
  return `<?xml version="1.0" encoding="UTF-8"?>
@@ -1386,13 +2101,21 @@ async function buildSite(options) {
1386
2101
  const pages = discoverPages(srcDir);
1387
2102
  const localePages = pages.map((p) => ({ ...p, localeKey: "/" }));
1388
2103
  if (config.locales) {
1389
- for (const [localeKey, locale] of Object.entries(config.locales)) {
2104
+ for (const [localeKey, _locale] of Object.entries(config.locales)) {
1390
2105
  if (localeKey === "/") continue;
1391
- const localeDir = resolve2(srcDir, localeKey.replace(/^\//, "").replace(/\/$/, ""));
2106
+ const localeDir = resolve2(
2107
+ srcDir,
2108
+ localeKey.replace(/^\//, "").replace(/\/$/, "")
2109
+ );
1392
2110
  if (!existsSync(localeDir)) continue;
1393
2111
  for (const p of discoverPages(localeDir)) {
1394
2112
  const prefix = localeKey.replace(/\/$/, "");
1395
- localePages.push({ filePath: p.filePath, route: prefix + p.route, outFile: p.outFile === "index.html" ? localeKey.replace(/^\//, "") + "index.html" : localeKey.replace(/^\//, "") + p.outFile, localeKey });
2113
+ localePages.push({
2114
+ filePath: p.filePath,
2115
+ route: prefix + p.route,
2116
+ outFile: p.outFile === "index.html" ? `${localeKey.replace(/^\//, "")}index.html` : localeKey.replace(/^\//, "") + p.outFile,
2117
+ localeKey
2118
+ });
1396
2119
  }
1397
2120
  }
1398
2121
  }
@@ -1403,7 +2126,12 @@ async function buildSite(options) {
1403
2126
  const searchDocs = [];
1404
2127
  for (const page of localePages) {
1405
2128
  const source = readFileSync2(page.filePath, "utf8");
1406
- const doc = await renderDoc(source, { filePath: page.filePath, docsDir: srcDir, repoRoot: srcDir, highlight });
2129
+ const doc = await renderDoc(source, {
2130
+ filePath: page.filePath,
2131
+ docsDir: srcDir,
2132
+ repoRoot: srcDir,
2133
+ highlight
2134
+ });
1407
2135
  if (doc.frontmatter.draft === true) {
1408
2136
  console.log(` \u21B7 ${page.route} (draft, skipped)`);
1409
2137
  continue;
@@ -1415,8 +2143,23 @@ async function buildSite(options) {
1415
2143
  const readingTime = estimateReadingTime(textContent);
1416
2144
  const lastUpdated = showLastUpdated ? getLastUpdated(page.filePath) : void 0;
1417
2145
  const relPath = relative2(srcDir, page.filePath).replace(/\\/g, "/");
1418
- built.push({ route: page.route, outFile: page.outFile, title: doc.title, localeKey: page.localeKey, doc, lastUpdated, readingTime, filePath: page.filePath, relPath });
1419
- searchDocs.push({ route: page.route, title: doc.title, text: textContent.slice(0, 2e4), toc: doc.toc });
2146
+ built.push({
2147
+ route: page.route,
2148
+ outFile: page.outFile,
2149
+ title: doc.title,
2150
+ localeKey: page.localeKey,
2151
+ doc,
2152
+ lastUpdated,
2153
+ readingTime,
2154
+ filePath: page.filePath,
2155
+ relPath
2156
+ });
2157
+ searchDocs.push({
2158
+ route: page.route,
2159
+ title: doc.title,
2160
+ text: textContent.slice(0, 2e4),
2161
+ toc: doc.toc
2162
+ });
1420
2163
  }
1421
2164
  const pageHeadMap = /* @__PURE__ */ new Map();
1422
2165
  const pageLangMap = /* @__PURE__ */ new Map();
@@ -1442,7 +2185,9 @@ async function buildSite(options) {
1442
2185
  const siteTitle = localeConfig?.title ?? config.title;
1443
2186
  const pageTitle = page.title === siteTitle ? siteTitle : `${page.title} | ${siteTitle}`;
1444
2187
  const canonical = page.route === "/" ? `${config.hostname}/` : `${config.hostname}${page.route}/`;
1445
- const pageHead = Array.isArray(page.doc.frontmatter.head) ? page.doc.frontmatter.head.filter((s) => typeof s === "string") : [];
2188
+ const pageHead = Array.isArray(page.doc.frontmatter.head) ? page.doc.frontmatter.head.filter(
2189
+ (s) => typeof s === "string"
2190
+ ) : [];
1446
2191
  pageHeadMap.set(page.route, pageHead);
1447
2192
  pageLangMap.set(page.route, lang);
1448
2193
  return {
@@ -1451,7 +2196,13 @@ async function buildSite(options) {
1451
2196
  title: pageTitle,
1452
2197
  description,
1453
2198
  metadataBase: config.hostname,
1454
- openGraph: { title: pageTitle, description, url: page.route === "/" ? "/" : `${page.route}/`, siteName: siteTitle, type: "website" },
2199
+ openGraph: {
2200
+ title: pageTitle,
2201
+ description,
2202
+ url: page.route === "/" ? "/" : `${page.route}/`,
2203
+ siteName: siteTitle,
2204
+ type: "website"
2205
+ },
1455
2206
  twitter: { card: "summary", title: pageTitle, description },
1456
2207
  alternates: { canonical }
1457
2208
  },
@@ -1469,28 +2220,54 @@ async function buildSite(options) {
1469
2220
  const result = await app.renderToString(page.route);
1470
2221
  const pageHead = pageHeadMap.get(page.route) ?? [];
1471
2222
  const lang = pageLangMap.get(page.route) ?? "en";
1472
- const html = htmlDocument(result, config, searchEnabled, generatedCss, pageHead, lang);
2223
+ const html = htmlDocument(
2224
+ result,
2225
+ config,
2226
+ searchEnabled,
2227
+ generatedCss,
2228
+ pageHead,
2229
+ lang
2230
+ );
1473
2231
  const outPath = join2(outDir, page.outFile);
1474
2232
  mkdirSync(dirname2(outPath), { recursive: true });
1475
2233
  writeFileSync(outPath, html, "utf8");
1476
2234
  totalBytes += html.length;
1477
- if (result.status !== 200) console.warn(` ! ${page.route} -> status ${result.status}`);
2235
+ if (result.status !== 200)
2236
+ console.warn(` ! ${page.route} -> status ${result.status}`);
1478
2237
  } catch (error) {
1479
- failures.push({ route: page.route, error: String(error.message || error) });
2238
+ failures.push({
2239
+ route: page.route,
2240
+ error: String(error.message || error)
2241
+ });
1480
2242
  }
1481
2243
  }
1482
2244
  if (failures.length > 0) {
1483
2245
  console.warn(`
1484
2246
  ${failures.length} page(s) failed:`);
1485
- for (const failure of failures) console.warn(` \u2717 ${failure.route}: ${failure.error}`);
2247
+ for (const failure of failures)
2248
+ console.warn(` \u2717 ${failure.route}: ${failure.error}`);
1486
2249
  }
1487
2250
  await buildIslandsBundle(outDir, searchEnabled);
1488
- writeFileSync(join2(outDir, "search-index.json"), buildSearchIndex(searchDocs), "utf8");
1489
- if (publicDir && existsSync(publicDir)) cpSync(publicDir, outDir, { recursive: true });
2251
+ writeFileSync(
2252
+ join2(outDir, "search-index.json"),
2253
+ buildSearchIndex(searchDocs),
2254
+ "utf8"
2255
+ );
2256
+ if (publicDir && existsSync(publicDir))
2257
+ cpSync(publicDir, outDir, { recursive: true });
1490
2258
  if (config.hostname) {
1491
- writeFileSync(join2(outDir, "sitemap.xml"), buildSitemap(built.map((p) => p.route), config.hostname), "utf8");
2259
+ writeFileSync(
2260
+ join2(outDir, "sitemap.xml"),
2261
+ buildSitemap(
2262
+ built.map((p) => p.route),
2263
+ config.hostname
2264
+ ),
2265
+ "utf8"
2266
+ );
1492
2267
  }
1493
- console.log(`Built ${built.length} pages (${(totalBytes / 1024).toFixed(0)} KB) \u2192 ${outDir}`);
2268
+ console.log(
2269
+ `Built ${built.length} pages (${(totalBytes / 1024).toFixed(0)} KB) \u2192 ${outDir}`
2270
+ );
1494
2271
  }
1495
2272
  export {
1496
2273
  buildSite