@domphy/press 0.19.1 → 0.20.0

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,6 +160,7 @@ 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
166
  // src/routes.ts
@@ -226,6 +237,22 @@ function prevNextForRoute(route, config) {
226
237
  }
227
238
 
228
239
  // src/layout.ts
240
+ var style = (obj) => obj;
241
+ var tc = (tone, color) => themeColor(null, tone, color);
242
+ var ts = (n) => themeSpacing(n);
243
+ var bg = tc("inherit");
244
+ var bgSoft = tc("shift-1");
245
+ var bgMute = tc("shift-2");
246
+ var border = tc("shift-3");
247
+ var textSoft = tc("shift-6");
248
+ var text = tc("shift-9");
249
+ var textStrong = tc("shift-11");
250
+ var brand = tc("shift-9", "primary");
251
+ var brandHover = tc("shift-10", "primary");
252
+ var headerH = ts(14);
253
+ var sidebarW = ts(62);
254
+ var asideW = ts(56);
255
+ var contentMax = ts(190);
229
256
  var SOCIAL_LABELS = {
230
257
  github: "GitHub",
231
258
  twitter: "Twitter",
@@ -239,42 +266,140 @@ var SOCIAL_LABELS = {
239
266
  function socialLinkEl(social) {
240
267
  const name = social.icon.toLowerCase();
241
268
  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" };
269
+ const innerEl = isUrl ? {
270
+ img: null,
271
+ src: social.icon,
272
+ alt: social.ariaLabel ?? name,
273
+ width: "18",
274
+ height: "18"
275
+ } : (
276
+ // dp-social-icon dp-icon-* classes drive SVG mask-image in pressCSS
277
+ {
278
+ span: "",
279
+ class: `dp-social-icon dp-icon-${name}`,
280
+ ariaHidden: "true"
281
+ }
282
+ );
243
283
  return {
244
284
  a: [innerEl],
245
285
  href: social.link,
246
- class: `dp-social-link dp-social-${name}`,
247
286
  ariaLabel: social.ariaLabel ?? SOCIAL_LABELS[name] ?? social.icon,
248
287
  target: "_blank",
249
- rel: "noopener noreferrer"
288
+ rel: "noopener noreferrer",
289
+ style: {
290
+ display: "inline-flex",
291
+ alignItems: "center",
292
+ justifyContent: "center",
293
+ width: ts(8.5),
294
+ height: ts(8.5),
295
+ borderRadius: ts(2),
296
+ color: textSoft,
297
+ background: bgSoft,
298
+ border: `1px solid ${border}`,
299
+ fontSize: "10px",
300
+ fontWeight: "700",
301
+ flexShrink: "0",
302
+ "&:hover": { color: text, borderColor: textSoft, textDecoration: "none" }
303
+ }
250
304
  };
251
305
  }
252
- function pageLink(text2, href, className) {
253
- return { a: text2, href, class: className, $: [navLink({ href })] };
306
+ function pageLink(text3, href) {
307
+ return { a: text3, href, $: [navLink({ href })] };
254
308
  }
255
309
  function navDropdown(item) {
310
+ const menuStyle = style({
311
+ display: "none",
312
+ position: "absolute",
313
+ top: `calc(100% + ${ts(2)})`,
314
+ right: "0",
315
+ background: bgSoft,
316
+ border: `1px solid ${border}`,
317
+ borderRadius: ts(2),
318
+ padding: ts(1.5),
319
+ minWidth: ts(40),
320
+ zIndex: "100",
321
+ flexDirection: "column",
322
+ gap: ts(0.5),
323
+ boxShadow: "0 4px 16px rgba(0,0,0,.1)",
324
+ "& a": {
325
+ display: "block",
326
+ padding: `${ts(1.25)} ${ts(2.5)}`,
327
+ borderRadius: ts(1.25),
328
+ fontSize: "13px"
329
+ },
330
+ "& a:hover": { background: bgMute }
331
+ });
256
332
  return {
257
333
  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" }
334
+ {
335
+ span: item.text,
336
+ style: {
337
+ color: textSoft,
338
+ fontSize: "14px",
339
+ fontWeight: "500",
340
+ cursor: "pointer",
341
+ userSelect: "none",
342
+ "&::after": { content: '" \u25BE"', fontSize: "10px", opacity: ".6" }
343
+ }
344
+ },
345
+ {
346
+ div: item.items.map((child) => pageLink(child.text, child.link)),
347
+ style: menuStyle
348
+ }
260
349
  ],
261
- class: "dp-nav-dropdown"
350
+ style: {
351
+ position: "relative",
352
+ display: "flex",
353
+ alignItems: "center",
354
+ "&:hover > div:last-child, &:focus-within > div:last-child": {
355
+ display: "flex"
356
+ }
357
+ }
262
358
  };
263
359
  }
264
360
  function announcementBar(config) {
265
361
  const bar = config.themeConfig.announcementBar;
266
362
  if (!bar) return null;
267
363
  const idAttr = bar.id ? bar.id : "";
268
- const children = [
269
- { span: bar.text, class: "dp-announcement-text" }
270
- ];
364
+ const children = [{ span: bar.text }];
271
365
  if (bar.dismissible !== false) {
272
- children.push({ button: "\u2715", type: "button", class: "dp-announcement-close", dataDismissAnnouncement: "", ariaLabel: "Dismiss" });
366
+ children.push({
367
+ button: "\u2715",
368
+ type: "button",
369
+ dataDismissAnnouncement: "",
370
+ ariaLabel: "Dismiss",
371
+ style: {
372
+ background: "none",
373
+ border: "none",
374
+ color: bg,
375
+ cursor: "pointer",
376
+ fontSize: "14px",
377
+ opacity: ".7",
378
+ padding: `${ts(0.5)} ${ts(1.5)}`,
379
+ borderRadius: ts(1),
380
+ flexShrink: "0",
381
+ "&:hover": { opacity: "1" }
382
+ }
383
+ });
273
384
  }
274
385
  return {
275
386
  div: children,
276
387
  class: "dp-announcement",
277
- ...idAttr ? { dataId: idAttr } : {}
388
+ // kept: JS uses querySelector('.dp-announcement')
389
+ ...idAttr ? { dataId: idAttr } : {},
390
+ style: {
391
+ display: "flex",
392
+ alignItems: "center",
393
+ justifyContent: "center",
394
+ gap: ts(3),
395
+ padding: `${ts(2.5)} ${ts(6)}`,
396
+ background: brand,
397
+ color: bg,
398
+ fontSize: "14px",
399
+ fontWeight: "500",
400
+ textAlign: "center",
401
+ "& a": { color: bg, fontWeight: "700" }
402
+ }
278
403
  };
279
404
  }
280
405
  function localeSwitcher(ctx) {
@@ -296,33 +421,116 @@ function localeSwitcher(ctx) {
296
421
  const links = entries.map(([key, locale]) => {
297
422
  const prefix = key === "/" ? "" : key.replace(/\/$/, "");
298
423
  const href = prefix + (barePath === "/" ? "/" : barePath);
424
+ const isActive = key === currentKey;
299
425
  return {
300
426
  a: locale.label,
301
427
  href,
302
- class: `dp-locale-option${key === currentKey ? " active" : ""}`,
303
- ...key === currentKey ? { ariaCurrent: "true" } : {},
304
- lang: locale.lang
428
+ ...isActive ? { ariaCurrent: "true" } : {},
429
+ lang: locale.lang,
430
+ style: {
431
+ display: "block",
432
+ padding: `${ts(1.25)} ${ts(2.5)}`,
433
+ borderRadius: ts(1.25),
434
+ fontSize: "13px",
435
+ color: textSoft,
436
+ ...isActive ? { color: brand, fontWeight: "600" } : {},
437
+ "&:hover": { background: bgMute, color: text, textDecoration: "none" }
438
+ }
305
439
  };
306
440
  });
441
+ const menuStyle = style({
442
+ display: "none",
443
+ position: "absolute",
444
+ top: `calc(100% + ${ts(2)})`,
445
+ right: "0",
446
+ background: bgSoft,
447
+ border: `1px solid ${border}`,
448
+ borderRadius: ts(2),
449
+ padding: ts(1.5),
450
+ minWidth: ts(32),
451
+ zIndex: "200",
452
+ flexDirection: "column",
453
+ gap: ts(0.5),
454
+ boxShadow: "0 4px 16px rgba(0,0,0,.1)"
455
+ });
307
456
  return {
308
457
  div: [
309
- { span: ["\u{1F310} ", currentLocale.label], class: "dp-locale-current" },
310
- { div: links, class: "dp-locale-menu" }
458
+ {
459
+ span: ["\u{1F310} ", currentLocale.label],
460
+ style: {
461
+ color: textSoft,
462
+ fontSize: "13px",
463
+ fontWeight: "500",
464
+ cursor: "pointer",
465
+ userSelect: "none",
466
+ padding: `${ts(1)} ${ts(2)}`,
467
+ border: `1px solid ${border}`,
468
+ borderRadius: ts(1.5),
469
+ background: bgSoft,
470
+ whiteSpace: "nowrap",
471
+ display: "flex",
472
+ alignItems: "center",
473
+ gap: ts(1),
474
+ "&::after": { content: '" \u25BE"', fontSize: "10px", opacity: ".6" }
475
+ }
476
+ },
477
+ { div: links, style: menuStyle }
311
478
  ],
312
- class: "dp-locale-switcher",
313
- ariaLabel: "Select language"
479
+ ariaLabel: "Select language",
480
+ style: {
481
+ position: "relative",
482
+ display: "flex",
483
+ alignItems: "center",
484
+ "&:hover > div:last-child, &:focus-within > div:last-child": {
485
+ display: "flex"
486
+ }
487
+ }
314
488
  };
315
489
  }
316
490
  function header(ctx) {
317
491
  const { config } = ctx;
318
492
  const searchEnabled = config.themeConfig.search !== false;
319
493
  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" }
494
+ const logoInner = logo ? typeof logo === "string" ? [
495
+ {
496
+ img: null,
497
+ src: logo,
498
+ alt: config.title,
499
+ style: { height: ts(7), width: "auto", display: "block" }
500
+ }
501
+ ] : [
502
+ {
503
+ img: null,
504
+ src: logo.light,
505
+ alt: config.title,
506
+ class: "dp-logo-light",
507
+ style: { height: ts(7), width: "auto", display: "block" }
508
+ },
509
+ {
510
+ img: null,
511
+ src: logo.dark,
512
+ alt: config.title,
513
+ class: "dp-logo-dark",
514
+ style: { height: ts(7), width: "auto", display: "block" }
515
+ }
323
516
  ] : [];
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);
517
+ const logoStyle = {
518
+ fontWeight: "700",
519
+ fontSize: "18px",
520
+ color: textStrong,
521
+ whiteSpace: "nowrap",
522
+ flexShrink: "0",
523
+ textDecoration: "none",
524
+ "&:hover": { textDecoration: "none" }
525
+ };
526
+ const logoEl = logo ? { a: logoInner, href: config.base, style: logoStyle } : {
527
+ a: config.title,
528
+ href: config.base,
529
+ style: logoStyle
530
+ };
531
+ const socialEls = (config.themeConfig.socialLinks ?? []).map(
532
+ socialLinkEl
533
+ );
326
534
  const localeEl = localeSwitcher(ctx);
327
535
  return {
328
536
  header: [
@@ -330,48 +538,153 @@ function header(ctx) {
330
538
  toolbarSpacer(),
331
539
  {
332
540
  nav: config.themeConfig.nav.map(
333
- (item) => item.items ? navDropdown(item) : pageLink(item.text, item.link)
541
+ (item) => item.items ? navDropdown(
542
+ item
543
+ ) : pageLink(item.text, item.link)
334
544
  ),
335
545
  $: [toolbar({ gap: 4 })],
336
- class: "dp-nav",
337
- ariaLabel: "Primary"
546
+ ariaLabel: "Primary",
547
+ style: {
548
+ "& a": {
549
+ color: textSoft,
550
+ fontSize: "14px",
551
+ fontWeight: "500",
552
+ whiteSpace: "nowrap",
553
+ lineHeight: "1"
554
+ },
555
+ "& a:hover, & a[aria-current='page']": {
556
+ color: brand,
557
+ textDecoration: "none"
558
+ },
559
+ "@media (max-width: 860px)": { display: "none" }
560
+ }
338
561
  },
339
562
  {
340
563
  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
- }] : [],
564
+ ...searchEnabled ? [
565
+ {
566
+ div: [
567
+ {
568
+ input: null,
569
+ type: "search",
570
+ placeholder: typeof config.themeConfig.search === "object" && config.themeConfig.search.placeholder || "Search...",
571
+ ariaLabel: "Search documentation",
572
+ style: {
573
+ width: "100%",
574
+ height: ts(8),
575
+ padding: `0 ${ts(2.5)}`,
576
+ border: `1px solid ${border}`,
577
+ borderRadius: ts(1.5),
578
+ background: bgSoft,
579
+ color: textSoft,
580
+ fontSize: "13px",
581
+ fontFamily: "inherit",
582
+ outline: "none",
583
+ cursor: "pointer",
584
+ "&::placeholder": { color: textSoft }
585
+ }
586
+ }
587
+ ],
588
+ dataIsland: "search",
589
+ style: {
590
+ width: ts(50),
591
+ "@media (max-width: 860px)": { width: ts(35) }
592
+ }
593
+ }
594
+ ] : [],
352
595
  ...socialEls,
353
596
  ...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: "" }
597
+ {
598
+ button: "\u25D0",
599
+ type: "button",
600
+ ariaLabel: "Toggle dark mode",
601
+ dataThemeToggle: "",
602
+ style: {
603
+ border: `1px solid ${border}`,
604
+ background: bgSoft,
605
+ color: text,
606
+ borderRadius: ts(2),
607
+ width: ts(8.5),
608
+ height: ts(8.5),
609
+ cursor: "pointer",
610
+ fontSize: "16px",
611
+ flexShrink: "0"
612
+ }
613
+ },
614
+ {
615
+ button: "\u2630",
616
+ type: "button",
617
+ ariaLabel: "Toggle menu",
618
+ dataMenuToggle: "",
619
+ style: {
620
+ border: `1px solid ${border}`,
621
+ background: bgSoft,
622
+ color: text,
623
+ borderRadius: ts(2),
624
+ width: ts(8.5),
625
+ height: ts(8.5),
626
+ cursor: "pointer",
627
+ fontSize: "16px",
628
+ flexShrink: "0",
629
+ display: "none",
630
+ "@media (max-width: 860px)": { display: "block" }
631
+ }
632
+ }
356
633
  ],
357
634
  $: [toolbar({ gap: 2 })],
358
- class: "dp-header-actions"
635
+ style: { flexShrink: "0" }
359
636
  }
360
637
  ],
361
638
  $: [toolbar({ gap: 4 })],
362
- class: "dp-header"
639
+ style: {
640
+ position: "sticky",
641
+ top: "0",
642
+ height: headerH,
643
+ background: bg,
644
+ borderBottom: `1px solid ${border}`,
645
+ zIndex: "100",
646
+ padding: `0 ${ts(6)}`,
647
+ "@media (max-width: 860px)": { padding: `0 ${ts(3)}` }
648
+ }
363
649
  };
364
650
  }
365
- function sidebarBadge(badge) {
366
- return { span: badge.text, class: `dp-badge dp-badge-${badge.type ?? "tip"}` };
651
+ function badgeEl(badge) {
652
+ const colorMap = {
653
+ tip: brand,
654
+ info: textSoft,
655
+ warning: tc("shift-9", "warning"),
656
+ danger: tc("shift-9", "danger")
657
+ };
658
+ const bgMap = {
659
+ tip: `color-mix(in srgb,${brand} 12%,${bg})`,
660
+ info: bgMute,
661
+ warning: `color-mix(in srgb,${tc("shift-9", "warning")} 12%,${bg})`,
662
+ danger: `color-mix(in srgb,${tc("shift-9", "danger")} 12%,${bg})`
663
+ };
664
+ const type = badge.type ?? "tip";
665
+ return {
666
+ span: badge.text,
667
+ style: {
668
+ display: "inline-block",
669
+ padding: `${ts(0.5)} ${ts(1.75)}`,
670
+ borderRadius: ts(2.5),
671
+ fontSize: "11px",
672
+ fontWeight: "700",
673
+ lineHeight: "1.4",
674
+ whiteSpace: "nowrap",
675
+ verticalAlign: "middle",
676
+ background: bgMap[type] ?? bgMute,
677
+ color: colorMap[type] ?? textSoft
678
+ }
679
+ };
367
680
  }
368
- function pageLinkWithBadge(text2, href, badge) {
369
- if (!badge) return pageLink(text2, href);
681
+ function pageLinkWithBadge(text3, href, badge) {
682
+ if (!badge) return pageLink(text3, href);
370
683
  return {
371
- a: [{ span: text2 }, sidebarBadge(badge)],
684
+ a: [{ span: text3 }, badgeEl(badge)],
372
685
  href,
373
686
  $: [navLink({ href })],
374
- class: "dp-sidebar-link-with-badge"
687
+ style: { display: "flex", alignItems: "center" }
375
688
  };
376
689
  }
377
690
  function sidebarGroup(group) {
@@ -383,63 +696,215 @@ function sidebarGroup(group) {
383
696
  const titleChildren = [
384
697
  { span: group.text }
385
698
  ];
386
- if (group.badge) titleChildren.push(sidebarBadge(group.badge));
699
+ if (group.badge) titleChildren.push(badgeEl(group.badge));
387
700
  if (isCollapsible) {
388
701
  titleChildren.push({
389
702
  button: group.collapsed ? "\u203A" : "\u2039",
390
703
  type: "button",
391
- class: "dp-sidebar-toggle",
392
704
  ariaLabel: group.collapsed ? "Expand" : "Collapse",
393
- dataSidebarToggle: ""
705
+ dataSidebarToggle: "",
706
+ style: {
707
+ marginLeft: "auto",
708
+ background: "none",
709
+ border: "none",
710
+ cursor: "pointer",
711
+ color: textSoft,
712
+ fontSize: "14px",
713
+ padding: `0 ${ts(1)}`,
714
+ lineHeight: "1",
715
+ "&:hover": { color: text }
716
+ }
394
717
  });
395
718
  }
396
- children.push({ div: titleChildren, class: "dp-sidebar-title" });
719
+ children.push({
720
+ div: titleChildren,
721
+ style: {
722
+ display: "flex",
723
+ alignItems: "center",
724
+ gap: ts(1.5),
725
+ fontSize: "13px",
726
+ fontWeight: "700",
727
+ color: textStrong,
728
+ margin: `${ts(2)} 0 ${ts(1)}`
729
+ }
730
+ });
397
731
  }
398
732
  if (group.items) {
399
733
  const itemsEl = [];
400
734
  for (const item of group.items) {
401
735
  if (item.items) {
402
- itemsEl.push({ div: item.text, class: "dp-sidebar-subtitle" });
736
+ itemsEl.push({
737
+ div: item.text,
738
+ style: {
739
+ fontSize: "12px",
740
+ color: textSoft,
741
+ padding: `${ts(1)} ${ts(3)}`,
742
+ fontWeight: "600"
743
+ }
744
+ });
403
745
  for (const leaf of item.items) {
404
- if (leaf.link) itemsEl.push(pageLinkWithBadge(leaf.text, leaf.link, leaf.badge));
746
+ if (leaf.link)
747
+ itemsEl.push(pageLinkWithBadge(leaf.text, leaf.link, leaf.badge));
405
748
  }
406
749
  } else if (item.link) {
407
750
  itemsEl.push(pageLinkWithBadge(item.text, item.link, item.badge));
408
751
  }
409
752
  }
410
- children.push({ div: itemsEl, class: "dp-sidebar-items" });
753
+ children.push({
754
+ div: itemsEl,
755
+ class: "dp-sidebar-items",
756
+ style: { display: "flex", flexDirection: "column" }
757
+ });
411
758
  }
412
- const groupClass = ["dp-sidebar-group", isCollapsible && group.collapsed ? "collapsed" : ""].filter(Boolean).join(" ");
413
- return { div: children, class: groupClass };
759
+ const groupClass = [
760
+ "dp-sidebar-group",
761
+ isCollapsible && group.collapsed ? "collapsed" : ""
762
+ ].filter(Boolean).join(" ");
763
+ return {
764
+ div: children,
765
+ class: groupClass,
766
+ style: { marginBottom: ts(3.5) }
767
+ };
414
768
  }
415
769
  function sidebar(ctx) {
416
770
  const groups = sidebarForRoute(ctx.route, ctx.config);
417
- return { nav: groups.map(sidebarGroup), class: "dp-sidebar", ariaLabel: "Documentation" };
771
+ return {
772
+ nav: groups.map(sidebarGroup),
773
+ ariaLabel: "Documentation",
774
+ // used as stable selector in pressCSS mobile-open rule
775
+ style: {
776
+ position: "sticky",
777
+ top: headerH,
778
+ maxHeight: `calc(100vh - ${headerH})`,
779
+ overflowY: "auto",
780
+ padding: `${ts(6)} ${ts(3)} ${ts(12)} ${ts(6)}`,
781
+ borderRight: `1px solid ${border}`,
782
+ "& a": {
783
+ display: "flex",
784
+ alignItems: "center",
785
+ gap: ts(1.5),
786
+ padding: `${ts(1.25)} ${ts(3)}`,
787
+ fontSize: "14px",
788
+ color: textSoft,
789
+ borderRadius: ts(1.5)
790
+ },
791
+ "& a:hover": { color: text, textDecoration: "none" },
792
+ "& a[aria-current='page']": {
793
+ color: brand,
794
+ fontWeight: "600",
795
+ background: bgSoft
796
+ },
797
+ "@media (max-width: 860px)": {
798
+ position: "fixed",
799
+ top: headerH,
800
+ left: "0",
801
+ bottom: "0",
802
+ width: "80%",
803
+ maxWidth: ts(80),
804
+ background: bg,
805
+ zIndex: "25",
806
+ transform: "translateX(-100%)",
807
+ transition: "transform .2s ease",
808
+ maxHeight: "none"
809
+ }
810
+ }
811
+ };
418
812
  }
419
813
  function tocAside(ctx) {
420
814
  if (ctx.frontmatter.aside === false) return null;
421
815
  const [minLevel, maxLevel] = ctx.config.themeConfig.outline?.level ?? [2, 3];
422
- const entries = ctx.toc.filter((e) => e.level >= minLevel && e.level <= maxLevel);
816
+ const entries = ctx.toc.filter(
817
+ (e) => e.level >= minLevel && e.level <= maxLevel
818
+ );
423
819
  if (entries.length === 0) return null;
424
820
  const tocTitle = ctx.config.themeConfig.tocTitle ?? "On this page";
821
+ const indentMap = { 2: "0", 3: ts(3), 4: ts(6) };
425
822
  return {
426
823
  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" }
824
+ {
825
+ div: tocTitle,
826
+ style: { fontWeight: "700", marginBottom: ts(2), color: text }
827
+ },
828
+ {
829
+ nav: entries.map((e) => ({
830
+ a: e.text,
831
+ href: `#${e.slug}`,
832
+ style: {
833
+ display: "block",
834
+ padding: `${ts(0.75)} 0`,
835
+ color: textSoft,
836
+ paddingLeft: indentMap[e.level] ?? "0",
837
+ "&:hover": { color: brand, textDecoration: "none" }
838
+ }
839
+ }))
840
+ }
429
841
  ],
430
- class: "dp-aside"
842
+ style: {
843
+ position: "sticky",
844
+ top: headerH,
845
+ maxHeight: `calc(100vh - ${headerH})`,
846
+ overflowY: "auto",
847
+ padding: `${ts(8)} ${ts(6)}`,
848
+ fontSize: "13px"
849
+ }
431
850
  };
432
851
  }
433
852
  function prevNext(ctx) {
434
853
  const { prev, next } = prevNextForRoute(ctx.route, ctx.config);
435
854
  if (!prev && !next) return null;
855
+ const linkStyle = style({
856
+ display: "block",
857
+ padding: `${ts(3)} ${ts(4)}`,
858
+ border: `1px solid ${border}`,
859
+ borderRadius: ts(2),
860
+ fontWeight: "600",
861
+ flex: "1",
862
+ "&:hover": { borderColor: brand, textDecoration: "none" }
863
+ });
436
864
  return {
437
865
  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: "" }
866
+ prev ? {
867
+ a: [
868
+ {
869
+ small: "Previous",
870
+ style: {
871
+ display: "block",
872
+ color: textSoft,
873
+ fontWeight: "400",
874
+ fontSize: "12px"
875
+ }
876
+ },
877
+ { span: prev.text }
878
+ ],
879
+ href: prev.link,
880
+ style: linkStyle
881
+ } : { span: "" },
882
+ next ? {
883
+ a: [
884
+ {
885
+ small: "Next",
886
+ style: {
887
+ display: "block",
888
+ color: textSoft,
889
+ fontWeight: "400",
890
+ fontSize: "12px"
891
+ }
892
+ },
893
+ { span: next.text }
894
+ ],
895
+ href: next.link,
896
+ style: { ...linkStyle, textAlign: "right" }
897
+ } : { span: "" }
440
898
  ],
441
- class: "dp-prevnext",
442
- ariaLabel: "Page navigation"
899
+ ariaLabel: "Page navigation",
900
+ style: {
901
+ display: "flex",
902
+ justifyContent: "space-between",
903
+ gap: ts(4),
904
+ marginTop: ts(12),
905
+ paddingTop: ts(6),
906
+ borderTop: `1px solid ${border}`
907
+ }
443
908
  };
444
909
  }
445
910
  function docFooter(ctx) {
@@ -451,70 +916,361 @@ function docFooter(ctx) {
451
916
  const children = [];
452
917
  if (hasDate) {
453
918
  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" });
919
+ const formatted = date.toLocaleDateString("en-US", {
920
+ year: "numeric",
921
+ month: "long",
922
+ day: "numeric"
923
+ });
924
+ children.push({
925
+ span: [`Last updated: `, { time: formatted, dateTime: ctx.lastUpdated }]
926
+ });
456
927
  }
457
928
  if (ctx.readingTime) {
458
- children.push({ span: `${ctx.readingTime} min read`, class: "dp-reading-time" });
929
+ children.push({ span: `\u{1F4D6} ${ctx.readingTime} min read` });
459
930
  }
460
931
  if (hasEdit) {
461
932
  const pattern = editLink.pattern;
462
933
  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" });
934
+ children.push({
935
+ a: editLink.text ?? "Edit this page",
936
+ href,
937
+ target: "_blank",
938
+ rel: "noopener noreferrer",
939
+ style: { fontWeight: "500", fontSize: "13px" }
940
+ });
464
941
  }
465
- return { div: children, class: "dp-doc-footer" };
942
+ return {
943
+ div: children,
944
+ style: {
945
+ display: "flex",
946
+ alignItems: "center",
947
+ gap: ts(4),
948
+ flexWrap: "wrap",
949
+ marginTop: ts(8),
950
+ paddingTop: ts(5),
951
+ borderTop: `1px solid ${border}`,
952
+ fontSize: "13px",
953
+ color: textSoft
954
+ }
955
+ };
466
956
  }
467
957
  function pageBadge(frontmatter) {
468
958
  const badge = frontmatter.badge;
469
959
  if (!badge) return null;
470
- const text2 = typeof badge === "string" ? badge : badge.text ?? "";
960
+ const text22 = typeof badge === "string" ? badge : badge.text ?? "";
471
961
  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` };
962
+ if (!text22) return null;
963
+ return badgeEl({
964
+ text: text22,
965
+ type
966
+ });
967
+ }
968
+ function resolveSlot(ctx, key, fallback) {
969
+ const override = ctx.config.themeConfig.slots?.[key];
970
+ return override ? override(ctx) : fallback(ctx);
971
+ }
972
+ function contentDiv(body) {
973
+ return {
974
+ div: body,
975
+ style: {
976
+ maxWidth: contentMax,
977
+ "& h1": {
978
+ fontSize: "30px",
979
+ fontWeight: "700",
980
+ lineHeight: "1.25",
981
+ margin: `0 0 ${ts(6)}`,
982
+ letterSpacing: "-.02em",
983
+ color: textStrong
984
+ },
985
+ "& h2": {
986
+ fontSize: "22px",
987
+ fontWeight: "700",
988
+ margin: `${ts(11)} 0 ${ts(4)}`,
989
+ paddingTop: ts(5),
990
+ borderTop: `1px solid ${border}`,
991
+ letterSpacing: "-.01em",
992
+ color: textStrong
993
+ },
994
+ "& h3": {
995
+ fontSize: "18px",
996
+ fontWeight: "600",
997
+ margin: `${ts(7)} 0 ${ts(3)}`,
998
+ color: textStrong
999
+ },
1000
+ "& h4": {
1001
+ fontSize: "16px",
1002
+ fontWeight: "600",
1003
+ margin: `${ts(5.5)} 0 ${ts(2)}`,
1004
+ color: textStrong
1005
+ },
1006
+ "& p": { margin: `${ts(4)} 0` },
1007
+ "& ul, & ol": { margin: `${ts(4)} 0`, paddingLeft: "1.4em" },
1008
+ "& li": { margin: `${ts(1.5)} 0` },
1009
+ "& a": { fontWeight: "500" },
1010
+ "& a[target='_blank']::after": {
1011
+ content: '" \u2197"',
1012
+ fontSize: ".75em",
1013
+ opacity: ".6"
1014
+ },
1015
+ "& strong": { fontWeight: "600", color: textStrong },
1016
+ "& em": { fontStyle: "italic" },
1017
+ "& mark": {
1018
+ background: `color-mix(in srgb,${tc("shift-6", "warning")} 40%,${bg})`,
1019
+ color: "inherit",
1020
+ padding: `${ts(0.25)} ${ts(0.75)}`,
1021
+ borderRadius: ts(0.75)
1022
+ },
1023
+ "& sup": { fontSize: ".75em", verticalAlign: "super" },
1024
+ "& sub": { fontSize: ".75em", verticalAlign: "sub" },
1025
+ "& del": { opacity: ".5" },
1026
+ "& blockquote": {
1027
+ margin: `${ts(4)} 0`,
1028
+ padding: `0 ${ts(4)}`,
1029
+ borderLeft: `3px solid ${border}`,
1030
+ color: textSoft
1031
+ },
1032
+ "& img": { maxWidth: "100%", height: "auto", borderRadius: ts(1.5) },
1033
+ "& hr": {
1034
+ border: "none",
1035
+ borderTop: `1px solid ${border}`,
1036
+ margin: `${ts(8)} 0`
1037
+ },
1038
+ "& :not(pre)>code": {
1039
+ fontFamily: `ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace`,
1040
+ fontSize: ".85em",
1041
+ background: bgMute,
1042
+ padding: `${ts(0.75)} ${ts(1.5)}`,
1043
+ borderRadius: ts(1)
1044
+ },
1045
+ "& pre": {
1046
+ margin: `${ts(4)} 0`,
1047
+ padding: `${ts(4)} ${ts(5)}`,
1048
+ background: bgSoft,
1049
+ border: `1px solid ${border}`,
1050
+ borderRadius: ts(2),
1051
+ overflowX: "auto",
1052
+ fontSize: "13.5px",
1053
+ lineHeight: "1.5"
1054
+ },
1055
+ "& pre code": {
1056
+ fontFamily: `ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace`,
1057
+ background: "none",
1058
+ padding: "0"
1059
+ },
1060
+ "& table": {
1061
+ borderCollapse: "collapse",
1062
+ margin: `${ts(4)} 0`,
1063
+ display: "block",
1064
+ overflowX: "auto"
1065
+ },
1066
+ "& th, & td": {
1067
+ border: `1px solid ${border}`,
1068
+ padding: `${ts(2)} ${ts(3.5)}`,
1069
+ textAlign: "left"
1070
+ },
1071
+ "& th": { background: bgSoft, fontWeight: "600" }
1072
+ }
1073
+ };
474
1074
  }
475
1075
  function pageShell(ctx) {
1076
+ const showSidebar = ctx.frontmatter.sidebar !== false;
476
1077
  const main = [];
477
1078
  const badge = pageBadge(ctx.frontmatter);
478
- if (badge) main.push({ div: [badge], class: "dp-page-badge-row" });
479
- main.push({ div: ctx.body, class: "dp-content" });
480
- const pn = prevNext(ctx);
1079
+ if (badge)
1080
+ main.push({
1081
+ div: [badge],
1082
+ style: { marginBottom: ts(-2) }
1083
+ });
1084
+ main.push(contentDiv(ctx.body));
1085
+ const pn = resolveSlot(ctx, "prevNext", prevNext);
481
1086
  if (pn) main.push(pn);
482
- const footer = docFooter(ctx);
483
- if (footer) main.push(footer);
484
- const shellChildren = [sidebar(ctx), { main, class: "dp-main" }];
485
- const aside = tocAside(ctx);
486
- if (aside) shellChildren.push(aside);
1087
+ const docFooterEl = resolveSlot(ctx, "docFooter", docFooter);
1088
+ if (docFooterEl) main.push(docFooterEl);
1089
+ const sidebarEl = showSidebar ? resolveSlot(ctx, "sidebar", sidebar) : null;
1090
+ const mainStyle = showSidebar ? {
1091
+ padding: `${ts(8)} ${ts(12)} ${ts(20)}`,
1092
+ minWidth: "0",
1093
+ "@media (max-width: 860px)": { padding: `${ts(6)} ${ts(5)} ${ts(16)}` }
1094
+ } : {
1095
+ padding: `${ts(8)} ${ts(12)} ${ts(20)}`,
1096
+ gridColumn: "1 / -1",
1097
+ maxWidth: contentMax,
1098
+ margin: "0 auto",
1099
+ "@media (max-width: 860px)": { padding: `${ts(6)} ${ts(5)} ${ts(16)}` }
1100
+ };
1101
+ const shellChildren = [
1102
+ ...sidebarEl ? [sidebarEl] : [],
1103
+ { main, style: mainStyle }
1104
+ ];
1105
+ const asideEl = resolveSlot(ctx, "aside", tocAside);
1106
+ if (asideEl && showSidebar) shellChildren.push(asideEl);
1107
+ const headerEl = resolveSlot(ctx, "header", header);
487
1108
  const bar = announcementBar(ctx.config);
1109
+ const slots = ctx.config.themeConfig.slots;
1110
+ const footerContent = slots?.footer ? slots.footer(ctx) : {
1111
+ footer: ctx.config.themeConfig.footerMessage ?? "",
1112
+ style: {
1113
+ padding: `${ts(6)} ${ts(12)}`,
1114
+ borderTop: `1px solid ${border}`,
1115
+ color: textSoft,
1116
+ fontSize: "13px"
1117
+ }
1118
+ };
488
1119
  return {
489
1120
  div: [
490
1121
  ...bar ? [bar] : [],
491
- header(ctx),
492
- { div: shellChildren, class: "dp-shell" },
493
- { footer: ctx.config.themeConfig.footerMessage ?? "", class: "dp-footer" }
1122
+ ...headerEl ? [headerEl] : [],
1123
+ {
1124
+ div: shellChildren,
1125
+ style: {
1126
+ display: "grid",
1127
+ gridTemplateColumns: showSidebar ? `${sidebarW} minmax(0,1fr) ${asideW}` : "1fr",
1128
+ alignItems: "start",
1129
+ maxWidth: "1440px",
1130
+ margin: "0 auto",
1131
+ "@media (max-width: 1200px)": showSidebar ? { gridTemplateColumns: `${sidebarW} minmax(0,1fr)` } : {},
1132
+ "@media (max-width: 860px)": { gridTemplateColumns: "1fr" }
1133
+ }
1134
+ },
1135
+ ...footerContent ? [footerContent] : []
494
1136
  ]
495
1137
  };
496
1138
  }
497
1139
  function heroSection(hero) {
498
1140
  const children = [];
499
- if (hero.name) children.push({ div: hero.name, class: "dp-hero-name" });
500
- if (hero.text) children.push({ h1: hero.text, class: "dp-hero-text" });
501
- if (hero.tagline) children.push({ p: hero.tagline, class: "dp-hero-tagline" });
1141
+ if (hero.name)
1142
+ children.push({
1143
+ div: hero.name,
1144
+ style: {
1145
+ fontSize: "56px",
1146
+ fontWeight: "800",
1147
+ lineHeight: "1.1",
1148
+ letterSpacing: "-.03em",
1149
+ background: `linear-gradient(120deg,${brand},${tc("shift-7", "secondary")})`,
1150
+ WebkitBackgroundClip: "text",
1151
+ backgroundClip: "text",
1152
+ color: "transparent"
1153
+ }
1154
+ });
1155
+ if (hero.text)
1156
+ children.push({
1157
+ h1: hero.text,
1158
+ style: {
1159
+ fontSize: "30px",
1160
+ fontWeight: "700",
1161
+ margin: `${ts(3)} 0 0`,
1162
+ color: textStrong
1163
+ }
1164
+ });
1165
+ if (hero.tagline)
1166
+ children.push({
1167
+ p: hero.tagline,
1168
+ style: {
1169
+ fontSize: "18px",
1170
+ color: textSoft,
1171
+ maxWidth: ts(160),
1172
+ margin: `${ts(5)} auto 0`
1173
+ }
1174
+ });
502
1175
  if (hero.actions?.length) {
503
- children.push({ div: hero.actions.map((a) => ({ a: a.text, href: a.link, class: `dp-hero-action ${a.theme ?? "brand"}` })), class: "dp-hero-actions" });
1176
+ const actionStyle = (theme) => {
1177
+ if (!theme || theme === "brand")
1178
+ return {
1179
+ padding: `${ts(2.5)} ${ts(5.5)}`,
1180
+ borderRadius: ts(5.5),
1181
+ fontWeight: "600",
1182
+ fontSize: "15px",
1183
+ background: brand,
1184
+ color: bg,
1185
+ "&:hover": { background: brandHover, textDecoration: "none" }
1186
+ };
1187
+ return {
1188
+ padding: `${ts(2.5)} ${ts(5.5)}`,
1189
+ borderRadius: ts(5.5),
1190
+ fontWeight: "600",
1191
+ fontSize: "15px",
1192
+ background: bgSoft,
1193
+ color: text,
1194
+ border: `1px solid ${border}`,
1195
+ "&:hover": { borderColor: brand, textDecoration: "none" }
1196
+ };
1197
+ };
1198
+ children.push({
1199
+ div: hero.actions.map(
1200
+ (a) => ({
1201
+ a: a.text,
1202
+ href: a.link,
1203
+ style: actionStyle(a.theme)
1204
+ })
1205
+ ),
1206
+ style: {
1207
+ display: "flex",
1208
+ gap: ts(3),
1209
+ justifyContent: "center",
1210
+ marginTop: ts(7),
1211
+ flexWrap: "wrap"
1212
+ }
1213
+ });
504
1214
  }
505
- return { section: children, class: "dp-hero" };
1215
+ return {
1216
+ section: children,
1217
+ style: { textAlign: "center", padding: `${ts(10)} 0 ${ts(6)}` }
1218
+ };
506
1219
  }
507
1220
  function featuresSection(features) {
508
1221
  return {
509
1222
  div: features.map((f) => {
510
1223
  const inner = [];
511
- if (f.icon) inner.push({ div: f.icon, class: "dp-feature-icon" });
512
- inner.push({ div: f.title, class: "dp-feature-title" });
513
- inner.push({ p: f.details, class: "dp-feature-details" });
514
- const el = { div: inner, class: "dp-feature" };
515
- return f.link ? { a: [el], href: f.link, class: "dp-feature-link" } : el;
1224
+ if (f.icon)
1225
+ inner.push({
1226
+ div: f.icon,
1227
+ style: { fontSize: "28px", marginBottom: ts(3) }
1228
+ });
1229
+ inner.push({
1230
+ div: f.title,
1231
+ style: {
1232
+ fontWeight: "700",
1233
+ fontSize: "17px",
1234
+ marginBottom: ts(2),
1235
+ color: textStrong
1236
+ }
1237
+ });
1238
+ inner.push({
1239
+ p: f.details,
1240
+ style: {
1241
+ fontSize: "14px",
1242
+ color: textSoft,
1243
+ margin: "0",
1244
+ lineHeight: "1.5"
1245
+ }
1246
+ });
1247
+ const featureStyle = {
1248
+ padding: ts(5),
1249
+ background: bgSoft,
1250
+ border: `1px solid ${border}`,
1251
+ borderRadius: ts(3)
1252
+ };
1253
+ const el = {
1254
+ div: inner,
1255
+ style: featureStyle
1256
+ };
1257
+ return f.link ? {
1258
+ a: [el],
1259
+ href: f.link,
1260
+ style: {
1261
+ display: "block",
1262
+ color: "inherit",
1263
+ "&:hover": { textDecoration: "none" },
1264
+ "&:hover > div": { borderColor: brand }
1265
+ }
1266
+ } : el;
516
1267
  }),
517
- class: "dp-features"
1268
+ style: {
1269
+ display: "grid",
1270
+ gridTemplateColumns: `repeat(auto-fit,minmax(${ts(60)},1fr))`,
1271
+ gap: ts(4),
1272
+ margin: `${ts(10)} 0`
1273
+ }
518
1274
  };
519
1275
  }
520
1276
  function homeShell(ctx) {
@@ -523,14 +1279,29 @@ function homeShell(ctx) {
523
1279
  const features = ctx.frontmatter.features;
524
1280
  if (hero) main.push(heroSection(hero));
525
1281
  if (features?.length) main.push(featuresSection(features));
526
- main.push({ div: ctx.body, class: "dp-content dp-home" });
1282
+ main.push(contentDiv(ctx.body));
527
1283
  const bar = announcementBar(ctx.config);
528
1284
  return {
529
1285
  div: [
530
1286
  ...bar ? [bar] : [],
531
1287
  header(ctx),
532
- { main, class: "dp-main dp-main-home" },
533
- { footer: ctx.config.themeConfig.footerMessage ?? "", class: "dp-footer" }
1288
+ {
1289
+ main,
1290
+ style: {
1291
+ maxWidth: "1100px",
1292
+ margin: "0 auto",
1293
+ padding: `${ts(12)} ${ts(6)} ${ts(20)}`
1294
+ }
1295
+ },
1296
+ {
1297
+ footer: ctx.config.themeConfig.footerMessage ?? "",
1298
+ style: {
1299
+ padding: `${ts(6)} ${ts(12)}`,
1300
+ borderTop: `1px solid ${border}`,
1301
+ color: textSoft,
1302
+ fontSize: "13px"
1303
+ }
1304
+ }
534
1305
  ]
535
1306
  };
536
1307
  }
@@ -538,14 +1309,17 @@ function homeShell(ctx) {
538
1309
  // src/pipeline.ts
539
1310
  import { readFileSync } from "fs";
540
1311
  import { dirname, extname, isAbsolute, resolve } from "path";
541
- import { splitFrontmatter, tokensToDomphy } from "@domphy/markdown";
1312
+ import {
1313
+ splitFrontmatter,
1314
+ tokensToDomphy
1315
+ } from "@domphy/markdown";
542
1316
  import MarkdownIt from "markdown-it";
543
1317
  import container from "markdown-it-container";
1318
+ import emojiPkg from "markdown-it-emoji";
1319
+ import includeUntyped from "markdown-it-include";
544
1320
  import markUntyped from "markdown-it-mark";
545
1321
  import subUntyped from "markdown-it-sub";
546
1322
  import supUntyped from "markdown-it-sup";
547
- import includeUntyped from "markdown-it-include";
548
- import emojiPkg from "markdown-it-emoji";
549
1323
  var include = includeUntyped;
550
1324
  var markPlugin = markUntyped;
551
1325
  var subPlugin = subUntyped;
@@ -579,19 +1353,22 @@ function resolveSpecifier(spec, fileDir, docsDir) {
579
1353
  return resolve(fileDir, spec);
580
1354
  }
581
1355
  function expandCodeImports(body, fileDir, docsDir) {
582
- return body.replace(CODE_IMPORT_PATTERN, (_whole, rawPath, label) => {
583
- const absolute = resolveSpecifier(rawPath, fileDir, docsDir);
584
- const fence = "```";
585
- let contents;
586
- try {
587
- contents = readFileSync(absolute, "utf8");
588
- } catch {
589
- return [fence, `Could not import: ${rawPath}`, fence].join("\n");
1356
+ return body.replace(
1357
+ CODE_IMPORT_PATTERN,
1358
+ (_whole, rawPath, label) => {
1359
+ const absolute = resolveSpecifier(rawPath, fileDir, docsDir);
1360
+ const fence = "```";
1361
+ let contents;
1362
+ try {
1363
+ contents = readFileSync(absolute, "utf8");
1364
+ } catch {
1365
+ return [fence, `Could not import: ${rawPath}`, fence].join("\n");
1366
+ }
1367
+ const language = EXT_LANG[extname(absolute).toLowerCase()] ?? "";
1368
+ const info = label ? `${language} [${label}]` : language;
1369
+ return [fence + info, contents.trimEnd(), fence].join("\n");
590
1370
  }
591
- const language = EXT_LANG[extname(absolute).toLowerCase()] ?? "";
592
- const info = label ? `${language} [${label}]` : language;
593
- return [fence + info, contents.trimEnd(), fence].join("\n");
594
- });
1371
+ );
595
1372
  }
596
1373
  function stripScriptBlocks(source) {
597
1374
  return source.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").replace(/^\s*\n/, "");
@@ -620,9 +1397,9 @@ function buildTitleTokens(Token, tag, openType, closeType, className, title) {
620
1397
  const inline = new Token("inline", "", 0);
621
1398
  inline.content = title;
622
1399
  inline.children = [];
623
- const text2 = new Token("text", "", 0);
624
- text2.content = title;
625
- inline.children.push(text2);
1400
+ const text3 = new Token("text", "", 0);
1401
+ text3.content = title;
1402
+ inline.children.push(text3);
626
1403
  const close = new Token(closeType, tag, -1);
627
1404
  close.block = true;
628
1405
  return [open, inline, close];
@@ -646,7 +1423,10 @@ function buildCodeGroupTokens(Token, tokens, openIndex, closeIndex, groupId) {
646
1423
  const info = (token.info ?? "").trim();
647
1424
  const labelMatch = info.match(/\[([^\]]+)\]/);
648
1425
  const language = info.split(/\s+/, 1)[0] ?? "";
649
- fences.push({ token, label: labelMatch ? labelMatch[1] : language || "Code" });
1426
+ fences.push({
1427
+ token,
1428
+ label: labelMatch ? labelMatch[1] : language || "Code"
1429
+ });
650
1430
  }
651
1431
  if (fences.length === 0) return tokens.slice(openIndex, closeIndex + 1);
652
1432
  const inputsHtml = fences.map(
@@ -673,7 +1453,9 @@ function shapeContainers(tokens) {
673
1453
  let groupCounter = 0;
674
1454
  const ALL_ADMONITIONS = Object.keys(ADMONITION_TITLES).join("|");
675
1455
  const admonitionRe = new RegExp(`^container_(${ALL_ADMONITIONS})_open$`);
676
- const admonitionCloseRe = new RegExp(`^container_(${ALL_ADMONITIONS})_close$`);
1456
+ const admonitionCloseRe = new RegExp(
1457
+ `^container_(${ALL_ADMONITIONS})_close$`
1458
+ );
677
1459
  for (let i = 0; i < tokens.length; i++) {
678
1460
  const token = tokens[i];
679
1461
  const admonition = token.type.match(admonitionRe);
@@ -683,7 +1465,16 @@ function shapeContainers(tokens) {
683
1465
  token.attrSet("class", `custom-block ${type}`);
684
1466
  const custom = containerTitle(token.info.trim(), type);
685
1467
  output.push(token);
686
- output.push(...buildTitleTokens(Token, "p", "paragraph_open", "paragraph_close", "custom-block-title", custom || ADMONITION_TITLES[type] || type.toUpperCase()));
1468
+ output.push(
1469
+ ...buildTitleTokens(
1470
+ Token,
1471
+ "p",
1472
+ "paragraph_open",
1473
+ "paragraph_close",
1474
+ "custom-block-title",
1475
+ custom || ADMONITION_TITLES[type] || type.toUpperCase()
1476
+ )
1477
+ );
687
1478
  continue;
688
1479
  }
689
1480
  if (admonitionCloseRe.test(token.type)) {
@@ -695,7 +1486,16 @@ function shapeContainers(tokens) {
695
1486
  token.tag = "details";
696
1487
  token.attrSet("class", "custom-block details");
697
1488
  output.push(token);
698
- output.push(...buildTitleTokens(Token, "summary", "summary_open", "summary_close", null, containerTitle(token.info.trim(), "details") || "Details"));
1489
+ output.push(
1490
+ ...buildTitleTokens(
1491
+ Token,
1492
+ "summary",
1493
+ "summary_open",
1494
+ "summary_close",
1495
+ null,
1496
+ containerTitle(token.info.trim(), "details") || "Details"
1497
+ )
1498
+ );
699
1499
  continue;
700
1500
  }
701
1501
  if (token.type === "container_details_close") {
@@ -730,7 +1530,17 @@ function shapeContainers(tokens) {
730
1530
  token.attrSet("class", "custom-block card");
731
1531
  const title = containerTitle(token.info.trim(), "card");
732
1532
  output.push(token);
733
- if (title) output.push(...buildTitleTokens(Token, "p", "paragraph_open", "paragraph_close", "card-title", title));
1533
+ if (title)
1534
+ output.push(
1535
+ ...buildTitleTokens(
1536
+ Token,
1537
+ "p",
1538
+ "paragraph_open",
1539
+ "paragraph_close",
1540
+ "card-title",
1541
+ title
1542
+ )
1543
+ );
734
1544
  continue;
735
1545
  }
736
1546
  if (token.type === "container_card_close") {
@@ -747,7 +1557,17 @@ function shapeContainers(tokens) {
747
1557
  token.attrSet("class", "custom-block link-card");
748
1558
  token.attrSet("href", href);
749
1559
  output.push(token);
750
- if (title) output.push(...buildTitleTokens(Token, "p", "paragraph_open", "paragraph_close", "link-card-title", title));
1560
+ if (title)
1561
+ output.push(
1562
+ ...buildTitleTokens(
1563
+ Token,
1564
+ "p",
1565
+ "paragraph_open",
1566
+ "paragraph_close",
1567
+ "link-card-title",
1568
+ title
1569
+ )
1570
+ );
751
1571
  continue;
752
1572
  }
753
1573
  if (token.type === "container_link-card_close") {
@@ -771,7 +1591,9 @@ function shapeContainers(tokens) {
771
1591
  output.push(token);
772
1592
  continue;
773
1593
  }
774
- output.push(...buildCodeGroupTokens(Token, tokens, i, closeIndex, groupCounter++));
1594
+ output.push(
1595
+ ...buildCodeGroupTokens(Token, tokens, i, closeIndex, groupCounter++)
1596
+ );
775
1597
  i = closeIndex;
776
1598
  continue;
777
1599
  }
@@ -789,13 +1611,16 @@ function shapeTaskLists(tokens) {
789
1611
  if (prev?.type !== "list_item_open") continue;
790
1612
  const firstChild = token.children[0];
791
1613
  if (firstChild.type !== "text") continue;
792
- const text2 = firstChild.content;
793
- const isTask = text2.startsWith("[ ] ") || text2.startsWith("[x] ") || text2.startsWith("[X] ");
1614
+ const text3 = firstChild.content;
1615
+ const isTask = text3.startsWith("[ ] ") || text3.startsWith("[x] ") || text3.startsWith("[X] ");
794
1616
  if (!isTask) continue;
795
- const checked = text2[1].toLowerCase() === "x";
796
- firstChild.content = text2.slice(4);
1617
+ const checked = text3[1].toLowerCase() === "x";
1618
+ firstChild.content = text3.slice(4);
797
1619
  token.content = token.content.replace(/^\[[ xX]\] /, "");
798
- prev.attrSet("class", ((prev.attrGet("class") ?? "") + " task-list-item").trim());
1620
+ prev.attrSet(
1621
+ "class",
1622
+ `${prev.attrGet("class") ?? ""} task-list-item`.trim()
1623
+ );
799
1624
  const checkToken = new Token("html_inline", "", 0);
800
1625
  checkToken.content = `<input type="checkbox"${checked ? " checked" : ""} disabled class="task-list-check" aria-label="${checked ? "done" : "todo"}">`;
801
1626
  token.children.unshift(checkToken);
@@ -812,7 +1637,15 @@ function createParser(docsDir, highlight) {
812
1637
  md.use(emojiPlugin);
813
1638
  const noopRender = () => "";
814
1639
  const ADMONITION_NAMES = Object.keys(ADMONITION_TITLES);
815
- for (const name of [...ADMONITION_NAMES, "details", "code-group", "steps", "card", "card-grid", "link-card"]) {
1640
+ for (const name of [
1641
+ ...ADMONITION_NAMES,
1642
+ "details",
1643
+ "code-group",
1644
+ "steps",
1645
+ "card",
1646
+ "card-grid",
1647
+ "link-card"
1648
+ ]) {
816
1649
  md.use(container, name, { render: noopRender });
817
1650
  }
818
1651
  md.core.ruler.push("press_containers", (state) => {
@@ -878,12 +1711,22 @@ function injectHeadingAnchors(elements) {
878
1711
  if (tag && typeof rec.id === "string") {
879
1712
  const id = rec.id;
880
1713
  const children = Array.isArray(rec[tag]) ? [...rec[tag]] : rec[tag] != null ? [rec[tag]] : [];
881
- children.push({ a: "#", href: `#${id}`, class: "header-anchor", ariaHidden: "true" });
1714
+ children.push({
1715
+ a: "#",
1716
+ href: `#${id}`,
1717
+ class: "header-anchor",
1718
+ ariaHidden: "true"
1719
+ });
882
1720
  return { ...rec, [tag]: children };
883
1721
  }
884
- 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");
1722
+ const tag2 = Object.keys(rec).find(
1723
+ (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"
1724
+ );
885
1725
  if (tag2 && Array.isArray(rec[tag2])) {
886
- return { ...rec, [tag2]: injectHeadingAnchors(rec[tag2]) };
1726
+ return {
1727
+ ...rec,
1728
+ [tag2]: injectHeadingAnchors(rec[tag2])
1729
+ };
887
1730
  }
888
1731
  return el;
889
1732
  });
@@ -905,27 +1748,28 @@ async function renderDoc(source, options) {
905
1748
 
906
1749
  // src/search.ts
907
1750
  import { ElementNode, RecordState } from "@domphy/core";
908
- import { themeColor, themeSpacing } from "@domphy/theme";
1751
+ import { themeColor as themeColor2, themeSpacing as themeSpacing2 } from "@domphy/theme";
909
1752
  import { card, inputSearch, link, menu, small } from "@domphy/ui";
910
1753
  var FIELD_TITLE = 3;
911
1754
  var FIELD_HEADING = 2;
912
1755
  var FIELD_BODY = 1;
913
- function tokenize(text2) {
1756
+ function tokenize(text3) {
914
1757
  const tokens = [];
915
- for (const raw of text2.toLowerCase().split(/[^\p{L}\p{N}]+/u)) {
1758
+ for (const raw of text3.toLowerCase().split(/[^\p{L}\p{N}]+/u)) {
916
1759
  if (raw.length >= 2) tokens.push(raw);
917
1760
  }
918
1761
  return tokens;
919
1762
  }
920
- function indexText(postings, entryIndex, text2, fieldWeight) {
921
- for (const term of tokenize(text2)) {
1763
+ function indexText(postings, entryIndex, text3, fieldWeight) {
1764
+ for (const term of tokenize(text3)) {
922
1765
  let perEntry = postings.get(term);
923
1766
  if (!perEntry) {
924
1767
  perEntry = /* @__PURE__ */ new Map();
925
1768
  postings.set(term, perEntry);
926
1769
  }
927
1770
  const existing = perEntry.get(entryIndex);
928
- if (existing === void 0 || fieldWeight > existing) perEntry.set(entryIndex, fieldWeight);
1771
+ if (existing === void 0 || fieldWeight > existing)
1772
+ perEntry.set(entryIndex, fieldWeight);
929
1773
  }
930
1774
  }
931
1775
  function buildSearchIndex(docs) {
@@ -933,283 +1777,155 @@ function buildSearchIndex(docs) {
933
1777
  const postings = /* @__PURE__ */ new Map();
934
1778
  for (const doc of docs) {
935
1779
  const pageIndex = entries.length;
936
- entries.push({ route: doc.route, pageTitle: doc.title, heading: doc.title, slug: "", isPage: true });
1780
+ entries.push({
1781
+ route: doc.route,
1782
+ pageTitle: doc.title,
1783
+ heading: doc.title,
1784
+ slug: "",
1785
+ isPage: true
1786
+ });
937
1787
  indexText(postings, pageIndex, doc.title, FIELD_TITLE);
938
1788
  indexText(postings, pageIndex, doc.text, FIELD_BODY);
939
1789
  for (const entry of doc.toc) {
940
1790
  const sectionIndex = entries.length;
941
- entries.push({ route: doc.route, pageTitle: doc.title, heading: entry.text, slug: entry.slug, isPage: false });
1791
+ entries.push({
1792
+ route: doc.route,
1793
+ pageTitle: doc.title,
1794
+ heading: entry.text,
1795
+ slug: entry.slug,
1796
+ isPage: false
1797
+ });
942
1798
  indexText(postings, sectionIndex, entry.text, FIELD_HEADING);
943
1799
  }
944
1800
  }
945
1801
  const serializedPostings = {};
946
- for (const [term, perEntry] of Array.from(postings.entries()).sort((a, b) => a[0] < b[0] ? -1 : 1)) {
1802
+ for (const [term, perEntry] of Array.from(postings.entries()).sort(
1803
+ (a, b) => a[0] < b[0] ? -1 : 1
1804
+ )) {
947
1805
  serializedPostings[term] = Array.from(perEntry.entries()).sort((a, b) => a[0] - b[0]).map(([i, w]) => [i, w]);
948
1806
  }
949
- return JSON.stringify({ entries, postings: serializedPostings });
1807
+ return JSON.stringify({
1808
+ entries,
1809
+ postings: serializedPostings
1810
+ });
950
1811
  }
951
1812
 
952
1813
  // src/theme.ts
953
- import { themeColor as themeColor2, themeSpacing as themeSpacing2 } from "@domphy/theme";
954
- var tc = (tone, color) => themeColor2(null, tone, color);
955
- var ts = (n) => themeSpacing2(n);
956
- var bg = tc("inherit");
957
- var bgSoft = tc("shift-1");
958
- var bgMute = tc("shift-2");
959
- var border = tc("shift-3");
960
- var textSoft = tc("shift-6");
961
- var text = tc("shift-9");
962
- var textStrong = tc("shift-11");
963
- var brand = tc("shift-9", "primary");
964
- var brandHover = tc("shift-10", "primary");
965
- var headerH = ts(14);
966
- var sidebarW = ts(62);
967
- var asideW = ts(56);
968
- var contentMax = ts(190);
1814
+ import { themeColor as themeColor3, themeSpacing as themeSpacing3 } from "@domphy/theme";
1815
+ var tc2 = (tone, color) => themeColor3(null, tone, color);
1816
+ var ts2 = (n) => themeSpacing3(n);
1817
+ var bg2 = tc2("inherit");
1818
+ var bgSoft2 = tc2("shift-1");
1819
+ var bgMute2 = tc2("shift-2");
1820
+ var border2 = tc2("shift-3");
1821
+ var textSoft2 = tc2("shift-6");
1822
+ var text2 = tc2("shift-9");
1823
+ var textStrong2 = tc2("shift-11");
1824
+ var brand2 = tc2("shift-9", "primary");
1825
+ var headerH2 = ts2(14);
969
1826
  function pressCSS() {
970
1827
  return `
971
1828
  /* ------------------------------------------------------------------ reset */
972
1829
  *,*::before,*::after{box-sizing:border-box}
973
- html{scroll-behavior:smooth;scroll-padding-top:calc(${headerH} + ${ts(4)})}
974
- 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}
975
- a{color:${brand};text-decoration:none}
1830
+ html{scroll-behavior:smooth;scroll-padding-top:calc(${headerH2} + ${ts2(4)})}
1831
+ 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}
1832
+ a{color:${brand2};text-decoration:none}
976
1833
  a:hover{text-decoration:underline}
977
1834
 
978
- /* -------------------------------------------------------- announcement bar */
979
- .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}
980
- .dp-announcement a{color:${bg};font-weight:700}
981
- .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}
982
- .dp-announcement-close:hover{opacity:1}
983
-
984
- /* ------------------------------------------------------------------ header */
985
- .dp-logo{font-weight:700;font-size:18px;color:${textStrong};white-space:nowrap;flex-shrink:0}
986
- .dp-logo:hover{text-decoration:none}
987
- .dp-logo-img{height:${ts(7)};width:auto;display:block}
988
- .dp-nav a{color:${textSoft};font-size:14px;font-weight:500;white-space:nowrap;line-height:1}
989
- .dp-nav a:hover,.dp-nav a[aria-current="page"]{color:${brand};text-decoration:none}
990
- .dp-nav-dropdown{position:relative;display:flex;align-items:center}
991
- .dp-nav-dropdown-label{color:${textSoft};font-size:14px;font-weight:500;cursor:pointer;user-select:none}
992
- .dp-nav-dropdown-label::after{content:" \u25BE";font-size:10px;opacity:.6}
993
- .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)}
994
- .dp-nav-dropdown-menu a{display:block;padding:${ts(1.25)} ${ts(2.5)};border-radius:${ts(1.25)};font-size:13px}
995
- .dp-nav-dropdown-menu a:hover{background:${bgMute}}
996
- .dp-nav-dropdown:hover .dp-nav-dropdown-menu,.dp-nav-dropdown:focus-within .dp-nav-dropdown-menu{display:flex}
997
- .dp-header-actions{flex-shrink:0}
998
- .dp-search-slot{width:${ts(50)}}
999
- .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}
1000
- .dp-search-static::placeholder{color:${textSoft}}
1001
- .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}
1002
- .dp-menu-toggle{display:none}
1003
-
1004
- /* --------------------------------------------------------- locale switcher */
1005
- .dp-locale-switcher{position:relative;display:flex;align-items:center}
1006
- .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)}}
1007
- .dp-locale-current::after{content:" \u25BE";font-size:10px;opacity:.6}
1008
- .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)}
1009
- .dp-locale-switcher:hover .dp-locale-menu,.dp-locale-switcher:focus-within .dp-locale-menu{display:flex}
1010
- .dp-locale-option{display:block;padding:${ts(1.25)} ${ts(2.5)};border-radius:${ts(1.25)};font-size:13px;color:${textSoft}}
1011
- .dp-locale-option:hover{background:${bgMute};color:${text};text-decoration:none}
1012
- .dp-locale-option.active{color:${brand};font-weight:600}
1013
-
1014
- /* -------------------------------------------------- logo light/dark variant */
1835
+ /* -------------------------------------------------------- logo theme variants */
1836
+ /* dp-logo-light/dark classes set in layout.ts img elements */
1015
1837
  [data-theme="dark"] .dp-logo-light{display:none}
1016
1838
  [data-theme="light"] .dp-logo-dark,.dp-logo-dark{display:none}
1017
1839
  [data-theme="dark"] .dp-logo-dark{display:block}
1018
1840
 
1019
- /* ------------------------------------------------------------ social links */
1020
- .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}
1021
- .dp-social-link:hover{color:${text};border-color:${textSoft};text-decoration:none}
1022
- .dp-social-icon{display:block;width:${ts(4)};height:${ts(4)};background:currentColor;flex-shrink:0}
1841
+ /* ---------------------------------------------------------- social icon masks */
1842
+ /* dp-social-icon + dp-icon-* classes set in layout.ts socialLinkEl */
1843
+ .dp-social-icon{display:block;width:${ts2(4)};height:${ts2(4)};background:currentColor;flex-shrink:0}
1023
1844
  .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}
1024
1845
  .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}
1025
1846
  .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}
1026
1847
 
1027
- /* ------------------------------------------------------------------ layout */
1028
- .dp-shell{display:grid;grid-template-columns:${sidebarW} minmax(0,1fr) ${asideW};align-items:start;max-width:1440px;margin:0 auto}
1029
- .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}}
1030
- .dp-sidebar-group{margin-bottom:${ts(3.5)}}
1031
- .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)}}
1032
- .dp-sidebar-subtitle{font-size:12px;color:${textSoft};padding:${ts(1)} ${ts(3)};font-weight:600}
1033
- .dp-sidebar-items{display:flex;flex-direction:column}
1034
- .dp-sidebar-toggle{margin-left:auto;background:none;border:none;cursor:pointer;color:${textSoft};font-size:14px;padding:0 ${ts(1)};line-height:1}
1035
- .dp-sidebar-toggle:hover{color:${text}}
1848
+ /* ------- sidebar collapsed state (JS toggles 'collapsed' class on group) ------- */
1036
1849
  .dp-sidebar-group.collapsed .dp-sidebar-items{display:none}
1037
- .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)}}
1038
- .dp-sidebar a:hover{color:${text};text-decoration:none}
1039
- .dp-sidebar a[aria-current="page"]{color:${brand};font-weight:600;background:${bgSoft}}
1040
- .dp-sidebar-link-with-badge{display:flex;align-items:center}
1041
- .dp-main{padding:${ts(8)} ${ts(12)} ${ts(20)};min-width:0}
1042
- .dp-content{max-width:${contentMax}}
1043
- .dp-aside{position:sticky;top:${headerH};max-height:calc(100vh - ${headerH});overflow-y:auto;padding:${ts(8)} ${ts(6)};font-size:13px}
1044
- .dp-aside-title{font-weight:700;margin-bottom:${ts(2)};color:${text}}
1045
- .dp-toc a{display:block;padding:${ts(0.75)} 0;color:${textSoft}}
1046
- .dp-toc a:hover{color:${brand};text-decoration:none}
1047
- .dp-toc-2{padding-left:0}
1048
- .dp-toc-3{padding-left:${ts(3)}}
1049
- .dp-toc-4{padding-left:${ts(6)}}
1050
-
1051
- /* -------------------------------------------------- card / link-card / card-grid */
1052
- .custom-block.card{background:${bgSoft};border:1px solid ${border};border-radius:${ts(3)};padding:${ts(5)} ${ts(6)};margin:${ts(3)} 0}
1053
- .custom-block.card .card-title{font-size:16px;font-weight:600;color:${textStrong};margin:0 0 ${ts(2)}}
1054
- .custom-block.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(${ts(56)},1fr));gap:${ts(4)};margin:${ts(4)} 0}
1055
- 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}}
1056
- a.custom-block.link-card:hover{border-color:${brand};background:${bgMute};text-decoration:none}
1057
- a.custom-block.link-card .link-card-title{font-size:16px;font-weight:600;color:${brand};margin:0 0 ${ts(2)}}
1058
- .custom-block.card-grid .custom-block.card,.custom-block.card-grid a.custom-block.link-card{margin:0}
1059
1850
 
1060
- /* ------------------------------------------------------------------ badges */
1061
- .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}
1062
- .dp-badge-tip{background:color-mix(in srgb,${brand} 12%,${bg});color:${brand}}
1063
- .dp-badge-info{background:${bgMute};color:${textSoft}}
1064
- .dp-badge-warning{background:color-mix(in srgb,${tc("shift-9", "warning")} 12%,${bg});color:${tc("shift-9", "warning")}}
1065
- .dp-badge-danger{background:color-mix(in srgb,${tc("shift-9", "danger")} 12%,${bg});color:${tc("shift-9", "danger")}}
1066
- .dp-page-badge{margin-left:${ts(2)}}
1067
- .dp-page-badge-row{margin-bottom:${ts(-2)}}
1068
-
1069
- /* ------------------------------------------------------------------- prose */
1070
- .dp-content h1{font-size:30px;font-weight:700;line-height:1.25;margin:0 0 ${ts(6)};letter-spacing:-.02em;color:${textStrong}}
1071
- .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}}
1072
- .dp-content h3{font-size:18px;font-weight:600;margin:${ts(7)} 0 ${ts(3)};color:${textStrong}}
1073
- .dp-content h4{font-size:16px;font-weight:600;margin:${ts(5.5)} 0 ${ts(2)};color:${textStrong}}
1074
- .dp-content p{margin:${ts(4)} 0}
1075
- .dp-content ul,.dp-content ol{margin:${ts(4)} 0;padding-left:1.4em}
1076
- .dp-content li{margin:${ts(1.5)} 0}
1077
- .dp-content a{font-weight:500}
1078
- .dp-content strong{font-weight:600;color:${textStrong}}
1079
- .dp-content em{font-style:italic}
1080
- .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)}}
1081
- .dp-content sup{font-size:.75em;vertical-align:super}
1082
- .dp-content sub{font-size:.75em;vertical-align:sub}
1083
- .dp-content del{opacity:.5}
1084
- .dp-content blockquote{margin:${ts(4)} 0;padding:0 ${ts(4)};border-left:3px solid ${border};color:${textSoft}}
1085
- .dp-content img{max-width:100%;height:auto;border-radius:${ts(1.5)}}
1086
- .dp-content hr{border:none;border-top:1px solid ${border};margin:${ts(8)} 0}
1087
- .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)}}
1088
- .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}
1089
- .dp-content pre code{font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;background:none;padding:0}
1090
- .dp-content table{border-collapse:collapse;margin:${ts(4)} 0;display:block;overflow-x:auto}
1091
- .dp-content th,.dp-content td{border:1px solid ${border};padding:${ts(2)} ${ts(3.5)};text-align:left}
1092
- .dp-content th{background:${bgSoft};font-weight:600}
1851
+ /* ------- sidebar open state on mobile (JS sets html[data-sidebar="open"]) ------ */
1852
+ @media(max-width:860px){
1853
+ html[data-sidebar="open"] nav[aria-label="Documentation"]{transform:translateX(0)}
1854
+ }
1093
1855
 
1094
1856
  /* -------------------------------------------------------- heading anchors */
1095
- .header-anchor{opacity:0;margin-left:${ts(2)};font-weight:400;font-size:.85em;color:${textSoft};transition:opacity .15s}
1857
+ .header-anchor{opacity:0;margin-left:${ts2(2)};font-weight:400;font-size:.85em;color:${textSoft2};transition:opacity .15s}
1096
1858
  :is(h1,h2,h3,h4,h5,h6):hover .header-anchor{opacity:1}
1097
- .header-anchor:hover{color:${brand};text-decoration:none}
1098
-
1099
- /* -------------------------------------------------------- external links */
1100
- .dp-content a[target="_blank"]::after{content:" \u2197";font-size:.75em;opacity:.6}
1101
-
1102
- /* --------------------------------------------------------------- task lists */
1103
- .task-list-item{list-style:none;margin-left:-1.4em;padding-left:1.8em;position:relative}
1104
- .task-list-check{position:absolute;left:0;top:.25em;width:14px;height:14px;cursor:default;accent-color:${brand}}
1859
+ .header-anchor:hover{color:${brand2};text-decoration:none}
1105
1860
 
1106
1861
  /* ------------------------------------------------------------ code blocks */
1107
- .code-block{margin:${ts(4)} 0;border:1px solid ${border};border-radius:${ts(2)};overflow:hidden}
1108
- .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}}
1862
+ .code-block{margin:${ts2(4)} 0;border:1px solid ${border2};border-radius:${ts2(2)};overflow:hidden}
1863
+ .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}}
1109
1864
  .code-block-inner{position:relative}
1110
- .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}
1865
+ .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}
1111
1866
  .code-block code{font-family:inherit;background:none;padding:0;font-size:inherit}
1112
1867
  .code-block .line{display:inline-block;width:100%}
1113
- .code-block .line.highlighted{background:color-mix(in srgb,${brand} 10%,transparent)}
1114
- .code-block .line.diff.add{background:color-mix(in srgb,${tc("shift-7", "success")} 12%,transparent)}
1115
- .code-block .line.diff.add::before{content:"+ ";color:${tc("shift-7", "success")}}
1116
- .code-block .line.diff.remove{background:color-mix(in srgb,${tc("shift-9", "danger")} 10%,transparent);opacity:.7}
1117
- .code-block .line.diff.remove::before{content:"- ";color:${tc("shift-9", "danger")}}
1118
- .code-block .line.highlighted.error{background:color-mix(in srgb,${tc("shift-9", "error")} 10%,transparent)}
1119
- .code-block .line.highlighted.warning{background:color-mix(in srgb,${tc("shift-7", "warning")} 10%,transparent)}
1868
+ .code-block .line.highlighted{background:color-mix(in srgb,${brand2} 10%,transparent)}
1869
+ .code-block .line.diff.add{background:color-mix(in srgb,${tc2("shift-7", "success")} 12%,transparent)}
1870
+ .code-block .line.diff.add::before{content:"+ ";color:${tc2("shift-7", "success")}}
1871
+ .code-block .line.diff.remove{background:color-mix(in srgb,${tc2("shift-9", "danger")} 10%,transparent);opacity:.7}
1872
+ .code-block .line.diff.remove::before{content:"- ";color:${tc2("shift-9", "danger")}}
1873
+ .code-block .line.highlighted.error{background:color-mix(in srgb,${tc2("shift-9", "error")} 10%,transparent)}
1874
+ .code-block .line.highlighted.warning{background:color-mix(in srgb,${tc2("shift-7", "warning")} 10%,transparent)}
1120
1875
  .code-block pre.has-focus .line:not(.focus){opacity:.4;filter:blur(.4px);transition:opacity .2s,filter .2s}
1121
1876
  .code-block pre.has-focus:hover .line{opacity:1;filter:none}
1122
- .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}
1123
- .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}
1877
+ .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}
1878
+ .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}
1124
1879
  .code-block-inner:hover .code-copy-btn{opacity:1}
1125
- .code-copy-btn:hover{background:${bgMute};color:${text}}
1880
+ .code-copy-btn:hover{background:${bgMute2};color:${text2}}
1126
1881
 
1127
1882
  /* ------------------------------------------------------------- code groups */
1128
- .code-group{margin:${ts(4)} 0;border:1px solid ${border};border-radius:${ts(2)};overflow:hidden}
1883
+ .code-group{margin:${ts2(4)} 0;border:1px solid ${border2};border-radius:${ts2(2)};overflow:hidden}
1129
1884
  .code-group>input[type="radio"]{position:absolute;opacity:0;pointer-events:none;width:0;height:0}
1130
- .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}
1131
- .code-group .tabs label{padding:${ts(1)} ${ts(3)};font-size:13px;font-weight:500;color:${textSoft};border-radius:${ts(1.25)};cursor:pointer}
1885
+ .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}
1886
+ .code-group .tabs label{padding:${ts2(1)} ${ts2(3)};font-size:13px;font-weight:500;color:${textSoft2};border-radius:${ts2(1.25)};cursor:pointer}
1132
1887
  .code-group .blocks>.code-block{display:none;margin:0;border:none;border-radius:0}
1133
1888
  .code-group .blocks>.code-block pre{border-radius:0}
1134
1889
  ${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}
1135
- ${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}}
1890
+ ${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}}
1891
+
1892
+ /* ---------------------------------------------------------- card containers */
1893
+ .custom-block.card{background:${bgSoft2};border:1px solid ${border2};border-radius:${ts2(3)};padding:${ts2(5)} ${ts2(6)};margin:${ts2(3)} 0}
1894
+ .custom-block.card .card-title{font-size:16px;font-weight:600;color:${textStrong2};margin:0 0 ${ts2(2)}}
1895
+ .custom-block.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(${ts2(56)},1fr));gap:${ts2(4)};margin:${ts2(4)} 0}
1896
+ 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}}
1897
+ a.custom-block.link-card:hover{border-color:${brand2};background:${bgMute2};text-decoration:none}
1898
+ a.custom-block.link-card .link-card-title{font-size:16px;font-weight:600;color:${brand2};margin:0 0 ${ts2(2)}}
1899
+ .custom-block.card-grid .custom-block.card,.custom-block.card-grid a.custom-block.link-card{margin:0}
1136
1900
 
1137
1901
  /* --------------------------------------------------------- custom blocks */
1138
- .custom-block{margin:${ts(4)} 0;padding:${ts(3)} ${ts(4)};border-radius:${ts(2)};border:1px solid transparent;font-size:14.5px}
1139
- .custom-block p{margin:${ts(2)} 0}
1140
- .custom-block-title{font-weight:700;margin:0 0 ${ts(1)} !important;font-size:13px}
1141
- .custom-block.tip,.custom-block.success{background:color-mix(in srgb,${brand} 8%,${bg});border-color:color-mix(in srgb,${brand} 28%,transparent)}
1142
- .custom-block.info,.custom-block.note,.custom-block.abstract{background:${bgSoft};border-color:${border}}
1143
- .custom-block.warning,.custom-block.question{background:color-mix(in srgb,${tc("shift-6", "warning")} 10%,${bg});border-color:${tc("shift-6", "warning")}}
1144
- .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")}}
1145
- .custom-block.example{background:color-mix(in srgb,${tc("shift-7", "secondary")} 10%,${bg});border-color:${tc("shift-7", "secondary")}}
1146
- .custom-block.quote{background:${bgSoft};border-color:${border};border-left-width:4px;border-radius:0 ${ts(2)} ${ts(2)} 0}
1902
+ .custom-block{margin:${ts2(4)} 0;padding:${ts2(3)} ${ts2(4)};border-radius:${ts2(2)};border:1px solid transparent;font-size:14.5px}
1903
+ .custom-block p{margin:${ts2(2)} 0}
1904
+ .custom-block-title{font-weight:700;margin:0 0 ${ts2(1)} !important;font-size:13px}
1905
+ .custom-block.tip,.custom-block.success{background:color-mix(in srgb,${brand2} 8%,${bg2});border-color:color-mix(in srgb,${brand2} 28%,transparent)}
1906
+ .custom-block.info,.custom-block.note,.custom-block.abstract{background:${bgSoft2};border-color:${border2}}
1907
+ .custom-block.warning,.custom-block.question{background:color-mix(in srgb,${tc2("shift-6", "warning")} 10%,${bg2});border-color:${tc2("shift-6", "warning")}}
1908
+ .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")}}
1909
+ .custom-block.example{background:color-mix(in srgb,${tc2("shift-7", "secondary")} 10%,${bg2});border-color:${tc2("shift-7", "secondary")}}
1910
+ .custom-block.quote{background:${bgSoft2};border-color:${border2};border-left-width:4px;border-radius:0 ${ts2(2)} ${ts2(2)} 0}
1147
1911
  details.custom-block summary{cursor:pointer;font-weight:600}
1148
1912
 
1149
1913
  /* ------------------------------------------------------------------- steps */
1150
1914
  .custom-block.steps{background:none;border:none;padding:0}
1151
1915
  .custom-block.steps>ol{counter-reset:step;list-style:none;padding:0;margin:0}
1152
- .custom-block.steps>ol>li{counter-increment:step;display:grid;grid-template-columns:${ts(9)} 1fr;gap:0 ${ts(4)};margin-bottom:${ts(6)}}
1153
- .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}
1916
+ .custom-block.steps>ol>li{counter-increment:step;display:grid;grid-template-columns:${ts2(9)} 1fr;gap:0 ${ts2(4)};margin-bottom:${ts2(6)}}
1917
+ .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}
1154
1918
 
1155
1919
  /* ----------------------------------------------------------------- mermaid */
1156
- .dp-mermaid{margin:${ts(5)} 0;text-align:center;overflow-x:auto}
1920
+ .dp-mermaid{margin:${ts2(5)} 0;text-align:center;overflow-x:auto}
1157
1921
  .dp-mermaid svg{max-width:100%;height:auto}
1158
1922
 
1159
- /* --------------------------------------------------------------- doc footer */
1160
- .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}}
1161
- .dp-edit-link{font-weight:500;font-size:13px}
1162
- .dp-reading-time::before{content:"\u{1F4D6} "}
1163
-
1164
- /* --------------------------------------------------------------- prev/next */
1165
- .dp-prevnext{display:flex;justify-content:space-between;gap:${ts(4)};margin-top:${ts(12)};padding-top:${ts(6)};border-top:1px solid ${border}}
1166
- .dp-prevnext a{display:block;padding:${ts(3)} ${ts(4)};border:1px solid ${border};border-radius:${ts(2)};font-weight:600;flex:1}
1167
- .dp-prevnext a:hover{border-color:${brand};text-decoration:none}
1168
- .dp-prevnext .next{text-align:right}
1169
- .dp-prevnext small{display:block;color:${textSoft};font-weight:400;font-size:12px}
1170
-
1171
- /* ----------------------------------------------------------------- footer */
1172
- .dp-footer{padding:${ts(6)} ${ts(12)};border-top:1px solid ${border};color:${textSoft};font-size:13px}
1173
-
1174
- /* ---------------------------------------------------------------- home page */
1175
- .dp-main-home{max-width:1100px;margin:0 auto;padding:${ts(12)} ${ts(6)} ${ts(20)}}
1176
- .dp-hero{text-align:center;padding:${ts(10)} 0 ${ts(6)}}
1177
- .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}
1178
- .dp-hero-text{font-size:30px;font-weight:700;margin:${ts(3)} 0 0;color:${textStrong}}
1179
- .dp-hero-tagline{font-size:18px;color:${textSoft};max-width:${ts(160)};margin:${ts(5)} auto 0}
1180
- .dp-hero-actions{display:flex;gap:${ts(3)};justify-content:center;margin-top:${ts(7)};flex-wrap:wrap}
1181
- .dp-hero-action{padding:${ts(2.5)} ${ts(5.5)};border-radius:${ts(5.5)};font-weight:600;font-size:15px}
1182
- .dp-hero-action.brand{background:${brand};color:${bg}}
1183
- .dp-hero-action.brand:hover{background:${brandHover};text-decoration:none}
1184
- .dp-hero-action.alt{background:${bgSoft};color:${text};border:1px solid ${border}}
1185
- .dp-hero-action.alt:hover{border-color:${brand};text-decoration:none}
1186
- .dp-features{display:grid;grid-template-columns:repeat(auto-fit,minmax(${ts(60)},1fr));gap:${ts(4)};margin:${ts(10)} 0}
1187
- .dp-feature{padding:${ts(5)};background:${bgSoft};border:1px solid ${border};border-radius:${ts(3)}}
1188
- .dp-feature-icon{font-size:28px;margin-bottom:${ts(3)}}
1189
- .dp-feature-title{font-weight:700;font-size:17px;margin-bottom:${ts(2)};color:${textStrong}}
1190
- .dp-feature-details{font-size:14px;color:${textSoft};margin:0;line-height:1.5}
1191
- .dp-feature-link{display:block;color:inherit}
1192
- .dp-feature-link:hover{text-decoration:none}
1193
- .dp-feature-link:hover .dp-feature{border-color:${brand}}
1194
- .dp-home{max-width:${contentMax};margin:0 auto}
1923
+ /* --------------------------------------------------------------- task lists */
1924
+ .task-list-item{list-style:none;margin-left:-1.4em;padding-left:1.8em;position:relative}
1925
+ .task-list-check{position:absolute;left:0;top:.25em;width:14px;height:14px;cursor:default;accent-color:${brand2}}
1195
1926
 
1196
1927
  /* ---------------------------------------------------------------- shiki dark */
1197
1928
  html[data-theme="dark"] .shiki,html[data-theme="dark"] .shiki span{color:var(--shiki-dark,inherit) !important}
1198
-
1199
- /* -------------------------------------------------------------- responsive */
1200
- @media(max-width:1200px){
1201
- .dp-shell{grid-template-columns:${sidebarW} minmax(0,1fr)}
1202
- .dp-aside{display:none}
1203
- }
1204
- @media(max-width:860px){
1205
- .dp-shell{grid-template-columns:1fr}
1206
- .dp-menu-toggle{display:block}
1207
- .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}
1208
- html[data-sidebar="open"] .dp-sidebar{transform:translateX(0)}
1209
- .dp-nav{display:none}
1210
- .dp-main{padding:${ts(6)} ${ts(5)} ${ts(16)}}
1211
- .dp-search-slot{width:${ts(35)}}
1212
- }
1213
1929
  `;
1214
1930
  }
1215
1931
 
@@ -1230,24 +1946,27 @@ function flattenText(node, out) {
1230
1946
  return;
1231
1947
  }
1232
1948
  if (typeof node === "object") {
1233
- for (const [key, value] of Object.entries(node)) {
1949
+ for (const [key, value] of Object.entries(
1950
+ node
1951
+ )) {
1234
1952
  if (key.startsWith("_") || key === "$" || key === "style") continue;
1235
- if (key === "class" || key.startsWith("data") || key === "href" || key === "id") continue;
1953
+ if (key === "class" || key.startsWith("data") || key === "href" || key === "id")
1954
+ continue;
1236
1955
  flattenText(value, out);
1237
1956
  }
1238
1957
  }
1239
1958
  }
1240
1959
  function parseStyleString(value) {
1241
- const style = {};
1960
+ const style2 = {};
1242
1961
  for (const decl of value.split(";")) {
1243
1962
  const colon = decl.indexOf(":");
1244
1963
  if (colon === -1) continue;
1245
1964
  const prop = decl.slice(0, colon).trim();
1246
1965
  const val = decl.slice(colon + 1).trim();
1247
1966
  if (!prop || !val) continue;
1248
- style[prop.replace(/-([a-z])/g, (_m, c) => c.toUpperCase())] = val;
1967
+ style2[prop.replace(/-([a-z])/g, (_m, c) => c.toUpperCase())] = val;
1249
1968
  }
1250
- return style;
1969
+ return style2;
1251
1970
  }
1252
1971
  function sanitizeStyles(node) {
1253
1972
  if (Array.isArray(node)) {
@@ -1256,9 +1975,11 @@ function sanitizeStyles(node) {
1256
1975
  }
1257
1976
  if (!node || typeof node !== "object") return;
1258
1977
  const record = node;
1259
- if (typeof record.style === "string") record.style = parseStyleString(record.style);
1978
+ if (typeof record.style === "string")
1979
+ record.style = parseStyleString(record.style);
1260
1980
  for (const value of Object.values(record)) {
1261
- if (value && (typeof value === "object" || Array.isArray(value))) sanitizeStyles(value);
1981
+ if (value && (typeof value === "object" || Array.isArray(value)))
1982
+ sanitizeStyles(value);
1262
1983
  }
1263
1984
  }
1264
1985
  function firstParagraphText(body) {
@@ -1268,8 +1989,8 @@ function firstParagraphText(body) {
1268
1989
  if ("p" in record) {
1269
1990
  const parts = [];
1270
1991
  flattenText(record.p, parts);
1271
- const text2 = parts.join(" ").replace(/\s+/g, " ").trim();
1272
- if (text2.length > 10) return text2.slice(0, 160);
1992
+ const text3 = parts.join(" ").replace(/\s+/g, " ").trim();
1993
+ if (text3.length > 10) return text3.slice(0, 160);
1273
1994
  }
1274
1995
  }
1275
1996
  return "";
@@ -1314,7 +2035,7 @@ async function buildIslandsBundle(outDir, searchEnabled) {
1314
2035
  }
1315
2036
  function buildSitemap(routes, hostname) {
1316
2037
  const urls = routes.map((route) => {
1317
- const loc = route === "/" ? `${hostname}/` : `${hostname}${route}`.replace(/\/+$/, "") + "/";
2038
+ const loc = route === "/" ? `${hostname}/` : `${`${hostname}${route}`.replace(/\/+$/, "")}/`;
1318
2039
  return ` <url><loc>${loc}</loc></url>`;
1319
2040
  });
1320
2041
  return `<?xml version="1.0" encoding="UTF-8"?>
@@ -1373,13 +2094,21 @@ async function buildSite(options) {
1373
2094
  const pages = discoverPages(srcDir);
1374
2095
  const localePages = pages.map((p) => ({ ...p, localeKey: "/" }));
1375
2096
  if (config.locales) {
1376
- for (const [localeKey, locale] of Object.entries(config.locales)) {
2097
+ for (const [localeKey, _locale] of Object.entries(config.locales)) {
1377
2098
  if (localeKey === "/") continue;
1378
- const localeDir = resolve2(srcDir, localeKey.replace(/^\//, "").replace(/\/$/, ""));
2099
+ const localeDir = resolve2(
2100
+ srcDir,
2101
+ localeKey.replace(/^\//, "").replace(/\/$/, "")
2102
+ );
1379
2103
  if (!existsSync(localeDir)) continue;
1380
2104
  for (const p of discoverPages(localeDir)) {
1381
2105
  const prefix = localeKey.replace(/\/$/, "");
1382
- localePages.push({ filePath: p.filePath, route: prefix + p.route, outFile: p.outFile === "index.html" ? localeKey.replace(/^\//, "") + "index.html" : localeKey.replace(/^\//, "") + p.outFile, localeKey });
2106
+ localePages.push({
2107
+ filePath: p.filePath,
2108
+ route: prefix + p.route,
2109
+ outFile: p.outFile === "index.html" ? `${localeKey.replace(/^\//, "")}index.html` : localeKey.replace(/^\//, "") + p.outFile,
2110
+ localeKey
2111
+ });
1383
2112
  }
1384
2113
  }
1385
2114
  }
@@ -1390,7 +2119,12 @@ async function buildSite(options) {
1390
2119
  const searchDocs = [];
1391
2120
  for (const page of localePages) {
1392
2121
  const source = readFileSync2(page.filePath, "utf8");
1393
- const doc = await renderDoc(source, { filePath: page.filePath, docsDir: srcDir, repoRoot: srcDir, highlight });
2122
+ const doc = await renderDoc(source, {
2123
+ filePath: page.filePath,
2124
+ docsDir: srcDir,
2125
+ repoRoot: srcDir,
2126
+ highlight
2127
+ });
1394
2128
  if (doc.frontmatter.draft === true) {
1395
2129
  console.log(` \u21B7 ${page.route} (draft, skipped)`);
1396
2130
  continue;
@@ -1402,8 +2136,23 @@ async function buildSite(options) {
1402
2136
  const readingTime = estimateReadingTime(textContent);
1403
2137
  const lastUpdated = showLastUpdated ? getLastUpdated(page.filePath) : void 0;
1404
2138
  const relPath = relative2(srcDir, page.filePath).replace(/\\/g, "/");
1405
- built.push({ route: page.route, outFile: page.outFile, title: doc.title, localeKey: page.localeKey, doc, lastUpdated, readingTime, filePath: page.filePath, relPath });
1406
- searchDocs.push({ route: page.route, title: doc.title, text: textContent.slice(0, 2e4), toc: doc.toc });
2139
+ built.push({
2140
+ route: page.route,
2141
+ outFile: page.outFile,
2142
+ title: doc.title,
2143
+ localeKey: page.localeKey,
2144
+ doc,
2145
+ lastUpdated,
2146
+ readingTime,
2147
+ filePath: page.filePath,
2148
+ relPath
2149
+ });
2150
+ searchDocs.push({
2151
+ route: page.route,
2152
+ title: doc.title,
2153
+ text: textContent.slice(0, 2e4),
2154
+ toc: doc.toc
2155
+ });
1407
2156
  }
1408
2157
  const pageHeadMap = /* @__PURE__ */ new Map();
1409
2158
  const pageLangMap = /* @__PURE__ */ new Map();
@@ -1429,7 +2178,9 @@ async function buildSite(options) {
1429
2178
  const siteTitle = localeConfig?.title ?? config.title;
1430
2179
  const pageTitle = page.title === siteTitle ? siteTitle : `${page.title} | ${siteTitle}`;
1431
2180
  const canonical = page.route === "/" ? `${config.hostname}/` : `${config.hostname}${page.route}/`;
1432
- const pageHead = Array.isArray(page.doc.frontmatter.head) ? page.doc.frontmatter.head.filter((s) => typeof s === "string") : [];
2181
+ const pageHead = Array.isArray(page.doc.frontmatter.head) ? page.doc.frontmatter.head.filter(
2182
+ (s) => typeof s === "string"
2183
+ ) : [];
1433
2184
  pageHeadMap.set(page.route, pageHead);
1434
2185
  pageLangMap.set(page.route, lang);
1435
2186
  return {
@@ -1438,7 +2189,13 @@ async function buildSite(options) {
1438
2189
  title: pageTitle,
1439
2190
  description,
1440
2191
  metadataBase: config.hostname,
1441
- openGraph: { title: pageTitle, description, url: page.route === "/" ? "/" : `${page.route}/`, siteName: siteTitle, type: "website" },
2192
+ openGraph: {
2193
+ title: pageTitle,
2194
+ description,
2195
+ url: page.route === "/" ? "/" : `${page.route}/`,
2196
+ siteName: siteTitle,
2197
+ type: "website"
2198
+ },
1442
2199
  twitter: { card: "summary", title: pageTitle, description },
1443
2200
  alternates: { canonical }
1444
2201
  },
@@ -1456,28 +2213,54 @@ async function buildSite(options) {
1456
2213
  const result = await app.renderToString(page.route);
1457
2214
  const pageHead = pageHeadMap.get(page.route) ?? [];
1458
2215
  const lang = pageLangMap.get(page.route) ?? "en";
1459
- const html = htmlDocument(result, config, searchEnabled, generatedCss, pageHead, lang);
2216
+ const html = htmlDocument(
2217
+ result,
2218
+ config,
2219
+ searchEnabled,
2220
+ generatedCss,
2221
+ pageHead,
2222
+ lang
2223
+ );
1460
2224
  const outPath = join2(outDir, page.outFile);
1461
2225
  mkdirSync(dirname2(outPath), { recursive: true });
1462
2226
  writeFileSync(outPath, html, "utf8");
1463
2227
  totalBytes += html.length;
1464
- if (result.status !== 200) console.warn(` ! ${page.route} -> status ${result.status}`);
2228
+ if (result.status !== 200)
2229
+ console.warn(` ! ${page.route} -> status ${result.status}`);
1465
2230
  } catch (error) {
1466
- failures.push({ route: page.route, error: String(error.message || error) });
2231
+ failures.push({
2232
+ route: page.route,
2233
+ error: String(error.message || error)
2234
+ });
1467
2235
  }
1468
2236
  }
1469
2237
  if (failures.length > 0) {
1470
2238
  console.warn(`
1471
2239
  ${failures.length} page(s) failed:`);
1472
- for (const failure of failures) console.warn(` \u2717 ${failure.route}: ${failure.error}`);
2240
+ for (const failure of failures)
2241
+ console.warn(` \u2717 ${failure.route}: ${failure.error}`);
1473
2242
  }
1474
2243
  await buildIslandsBundle(outDir, searchEnabled);
1475
- writeFileSync(join2(outDir, "search-index.json"), buildSearchIndex(searchDocs), "utf8");
1476
- if (publicDir && existsSync(publicDir)) cpSync(publicDir, outDir, { recursive: true });
2244
+ writeFileSync(
2245
+ join2(outDir, "search-index.json"),
2246
+ buildSearchIndex(searchDocs),
2247
+ "utf8"
2248
+ );
2249
+ if (publicDir && existsSync(publicDir))
2250
+ cpSync(publicDir, outDir, { recursive: true });
1477
2251
  if (config.hostname) {
1478
- writeFileSync(join2(outDir, "sitemap.xml"), buildSitemap(built.map((p) => p.route), config.hostname), "utf8");
2252
+ writeFileSync(
2253
+ join2(outDir, "sitemap.xml"),
2254
+ buildSitemap(
2255
+ built.map((p) => p.route),
2256
+ config.hostname
2257
+ ),
2258
+ "utf8"
2259
+ );
1479
2260
  }
1480
- console.log(`Built ${built.length} pages (${(totalBytes / 1024).toFixed(0)} KB) \u2192 ${outDir}`);
2261
+ console.log(
2262
+ `Built ${built.length} pages (${(totalBytes / 1024).toFixed(0)} KB) \u2192 ${outDir}`
2263
+ );
1481
2264
  }
1482
2265
  export {
1483
2266
  buildSite