@tomehq/theme 0.3.3 → 0.4.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/chunk-2APCPR2Y.js +2110 -0
  3. package/dist/chunk-2AXAEADQ.js +2525 -0
  4. package/dist/chunk-2WNOJXK3.js +2581 -0
  5. package/dist/chunk-37JI6XGT.js +1720 -0
  6. package/dist/chunk-3A2LPGUL.js +1991 -0
  7. package/dist/chunk-3I2QTWTW.js +1948 -0
  8. package/dist/chunk-3I4SJMER.js +2538 -0
  9. package/dist/chunk-45M5UIAB.js +2110 -0
  10. package/dist/chunk-462AGU3S.js +1959 -0
  11. package/dist/chunk-5GVQFIPI.js +2581 -0
  12. package/dist/chunk-7MUTU5D4.js +1720 -0
  13. package/dist/chunk-7NQ4IMDY.js +2294 -0
  14. package/dist/chunk-ABNPB6BB.js +2133 -0
  15. package/dist/chunk-BZGWSKT2.js +573 -0
  16. package/dist/chunk-BZIB2LMI.js +2519 -0
  17. package/dist/chunk-CMQCNCSY.js +2127 -0
  18. package/dist/chunk-CTPOZMMK.js +1703 -0
  19. package/dist/chunk-DKSQZLWR.js +2569 -0
  20. package/dist/chunk-DO544M3G.js +1702 -0
  21. package/dist/chunk-DPKZBFQP.js +1777 -0
  22. package/dist/chunk-EK7PZUEB.js +2147 -0
  23. package/dist/chunk-FMOLIHQF.js +2182 -0
  24. package/dist/chunk-FWBTK5TL.js +1444 -0
  25. package/dist/chunk-GDQIBNX5.js +1962 -0
  26. package/dist/chunk-GHQ2MODM.js +2127 -0
  27. package/dist/chunk-GR2WCRGK.js +2182 -0
  28. package/dist/chunk-H5XZVNBW.js +2291 -0
  29. package/dist/chunk-HNLKDQ64.js +2139 -0
  30. package/dist/chunk-INUMUXN5.js +2095 -0
  31. package/dist/chunk-IW3NHNOQ.js +2187 -0
  32. package/dist/chunk-JA4PMX6M.js +1500 -0
  33. package/dist/chunk-JSPFS7G5.js +2102 -0
  34. package/dist/chunk-JZRT4WNC.js +1441 -0
  35. package/dist/chunk-KQBY2JDB.js +2112 -0
  36. package/dist/chunk-LIMYFTPC.js +1468 -0
  37. package/dist/chunk-LIY62BGC.js +2519 -0
  38. package/dist/chunk-MEP7P6A7.js +1500 -0
  39. package/dist/chunk-MHYKO7KM.js +2570 -0
  40. package/dist/chunk-NOZBIES7.js +1948 -0
  41. package/dist/chunk-O4GH3KYX.js +1712 -0
  42. package/dist/chunk-OEDJTH5F.js +2569 -0
  43. package/dist/chunk-OEXM3BEC.js +1702 -0
  44. package/dist/chunk-PGKSFQ7A.js +2459 -0
  45. package/dist/chunk-PIV6CPY2.js +2395 -0
  46. package/dist/chunk-Q7PYTVW3.js +1771 -0
  47. package/dist/chunk-QCWZYABW.js +1468 -0
  48. package/dist/chunk-QYINBNMJ.js +2545 -0
  49. package/dist/chunk-RDF25WB2.js +2085 -0
  50. package/dist/chunk-RKTT3ZEX.js +1500 -0
  51. package/dist/chunk-S47BRMNQ.js +1715 -0
  52. package/dist/chunk-S4ZH5F56.js +1949 -0
  53. package/dist/chunk-SRD7NJHS.js +1949 -0
  54. package/dist/chunk-SWFYJO5H.js +2187 -0
  55. package/dist/chunk-TQDWPSTO.js +2087 -0
  56. package/dist/chunk-TTRXRPP6.js +1941 -0
  57. package/dist/chunk-UKYFJSUA.js +509 -0
  58. package/dist/chunk-VKEQHP2E.js +2133 -0
  59. package/dist/chunk-VUT2FMSI.js +1937 -0
  60. package/dist/chunk-VVCC5JHK.js +1949 -0
  61. package/dist/chunk-W732TVBK.js +1944 -0
  62. package/dist/chunk-X4VQYPKO.js +1768 -0
  63. package/dist/chunk-YX7HV4EP.js +2568 -0
  64. package/dist/chunk-YXKONM3A.js +2192 -0
  65. package/dist/chunk-YZ3P3TNS.js +1760 -0
  66. package/dist/chunk-ZVZ7JN3V.js +2568 -0
  67. package/dist/chunk-ZXW4STTN.js +2568 -0
  68. package/dist/entry.js +1 -1
  69. package/dist/index.js +1 -1
  70. package/package.json +3 -3
  71. package/src/Shell.test.tsx +25 -0
  72. package/src/Shell.tsx +8 -8
  73. package/src/entry-helpers.test.ts +60 -12
  74. package/src/entry-helpers.ts +56 -30
  75. package/src/entry.test.tsx +208 -3
  76. package/src/entry.tsx +28 -2
@@ -0,0 +1,573 @@
1
+ // src/entry.tsx
2
+ import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
3
+ import { createRoot } from "react-dom/client";
4
+
5
+ // src/Shell.tsx
6
+ import { useState, useEffect, useRef, useMemo } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var THEMES = {
9
+ amber: {
10
+ dark: {
11
+ bg: "#09090b",
12
+ sf: "#111114",
13
+ sfH: "#18181c",
14
+ bd: "#1e1e24",
15
+ tx: "#e4e4e7",
16
+ tx2: "#a1a1aa",
17
+ txM: "#919199",
18
+ ac: "#e8a845",
19
+ acD: "rgba(232,168,69,0.12)",
20
+ acT: "#fbbf24",
21
+ cdBg: "#0c0c0f",
22
+ cdTx: "#c4c4cc",
23
+ sbBg: "#0c0c0e",
24
+ hdBg: "rgba(9,9,11,0.85)"
25
+ },
26
+ light: {
27
+ bg: "#fafaf9",
28
+ sf: "#ffffff",
29
+ sfH: "#f5f5f4",
30
+ bd: "#e7e5e4",
31
+ tx: "#1c1917",
32
+ tx2: "#57534e",
33
+ txM: "#706b66",
34
+ ac: "#96640a",
35
+ acD: "rgba(150,100,10,0.08)",
36
+ acT: "#7a5208",
37
+ cdBg: "#f5f3f0",
38
+ cdTx: "#2c2520",
39
+ sbBg: "#f5f5f3",
40
+ hdBg: "rgba(250,250,249,0.85)"
41
+ },
42
+ fonts: { heading: "Instrument Serif", body: "DM Sans", code: "JetBrains Mono" }
43
+ },
44
+ editorial: {
45
+ dark: {
46
+ bg: "#080c1f",
47
+ sf: "#0e1333",
48
+ sfH: "#141940",
49
+ bd: "#1a2050",
50
+ tx: "#e8e6f0",
51
+ tx2: "#b5b1c8",
52
+ txM: "#9490ae",
53
+ ac: "#ff6b4a",
54
+ acD: "rgba(255,107,74,0.1)",
55
+ acT: "#ff8a70",
56
+ cdBg: "#0a0e27",
57
+ cdTx: "#b8b4cc",
58
+ sbBg: "#0a0e27",
59
+ hdBg: "rgba(8,12,31,0.9)"
60
+ },
61
+ light: {
62
+ bg: "#f6f4f0",
63
+ sf: "#ffffff",
64
+ sfH: "#eeece6",
65
+ bd: "#ddd9d0",
66
+ tx: "#1a1716",
67
+ tx2: "#4a443e",
68
+ txM: "#706960",
69
+ ac: "#b83d22",
70
+ acD: "rgba(184,61,34,0.07)",
71
+ acT: "#9c3019",
72
+ cdBg: "#edeae4",
73
+ cdTx: "#3a3530",
74
+ sbBg: "#f0ede8",
75
+ hdBg: "rgba(246,244,240,0.92)"
76
+ },
77
+ fonts: { heading: "Cormorant Garamond", body: "Bricolage Grotesque", code: "Fira Code" }
78
+ }
79
+ };
80
+ function hexToRgb(hex) {
81
+ const m = /^#([0-9a-f]{6})$/i.exec(hex.trim());
82
+ if (!m) return null;
83
+ const n = parseInt(m[1], 16);
84
+ return [n >> 16 & 255, n >> 8 & 255, n & 255];
85
+ }
86
+ function buildAccentOverride(hex, isDark) {
87
+ const rgb = hexToRgb(hex);
88
+ if (!rgb) return null;
89
+ const [r, g, b] = rgb;
90
+ const acD = `rgba(${r},${g},${b},${isDark ? 0.12 : 0.08})`;
91
+ const factor = isDark ? 1.15 : 0.85;
92
+ const tr = Math.min(255, Math.round(r * factor));
93
+ const tg = Math.min(255, Math.round(g * factor));
94
+ const tb = Math.min(255, Math.round(b * factor));
95
+ const acT = `rgb(${tr},${tg},${tb})`;
96
+ return { ac: hex, acD, acT };
97
+ }
98
+ var Icon = ({ d, size = 16 }) => /* @__PURE__ */ jsx(
99
+ "svg",
100
+ {
101
+ width: size,
102
+ height: size,
103
+ viewBox: "0 0 24 24",
104
+ fill: "none",
105
+ stroke: "currentColor",
106
+ strokeWidth: "1.5",
107
+ strokeLinecap: "round",
108
+ strokeLinejoin: "round",
109
+ children: /* @__PURE__ */ jsx("path", { d })
110
+ }
111
+ );
112
+ var SearchIcon = () => /* @__PURE__ */ jsx(Icon, { d: "M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16ZM21 21l-4.3-4.3" });
113
+ var ChevRight = () => /* @__PURE__ */ jsx(Icon, { d: "M9 18l6-6-6-6", size: 14 });
114
+ var ChevDown = () => /* @__PURE__ */ jsx(Icon, { d: "M6 9l6 6 6-6", size: 14 });
115
+ var MenuIcon = () => /* @__PURE__ */ jsx(Icon, { d: "M3 12h18M3 6h18M3 18h18", size: 20 });
116
+ var XIcon = () => /* @__PURE__ */ jsx(Icon, { d: "M18 6L6 18M6 6l12 12", size: 18 });
117
+ var MoonIcon = () => /* @__PURE__ */ jsx(Icon, { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" });
118
+ var SunIcon = () => /* @__PURE__ */ jsx(Icon, { d: "M12 7a5 5 0 1 0 0 10 5 5 0 0 0 0-10Z" });
119
+ var ArrowLeft = () => /* @__PURE__ */ jsx(Icon, { d: "M19 12H5M12 19l-7-7 7-7", size: 14 });
120
+ var ArrowRight = () => /* @__PURE__ */ jsx(Icon, { d: "M5 12h14M12 5l7 7-7 7", size: 14 });
121
+ function Shell({
122
+ config: config2,
123
+ navigation: navigation2,
124
+ currentPageId,
125
+ pageHtml,
126
+ pageComponent,
127
+ mdxComponents,
128
+ pageTitle,
129
+ pageDescription,
130
+ headings,
131
+ onNavigate,
132
+ allPages
133
+ }) {
134
+ const themeMode = config2.theme?.mode || "auto";
135
+ const [isDark, setDark] = useState(() => {
136
+ if (themeMode === "dark") return true;
137
+ if (themeMode === "light") return false;
138
+ return window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? true;
139
+ });
140
+ const [sbOpen, setSb] = useState(true);
141
+ const [searchOpen, setSearch] = useState(false);
142
+ const [expanded, setExpanded] = useState(navigation2.map((n) => n.section));
143
+ const contentRef = useRef(null);
144
+ const [wide, setWide] = useState(true);
145
+ const preset = config2.theme?.preset || "amber";
146
+ const baseTokens = THEMES[preset]?.[isDark ? "dark" : "light"] || THEMES.amber.dark;
147
+ const accentOverride = config2.theme?.accent ? buildAccentOverride(config2.theme.accent, isDark) : null;
148
+ const t = accentOverride ? { ...baseTokens, ...accentOverride } : baseTokens;
149
+ const presetFonts = THEMES[preset]?.fonts || THEMES.amber.fonts;
150
+ const fonts = {
151
+ heading: config2.theme?.fonts?.heading || presetFonts.heading,
152
+ body: config2.theme?.fonts?.body || presetFonts.body,
153
+ code: config2.theme?.fonts?.code || presetFonts.code
154
+ };
155
+ useEffect(() => {
156
+ if (themeMode !== "auto") return;
157
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
158
+ const handler = (e) => setDark(e.matches);
159
+ mq.addEventListener("change", handler);
160
+ return () => mq.removeEventListener("change", handler);
161
+ }, [themeMode]);
162
+ useEffect(() => {
163
+ const c = () => setWide(window.innerWidth > 1100);
164
+ c();
165
+ window.addEventListener("resize", c);
166
+ return () => window.removeEventListener("resize", c);
167
+ }, []);
168
+ useEffect(() => {
169
+ contentRef.current?.scrollTo(0, 0);
170
+ }, [currentPageId]);
171
+ useEffect(() => {
172
+ const h = (e) => {
173
+ if ((e.metaKey || e.ctrlKey) && e.key === "k") {
174
+ e.preventDefault();
175
+ setSearch(true);
176
+ }
177
+ if (e.key === "Escape") setSearch(false);
178
+ };
179
+ window.addEventListener("keydown", h);
180
+ return () => window.removeEventListener("keydown", h);
181
+ }, []);
182
+ const allNavPages = navigation2.flatMap((g) => g.pages);
183
+ const idx = allNavPages.findIndex((p) => p.id === currentPageId);
184
+ const prev = idx > 0 ? allNavPages[idx - 1] : null;
185
+ const next = idx < allNavPages.length - 1 ? allNavPages[idx + 1] : null;
186
+ const togSec = (s) => setExpanded((p) => p.includes(s) ? p.filter((x) => x !== s) : [...p, s]);
187
+ const cssVars = {
188
+ "--bg": t.bg,
189
+ "--sf": t.sf,
190
+ "--sfH": t.sfH,
191
+ "--bd": t.bd,
192
+ "--tx": t.tx,
193
+ "--tx2": t.tx2,
194
+ "--txM": t.txM,
195
+ "--ac": t.ac,
196
+ "--acD": t.acD,
197
+ "--acT": t.acT,
198
+ "--cdBg": t.cdBg,
199
+ "--cdTx": t.cdTx,
200
+ "--sbBg": t.sbBg,
201
+ "--hdBg": t.hdBg,
202
+ "--font-heading": `"${fonts.heading}", serif`,
203
+ "--font-body": `"${fonts.body}", sans-serif`,
204
+ "--font-code": `"${fonts.code}", monospace`
205
+ };
206
+ const PageComponent = pageComponent;
207
+ return /* @__PURE__ */ jsxs("div", { style: { ...cssVars, color: "var(--tx)", background: "var(--bg)", fontFamily: "var(--font-body)", minHeight: "100vh" }, children: [
208
+ searchOpen && /* @__PURE__ */ jsx(
209
+ SearchModal,
210
+ {
211
+ allPages,
212
+ onNavigate: (id) => {
213
+ onNavigate(id);
214
+ setSearch(false);
215
+ },
216
+ onClose: () => setSearch(false)
217
+ }
218
+ ),
219
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", height: "100vh" }, children: [
220
+ /* @__PURE__ */ jsxs("aside", { style: {
221
+ width: sbOpen ? 260 : 0,
222
+ minWidth: sbOpen ? 260 : 0,
223
+ background: "var(--sbBg)",
224
+ borderRight: "1px solid var(--bd)",
225
+ display: "flex",
226
+ flexDirection: "column",
227
+ transition: "width .2s, min-width .2s",
228
+ overflow: "hidden"
229
+ }, children: [
230
+ /* @__PURE__ */ jsx("div", { style: { padding: "16px 18px", display: "flex", alignItems: "center", gap: 8, borderBottom: "1px solid var(--bd)" }, children: /* @__PURE__ */ jsx("span", { style: { fontFamily: "var(--font-heading)", fontSize: 20, fontWeight: 700, fontStyle: "italic" }, children: config2.name }) }),
231
+ /* @__PURE__ */ jsx("div", { style: { padding: "10px 12px" }, children: /* @__PURE__ */ jsxs("button", { onClick: () => setSearch(true), style: {
232
+ display: "flex",
233
+ alignItems: "center",
234
+ gap: 8,
235
+ width: "100%",
236
+ background: "var(--cdBg)",
237
+ border: "1px solid var(--bd)",
238
+ borderRadius: 6,
239
+ padding: "7px 10px",
240
+ cursor: "pointer",
241
+ color: "var(--txM)",
242
+ fontSize: 13,
243
+ fontFamily: "var(--font-body)"
244
+ }, children: [
245
+ /* @__PURE__ */ jsx(SearchIcon, {}),
246
+ /* @__PURE__ */ jsx("span", { style: { flex: 1, textAlign: "left" }, children: "Search..." }),
247
+ /* @__PURE__ */ jsx("kbd", { style: { fontFamily: "var(--font-code)", fontSize: 10, background: "var(--sf)", border: "1px solid var(--bd)", borderRadius: 3, padding: "1px 5px" }, children: "\u2318K" })
248
+ ] }) }),
249
+ /* @__PURE__ */ jsx("nav", { style: { flex: 1, overflow: "auto", padding: "4px 8px 16px" }, children: navigation2.map((sec) => /* @__PURE__ */ jsxs("div", { style: { marginBottom: 4 }, children: [
250
+ /* @__PURE__ */ jsxs("button", { onClick: () => togSec(sec.section), style: {
251
+ display: "flex",
252
+ alignItems: "center",
253
+ gap: 6,
254
+ width: "100%",
255
+ background: "none",
256
+ border: "none",
257
+ padding: "6px 8px",
258
+ cursor: "pointer",
259
+ borderRadius: 4,
260
+ color: "var(--txM)",
261
+ fontSize: 11,
262
+ fontWeight: 600,
263
+ textTransform: "uppercase",
264
+ letterSpacing: ".06em",
265
+ fontFamily: "var(--font-body)"
266
+ }, children: [
267
+ expanded.includes(sec.section) ? /* @__PURE__ */ jsx(ChevDown, {}) : /* @__PURE__ */ jsx(ChevRight, {}),
268
+ sec.section
269
+ ] }),
270
+ expanded.includes(sec.section) && /* @__PURE__ */ jsx("div", { style: { paddingLeft: 8 }, children: sec.pages.map((p) => {
271
+ const active = currentPageId === p.id;
272
+ return /* @__PURE__ */ jsx("button", { onClick: () => onNavigate(p.id), style: {
273
+ display: "flex",
274
+ alignItems: "center",
275
+ gap: 8,
276
+ width: "100%",
277
+ textAlign: "left",
278
+ background: active ? "var(--acD)" : "none",
279
+ border: "none",
280
+ borderRadius: 5,
281
+ padding: "6px 10px",
282
+ cursor: "pointer",
283
+ color: active ? "var(--ac)" : "var(--tx2)",
284
+ fontSize: 13,
285
+ fontWeight: active ? 500 : 400,
286
+ fontFamily: "var(--font-body)",
287
+ transition: "background .1s"
288
+ }, children: p.title }, p.id);
289
+ }) })
290
+ ] }, sec.section)) }),
291
+ /* @__PURE__ */ jsxs("div", { style: { padding: "12px 16px", borderTop: "1px solid var(--bd)", display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
292
+ themeMode === "auto" ? /* @__PURE__ */ jsx("button", { onClick: () => setDark((d) => !d), style: { background: "none", border: "none", color: "var(--txM)", cursor: "pointer", display: "flex" }, children: isDark ? /* @__PURE__ */ jsx(SunIcon, {}) : /* @__PURE__ */ jsx(MoonIcon, {}) }) : /* @__PURE__ */ jsx("div", {}),
293
+ /* @__PURE__ */ jsx("span", { style: { fontFamily: "var(--font-code)", fontSize: 10, color: "var(--txM)" }, children: "v0.1.0" })
294
+ ] })
295
+ ] }),
296
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: [
297
+ /* @__PURE__ */ jsxs("header", { style: {
298
+ display: "flex",
299
+ alignItems: "center",
300
+ gap: 12,
301
+ padding: "10px 24px",
302
+ borderBottom: "1px solid var(--bd)",
303
+ background: "var(--hdBg)",
304
+ backdropFilter: "blur(12px)"
305
+ }, children: [
306
+ /* @__PURE__ */ jsx("button", { onClick: () => setSb(!sbOpen), style: { background: "none", border: "none", color: "var(--txM)", cursor: "pointer", display: "flex" }, children: sbOpen ? /* @__PURE__ */ jsx(XIcon, {}) : /* @__PURE__ */ jsx(MenuIcon, {}) }),
307
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--txM)" }, children: navigation2.map((s) => {
308
+ const f = s.pages.find((p) => p.id === currentPageId);
309
+ if (!f) return null;
310
+ return /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
311
+ /* @__PURE__ */ jsx("span", { children: s.section }),
312
+ /* @__PURE__ */ jsx(ChevRight, {}),
313
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--tx)" }, children: f.title })
314
+ ] }, s.section);
315
+ }) })
316
+ ] }),
317
+ /* @__PURE__ */ jsxs("div", { ref: contentRef, style: { flex: 1, overflow: "auto", display: "flex" }, children: [
318
+ /* @__PURE__ */ jsxs("main", { style: { flex: 1, maxWidth: 760, padding: "40px 48px 80px", margin: "0 auto" }, children: [
319
+ /* @__PURE__ */ jsx("h1", { style: { fontFamily: "var(--font-heading)", fontSize: 38, fontWeight: 400, fontStyle: "italic", lineHeight: 1.15, marginBottom: 8 }, children: pageTitle }),
320
+ pageDescription && /* @__PURE__ */ jsx("p", { style: { fontSize: 16, color: "var(--tx2)", lineHeight: 1.6, marginBottom: 32 }, children: pageDescription }),
321
+ /* @__PURE__ */ jsx("div", { style: { borderTop: "1px solid var(--bd)", paddingTop: 28 }, children: PageComponent ? /* @__PURE__ */ jsx("div", { className: "tome-content", children: /* @__PURE__ */ jsx(PageComponent, { components: mdxComponents || {} }) }) : /* @__PURE__ */ jsx(
322
+ "div",
323
+ {
324
+ className: "tome-content",
325
+ dangerouslySetInnerHTML: { __html: pageHtml || "" }
326
+ }
327
+ ) }),
328
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", marginTop: 48, paddingTop: 24, borderTop: "1px solid var(--bd)", gap: 16 }, children: [
329
+ prev ? /* @__PURE__ */ jsxs("button", { onClick: () => onNavigate(prev.id), style: {
330
+ display: "flex",
331
+ alignItems: "center",
332
+ gap: 8,
333
+ background: "none",
334
+ border: "1px solid var(--bd)",
335
+ borderRadius: 6,
336
+ padding: "10px 16px",
337
+ cursor: "pointer",
338
+ color: "var(--tx2)",
339
+ fontSize: 13,
340
+ fontFamily: "var(--font-body)"
341
+ }, children: [
342
+ /* @__PURE__ */ jsx(ArrowLeft, {}),
343
+ " ",
344
+ prev.title
345
+ ] }) : /* @__PURE__ */ jsx("div", {}),
346
+ next ? /* @__PURE__ */ jsxs("button", { onClick: () => onNavigate(next.id), style: {
347
+ display: "flex",
348
+ alignItems: "center",
349
+ gap: 8,
350
+ background: "none",
351
+ border: "1px solid var(--bd)",
352
+ borderRadius: 6,
353
+ padding: "10px 16px",
354
+ cursor: "pointer",
355
+ color: "var(--tx2)",
356
+ fontSize: 13,
357
+ fontFamily: "var(--font-body)"
358
+ }, children: [
359
+ next.title,
360
+ " ",
361
+ /* @__PURE__ */ jsx(ArrowRight, {})
362
+ ] }) : /* @__PURE__ */ jsx("div", {})
363
+ ] })
364
+ ] }),
365
+ headings.length > 0 && wide && /* @__PURE__ */ jsxs("aside", { style: { width: 200, padding: "40px 16px 40px 0", position: "sticky", top: 0, alignSelf: "flex-start", flexShrink: 0 }, children: [
366
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".08em", color: "var(--txM)", marginBottom: 12 }, children: "On this page" }),
367
+ headings.map((h, i) => /* @__PURE__ */ jsx("a", { href: `#${h.id}`, style: {
368
+ display: "block",
369
+ fontSize: 12.5,
370
+ color: "var(--txM)",
371
+ textDecoration: "none",
372
+ padding: "4px 0",
373
+ paddingLeft: (h.depth - 2) * 12,
374
+ lineHeight: 1.4
375
+ }, children: h.text }, i))
376
+ ] })
377
+ ] })
378
+ ] })
379
+ ] })
380
+ ] });
381
+ }
382
+ function SearchModal({ allPages, onNavigate, onClose }) {
383
+ const [q, setQ] = useState("");
384
+ const ref = useRef(null);
385
+ useEffect(() => {
386
+ setTimeout(() => ref.current?.focus(), 50);
387
+ }, []);
388
+ const results = useMemo(() => {
389
+ if (!q.trim()) return [];
390
+ const ql = q.toLowerCase();
391
+ return allPages.filter((p) => p.title.toLowerCase().includes(ql) || (p.description || "").toLowerCase().includes(ql)).slice(0, 8);
392
+ }, [q, allPages]);
393
+ return /* @__PURE__ */ jsx("div", { onClick: onClose, style: {
394
+ position: "fixed",
395
+ inset: 0,
396
+ zIndex: 1e3,
397
+ background: "rgba(0,0,0,0.55)",
398
+ backdropFilter: "blur(6px)",
399
+ display: "flex",
400
+ alignItems: "flex-start",
401
+ justifyContent: "center",
402
+ paddingTop: "12vh"
403
+ }, children: /* @__PURE__ */ jsxs("div", { onClick: (e) => e.stopPropagation(), style: {
404
+ background: "var(--sf)",
405
+ border: "1px solid var(--bd)",
406
+ borderRadius: 12,
407
+ width: "100%",
408
+ maxWidth: 520,
409
+ boxShadow: "0 24px 80px rgba(0,0,0,0.4)",
410
+ overflow: "hidden"
411
+ }, children: [
412
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10, padding: "14px 18px", borderBottom: "1px solid var(--bd)" }, children: [
413
+ /* @__PURE__ */ jsx(SearchIcon, {}),
414
+ /* @__PURE__ */ jsx(
415
+ "input",
416
+ {
417
+ ref,
418
+ value: q,
419
+ onChange: (e) => setQ(e.target.value),
420
+ placeholder: "Search documentation...",
421
+ style: { flex: 1, background: "none", border: "none", outline: "none", color: "var(--tx)", fontSize: 15, fontFamily: "var(--font-body)" }
422
+ }
423
+ ),
424
+ /* @__PURE__ */ jsx("kbd", { style: { fontFamily: "var(--font-code)", fontSize: 11, color: "var(--txM)", background: "var(--cdBg)", padding: "2px 6px", borderRadius: 4, border: "1px solid var(--bd)" }, children: "ESC" })
425
+ ] }),
426
+ results.length > 0 && /* @__PURE__ */ jsx("div", { style: { padding: 6, maxHeight: 360, overflow: "auto" }, children: results.map((r) => /* @__PURE__ */ jsxs("button", { onClick: () => onNavigate(r.id), style: {
427
+ display: "block",
428
+ width: "100%",
429
+ textAlign: "left",
430
+ background: "none",
431
+ border: "none",
432
+ borderRadius: 6,
433
+ padding: "10px 14px",
434
+ cursor: "pointer",
435
+ color: "var(--tx)"
436
+ }, children: [
437
+ /* @__PURE__ */ jsx("div", { style: { fontWeight: 500, fontSize: 14, marginBottom: 2 }, children: r.title }),
438
+ r.description && /* @__PURE__ */ jsx("div", { style: { fontSize: 12, color: "var(--txM)", lineHeight: 1.3 }, children: r.description })
439
+ ] }, r.id)) }),
440
+ q && !results.length && /* @__PURE__ */ jsx("div", { style: { padding: "32px 18px", textAlign: "center", color: "var(--txM)", fontSize: 14 }, children: "No results found" })
441
+ ] }) });
442
+ }
443
+
444
+ // src/entry.tsx
445
+ import config from "virtual:tome/config";
446
+ import { routes, navigation } from "virtual:tome/routes";
447
+ import {
448
+ Callout,
449
+ Tabs,
450
+ Card,
451
+ CardGroup,
452
+ Steps,
453
+ Accordion
454
+ } from "@tome/components";
455
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
456
+ var MDX_COMPONENTS = {
457
+ Callout,
458
+ Tabs,
459
+ Card,
460
+ CardGroup,
461
+ Steps,
462
+ Accordion
463
+ };
464
+ var contentStyles = `
465
+ .tome-content h2 { font-size: 1.4em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em; }
466
+ .tome-content h3 { font-size: 1.2em; font-weight: 600; margin-top: 1.5em; margin-bottom: 0.5em; }
467
+ .tome-content h4 { font-size: 1.05em; font-weight: 600; margin-top: 1.2em; margin-bottom: 0.5em; }
468
+ .tome-content p { color: var(--tx2); line-height: 1.75; margin-bottom: 1em; }
469
+ .tome-content a { color: var(--ac); text-decoration: none; }
470
+ .tome-content a:hover { text-decoration: underline; }
471
+ .tome-content ul, .tome-content ol { color: var(--tx2); padding-left: 1.5em; margin-bottom: 1em; }
472
+ .tome-content li { margin-bottom: 0.3em; line-height: 1.7; }
473
+ .tome-content code { font-family: var(--font-code); font-size: 0.88em; background: var(--cdBg); padding: 0.15em 0.4em; border-radius: 4px; color: var(--ac); }
474
+ .tome-content pre { margin-bottom: 1.2em; border-radius: 8px; overflow-x: auto; border: 1px solid var(--bd); }
475
+ .tome-content pre code { background: none; padding: 1em 1.2em; display: block; font-size: 13px; line-height: 1.65; color: var(--cdTx); }
476
+ .tome-content blockquote { border-left: 3px solid var(--ac); padding: 0.5em 1em; margin: 1em 0; background: var(--acD); border-radius: 0 6px 6px 0; }
477
+ .tome-content blockquote p { color: var(--tx2); margin: 0; }
478
+ .tome-content table { width: 100%; border-collapse: collapse; margin-bottom: 1em; }
479
+ .tome-content th, .tome-content td { padding: 0.5em 0.8em; border: 1px solid var(--bd); text-align: left; font-size: 0.9em; }
480
+ .tome-content th { background: var(--sf); font-weight: 600; }
481
+ .tome-content img { max-width: 100%; border-radius: 6px; }
482
+ .tome-content hr { border: none; border-top: 1px solid var(--bd); margin: 2em 0; }
483
+
484
+ /* Shiki dual-theme support */
485
+ .shiki { background: var(--cdBg) !important; }
486
+ html.dark .shiki .shiki-light { display: none; }
487
+ html.light .shiki .shiki-dark { display: none; }
488
+ `;
489
+ async function loadPage(id) {
490
+ try {
491
+ const route = routes.find((r) => r.id === id);
492
+ const mod = await import(
493
+ /* @vite-ignore */
494
+ `virtual:tome/page/${id}`
495
+ );
496
+ if (route?.isMdx && mod.meta) {
497
+ return {
498
+ isMdx: true,
499
+ component: mod.default,
500
+ frontmatter: mod.meta.frontmatter,
501
+ headings: mod.meta.headings
502
+ };
503
+ }
504
+ if (!mod.default) return null;
505
+ return { isMdx: false, ...mod.default };
506
+ } catch (err) {
507
+ console.error(`Failed to load page: ${id}`, err);
508
+ return null;
509
+ }
510
+ }
511
+ function App() {
512
+ const [currentPageId, setCurrentPageId] = useState2(() => {
513
+ const hash = window.location.hash.slice(1);
514
+ if (hash && routes.some((r) => r.id === hash)) return hash;
515
+ return routes[0]?.id || "index";
516
+ });
517
+ const [pageData, setPageData] = useState2(null);
518
+ const [loading, setLoading] = useState2(true);
519
+ const navigateTo = useCallback2(async (id) => {
520
+ setLoading(true);
521
+ setCurrentPageId(id);
522
+ window.location.hash = id;
523
+ const data = await loadPage(id);
524
+ setPageData(data);
525
+ setLoading(false);
526
+ }, []);
527
+ useEffect2(() => {
528
+ navigateTo(currentPageId);
529
+ }, []);
530
+ useEffect2(() => {
531
+ const onHashChange = () => {
532
+ const hash = window.location.hash.slice(1);
533
+ if (hash && hash !== currentPageId) navigateTo(hash);
534
+ };
535
+ window.addEventListener("hashchange", onHashChange);
536
+ return () => window.removeEventListener("hashchange", onHashChange);
537
+ }, [currentPageId, navigateTo]);
538
+ const allPages = routes.map((r) => ({
539
+ id: r.id,
540
+ title: r.frontmatter.title,
541
+ description: r.frontmatter.description
542
+ }));
543
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
544
+ /* @__PURE__ */ jsx2("style", { children: contentStyles }),
545
+ /* @__PURE__ */ jsx2(
546
+ Shell,
547
+ {
548
+ config,
549
+ navigation,
550
+ currentPageId,
551
+ pageHtml: !pageData?.isMdx ? loading ? "<p>Loading...</p>" : pageData?.html || "<p>Page not found</p>" : void 0,
552
+ pageComponent: pageData?.isMdx ? pageData.component : void 0,
553
+ mdxComponents: MDX_COMPONENTS,
554
+ pageTitle: pageData?.frontmatter.title || (loading ? "Loading..." : "Not Found"),
555
+ pageDescription: pageData?.frontmatter.description,
556
+ headings: pageData?.headings || [],
557
+ onNavigate: navigateTo,
558
+ allPages
559
+ }
560
+ )
561
+ ] });
562
+ }
563
+ var container = document.getElementById("tome-root");
564
+ if (container) {
565
+ const root = createRoot(container);
566
+ root.render(/* @__PURE__ */ jsx2(App, {}));
567
+ }
568
+ var entry_default = App;
569
+
570
+ export {
571
+ Shell,
572
+ entry_default
573
+ };