@tomehq/theme 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/{chunk-YXKONM3A.js → chunk-2AXAEADQ.js} +471 -138
  2. package/dist/entry.js +1 -1
  3. package/dist/index.d.ts +21 -1
  4. package/dist/index.js +1 -1
  5. package/package.json +5 -5
  6. package/src/Shell.test.tsx +183 -0
  7. package/src/Shell.tsx +231 -21
  8. package/src/entry.tsx +173 -4
  9. package/src/global.d.ts +11 -0
  10. package/dist/chunk-2APCPR2Y.js +0 -2110
  11. package/dist/chunk-37JI6XGT.js +0 -1720
  12. package/dist/chunk-3A2LPGUL.js +0 -1991
  13. package/dist/chunk-3I2QTWTW.js +0 -1948
  14. package/dist/chunk-45M5UIAB.js +0 -2110
  15. package/dist/chunk-462AGU3S.js +0 -1959
  16. package/dist/chunk-7MUTU5D4.js +0 -1720
  17. package/dist/chunk-ABNPB6BB.js +0 -2133
  18. package/dist/chunk-BZGWSKT2.js +0 -573
  19. package/dist/chunk-CMQCNCSY.js +0 -2127
  20. package/dist/chunk-CTPOZMMK.js +0 -1703
  21. package/dist/chunk-DO544M3G.js +0 -1702
  22. package/dist/chunk-DPKZBFQP.js +0 -1777
  23. package/dist/chunk-EK7PZUEB.js +0 -2147
  24. package/dist/chunk-FMOLIHQF.js +0 -2182
  25. package/dist/chunk-FWBTK5TL.js +0 -1444
  26. package/dist/chunk-GDQIBNX5.js +0 -1962
  27. package/dist/chunk-GHQ2MODM.js +0 -2127
  28. package/dist/chunk-GR2WCRGK.js +0 -2182
  29. package/dist/chunk-HNLKDQ64.js +0 -2139
  30. package/dist/chunk-INUMUXN5.js +0 -2095
  31. package/dist/chunk-IW3NHNOQ.js +0 -2187
  32. package/dist/chunk-JA4PMX6M.js +0 -1500
  33. package/dist/chunk-JSPFS7G5.js +0 -2102
  34. package/dist/chunk-JZRT4WNC.js +0 -1441
  35. package/dist/chunk-KQBY2JDB.js +0 -2112
  36. package/dist/chunk-LIMYFTPC.js +0 -1468
  37. package/dist/chunk-MEP7P6A7.js +0 -1500
  38. package/dist/chunk-NOZBIES7.js +0 -1948
  39. package/dist/chunk-O4GH3KYX.js +0 -1712
  40. package/dist/chunk-OEXM3BEC.js +0 -1702
  41. package/dist/chunk-Q7PYTVW3.js +0 -1771
  42. package/dist/chunk-QCWZYABW.js +0 -1468
  43. package/dist/chunk-RDF25WB2.js +0 -2085
  44. package/dist/chunk-RKTT3ZEX.js +0 -1500
  45. package/dist/chunk-S47BRMNQ.js +0 -1715
  46. package/dist/chunk-S4ZH5F56.js +0 -1949
  47. package/dist/chunk-SRD7NJHS.js +0 -1949
  48. package/dist/chunk-SWFYJO5H.js +0 -2187
  49. package/dist/chunk-TQDWPSTO.js +0 -2087
  50. package/dist/chunk-TTRXRPP6.js +0 -1941
  51. package/dist/chunk-UKYFJSUA.js +0 -509
  52. package/dist/chunk-VKEQHP2E.js +0 -2133
  53. package/dist/chunk-VUT2FMSI.js +0 -1937
  54. package/dist/chunk-VVCC5JHK.js +0 -1949
  55. package/dist/chunk-W732TVBK.js +0 -1944
  56. package/dist/chunk-X4VQYPKO.js +0 -1768
  57. package/dist/chunk-YZ3P3TNS.js +0 -1760
@@ -3,7 +3,7 @@ import { useState as useState3, useEffect as useEffect3, useCallback as useCallb
3
3
  import { createRoot } from "react-dom/client";
4
4
 
5
5
  // src/Shell.tsx
6
- import { useState as useState2, useEffect as useEffect2, useRef as useRef2, useCallback as useCallback2 } from "react";
6
+ import React2, { useState as useState2, useEffect as useEffect2, useRef as useRef2, useCallback as useCallback2 } from "react";
7
7
 
8
8
  // src/presets.ts
9
9
  var THEME_PRESETS = {
@@ -711,6 +711,20 @@ function AlgoliaSearchModal({
711
711
  var VersionIcon = () => /* @__PURE__ */ jsx2(Icon, { d: "M12 8v4l3 3m6-3a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z", size: 14 });
712
712
  var GlobeIcon = () => /* @__PURE__ */ jsx2(Icon, { d: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18ZM3.6 9h16.8M3.6 15h16.8M12 3a15 15 0 0 1 4 9 15 15 0 0 1-4 9 15 15 0 0 1-4-9 15 15 0 0 1 4-9Z", size: 14 });
713
713
  var ExtLinkIcon = () => /* @__PURE__ */ jsx2(Icon, { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3", size: 11 });
714
+ var SOCIAL_ICON_PATHS = {
715
+ github: "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z",
716
+ twitter: "M12.6.75h2.454l-5.36 6.142L16 15.25h-4.937l-3.867-5.07-4.425 5.07H.316l5.733-6.57L0 .75h5.063l3.495 4.633L12.601.75Zm-.86 13.028h1.36L4.323 2.145H2.865l8.875 11.633Z",
717
+ discord: "M13.545 2.907a13.227 13.227 0 00-3.257-1.011.05.05 0 00-.052.025c-.141.25-.297.577-.406.833a12.19 12.19 0 00-3.658 0 8.258 8.258 0 00-.412-.833.051.051 0 00-.052-.025c-1.125.194-2.22.534-3.257 1.011a.041.041 0 00-.021.018C.356 6.024-.213 9.047.066 12.032c.001.014.01.028.021.037a13.276 13.276 0 003.995 2.02.05.05 0 00.056-.019c.308-.42.582-.863.818-1.329a.05.05 0 00-.028-.07 8.735 8.735 0 01-1.248-.595.05.05 0 01-.005-.083c.084-.063.168-.129.248-.195a.05.05 0 01.051-.007c2.619 1.196 5.454 1.196 8.041 0a.052.052 0 01.053.007c.08.066.164.132.248.195a.051.051 0 01-.004.085c-.399.232-.813.431-1.249.594a.05.05 0 00-.03.07c.24.465.515.909.817 1.329a.05.05 0 00.056.019 13.235 13.235 0 004.001-2.02.049.049 0 00.021-.037c.334-3.451-.559-6.449-2.366-9.106a.034.034 0 00-.02-.019z",
718
+ linkedin: "M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854V1.146zm4.943 12.248V6.169H2.542v7.225h2.401zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248-.822 0-1.359.54-1.359 1.248 0 .694.521 1.248 1.327 1.248h.016zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016a5.54 5.54 0 01.016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225h2.4z",
719
+ youtube: "M8.051 1.999h.089c.822.003 4.987.033 6.11.335a2.01 2.01 0 011.415 1.42c.101.38.172.883.22 1.402l.01.104.022.26.008.104c.065.914.073 1.77.074 1.957v.075c-.001.194-.01 1.108-.082 2.06l-.008.105-.009.104c-.05.572-.124 1.14-.235 1.558a2.007 2.007 0 01-1.415 1.42c-1.16.312-5.569.334-6.18.335h-.142c-.309 0-1.587-.006-2.927-.052l-.17-.006-.087-.004-.171-.007-.171-.007c-1.11-.049-2.167-.128-2.654-.26a2.007 2.007 0 01-1.415-1.419c-.111-.417-.185-.986-.235-1.558L.09 9.82l-.008-.104A31.4 31.4 0 010 7.68v-.123c.002-.215.01-.958.064-1.778l.007-.103.003-.052.008-.104.022-.26.01-.104c.048-.519.119-1.023.22-1.402a2.007 2.007 0 011.415-1.42c.487-.13 1.544-.21 2.654-.26l.17-.007.172-.006.086-.003.171-.007A99.788 99.788 0 017.858 2h.193zM6.4 5.209v4.818l4.157-2.408L6.4 5.209z",
720
+ mastodon: "M11.19 12.195c2.016-.24 3.77-1.475 3.99-2.603.348-1.778.32-4.339.32-4.339 0-3.47-2.286-4.488-2.286-4.488C12.062.238 10.083.017 8.027 0h-.05C5.92.017 3.942.238 2.79.765 2.79.765.504 1.783.504 5.253c-.005.995-.01 2.19.013 3.44.075 4.21.56 8.354 3.383 9.386 1.302.476 2.418.576 3.317.507 1.628-.125 2.541-.8 2.541-.8l-.054-1.182s-1.163.366-2.47.322c-1.293-.044-2.658-.138-2.867-1.716a3.23 3.23 0 01-.028-.465s1.27.31 2.879.384c.984.045 1.905-.058 2.842-.17zM13 8.59V5.319c0-.67-.17-1.2-.507-1.592-.348-.4-.806-.605-1.373-.605-.656 0-1.154.252-1.486.756L9.2 4.595l-.434-.717c-.332-.504-.83-.756-1.486-.756-.567 0-1.025.204-1.373.605-.338.392-.507.923-.507 1.592V8.59h1.69V5.468c0-.67.285-1.012.855-1.012.63 0 .946.404.946 1.204V7.11h1.682V5.66c0-.8.316-1.204.946-1.204.57 0 .855.342.855 1.012V8.59H13z",
721
+ bluesky: "M3.468 1.948C5.303 3.325 7.276 6.118 8 7.616c.724-1.498 2.697-4.29 4.532-5.668C13.855 1.013 16 .638 16 3.14c0 .5-.286 4.2-.454 4.8-.585 2.093-2.716 2.628-4.544 2.305 3.195.564 4.007 2.433 2.25 4.302-3.337 3.548-4.8-1.244-5.252-2.547 0 0-.116-.334-.166-.334h.332C8.166 11.666 8.05 12 8.05 12c-.452 1.303-1.916 6.095-5.252 2.547-1.756-1.869-.946-3.738 2.25-4.302-1.829.323-3.96-.212-4.544-2.305C.336 7.34.05 3.64.05 3.14.05.638 2.195 1.013 3.468 1.948z"
722
+ };
723
+ var SocialIcon = ({ platform, customIcon }) => {
724
+ const d = platform === "custom" && customIcon ? customIcon : SOCIAL_ICON_PATHS[platform];
725
+ if (!d) return null;
726
+ return /* @__PURE__ */ jsx2("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx2("path", { d }) });
727
+ };
714
728
  var CHANGELOG_SECTION_COLORS = {
715
729
  Added: "#22c55e",
716
730
  Changed: "#3b82f6",
@@ -773,6 +787,23 @@ function ChangelogView({ entries }) {
773
787
  ) })
774
788
  ] });
775
789
  }
790
+ function getBreadcrumbs(navigation2, currentPageId, pageTitle) {
791
+ if (currentPageId === "index") return [];
792
+ for (const section of navigation2) {
793
+ const found = section.pages.find((p) => p.id === currentPageId);
794
+ if (found) {
795
+ const crumbs = [];
796
+ const firstPage = section.pages[0];
797
+ crumbs.push({
798
+ label: section.section,
799
+ href: firstPage ? firstPage.urlPath : null
800
+ });
801
+ crumbs.push({ label: pageTitle, href: null });
802
+ return crumbs;
803
+ }
804
+ }
805
+ return [];
806
+ }
776
807
  function Shell({
777
808
  config: config2,
778
809
  navigation: navigation2,
@@ -791,11 +822,17 @@ function Shell({
791
822
  allPages,
792
823
  versioning,
793
824
  currentVersion,
794
- i18n,
825
+ i18n: i18n2,
795
826
  currentLocale,
796
827
  docContext: docContext2,
797
- basePath: basePath2 = ""
828
+ basePath: basePath2 = "",
829
+ isDraft,
830
+ dir: dirProp,
831
+ overrides: overrides2
798
832
  }) {
833
+ const resolvedLocale = currentLocale || i18n2?.defaultLocale || "en";
834
+ const dir = dirProp || i18n2?.localeDirs?.[resolvedLocale] || "ltr";
835
+ const isRtl = dir === "rtl";
799
836
  const themeMode = config2.theme?.mode || "auto";
800
837
  const [isDark, setDark] = useState2(() => {
801
838
  if (themeMode === "dark") return true;
@@ -988,6 +1025,7 @@ function Shell({
988
1025
  const idx = allNavPages.findIndex((p) => p.id === currentPageId);
989
1026
  const prev = idx > 0 ? allNavPages[idx - 1] : null;
990
1027
  const next = idx < allNavPages.length - 1 ? allNavPages[idx + 1] : null;
1028
+ const breadcrumbs = getBreadcrumbs(navigation2, currentPageId, pageTitle);
991
1029
  const togSec = (s) => setExpanded((p) => p.includes(s) ? p.filter((x) => x !== s) : [...p, s]);
992
1030
  const cssVars = {
993
1031
  "--bg": t.bg,
@@ -1011,7 +1049,7 @@ function Shell({
1011
1049
  const PageComponent = pageComponent;
1012
1050
  const bannerLink = config2.banner?.link;
1013
1051
  const bannerIsInternal = bannerLink ? bannerLink.startsWith("#") || basePath2 && bannerLink.startsWith(basePath2 + "/") : false;
1014
- return /* @__PURE__ */ jsxs2("div", { className: "tome-grain", style: { ...cssVars, color: "var(--tx)", background: "var(--bg)", fontFamily: "var(--font-body)", minHeight: "100vh", overflow: "hidden" }, children: [
1052
+ return /* @__PURE__ */ jsxs2("div", { dir, className: "tome-grain", style: { ...cssVars, color: "var(--tx)", background: "var(--bg)", fontFamily: "var(--font-body)", minHeight: "100vh", overflow: "hidden" }, children: [
1015
1053
  config2.banner?.text && !bannerDismissed && /* @__PURE__ */ jsxs2("div", { style: {
1016
1054
  display: "flex",
1017
1055
  alignItems: "center",
@@ -1084,7 +1122,7 @@ function Shell({
1084
1122
  mobile
1085
1123
  }
1086
1124
  ) : null,
1087
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flex: 1, height: config2.banner?.text && !bannerDismissed ? "calc(100vh - 32px)" : "100vh" }, children: [
1125
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: isRtl ? "row-reverse" : "row", flex: 1, height: config2.banner?.text && !bannerDismissed ? "calc(100vh - 32px)" : "100vh" }, children: [
1088
1126
  mobile && sbOpen && /* @__PURE__ */ jsx2("div", { onClick: () => setSb(false), style: {
1089
1127
  position: "fixed",
1090
1128
  inset: 0,
@@ -1092,16 +1130,29 @@ function Shell({
1092
1130
  background: "rgba(0,0,0,0.4)",
1093
1131
  backdropFilter: "blur(2px)"
1094
1132
  } }),
1095
- /* @__PURE__ */ jsxs2("aside", { style: {
1133
+ overrides2?.Sidebar ? /* @__PURE__ */ jsx2(
1134
+ overrides2.Sidebar,
1135
+ {
1136
+ config: config2,
1137
+ navigation: navigation2,
1138
+ currentPageId,
1139
+ onNavigate,
1140
+ mobile,
1141
+ sbOpen,
1142
+ setSbOpen: setSb,
1143
+ versioning,
1144
+ currentVersion
1145
+ }
1146
+ ) : /* @__PURE__ */ jsxs2("aside", { style: {
1096
1147
  width: sbOpen ? 270 : 0,
1097
1148
  minWidth: sbOpen ? 270 : 0,
1098
1149
  background: "var(--sbBg)",
1099
- borderRight: "1px solid var(--bd)",
1150
+ [isRtl ? "borderLeft" : "borderRight"]: "1px solid var(--bd)",
1100
1151
  display: "flex",
1101
1152
  flexDirection: "column",
1102
1153
  transition: "width .2s, min-width .2s",
1103
1154
  overflow: "hidden",
1104
- ...mobile ? { position: "fixed", top: 0, left: 0, bottom: 0, zIndex: 201 } : {}
1155
+ ...mobile ? { position: "fixed", top: 0, [isRtl ? "right" : "left"]: 0, bottom: 0, zIndex: 201 } : {}
1105
1156
  }, children: [
1106
1157
  /* @__PURE__ */ jsxs2("a", { href: "/", style: { padding: "18px 20px", display: "flex", alignItems: "baseline", gap: 6, borderBottom: "1px solid var(--bd)", textDecoration: "none", color: "inherit" }, children: [
1107
1158
  /* @__PURE__ */ jsx2("span", { style: { fontFamily: "var(--font-heading)", fontSize: 22, fontWeight: 700, fontStyle: "italic" }, children: config2.name }),
@@ -1125,7 +1176,7 @@ function Shell({
1125
1176
  fontFamily: "var(--font-body)"
1126
1177
  }, children: [
1127
1178
  /* @__PURE__ */ jsx2(SearchIcon, {}),
1128
- /* @__PURE__ */ jsx2("span", { style: { flex: 1, textAlign: "left" }, children: "Search..." }),
1179
+ /* @__PURE__ */ jsx2("span", { style: { flex: 1, textAlign: isRtl ? "right" : "left" }, children: "Search..." }),
1129
1180
  /* @__PURE__ */ jsx2("kbd", { style: { fontFamily: "var(--font-code)", fontSize: 9, background: "var(--sf)", border: "1px solid var(--bd)", borderRadius: 2, padding: "2px 6px" }, children: "\u2318K" })
1130
1181
  ] }) }),
1131
1182
  /* @__PURE__ */ jsx2("nav", { style: { flex: 1, overflow: "auto", padding: "4px 10px 20px" }, children: navigation2.map((sec) => /* @__PURE__ */ jsxs2("div", { style: { marginBottom: 8 }, children: [
@@ -1149,9 +1200,9 @@ function Shell({
1149
1200
  expanded.includes(sec.section) ? /* @__PURE__ */ jsx2(ChevDown, {}) : /* @__PURE__ */ jsx2(ChevRight, {}),
1150
1201
  sec.section
1151
1202
  ] }),
1152
- expanded.includes(sec.section) && /* @__PURE__ */ jsx2("div", { style: { marginLeft: 8, borderLeft: "1px solid var(--bd)", paddingLeft: 0 }, children: sec.pages.map((p) => {
1203
+ expanded.includes(sec.section) && /* @__PURE__ */ jsx2("div", { style: { [isRtl ? "marginRight" : "marginLeft"]: 8, [isRtl ? "borderRight" : "borderLeft"]: "1px solid var(--bd)", [isRtl ? "paddingRight" : "paddingLeft"]: 0 }, children: sec.pages.map((p) => {
1153
1204
  const active = currentPageId === p.id;
1154
- return /* @__PURE__ */ jsx2("button", { onClick: () => {
1205
+ return /* @__PURE__ */ jsxs2("button", { onClick: () => {
1155
1206
  onNavigate(p.id);
1156
1207
  if (mobile) setSb(false);
1157
1208
  }, style: {
@@ -1159,11 +1210,11 @@ function Shell({
1159
1210
  alignItems: "center",
1160
1211
  gap: 10,
1161
1212
  width: "100%",
1162
- textAlign: "left",
1213
+ textAlign: isRtl ? "right" : "left",
1163
1214
  background: "none",
1164
1215
  border: "none",
1165
1216
  borderRadius: 0,
1166
- borderLeft: active ? "2px solid var(--ac)" : "2px solid transparent",
1217
+ [isRtl ? "borderRight" : "borderLeft"]: active ? "2px solid var(--ac)" : "2px solid transparent",
1167
1218
  padding: "7px 14px",
1168
1219
  cursor: "pointer",
1169
1220
  color: active ? "var(--ac)" : "var(--tx2)",
@@ -1171,7 +1222,29 @@ function Shell({
1171
1222
  fontWeight: active ? 500 : 400,
1172
1223
  fontFamily: "var(--font-body)",
1173
1224
  transition: "all .12s"
1174
- }, children: p.title }, p.id);
1225
+ }, children: [
1226
+ p.title,
1227
+ p.badge && (() => {
1228
+ const badgeColors = {
1229
+ default: { bg: "var(--sf)", text: "var(--tx2)" },
1230
+ info: { bg: "rgba(59,130,246,0.15)", text: "rgb(59,130,246)" },
1231
+ success: { bg: "rgba(34,197,94,0.15)", text: "rgb(34,197,94)" },
1232
+ warning: { bg: "rgba(234,179,8,0.15)", text: "rgb(202,138,4)" },
1233
+ danger: { bg: "rgba(239,68,68,0.15)", text: "rgb(239,68,68)" }
1234
+ };
1235
+ const bc = badgeColors[p.badge.variant || "default"] || badgeColors.default;
1236
+ return /* @__PURE__ */ jsx2("span", { style: {
1237
+ fontSize: 10,
1238
+ fontWeight: 600,
1239
+ padding: "2px 6px",
1240
+ borderRadius: 4,
1241
+ marginLeft: 6,
1242
+ whiteSpace: "nowrap",
1243
+ background: bc.bg,
1244
+ color: bc.text
1245
+ }, children: p.badge.text });
1246
+ })()
1247
+ ] }, p.id);
1175
1248
  }) })
1176
1249
  ] }, sec.section)) }),
1177
1250
  versioning && mobile && /* @__PURE__ */ jsx2("div", { style: { padding: "8px 16px", borderTop: "1px solid var(--bd)", display: "flex", gap: 6 }, children: versioning.versions.map((v) => /* @__PURE__ */ jsxs2(
@@ -1183,14 +1256,14 @@ function Shell({
1183
1256
  },
1184
1257
  style: {
1185
1258
  flex: 1,
1186
- padding: "6px 0",
1259
+ padding: "3px 0",
1187
1260
  textAlign: "center",
1188
1261
  background: v === (currentVersion || versioning.current) ? "var(--acD)" : "var(--sf)",
1189
1262
  border: "1px solid var(--bd)",
1190
1263
  borderRadius: 2,
1191
1264
  cursor: "pointer",
1192
1265
  color: v === (currentVersion || versioning.current) ? "var(--ac)" : "var(--tx2)",
1193
- fontSize: 12,
1266
+ fontSize: 11,
1194
1267
  fontFamily: "var(--font-code)",
1195
1268
  fontWeight: v === versioning.current ? 600 : 400
1196
1269
  },
@@ -1212,7 +1285,26 @@ function Shell({
1212
1285
  ] })
1213
1286
  ] }),
1214
1287
  /* @__PURE__ */ jsxs2("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: [
1215
- /* @__PURE__ */ jsxs2("header", { style: {
1288
+ overrides2?.Header ? /* @__PURE__ */ jsx2(
1289
+ overrides2.Header,
1290
+ {
1291
+ config: config2,
1292
+ navigation: navigation2,
1293
+ currentPageId,
1294
+ onNavigate,
1295
+ mobile,
1296
+ sbOpen,
1297
+ setSbOpen: setSb,
1298
+ isDark,
1299
+ setDark,
1300
+ versioning,
1301
+ currentVersion,
1302
+ i18n: i18n2,
1303
+ currentLocale,
1304
+ onSearchOpen: () => setSearch(true),
1305
+ basePath: basePath2
1306
+ }
1307
+ ) : /* @__PURE__ */ jsxs2("header", { style: {
1216
1308
  display: "flex",
1217
1309
  alignItems: "center",
1218
1310
  gap: mobile ? 8 : 12,
@@ -1272,6 +1364,28 @@ function Shell({
1272
1364
  }),
1273
1365
  /* @__PURE__ */ jsx2("span", { style: { width: 1, height: 16, background: "var(--bd)" } })
1274
1366
  ] }),
1367
+ config2.socialLinks && config2.socialLinks.length > 0 && !mobile && /* @__PURE__ */ jsx2("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: config2.socialLinks.map((link) => /* @__PURE__ */ jsx2(
1368
+ "a",
1369
+ {
1370
+ href: link.url,
1371
+ target: "_blank",
1372
+ rel: "noopener noreferrer",
1373
+ "aria-label": link.label || link.platform,
1374
+ "data-testid": `social-link-${link.platform}`,
1375
+ style: {
1376
+ display: "flex",
1377
+ alignItems: "center",
1378
+ justifyContent: "center",
1379
+ color: "var(--tx2)",
1380
+ cursor: "pointer",
1381
+ transition: "color .15s"
1382
+ },
1383
+ onMouseOver: (e) => e.currentTarget.style.color = "var(--tx)",
1384
+ onMouseOut: (e) => e.currentTarget.style.color = "var(--tx2)",
1385
+ children: /* @__PURE__ */ jsx2(SocialIcon, { platform: link.platform, customIcon: link.icon })
1386
+ },
1387
+ link.url
1388
+ )) }),
1275
1389
  mobile && themeMode === "auto" && /* @__PURE__ */ jsx2("button", { "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode", onClick: () => setDark((d) => !d), style: { background: "none", border: "none", color: "var(--txM)", cursor: "pointer", display: "flex", flexShrink: 0 }, children: isDark ? /* @__PURE__ */ jsx2(SunIcon, {}) : /* @__PURE__ */ jsx2(MoonIcon, {}) }),
1276
1390
  versioning && !mobile && /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
1277
1391
  /* @__PURE__ */ jsxs2(
@@ -1347,7 +1461,7 @@ function Shell({
1347
1461
  }
1348
1462
  )
1349
1463
  ] }),
1350
- i18n && i18n.locales.length > 1 && !mobile && /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
1464
+ i18n2 && i18n2.locales.length > 1 && !mobile && /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
1351
1465
  /* @__PURE__ */ jsxs2(
1352
1466
  "button",
1353
1467
  {
@@ -1368,7 +1482,7 @@ function Shell({
1368
1482
  },
1369
1483
  children: [
1370
1484
  /* @__PURE__ */ jsx2(GlobeIcon, {}),
1371
- i18n.localeNames?.[currentLocale || i18n.defaultLocale] || currentLocale || i18n.defaultLocale,
1485
+ i18n2.localeNames?.[currentLocale || i18n2.defaultLocale] || currentLocale || i18n2.defaultLocale,
1372
1486
  /* @__PURE__ */ jsx2(ChevDown, {})
1373
1487
  ]
1374
1488
  }
@@ -1390,15 +1504,15 @@ function Shell({
1390
1504
  zIndex: 100,
1391
1505
  minWidth: 120
1392
1506
  },
1393
- children: i18n.locales.map((locale) => {
1394
- const isActive = locale === (currentLocale || i18n.defaultLocale);
1395
- const displayName = i18n.localeNames?.[locale] || locale;
1396
- const activeLocale = currentLocale || i18n.defaultLocale;
1507
+ children: i18n2.locales.map((locale) => {
1508
+ const isActive = locale === (currentLocale || i18n2.defaultLocale);
1509
+ const displayName = i18n2.localeNames?.[locale] || locale;
1510
+ const activeLocale = currentLocale || i18n2.defaultLocale;
1397
1511
  let basePageId = currentPageId;
1398
- if (activeLocale !== i18n.defaultLocale && currentPageId.startsWith(`${activeLocale}/`)) {
1512
+ if (activeLocale !== i18n2.defaultLocale && currentPageId.startsWith(`${activeLocale}/`)) {
1399
1513
  basePageId = currentPageId.slice(activeLocale.length + 1);
1400
1514
  }
1401
- const targetId = locale === i18n.defaultLocale ? basePageId : `${locale}/${basePageId}`;
1515
+ const targetId = locale === i18n2.defaultLocale ? basePageId : `${locale}/${basePageId}`;
1402
1516
  return /* @__PURE__ */ jsx2(
1403
1517
  "button",
1404
1518
  {
@@ -1473,7 +1587,31 @@ function Shell({
1473
1587
  ),
1474
1588
  /* @__PURE__ */ jsxs2("div", { ref: contentRef, style: { flex: 1, overflow: "auto", display: "flex" }, children: [
1475
1589
  /* @__PURE__ */ jsxs2("main", { style: { flex: 1, maxWidth: mobile ? "100%" : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }, children: [
1590
+ breadcrumbs.length > 0 && /* @__PURE__ */ jsx2("nav", { "aria-label": "Breadcrumbs", "data-testid": "breadcrumbs", style: {
1591
+ display: "flex",
1592
+ alignItems: "center",
1593
+ gap: 6,
1594
+ fontSize: 13,
1595
+ color: "var(--tx2)",
1596
+ marginBottom: 8
1597
+ }, children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs2(React2.Fragment, { children: [
1598
+ i > 0 && /* @__PURE__ */ jsx2("span", { style: { color: "var(--tx2)", opacity: 0.5 }, children: "\u203A" }),
1599
+ i < breadcrumbs.length - 1 && crumb.href !== null ? /* @__PURE__ */ jsx2(
1600
+ "a",
1601
+ {
1602
+ href: crumb.href,
1603
+ onClick: (e) => {
1604
+ e.preventDefault();
1605
+ const page = navigation2.flatMap((s) => s.pages).find((p) => p.urlPath === crumb.href);
1606
+ if (page) onNavigate(page.id);
1607
+ },
1608
+ style: { color: "var(--tx2)", textDecoration: "none", cursor: "pointer" },
1609
+ children: crumb.label
1610
+ }
1611
+ ) : /* @__PURE__ */ jsx2("span", { style: i === breadcrumbs.length - 1 ? { color: "var(--tx)" } : void 0, children: crumb.label })
1612
+ ] }, i)) }),
1476
1613
  /* @__PURE__ */ jsx2("h1", { style: { fontFamily: "var(--font-heading)", fontSize: mobile ? 26 : 38, fontWeight: 400, fontStyle: "italic", lineHeight: 1.15, marginBottom: 8 }, children: pageTitle }),
1614
+ isDraft && /* @__PURE__ */ jsx2("div", { "data-testid": "draft-banner", style: { background: "#fef3c7", color: "#92400e", padding: "8px 16px", borderRadius: 6, fontSize: 13, marginBottom: 16 }, children: "Draft \u2014 This page is only visible in development" }),
1477
1615
  pageDescription && /* @__PURE__ */ jsx2("p", { style: { fontSize: 16, color: "var(--tx2)", lineHeight: 1.6, marginBottom: 32 }, children: pageDescription }),
1478
1616
  /* @__PURE__ */ jsx2("div", { style: { borderTop: "1px solid var(--bd)", paddingTop: 28 }, children: changelogEntries && changelogEntries.length > 0 ? /* @__PURE__ */ jsx2(ChangelogView, { entries: changelogEntries }) : PageComponent ? /* @__PURE__ */ jsx2("div", { className: "tome-content", children: /* @__PURE__ */ jsx2(PageComponent, { components: mdxComponents || {} }) }) : /* @__PURE__ */ jsx2(
1479
1617
  "div",
@@ -1482,113 +1620,133 @@ function Shell({
1482
1620
  ref: htmlContentRef
1483
1621
  }
1484
1622
  ) }),
1485
- (editUrl || lastUpdated) && /* @__PURE__ */ jsxs2("div", { style: { marginTop: 40, display: "flex", flexDirection: mobile ? "column" : "row", alignItems: mobile ? "flex-start" : "center", justifyContent: "space-between", gap: mobile ? 8 : 16 }, children: [
1486
- editUrl && /* @__PURE__ */ jsx2("div", { "data-testid": "edit-page-link", children: /* @__PURE__ */ jsxs2(
1487
- "a",
1488
- {
1489
- href: editUrl,
1490
- target: "_blank",
1491
- rel: "noopener noreferrer",
1492
- style: {
1493
- display: "inline-flex",
1494
- alignItems: "center",
1495
- gap: 6,
1496
- color: "var(--txM)",
1497
- textDecoration: "none",
1498
- fontSize: 13,
1499
- fontFamily: "var(--font-body)",
1500
- transition: "color .15s"
1501
- },
1502
- onMouseOver: (e) => e.currentTarget.style.color = "var(--ac)",
1503
- onMouseOut: (e) => e.currentTarget.style.color = "var(--txM)",
1504
- children: [
1505
- /* @__PURE__ */ jsx2(PencilIcon, {}),
1506
- " Edit this page on GitHub"
1507
- ]
1508
- }
1509
- ) }),
1510
- lastUpdated && /* @__PURE__ */ jsxs2("div", { "data-testid": "last-updated", style: { fontSize: 12, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: [
1511
- "Last updated ",
1512
- formatRelativeDate(lastUpdated)
1623
+ overrides2?.PageFooter ? /* @__PURE__ */ jsx2(
1624
+ overrides2.PageFooter,
1625
+ {
1626
+ editUrl,
1627
+ lastUpdated,
1628
+ currentPageId,
1629
+ prev,
1630
+ next,
1631
+ onNavigate,
1632
+ mobile
1633
+ }
1634
+ ) : /* @__PURE__ */ jsxs2(Fragment, { children: [
1635
+ (editUrl || lastUpdated) && /* @__PURE__ */ jsxs2("div", { style: { marginTop: 40, display: "flex", flexDirection: mobile ? "column" : "row", alignItems: mobile ? "flex-start" : "center", justifyContent: "space-between", gap: mobile ? 8 : 16 }, children: [
1636
+ editUrl && /* @__PURE__ */ jsx2("div", { "data-testid": "edit-page-link", children: /* @__PURE__ */ jsxs2(
1637
+ "a",
1638
+ {
1639
+ href: editUrl,
1640
+ target: "_blank",
1641
+ rel: "noopener noreferrer",
1642
+ style: {
1643
+ display: "inline-flex",
1644
+ alignItems: "center",
1645
+ gap: 6,
1646
+ color: "var(--txM)",
1647
+ textDecoration: "none",
1648
+ fontSize: 13,
1649
+ fontFamily: "var(--font-body)",
1650
+ transition: "color .15s"
1651
+ },
1652
+ onMouseOver: (e) => e.currentTarget.style.color = "var(--ac)",
1653
+ onMouseOut: (e) => e.currentTarget.style.color = "var(--txM)",
1654
+ children: [
1655
+ /* @__PURE__ */ jsx2(PencilIcon, {}),
1656
+ " Edit this page on GitHub"
1657
+ ]
1658
+ }
1659
+ ) }),
1660
+ lastUpdated && /* @__PURE__ */ jsxs2("div", { "data-testid": "last-updated", style: { fontSize: 12, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: [
1661
+ "Last updated ",
1662
+ formatRelativeDate(lastUpdated)
1663
+ ] })
1664
+ ] }),
1665
+ /* @__PURE__ */ jsx2("div", { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 24, padding: "12px 0" }, children: feedbackGiven[currentPageId] ? /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Thanks for your feedback!" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
1666
+ /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Was this helpful?" }),
1667
+ /* @__PURE__ */ jsx2("button", { onClick: () => {
1668
+ setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
1669
+ try {
1670
+ localStorage.setItem(`tome-feedback-${currentPageId}`, "up");
1671
+ } catch {
1672
+ }
1673
+ }, style: {
1674
+ background: "none",
1675
+ border: "1px solid var(--bd)",
1676
+ borderRadius: 2,
1677
+ padding: "4px 10px",
1678
+ cursor: "pointer",
1679
+ fontSize: 13,
1680
+ color: "var(--txM)",
1681
+ transition: "border-color .15s"
1682
+ }, children: "\u{1F44D}" }),
1683
+ /* @__PURE__ */ jsx2("button", { onClick: () => {
1684
+ setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
1685
+ try {
1686
+ localStorage.setItem(`tome-feedback-${currentPageId}`, "down");
1687
+ } catch {
1688
+ }
1689
+ }, style: {
1690
+ background: "none",
1691
+ border: "1px solid var(--bd)",
1692
+ borderRadius: 2,
1693
+ padding: "4px 10px",
1694
+ cursor: "pointer",
1695
+ fontSize: 13,
1696
+ color: "var(--txM)",
1697
+ transition: "border-color .15s"
1698
+ }, children: "\u{1F44E}" })
1699
+ ] }) }),
1700
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: mobile ? "column" : "row", justifyContent: "space-between", marginTop: 16, paddingTop: 24, borderTop: "1px solid var(--bd)", gap: mobile ? 12 : 16 }, children: [
1701
+ prev ? /* @__PURE__ */ jsxs2("button", { onClick: () => onNavigate(prev.id), style: {
1702
+ display: "flex",
1703
+ alignItems: "center",
1704
+ gap: 8,
1705
+ background: "none",
1706
+ border: "1px solid var(--bd)",
1707
+ borderRadius: 2,
1708
+ padding: "10px 16px",
1709
+ cursor: "pointer",
1710
+ color: "var(--tx2)",
1711
+ fontSize: 13,
1712
+ fontFamily: "var(--font-body)",
1713
+ transition: "border-color .15s, color .15s"
1714
+ }, children: [
1715
+ isRtl ? /* @__PURE__ */ jsx2(ArrowRight, {}) : /* @__PURE__ */ jsx2(ArrowLeft, {}),
1716
+ " ",
1717
+ prev.title
1718
+ ] }) : /* @__PURE__ */ jsx2("div", {}),
1719
+ next ? /* @__PURE__ */ jsxs2("button", { onClick: () => onNavigate(next.id), style: {
1720
+ display: "flex",
1721
+ alignItems: "center",
1722
+ gap: 8,
1723
+ background: "none",
1724
+ border: "1px solid var(--bd)",
1725
+ borderRadius: 2,
1726
+ padding: "10px 16px",
1727
+ cursor: "pointer",
1728
+ color: "var(--tx2)",
1729
+ fontSize: 13,
1730
+ fontFamily: "var(--font-body)",
1731
+ transition: "border-color .15s, color .15s"
1732
+ }, children: [
1733
+ next.title,
1734
+ " ",
1735
+ isRtl ? /* @__PURE__ */ jsx2(ArrowLeft, {}) : /* @__PURE__ */ jsx2(ArrowRight, {})
1736
+ ] }) : /* @__PURE__ */ jsx2("div", {})
1513
1737
  ] })
1514
- ] }),
1515
- /* @__PURE__ */ jsx2("div", { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 24, padding: "12px 0" }, children: feedbackGiven[currentPageId] ? /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Thanks for your feedback!" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
1516
- /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Was this helpful?" }),
1517
- /* @__PURE__ */ jsx2("button", { onClick: () => {
1518
- setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
1519
- try {
1520
- localStorage.setItem(`tome-feedback-${currentPageId}`, "up");
1521
- } catch {
1522
- }
1523
- }, style: {
1524
- background: "none",
1525
- border: "1px solid var(--bd)",
1526
- borderRadius: 2,
1527
- padding: "4px 10px",
1528
- cursor: "pointer",
1529
- fontSize: 13,
1530
- color: "var(--txM)",
1531
- transition: "border-color .15s"
1532
- }, children: "\u{1F44D}" }),
1533
- /* @__PURE__ */ jsx2("button", { onClick: () => {
1534
- setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
1535
- try {
1536
- localStorage.setItem(`tome-feedback-${currentPageId}`, "down");
1537
- } catch {
1538
- }
1539
- }, style: {
1540
- background: "none",
1541
- border: "1px solid var(--bd)",
1542
- borderRadius: 2,
1543
- padding: "4px 10px",
1544
- cursor: "pointer",
1545
- fontSize: 13,
1546
- color: "var(--txM)",
1547
- transition: "border-color .15s"
1548
- }, children: "\u{1F44E}" })
1549
- ] }) }),
1550
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: mobile ? "column" : "row", justifyContent: "space-between", marginTop: 16, paddingTop: 24, borderTop: "1px solid var(--bd)", gap: mobile ? 12 : 16 }, children: [
1551
- prev ? /* @__PURE__ */ jsxs2("button", { onClick: () => onNavigate(prev.id), style: {
1552
- display: "flex",
1553
- alignItems: "center",
1554
- gap: 8,
1555
- background: "none",
1556
- border: "1px solid var(--bd)",
1557
- borderRadius: 2,
1558
- padding: "10px 16px",
1559
- cursor: "pointer",
1560
- color: "var(--tx2)",
1561
- fontSize: 13,
1562
- fontFamily: "var(--font-body)",
1563
- transition: "border-color .15s, color .15s"
1564
- }, children: [
1565
- /* @__PURE__ */ jsx2(ArrowLeft, {}),
1566
- " ",
1567
- prev.title
1568
- ] }) : /* @__PURE__ */ jsx2("div", {}),
1569
- next ? /* @__PURE__ */ jsxs2("button", { onClick: () => onNavigate(next.id), style: {
1570
- display: "flex",
1571
- alignItems: "center",
1572
- gap: 8,
1573
- background: "none",
1574
- border: "1px solid var(--bd)",
1575
- borderRadius: 2,
1576
- padding: "10px 16px",
1577
- cursor: "pointer",
1578
- color: "var(--tx2)",
1579
- fontSize: 13,
1580
- fontFamily: "var(--font-body)",
1581
- transition: "border-color .15s, color .15s"
1582
- }, children: [
1583
- next.title,
1584
- " ",
1585
- /* @__PURE__ */ jsx2(ArrowRight, {})
1586
- ] }) : /* @__PURE__ */ jsx2("div", {})
1587
1738
  ] })
1588
1739
  ] }),
1589
- showToc && filteredHeadings.length >= 2 && wide && /* @__PURE__ */ jsxs2("aside", { "data-testid": "toc-sidebar", style: { width: 200, padding: "40px 16px 40px 0", position: "sticky", top: 0, alignSelf: "flex-start", flexShrink: 0 }, children: [
1740
+ overrides2?.Toc ? showToc && filteredHeadings.length >= 2 && wide && /* @__PURE__ */ jsx2(
1741
+ overrides2.Toc,
1742
+ {
1743
+ headings: filteredHeadings,
1744
+ activeHeadingId,
1745
+ onScrollToHeading: scrollToHeading
1746
+ }
1747
+ ) : showToc && filteredHeadings.length >= 2 && wide && /* @__PURE__ */ jsxs2("aside", { "data-testid": "toc-sidebar", style: { width: 200, padding: isRtl ? "40px 0 40px 16px" : "40px 16px 40px 0", position: "sticky", top: 0, alignSelf: "flex-start", flexShrink: 0 }, children: [
1590
1748
  /* @__PURE__ */ jsx2("div", { style: { fontSize: 10, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".1em", color: "var(--txM)", marginBottom: 12, fontFamily: "var(--font-code)" }, children: "On this page" }),
1591
- /* @__PURE__ */ jsx2("nav", { "aria-label": "Table of contents", style: { borderLeft: "1px solid var(--bd)", paddingLeft: 0 }, children: filteredHeadings.map((h, i) => {
1749
+ /* @__PURE__ */ jsx2("nav", { "aria-label": "Table of contents", style: { [isRtl ? "borderRight" : "borderLeft"]: "1px solid var(--bd)", [isRtl ? "paddingRight" : "paddingLeft"]: 0 }, children: filteredHeadings.map((h, i) => {
1592
1750
  const isActive = activeHeadingId === h.id;
1593
1751
  return /* @__PURE__ */ jsx2(
1594
1752
  "a",
@@ -1603,11 +1761,11 @@ function Shell({
1603
1761
  fontWeight: isActive ? 500 : 400,
1604
1762
  textDecoration: "none",
1605
1763
  padding: "4px 12px",
1606
- paddingLeft: 12 + (h.depth - 2) * 12,
1764
+ [isRtl ? "paddingRight" : "paddingLeft"]: 12 + (h.depth - 2) * 12,
1607
1765
  lineHeight: 1.4,
1608
1766
  transition: "color .15s, font-weight .15s",
1609
- borderLeft: isActive ? "2px solid var(--ac)" : "2px solid transparent",
1610
- marginLeft: -1
1767
+ [isRtl ? "borderRight" : "borderLeft"]: isActive ? "2px solid var(--ac)" : "2px solid transparent",
1768
+ [isRtl ? "marginRight" : "marginLeft"]: -1
1611
1769
  },
1612
1770
  children: h.text
1613
1771
  },
@@ -1618,6 +1776,15 @@ function Shell({
1618
1776
  ] })
1619
1777
  ] })
1620
1778
  ] }),
1779
+ overrides2?.Footer && /* @__PURE__ */ jsx2(
1780
+ overrides2.Footer,
1781
+ {
1782
+ config: config2,
1783
+ navigation: navigation2,
1784
+ currentPageId,
1785
+ onNavigate
1786
+ }
1787
+ ),
1621
1788
  config2.ai?.enabled && /* @__PURE__ */ jsx2(
1622
1789
  AiChat,
1623
1790
  {
@@ -1834,9 +2001,10 @@ function detectCurrentVersion(currentRoute, versions2) {
1834
2001
 
1835
2002
  // src/entry.tsx
1836
2003
  import config from "virtual:tome/config";
1837
- import { routes, navigation, versions } from "virtual:tome/routes";
2004
+ import { routes, navigation, versions, i18n } from "virtual:tome/routes";
1838
2005
  import loadPageModule from "virtual:tome/page-loader";
1839
2006
  import docContext from "virtual:tome/doc-context";
2007
+ import overrides from "virtual:tome/overrides";
1840
2008
  import {
1841
2009
  Callout,
1842
2010
  Tabs,
@@ -1847,7 +2015,10 @@ import {
1847
2015
  ChangelogTimeline,
1848
2016
  PackageManager,
1849
2017
  TypeTable,
1850
- FileTree
2018
+ FileTree,
2019
+ CodeSamples,
2020
+ LinkCard,
2021
+ CardGrid
1851
2022
  } from "@tomehq/components";
1852
2023
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1853
2024
  var MDX_COMPONENTS = {
@@ -1860,8 +2031,11 @@ var MDX_COMPONENTS = {
1860
2031
  ChangelogTimeline,
1861
2032
  PackageManager,
1862
2033
  TypeTable,
1863
- FileTree
2034
+ FileTree,
1864
2035
  // Sub-components accessible as <FileTree.File /> and <FileTree.Folder /> in MDX
2036
+ CodeSamples,
2037
+ LinkCard,
2038
+ CardGrid
1865
2039
  };
1866
2040
  var contentStyles = `
1867
2041
  @import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@300;400;500;600;700&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;0,700;1,300;1,400;1,700&family=Fira+Code:wght@400;500;600&display=swap');
@@ -1875,15 +2049,15 @@ var contentStyles = `
1875
2049
  .tome-content a { color: var(--ac); text-decoration: none; }
1876
2050
  .tome-content a:hover { text-decoration: underline; }
1877
2051
  .tome-content .heading-anchor { display: none; }
1878
- .tome-content ul, .tome-content ol { color: var(--tx2); padding-left: 1.5em; margin-bottom: 1em; }
2052
+ .tome-content ul, .tome-content ol { color: var(--tx2); padding-inline-start: 1.5em; margin-bottom: 1em; }
1879
2053
  .tome-content li { margin-bottom: 0.3em; line-height: 1.7; }
1880
2054
  .tome-content code { font-family: var(--font-code); font-size: 0.88em; background: var(--cdBg); padding: 0.15em 0.4em; border-radius: 2px; color: var(--ac); }
1881
2055
  .tome-content pre { margin-bottom: 1.2em; border-radius: 2px; overflow-x: auto; border: 1px solid var(--bd); }
1882
2056
  .tome-content pre code { background: none; padding: 1em 1.2em; display: block; font-size: 12.5px; line-height: 1.7; color: var(--cdTx); }
1883
- .tome-content blockquote { border-left: 3px solid var(--ac); padding: 0.5em 1em; margin: 1em 0; background: var(--acD); border-radius: 0 2px 2px 0; }
2057
+ .tome-content blockquote { border-inline-start: 3px solid var(--ac); padding: 0.5em 1em; margin: 1em 0; background: var(--acD); border-radius: 0 2px 2px 0; }
1884
2058
  .tome-content blockquote p { color: var(--tx2); margin: 0; }
1885
2059
  .tome-content table { width: 100%; border-collapse: collapse; margin-bottom: 1em; }
1886
- .tome-content th, .tome-content td { padding: 0.5em 0.8em; border: 1px solid var(--bd); text-align: left; font-size: 0.9em; }
2060
+ .tome-content th, .tome-content td { padding: 0.5em 0.8em; border: 1px solid var(--bd); text-align: start; font-size: 0.9em; }
1887
2061
  .tome-content th { background: var(--sf); font-weight: 600; }
1888
2062
  .tome-content img { max-width: 100%; border-radius: 2px; cursor: zoom-in; }
1889
2063
  .tome-content hr { border: none; border-top: 1px solid var(--bd); margin: 2em 0; }
@@ -1937,6 +2111,74 @@ var contentStyles = `
1937
2111
  background-repeat: repeat; background-size: 256px;
1938
2112
  }
1939
2113
 
2114
+ /* \u2500\u2500 Expressive code blocks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
2115
+
2116
+ /* Code block wrapper (for titled blocks) */
2117
+ .tome-code-block-wrapper { position: relative; margin-bottom: 1.2em; border: 1px solid var(--bd); border-radius: 2px; overflow: hidden; }
2118
+ .tome-code-block-wrapper pre { margin-bottom: 0; border: none; border-radius: 0; }
2119
+ .tome-code-title {
2120
+ font-family: var(--font-code); font-size: 12px; color: var(--tx2);
2121
+ background: var(--sf); padding: 6px 12px; border-bottom: 1px solid var(--bd);
2122
+ letter-spacing: 0.01em; font-weight: 500;
2123
+ }
2124
+
2125
+ /* Line highlighting */
2126
+ .tome-content pre .line.tome-line-highlight {
2127
+ background: rgba(139, 148, 158, 0.1);
2128
+ display: inline-block; width: 100%; margin: 0 -1.2em; padding: 0 1.2em;
2129
+ }
2130
+ html.dark .tome-content pre .line.tome-line-highlight {
2131
+ background: rgba(200, 210, 220, 0.08);
2132
+ }
2133
+
2134
+ /* Diff lines */
2135
+ .tome-content pre .line.tome-line-added {
2136
+ background: rgba(34, 197, 94, 0.12);
2137
+ display: inline-block; width: 100%; margin: 0 -1.2em; padding: 0 1.2em;
2138
+ }
2139
+ .tome-content pre .line.tome-line-removed {
2140
+ background: rgba(239, 68, 68, 0.12);
2141
+ display: inline-block; width: 100%; margin: 0 -1.2em; padding: 0 1.2em;
2142
+ }
2143
+ html.dark .tome-content pre .line.tome-line-added { background: rgba(34, 197, 94, 0.15); }
2144
+ html.dark .tome-content pre .line.tome-line-removed { background: rgba(239, 68, 68, 0.15); }
2145
+
2146
+ /* Line numbers (CSS counter) */
2147
+ .tome-content pre[data-line-numbers] code {
2148
+ counter-reset: line;
2149
+ }
2150
+ .tome-content pre[data-line-numbers] .line::before {
2151
+ counter-increment: line;
2152
+ content: counter(line);
2153
+ display: inline-block; width: 2.5em; margin-inline-end: 1em;
2154
+ text-align: end; color: var(--txM); opacity: 0.4;
2155
+ font-size: 0.85em; user-select: none;
2156
+ border-inline-end: 1px solid var(--bd); padding-inline-end: 0.8em; margin-inline-end: 0.8em;
2157
+ }
2158
+
2159
+ /* Word highlighting */
2160
+ .tome-word-highlight {
2161
+ background: rgba(139, 148, 158, 0.2); border-radius: 2px;
2162
+ padding: 1px 3px; margin: 0 -1px;
2163
+ }
2164
+ html.dark .tome-word-highlight {
2165
+ background: rgba(200, 210, 220, 0.15);
2166
+ }
2167
+
2168
+ /* Copy button */
2169
+ .tome-content pre { position: relative; }
2170
+ .tome-copy-btn {
2171
+ position: absolute; top: 8px; inset-inline-end: 8px;
2172
+ font-family: var(--font-code); font-size: 11px;
2173
+ color: var(--tx2); background: var(--sf); border: 1px solid var(--bd);
2174
+ padding: 3px 8px; border-radius: 2px; cursor: pointer;
2175
+ opacity: 0; transition: opacity 0.15s;
2176
+ z-index: 2; line-height: 1.4;
2177
+ }
2178
+ .tome-content pre:hover .tome-copy-btn,
2179
+ .tome-copy-btn:focus { opacity: 1; }
2180
+ .tome-copy-btn:hover { background: var(--sfH); }
2181
+
1940
2182
  /* Shiki dual-theme support */
1941
2183
  .shiki { background: var(--cdBg) !important; }
1942
2184
 
@@ -1958,6 +2200,57 @@ var contentStyles = `
1958
2200
  html:not(.dark) .shiki span[style*="color:#22863A"] { color: #1a6e2e !important; }
1959
2201
  html:not(.dark) .shiki span[style*="color:#D73A49"] { color: #b62324 !important; }
1960
2202
  html:not(.dark) .shiki span[style*="color:#005CC5"] { color: #0349b4 !important; }
2203
+
2204
+ /* \u2500\u2500 Twoslash type hover tooltips \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
2205
+ .twoslash-hover {
2206
+ position: relative;
2207
+ border-bottom: 1px dotted var(--tx2);
2208
+ cursor: help;
2209
+ }
2210
+ .twoslash-popup-container {
2211
+ position: absolute;
2212
+ opacity: 0;
2213
+ display: none;
2214
+ z-index: 10;
2215
+ left: 0;
2216
+ top: 100%;
2217
+ margin-top: 4px;
2218
+ padding: 6px 10px;
2219
+ background: var(--sf);
2220
+ border: 1px solid var(--bd);
2221
+ border-radius: 6px;
2222
+ font-size: 12px;
2223
+ font-family: var(--font-code);
2224
+ color: var(--tx);
2225
+ white-space: pre-wrap;
2226
+ max-width: 500px;
2227
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
2228
+ pointer-events: none;
2229
+ }
2230
+ .twoslash-hover:hover .twoslash-popup-container {
2231
+ opacity: 1;
2232
+ display: block;
2233
+ }
2234
+ /* Twoslash error/warning underlines */
2235
+ .twoslash-error {
2236
+ position: relative;
2237
+ background: rgba(239, 68, 68, 0.1);
2238
+ border-bottom: 2px wavy rgba(239, 68, 68, 0.6);
2239
+ }
2240
+ /* Twoslash highlighted identifiers */
2241
+ .twoslash-highlighted {
2242
+ background: rgba(139, 148, 158, 0.15);
2243
+ border-radius: 2px;
2244
+ padding: 1px 2px;
2245
+ }
2246
+ /* Twoslash type annotation line (^?) */
2247
+ .twoslash-popup-code .shiki { background: transparent !important; padding: 0; margin: 0; }
2248
+ .twoslash-popup-code .shiki code { padding: 0; font-size: 12px; }
2249
+ html.dark .twoslash-popup-container {
2250
+ background: var(--sf);
2251
+ border-color: var(--bd);
2252
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
2253
+ }
1961
2254
  `;
1962
2255
  var basePath = (config.basePath || "/").replace(/\/$/, "");
1963
2256
  function pathnameToPageId2(pathname) {
@@ -2095,6 +2388,39 @@ function App() {
2095
2388
  cancelled = true;
2096
2389
  };
2097
2390
  }, [pageData, loading, mermaidTheme]);
2391
+ useEffect3(() => {
2392
+ if (loading) return;
2393
+ const preBlocks = document.querySelectorAll(".tome-content pre");
2394
+ const buttons = [];
2395
+ preBlocks.forEach((pre) => {
2396
+ if (pre.querySelector(".tome-copy-btn")) return;
2397
+ const btn = document.createElement("button");
2398
+ btn.className = "tome-copy-btn";
2399
+ btn.textContent = "Copy";
2400
+ btn.addEventListener("click", async () => {
2401
+ const code = pre.querySelector("code");
2402
+ if (code) {
2403
+ try {
2404
+ await navigator.clipboard.writeText(code.textContent || "");
2405
+ btn.textContent = "Copied!";
2406
+ setTimeout(() => {
2407
+ btn.textContent = "Copy";
2408
+ }, 2e3);
2409
+ } catch {
2410
+ btn.textContent = "Failed";
2411
+ setTimeout(() => {
2412
+ btn.textContent = "Copy";
2413
+ }, 2e3);
2414
+ }
2415
+ }
2416
+ });
2417
+ pre.appendChild(btn);
2418
+ buttons.push(btn);
2419
+ });
2420
+ return () => {
2421
+ buttons.forEach((btn) => btn.remove());
2422
+ };
2423
+ }, [pageData, loading]);
2098
2424
  const allPages = routes.map((r) => ({
2099
2425
  id: r.id,
2100
2426
  title: r.frontmatter.title,
@@ -2103,6 +2429,8 @@ function App() {
2103
2429
  const currentRoute = routes.find((r) => r.id === currentPageId);
2104
2430
  const currentVersion = detectCurrentVersion(currentRoute, versions);
2105
2431
  const editUrl = computeEditUrl(config.editLink, currentRoute?.filePath);
2432
+ const currentLocale = currentRoute?.locale || i18n?.defaultLocale || "en";
2433
+ const dir = i18n?.localeDirs?.[currentLocale] || "ltr";
2106
2434
  useEffect3(() => {
2107
2435
  const hasMathPlaceholders = document.querySelectorAll(".tome-math[data-math]").length > 0;
2108
2436
  if (!config.math && !hasMathPlaceholders) return;
@@ -2172,7 +2500,12 @@ function App() {
2172
2500
  docContext,
2173
2501
  versioning: versions || void 0,
2174
2502
  currentVersion,
2175
- basePath
2503
+ basePath,
2504
+ isDraft: currentRoute?.frontmatter?.draft === true,
2505
+ dir,
2506
+ i18n: i18n || void 0,
2507
+ currentLocale,
2508
+ overrides
2176
2509
  }
2177
2510
  )
2178
2511
  ] });