@tomehq/theme 0.4.0 → 0.5.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 (77) hide show
  1. package/CHANGELOG.md +1 -96
  2. package/dist/{chunk-DKSQZLWR.js → chunk-FIUZY65C.js} +74 -5
  3. package/dist/entry.js +1 -1
  4. package/dist/index.d.ts +78 -0
  5. package/dist/index.js +1 -1
  6. package/package.json +3 -3
  7. package/src/Shell.test.tsx +30 -0
  8. package/src/Shell.tsx +2 -2
  9. package/src/entry.tsx +2 -3
  10. package/src/presets.test.ts +4 -2
  11. package/src/presets.ts +30 -0
  12. package/dist/chunk-2APCPR2Y.js +0 -2110
  13. package/dist/chunk-2AXAEADQ.js +0 -2525
  14. package/dist/chunk-2WNOJXK3.js +0 -2581
  15. package/dist/chunk-37JI6XGT.js +0 -1720
  16. package/dist/chunk-3A2LPGUL.js +0 -1991
  17. package/dist/chunk-3I2QTWTW.js +0 -1948
  18. package/dist/chunk-3I4SJMER.js +0 -2538
  19. package/dist/chunk-45M5UIAB.js +0 -2110
  20. package/dist/chunk-462AGU3S.js +0 -1959
  21. package/dist/chunk-5GVQFIPI.js +0 -2581
  22. package/dist/chunk-7MUTU5D4.js +0 -1720
  23. package/dist/chunk-7NQ4IMDY.js +0 -2294
  24. package/dist/chunk-ABNPB6BB.js +0 -2133
  25. package/dist/chunk-BZGWSKT2.js +0 -573
  26. package/dist/chunk-BZIB2LMI.js +0 -2519
  27. package/dist/chunk-CMQCNCSY.js +0 -2127
  28. package/dist/chunk-CTPOZMMK.js +0 -1703
  29. package/dist/chunk-DO544M3G.js +0 -1702
  30. package/dist/chunk-DPKZBFQP.js +0 -1777
  31. package/dist/chunk-EK7PZUEB.js +0 -2147
  32. package/dist/chunk-FMOLIHQF.js +0 -2182
  33. package/dist/chunk-FWBTK5TL.js +0 -1444
  34. package/dist/chunk-GDQIBNX5.js +0 -1962
  35. package/dist/chunk-GHQ2MODM.js +0 -2127
  36. package/dist/chunk-GR2WCRGK.js +0 -2182
  37. package/dist/chunk-H5XZVNBW.js +0 -2291
  38. package/dist/chunk-HNLKDQ64.js +0 -2139
  39. package/dist/chunk-INUMUXN5.js +0 -2095
  40. package/dist/chunk-IW3NHNOQ.js +0 -2187
  41. package/dist/chunk-JA4PMX6M.js +0 -1500
  42. package/dist/chunk-JSPFS7G5.js +0 -2102
  43. package/dist/chunk-JZRT4WNC.js +0 -1441
  44. package/dist/chunk-KQBY2JDB.js +0 -2112
  45. package/dist/chunk-LIMYFTPC.js +0 -1468
  46. package/dist/chunk-LIY62BGC.js +0 -2519
  47. package/dist/chunk-MEP7P6A7.js +0 -1500
  48. package/dist/chunk-MHYKO7KM.js +0 -2570
  49. package/dist/chunk-MSXVVBDW.js +0 -2542
  50. package/dist/chunk-NOZBIES7.js +0 -1948
  51. package/dist/chunk-O4GH3KYX.js +0 -1712
  52. package/dist/chunk-OEDJTH5F.js +0 -2569
  53. package/dist/chunk-OEXM3BEC.js +0 -1702
  54. package/dist/chunk-PGKSFQ7A.js +0 -2459
  55. package/dist/chunk-PIV6CPY2.js +0 -2395
  56. package/dist/chunk-Q7PYTVW3.js +0 -1771
  57. package/dist/chunk-QCWZYABW.js +0 -1468
  58. package/dist/chunk-QYINBNMJ.js +0 -2545
  59. package/dist/chunk-RDF25WB2.js +0 -2085
  60. package/dist/chunk-RKTT3ZEX.js +0 -1500
  61. package/dist/chunk-S47BRMNQ.js +0 -1715
  62. package/dist/chunk-S4ZH5F56.js +0 -1949
  63. package/dist/chunk-SRD7NJHS.js +0 -1949
  64. package/dist/chunk-SWFYJO5H.js +0 -2187
  65. package/dist/chunk-TQDWPSTO.js +0 -2087
  66. package/dist/chunk-TTRXRPP6.js +0 -1941
  67. package/dist/chunk-UKYFJSUA.js +0 -509
  68. package/dist/chunk-VKEQHP2E.js +0 -2133
  69. package/dist/chunk-VUT2FMSI.js +0 -1937
  70. package/dist/chunk-VVCC5JHK.js +0 -1949
  71. package/dist/chunk-W732TVBK.js +0 -1944
  72. package/dist/chunk-X4VQYPKO.js +0 -1768
  73. package/dist/chunk-YX7HV4EP.js +0 -2568
  74. package/dist/chunk-YXKONM3A.js +0 -2192
  75. package/dist/chunk-YZ3P3TNS.js +0 -1760
  76. package/dist/chunk-ZVZ7JN3V.js +0 -2568
  77. package/dist/chunk-ZXW4STTN.js +0 -2568
package/CHANGELOG.md CHANGED
@@ -1,96 +1 @@
1
- # @tomehq/theme
2
-
3
- ## 0.4.0
4
-
5
- ### Minor Changes
6
-
7
- - c4eae3b: Fix client-side navigation race conditions, content flash, and feedback section disappearing
8
-
9
- **Theme:**
10
-
11
- - Replace AbortController with navigation counter pattern for reliable race condition protection during rapid sidebar navigation
12
- - Switch content innerHTML update from `useEffect` to `useLayoutEffect` to prevent visual flash artifacts (thumbs up/down flicker)
13
- - Add `key={currentPageId}` on content div to force DOM recreation on page change
14
- - Change `overflow: hidden` to `overflow: clip` on root container to prevent feedback section from disappearing on scroll
15
- - Move `setCurrentPageId` after page load completes (load-before-push) so sidebar highlighting stays correct during navigation
16
- - Remove stale HTML comparison guard that prevented content updates during rapid navigation
17
- - Add error classes (PageNotFoundError, PageLoadError, NavigationCancelledError) for better error handling
18
-
19
- **Core:**
20
-
21
- - Page loader virtual module now throws `Error("Unknown page: " + id)` for unknown page IDs instead of silently returning null
22
-
23
- **CLI:**
24
-
25
- - Restructure `tome init` scaffolding to use Diataxis framework (tutorials, guides, reference, concepts)
26
- - Add comprehensive starter pages for each Diataxis category
27
- - Add create-tome template with same Diataxis structure
28
-
29
- ### Patch Changes
30
-
31
- - Updated dependencies [c4eae3b]
32
- - @tomehq/core@0.3.4
33
-
34
- ## 0.3.4
35
-
36
- ### Patch Changes
37
-
38
- - f03e6c2: Fix page scrolling beyond viewport bounds in all directions. Lock layout to 100vh with overflow hidden on html, body, and root container.
39
-
40
- ## 0.3.3
41
-
42
- ### Patch Changes
43
-
44
- - 062349c: Fix MCP server stdout corruption, add dashboard mobile responsiveness, improve test coverage, and update docs.
45
-
46
- - Fix: MCP CLI banner no longer writes to stdout, preventing JSON-RPC protocol corruption
47
- - Fix: API Playground prop wiring and githubSource route crash
48
- - Feat: MCP server `createMcpServer()` exported for programmatic use with graceful shutdown
49
- - Feat: Dashboard mobile-responsive layout with media query breakpoints
50
- - Feat: 13 MCP server integration tests using InMemoryTransport
51
- - Docs: Add missing typedoc CLI command, fix social link examples, update package list
52
-
53
- - Updated dependencies [062349c]
54
- - @tomehq/core@0.3.3
55
- - @tomehq/components@0.3.3
56
-
57
- ## 0.2.8
58
-
59
- ### Minor Changes
60
-
61
- - Replace hash-based SPA routing with History API (pushState + popstate + pathname parsing)
62
- - Content link interception: in-content markdown links navigate via SPA instead of full page reload
63
- - Banner link internal navigation support
64
- - Algolia search basePath stripping for correct page ID extraction
65
- - Extract routing helpers (`pathnameToPageId`, `pageIdToPath`) into testable `routing.ts` module
66
- - Extract entry helpers (`loadPage`, `computeEditUrl`, `resolveInitialPageId`, `detectCurrentVersion`) into testable `entry-helpers.ts` module
67
- - Pass `basePath` prop through Shell for correct URL construction
68
- - Updated dependencies
69
- - @tomehq/core@0.2.8
70
- - @tomehq/components@0.2.8
71
-
72
- ## 0.2.0
73
-
74
- ### Minor Changes
75
-
76
- - Shell: logo links back to landing page, dynamic version in sidebar footer
77
- - Shell: edit link support, table of contents depth config, changelog page layout
78
- - Entry: pass new config fields (editLink, tableOfContents, plugins) to Shell
79
- - Updated dependencies
80
- - @tomehq/core@0.2.0
81
- - @tomehq/components@0.2.0
82
-
83
- ## 0.1.2
84
-
85
- ### Patch Changes
86
-
87
- - Updated dependencies
88
- - @tomehq/components@0.1.1
89
-
90
- ## 0.1.1
91
-
92
- ### Patch Changes
93
-
94
- - Fix bugs found in functionality audit: invalid search provider, AI key naming mismatch, hardcoded version. Remove dead billing stubs. Add 57 API route tests.
95
- - Updated dependencies
96
- - @tomehq/core@0.1.1
1
+ # Changelog
@@ -76,6 +76,76 @@ var THEME_PRESETS = {
76
76
  hdBg: "rgba(246,244,240,0.92)"
77
77
  },
78
78
  fonts: { heading: "Cormorant Garamond", body: "Bricolage Grotesque", code: "Fira Code" }
79
+ },
80
+ cipher: {
81
+ dark: {
82
+ bg: "#050508",
83
+ sf: "#0c0c12",
84
+ sfH: "#12121a",
85
+ bd: "#1a1a25",
86
+ tx: "#d4ff00",
87
+ tx2: "#8a90a0",
88
+ txM: "#6a7080",
89
+ ac: "#6666ff",
90
+ acD: "rgba(102,102,255,0.10)",
91
+ acT: "#8080ff",
92
+ cdBg: "#08080e",
93
+ cdTx: "#b0c870",
94
+ sbBg: "#08080d",
95
+ hdBg: "rgba(5,5,8,0.88)"
96
+ },
97
+ light: {
98
+ bg: "#f0f2f5",
99
+ sf: "#ffffff",
100
+ sfH: "#e8eaef",
101
+ bd: "#d0d4db",
102
+ tx: "#0f1219",
103
+ tx2: "#4a5060",
104
+ txM: "#6a7080",
105
+ ac: "#2020cc",
106
+ acD: "rgba(32,32,204,0.08)",
107
+ acT: "#1a1aa8",
108
+ cdBg: "#e6e9ef",
109
+ cdTx: "#2a3520",
110
+ sbBg: "#ebedf2",
111
+ hdBg: "rgba(240,242,245,0.90)"
112
+ },
113
+ fonts: { heading: "Bodoni Moda", body: "Space Grotesk", code: "Source Code Pro" }
114
+ },
115
+ mint: {
116
+ dark: {
117
+ bg: "#0d1117",
118
+ sf: "#161b22",
119
+ sfH: "#1c2129",
120
+ bd: "#21262d",
121
+ tx: "#e6edf3",
122
+ tx2: "#8b949e",
123
+ txM: "#6e7681",
124
+ ac: "#0ea371",
125
+ acD: "rgba(14,163,113,0.10)",
126
+ acT: "#2dd4a0",
127
+ cdBg: "#0a0e14",
128
+ cdTx: "#adbac7",
129
+ sbBg: "#0d1117",
130
+ hdBg: "rgba(13,17,23,0.88)"
131
+ },
132
+ light: {
133
+ bg: "#ffffff",
134
+ sf: "#f6f8fa",
135
+ sfH: "#eef1f5",
136
+ bd: "#d8dee4",
137
+ tx: "#1f2328",
138
+ tx2: "#59636e",
139
+ txM: "#6e7681",
140
+ ac: "#0a7b53",
141
+ acD: "rgba(10,123,83,0.07)",
142
+ acT: "#087a50",
143
+ cdBg: "#f0f3f6",
144
+ cdTx: "#24292f",
145
+ sbBg: "#f6f8fa",
146
+ hdBg: "rgba(255,255,255,0.90)"
147
+ },
148
+ fonts: { heading: "Inter", body: "Inter", code: "Fira Code" }
79
149
  }
80
150
  };
81
151
 
@@ -842,7 +912,7 @@ function Shell({
842
912
  const [isDark, setDark] = useState2(() => {
843
913
  if (themeMode === "dark") return true;
844
914
  if (themeMode === "light") return false;
845
- return window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? true;
915
+ return window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? false;
846
916
  });
847
917
  const [mobile, setMobile] = useState2(() => typeof window !== "undefined" && window.innerWidth < 768);
848
918
  const [sbOpen, setSb] = useState2(() => typeof window !== "undefined" && window.innerWidth >= 768);
@@ -1589,7 +1659,7 @@ function Shell({
1589
1659
  }
1590
1660
  ),
1591
1661
  /* @__PURE__ */ jsxs2("div", { ref: contentRef, style: { flex: 1, overflow: "auto", display: "flex" }, children: [
1592
- /* @__PURE__ */ jsxs2("main", { style: { flex: 1, maxWidth: mobile ? "100%" : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }, children: [
1662
+ /* @__PURE__ */ jsxs2("main", { style: { flex: 1, maxWidth: mobile ? "100%" : apiManifest ? 1100 : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }, children: [
1593
1663
  breadcrumbs.length > 0 && /* @__PURE__ */ jsx2("nav", { "aria-label": "Breadcrumbs", "data-testid": "breadcrumbs", style: {
1594
1664
  display: "flex",
1595
1665
  alignItems: "center",
@@ -2064,14 +2134,13 @@ var MDX_COMPONENTS = {
2064
2134
  CardGrid
2065
2135
  };
2066
2136
  var contentStyles = `
2067
- @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');
2137
+ @import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&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&family=Bodoni+Moda:ital,wght@0,400;0,700;0,900;1,400&family=Space+Grotesk:wght@400;500;600;700&family=Source+Code+Pro:wght@400;500;600&family=Inter:wght@300;400;500;600;700&display=swap');
2068
2138
 
2069
2139
  html, body { margin: 0; padding: 0; height: 100%; overflow: clip; }
2070
2140
  #tome-root { height: 100%; overflow: clip; }
2071
2141
 
2072
2142
  .tome-content h1 { display: none; }
2073
- .tome-content h2 { font-family: var(--font-body); font-size: 1.35em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em; display: flex; align-items: center; gap: 10px; letter-spacing: 0.01em; }
2074
- .tome-content h2::before { content: "#"; font-family: var(--font-heading); font-size: 1.2em; font-weight: 300; font-style: italic; color: var(--ac); opacity: 0.5; }
2143
+ .tome-content h2 { font-family: var(--font-body); font-size: 1.35em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em; letter-spacing: 0.01em; }
2075
2144
  .tome-content h3 { font-family: var(--font-body); font-size: 1.15em; font-weight: 600; margin-top: 1.5em; margin-bottom: 0.5em; }
2076
2145
  .tome-content h4 { font-family: var(--font-body); font-size: 1.05em; font-weight: 600; margin-top: 1.2em; margin-bottom: 0.5em; }
2077
2146
  .tome-content p { color: var(--tx2); line-height: 1.8; margin-bottom: 1em; font-size: 14.5px; }
package/dist/entry.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  entry_default
3
- } from "./chunk-DKSQZLWR.js";
3
+ } from "./chunk-FIUZY65C.js";
4
4
  export {
5
5
  entry_default as default
6
6
  };
package/dist/index.d.ts CHANGED
@@ -252,6 +252,84 @@ declare const THEME_PRESETS: {
252
252
  readonly code: "Fira Code";
253
253
  };
254
254
  };
255
+ readonly cipher: {
256
+ readonly dark: {
257
+ readonly bg: "#050508";
258
+ readonly sf: "#0c0c12";
259
+ readonly sfH: "#12121a";
260
+ readonly bd: "#1a1a25";
261
+ readonly tx: "#d4ff00";
262
+ readonly tx2: "#8a90a0";
263
+ readonly txM: "#6a7080";
264
+ readonly ac: "#6666ff";
265
+ readonly acD: "rgba(102,102,255,0.10)";
266
+ readonly acT: "#8080ff";
267
+ readonly cdBg: "#08080e";
268
+ readonly cdTx: "#b0c870";
269
+ readonly sbBg: "#08080d";
270
+ readonly hdBg: "rgba(5,5,8,0.88)";
271
+ };
272
+ readonly light: {
273
+ readonly bg: "#f0f2f5";
274
+ readonly sf: "#ffffff";
275
+ readonly sfH: "#e8eaef";
276
+ readonly bd: "#d0d4db";
277
+ readonly tx: "#0f1219";
278
+ readonly tx2: "#4a5060";
279
+ readonly txM: "#6a7080";
280
+ readonly ac: "#2020cc";
281
+ readonly acD: "rgba(32,32,204,0.08)";
282
+ readonly acT: "#1a1aa8";
283
+ readonly cdBg: "#e6e9ef";
284
+ readonly cdTx: "#2a3520";
285
+ readonly sbBg: "#ebedf2";
286
+ readonly hdBg: "rgba(240,242,245,0.90)";
287
+ };
288
+ readonly fonts: {
289
+ readonly heading: "Bodoni Moda";
290
+ readonly body: "Space Grotesk";
291
+ readonly code: "Source Code Pro";
292
+ };
293
+ };
294
+ readonly mint: {
295
+ readonly dark: {
296
+ readonly bg: "#0d1117";
297
+ readonly sf: "#161b22";
298
+ readonly sfH: "#1c2129";
299
+ readonly bd: "#21262d";
300
+ readonly tx: "#e6edf3";
301
+ readonly tx2: "#8b949e";
302
+ readonly txM: "#6e7681";
303
+ readonly ac: "#0ea371";
304
+ readonly acD: "rgba(14,163,113,0.10)";
305
+ readonly acT: "#2dd4a0";
306
+ readonly cdBg: "#0a0e14";
307
+ readonly cdTx: "#adbac7";
308
+ readonly sbBg: "#0d1117";
309
+ readonly hdBg: "rgba(13,17,23,0.88)";
310
+ };
311
+ readonly light: {
312
+ readonly bg: "#ffffff";
313
+ readonly sf: "#f6f8fa";
314
+ readonly sfH: "#eef1f5";
315
+ readonly bd: "#d8dee4";
316
+ readonly tx: "#1f2328";
317
+ readonly tx2: "#59636e";
318
+ readonly txM: "#6e7681";
319
+ readonly ac: "#0a7b53";
320
+ readonly acD: "rgba(10,123,83,0.07)";
321
+ readonly acT: "#087a50";
322
+ readonly cdBg: "#f0f3f6";
323
+ readonly cdTx: "#24292f";
324
+ readonly sbBg: "#f6f8fa";
325
+ readonly hdBg: "rgba(255,255,255,0.90)";
326
+ };
327
+ readonly fonts: {
328
+ readonly heading: "Inter";
329
+ readonly body: "Inter";
330
+ readonly code: "Fira Code";
331
+ };
332
+ };
255
333
  };
256
334
  type PresetName = keyof typeof THEME_PRESETS;
257
335
 
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  Shell,
4
4
  THEME_PRESETS,
5
5
  entry_default
6
- } from "./chunk-DKSQZLWR.js";
6
+ } from "./chunk-FIUZY65C.js";
7
7
  export {
8
8
  AiChat,
9
9
  entry_default as App,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomehq/theme",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Tome default theme and React app shell",
5
5
  "type": "module",
6
6
  "main": "./src/index.tsx",
@@ -9,8 +9,8 @@
9
9
  "./entry": "./src/entry.tsx"
10
10
  },
11
11
  "dependencies": {
12
- "@tomehq/core": "0.3.4",
13
- "@tomehq/components": "0.3.3"
12
+ "@tomehq/components": "0.5.0",
13
+ "@tomehq/core": "0.5.0"
14
14
  },
15
15
  "peerDependencies": {
16
16
  "react": "^18.0.0 || ^19.0.0",
@@ -180,6 +180,18 @@ describe("Shell theme mode", () => {
180
180
  const buttons = footer?.querySelectorAll("button");
181
181
  expect(buttons?.length).toBeGreaterThan(0);
182
182
  });
183
+
184
+ it("defaults to light mode when mode is 'auto' and system preference is unavailable", () => {
185
+ const { container } = renderShell({
186
+ config: { ...baseConfig, theme: { preset: "amber", mode: "auto" } },
187
+ });
188
+ // matchMedia mock returns matches: false → light mode
189
+ // In light mode, the root container uses light theme background
190
+ const root = container.firstElementChild as HTMLElement;
191
+ const bg = root?.style.getPropertyValue("--bg");
192
+ // Amber light bg is #fafaf9 (not dark bg #09090b)
193
+ expect(bg).toBe("#fafaf9");
194
+ });
183
195
  });
184
196
 
185
197
  // ── TOC (TOM-52) ──────────────────────────────────────────
@@ -1211,6 +1223,24 @@ describe("Shell API reference rendering", () => {
1211
1223
  expect(screen.queryByTestId("api-playground")).not.toBeInTheDocument();
1212
1224
  expect(screen.queryByTestId("api-auth")).not.toBeInTheDocument();
1213
1225
  });
1226
+
1227
+ it("uses wider max-width for API reference pages", () => {
1228
+ const { container } = renderShell({
1229
+ apiManifest: mockManifest,
1230
+ ApiReferenceComponent: MockApiRef,
1231
+ pageHtml: undefined,
1232
+ });
1233
+ const main = container.querySelector("main") as HTMLElement;
1234
+ expect(main.style.maxWidth).toBe("1100px");
1235
+ });
1236
+
1237
+ it("uses standard max-width for non-API pages", () => {
1238
+ const { container } = renderShell({
1239
+ pageHtml: "<p>Regular prose content</p>",
1240
+ });
1241
+ const main = container.querySelector("main") as HTMLElement;
1242
+ expect(main.style.maxWidth).toBe("760px");
1243
+ });
1214
1244
  });
1215
1245
 
1216
1246
  // ── Content link interception ───────────────────────────────
package/src/Shell.tsx CHANGED
@@ -413,7 +413,7 @@ export function Shell({
413
413
  const [isDark, setDark] = useState(() => {
414
414
  if (themeMode === "dark") return true;
415
415
  if (themeMode === "light") return false;
416
- return window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? true;
416
+ return window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? false;
417
417
  });
418
418
 
419
419
  const [mobile, setMobile] = useState(() => typeof window !== "undefined" && window.innerWidth < 768);
@@ -1127,7 +1127,7 @@ export function Shell({
1127
1127
 
1128
1128
  {/* Content + TOC */}
1129
1129
  <div ref={contentRef} style={{ flex: 1, overflow: "auto", display: "flex" }}>
1130
- <main style={{ flex: 1, maxWidth: mobile ? "100%" : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }}>
1130
+ <main style={{ flex: 1, maxWidth: mobile ? "100%" : apiManifest ? 1100 : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }}>
1131
1131
  {breadcrumbs.length > 0 && (
1132
1132
  <nav aria-label="Breadcrumbs" data-testid="breadcrumbs" style={{
1133
1133
  display: "flex", alignItems: "center", gap: 6,
package/src/entry.tsx CHANGED
@@ -59,14 +59,13 @@ const MDX_COMPONENTS: Record<string, React.ComponentType<any>> = {
59
59
 
60
60
  // ── CONTENT STYLES ───────────────────────────────────────
61
61
  const contentStyles = `
62
- @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');
62
+ @import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&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&family=Bodoni+Moda:ital,wght@0,400;0,700;0,900;1,400&family=Space+Grotesk:wght@400;500;600;700&family=Source+Code+Pro:wght@400;500;600&family=Inter:wght@300;400;500;600;700&display=swap');
63
63
 
64
64
  html, body { margin: 0; padding: 0; height: 100%; overflow: clip; }
65
65
  #tome-root { height: 100%; overflow: clip; }
66
66
 
67
67
  .tome-content h1 { display: none; }
68
- .tome-content h2 { font-family: var(--font-body); font-size: 1.35em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em; display: flex; align-items: center; gap: 10px; letter-spacing: 0.01em; }
69
- .tome-content h2::before { content: "#"; font-family: var(--font-heading); font-size: 1.2em; font-weight: 300; font-style: italic; color: var(--ac); opacity: 0.5; }
68
+ .tome-content h2 { font-family: var(--font-body); font-size: 1.35em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em; letter-spacing: 0.01em; }
70
69
  .tome-content h3 { font-family: var(--font-body); font-size: 1.15em; font-weight: 600; margin-top: 1.5em; margin-bottom: 0.5em; }
71
70
  .tome-content h4 { font-family: var(--font-body); font-size: 1.05em; font-weight: 600; margin-top: 1.2em; margin-bottom: 0.5em; }
72
71
  .tome-content p { color: var(--tx2); line-height: 1.8; margin-bottom: 1em; font-size: 14.5px; }
@@ -11,12 +11,14 @@ const TOKEN_KEYS = [
11
11
 
12
12
  const FONT_KEYS = ["heading", "body", "code"] as const;
13
13
 
14
- const PRESET_NAMES: PresetName[] = ["amber", "editorial"];
14
+ const PRESET_NAMES: PresetName[] = ["amber", "editorial", "cipher", "mint"];
15
15
 
16
16
  describe("THEME_PRESETS", () => {
17
- it("contains both amber and editorial presets", () => {
17
+ it("contains all presets", () => {
18
18
  expect(THEME_PRESETS).toHaveProperty("amber");
19
19
  expect(THEME_PRESETS).toHaveProperty("editorial");
20
+ expect(THEME_PRESETS).toHaveProperty("cipher");
21
+ expect(THEME_PRESETS).toHaveProperty("mint");
20
22
  });
21
23
 
22
24
  for (const name of PRESET_NAMES) {
package/src/presets.ts CHANGED
@@ -46,6 +46,36 @@ export const THEME_PRESETS = {
46
46
  },
47
47
  fonts: { heading: "Cormorant Garamond", body: "Bricolage Grotesque", code: "Fira Code" },
48
48
  },
49
+ cipher: {
50
+ dark: {
51
+ bg:"#050508",sf:"#0c0c12",sfH:"#12121a",bd:"#1a1a25",
52
+ tx:"#d4ff00",tx2:"#8a90a0",txM:"#6a7080",
53
+ ac:"#6666ff",acD:"rgba(102,102,255,0.10)",acT:"#8080ff",
54
+ cdBg:"#08080e",cdTx:"#b0c870",sbBg:"#08080d",hdBg:"rgba(5,5,8,0.88)",
55
+ },
56
+ light: {
57
+ bg:"#f0f2f5",sf:"#ffffff",sfH:"#e8eaef",bd:"#d0d4db",
58
+ tx:"#0f1219",tx2:"#4a5060",txM:"#6a7080",
59
+ ac:"#2020cc",acD:"rgba(32,32,204,0.08)",acT:"#1a1aa8",
60
+ cdBg:"#e6e9ef",cdTx:"#2a3520",sbBg:"#ebedf2",hdBg:"rgba(240,242,245,0.90)",
61
+ },
62
+ fonts: { heading: "Bodoni Moda", body: "Space Grotesk", code: "Source Code Pro" },
63
+ },
64
+ mint: {
65
+ dark: {
66
+ bg:"#0d1117",sf:"#161b22",sfH:"#1c2129",bd:"#21262d",
67
+ tx:"#e6edf3",tx2:"#8b949e",txM:"#6e7681",
68
+ ac:"#0ea371",acD:"rgba(14,163,113,0.10)",acT:"#2dd4a0",
69
+ cdBg:"#0a0e14",cdTx:"#adbac7",sbBg:"#0d1117",hdBg:"rgba(13,17,23,0.88)",
70
+ },
71
+ light: {
72
+ bg:"#ffffff",sf:"#f6f8fa",sfH:"#eef1f5",bd:"#d8dee4",
73
+ tx:"#1f2328",tx2:"#59636e",txM:"#6e7681",
74
+ ac:"#0a7b53",acD:"rgba(10,123,83,0.07)",acT:"#087a50",
75
+ cdBg:"#f0f3f6",cdTx:"#24292f",sbBg:"#f6f8fa",hdBg:"rgba(255,255,255,0.90)",
76
+ },
77
+ fonts: { heading: "Inter", body: "Inter", code: "Fira Code" },
78
+ },
49
79
  } as const satisfies Record<string, ThemePreset>;
50
80
 
51
81
  export type PresetName = keyof typeof THEME_PRESETS;